diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000..3330a74c --- /dev/null +++ b/.editorconfig @@ -0,0 +1,9 @@ +root = true + +[*.yml] +indent_size = 2 +indent_style = space + +[*.sh] +indent_size = 4 +indent_style = tab diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000..6c414dd6 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +vars/secrets.yml diff=ansible-vault merge=ansible-vault \ No newline at end of file diff --git a/.gitignore b/.gitignore index d777887b..d4cd74b0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,11 @@ keys/* +keys* +include bin/ lib/ +*.retry +keys/ +production +_vault_pass +_secrets.yml +share/ diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/.nojekyll @@ -0,0 +1 @@ + diff --git a/.prettierrc.yml b/.prettierrc.yml new file mode 100644 index 00000000..3ab655a8 --- /dev/null +++ b/.prettierrc.yml @@ -0,0 +1,4 @@ +trailingComma: "es5" +tabWidth: 2 +semi: true +singleQuote: true \ No newline at end of file diff --git a/README.md b/README.md index cd6c526a..d15da2ba 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,46 @@ -# NaC - Netsoc As Code + -## Architecture Overview \ No newline at end of file +## I'm a new SysAdmin, what the heck do I do? + +* `ssh` into the Ansible control server (currently `control.netsoc.co:2222`) + * `ssh @control.netsoc.co -p 2222 -i ` + * If you have not supplied an SSH key to the Head SysAdmin already: + * Open a PR adding your username and key to `setup-control-host.yml` + +* Clone this repo + +* Run `./start-dev.sh` inside the cloned folder (or `./start-dev.sh fish` to use fish instead of bash) + * You will need to run `./start-dev.sh` to setup the correct Python packages and environment variables. You must do this before beginning any development/deployment + * You will be able to tell you have done this when your terminal prompt looks like this: + * `(NaC) @feynman:~/NaC#` + +* You will need a `keys/` folder which contains SSH keys to target all physical and virtual machines. Ask the Head SysAdmin for this. + * Do **NOT** commit them or remove the `keys/` clause from `.gitignore`. + * Do **NOT** share them with people who are not SysAdmins + * Do **NOT** leave them sitting on a random server somewhere + +* You can peek and edit the vault using `./vault-peek.sh` and `./vault-edit.sh` + +* You can list *.vm.netsoc.co by using `./vm-list.sh` +* You can ssh into *.vm.netsoc.co by running `./vm-ssh.sh `, i.e `./vm-ssh.sh web.infra.netsoc.co` + +* The Proxmox Web UI is available at [`proxmox.netsoc.co`](https://proxmox.netsoc.co). You may need to type `thisisunsafe` (if using Chrome) to get past the SSL warning + +* For your development, you can use `sshfs` / VSCode Remote / `vim` on the control server / a git branch. + * You _will_ need to run your playbooks on the control server + + +## I want to contribute but I'm not a SysAdmin? + +* Consider making an issue or contact us in `#servers` in our [Discord](https://discord.netsoc.co) + * We'll welcome any help! + +## I like this repo and want to learn more about UCC Netsoc + +* Check out our [wiki](https://wiki.netsoc.co) + +## **Important** + +This repo currently contains both playbooks for managing 2019/2020 bare-metal infra and 2020/2021 Proxmox infra. Do not get them confused, have a look at `./hosts` to see what's going on. + +### **Read [wiki.netsoc.co](wiki.netsoc.co)** diff --git a/ansible.cfg b/ansible.cfg new file mode 100644 index 00000000..4e2c204c --- /dev/null +++ b/ansible.cfg @@ -0,0 +1,9 @@ +[defaults] +inventory = ./hosts +nocows = 1 + +# Use the YAML callback plugin. +stdout_callback = debug + +# Use the stdout_callback when running ad-hoc commands. +bin_ansible_callbacks = True diff --git a/bass.fish b/bass.fish new file mode 100644 index 00000000..15a09b3a --- /dev/null +++ b/bass.fish @@ -0,0 +1,34 @@ +# MIT License +# +# Copyright (c) 2017 Eddie Cao +# https://github.com/edc/bass + +function bass + set -l bash_args $argv + set -l bass_debug + if test "$bash_args[1]_" = '-d_' + set bass_debug true + set -e bash_args[1] + end + + set -l script_file (mktemp) + if command -v python3 >/dev/null 2>&1 + command python3 -sS (dirname (status -f))/bass.py $bash_args 3>$script_file + else + command python -sS (dirname (status -f))/bass.py $bash_args 3>$script_file + end + set -l bass_status $status + if test $bass_status -ne 0 + return $bass_status + end + + if test -n "$bass_debug" + cat $script_file + end + source $script_file + command rm $script_file +end + +function __bass_usage + echo "Usage: bass [-d] " +end \ No newline at end of file diff --git a/bass.py b/bass.py new file mode 100644 index 00000000..8a48bdf2 --- /dev/null +++ b/bass.py @@ -0,0 +1,141 @@ +""" +MIT License + +Copyright (c) 2017 Eddie Cao +https://github.com/edc/bass + +To be used with a companion fish function like this: + function refish + set -l _x (python /tmp/bass.py source ~/.nvm/nvim.sh ';' nvm use iojs); source $_x; and rm -f $_x + end +""" + +from __future__ import print_function + +import json +import os +import signal +import subprocess +import sys +import traceback + + +BASH = 'bash' + +FISH_READONLY = [ + 'PWD', 'SHLVL', 'history', 'pipestatus', 'status', 'version', + 'FISH_VERSION', 'fish_pid', 'hostname', '_', 'fish_private_mode' +] + +IGNORED = [ + 'PS1', 'XPC_SERVICE_NAME' +] + +def ignored(name): + if name == 'PWD': # this is read only, but has special handling + return False + # ignore other read only variables + if name in FISH_READONLY: + return True + if name in IGNORED or name.startswith("BASH_FUNC"): + return True + return False + +def escape(string): + # use json.dumps to reliably escape quotes and backslashes + return json.dumps(string).replace(r'$', r'\$') + +def escape_identifier(word): + return escape(word.replace('?', '\\?')) + +def comment(string): + return '\n'.join(['# ' + line for line in string.split('\n')]) + +def gen_script(): + # Use the following instead of /usr/bin/env to read environment so we can + # deal with multi-line environment variables (and other odd cases). + env_reader = "%s -c 'import os,json; print(json.dumps({k:v for k,v in os.environ.items()}))'" % (sys.executable) + args = [BASH, '-c', env_reader] + output = subprocess.check_output(args, universal_newlines=True) + old_env = output.strip() + + pipe_r, pipe_w = os.pipe() + if sys.version_info >= (3, 4): + os.set_inheritable(pipe_w, True) + command = 'eval $1 && ({}; alias) >&{}'.format( + env_reader, + pipe_w + ) + args = [BASH, '-c', command, 'bass', ' '.join(sys.argv[1:])] + p = subprocess.Popen(args, universal_newlines=True, close_fds=False) + os.close(pipe_w) + with os.fdopen(pipe_r) as f: + new_env = f.readline() + alias_str = f.read() + if p.wait() != 0: + raise subprocess.CalledProcessError( + returncode=p.returncode, + cmd=' '.join(sys.argv[1:]), + output=new_env + alias_str + ) + new_env = new_env.strip() + + old_env = json.loads(old_env) + new_env = json.loads(new_env) + + script_lines = [] + + for k, v in new_env.items(): + if ignored(k): + continue + v1 = old_env.get(k) + if not v1: + script_lines.append(comment('adding %s=%s' % (k, v))) + elif v1 != v: + script_lines.append(comment('updating %s=%s -> %s' % (k, v1, v))) + # process special variables + if k == 'PWD': + script_lines.append('cd %s' % escape(v)) + continue + else: + continue + if k == 'PATH': + value = ' '.join([escape(directory) + for directory in v.split(':')]) + else: + value = escape(v) + script_lines.append('set -g -x %s %s' % (k, value)) + + for var in set(old_env.keys()) - set(new_env.keys()): + script_lines.append(comment('removing %s' % var)) + script_lines.append('set -e %s' % var) + + script = '\n'.join(script_lines) + + alias_lines = [] + for line in alias_str.splitlines(): + _, rest = line.split(None, 1) + k, v = rest.split("=", 1) + alias_lines.append("alias " + escape_identifier(k) + "=" + v) + alias = '\n'.join(alias_lines) + + return script + '\n' + alias + +script_file = os.fdopen(3, 'w') + +if not sys.argv[1:]: + print('__bass_usage', file=script_file, end='') + sys.exit(0) + +try: + script = gen_script() +except subprocess.CalledProcessError as e: + sys.exit(e.returncode) +except Exception: + print('Bass internal error!', file=sys.stderr) + raise # traceback will output to stderr +except KeyboardInterrupt: + signal.signal(signal.SIGINT, signal.SIG_DFL) + os.kill(os.getpid(), signal.SIGINT) +else: + script_file.write(script) \ No newline at end of file diff --git a/create-auth.yml b/create-auth.yml deleted file mode 100644 index 7d9dacd9..00000000 --- a/create-auth.yml +++ /dev/null @@ -1,57 +0,0 @@ ---- - - -- name: "Ensure auth server" - hosts: lovelace - roles: - - role: proxmox-infra-cloudinit-vm - vars: - vm: - name: "auth.vm.netsoc.co" - clone: "netsoc-ubuntu-server-{{ inventory_hostname }}" - net: - net0: "virtio,bridge=vmbr0,tag=30" - disks: - virtio0: - resize: "20G" - virtio1: - pool: local-lvm - definition: "25,format=raw" - cores: 4 - memory: 2048 - description: - groups: - - vm - - auth - - ipaclients - host_vars: - ansible_ssh_private_key_file: "./keys/auth/id_rsa" - cloudinit: - drive_device: ide2 - userdata: | - #cloud-config - users: - - name: netsoc - gecos: Netsoc Management User - primary_group: netsoc - sudo: ALL=(ALL) NOPASSWD:ALL - ssh_authorized_keys: - - {{ lookup('file', './keys/auth/id_rsa.pub') }} - preserve_hostname: false - manage_etc_hosts: true - fqdn: auth.vm.netsoc.co - networkconfig: - version: 2 - ethernets: - ens18: "{{ interfaces.auth.net0 }}" - wait_for_ssh_ip: "{{ interfaces.auth.net0.addresses[0] }}" - vars_files: - - vars/network.yml - - vars/proxmox.yml - - vars/secrets.yml - -- name: "Reload inventory to pull new VMs" - hosts: 127.0.0.1 - connection: local - tasks: - - meta: refresh_inventory diff --git a/create-databases.yml b/create-databases.yml deleted file mode 100644 index f5e2cb03..00000000 --- a/create-databases.yml +++ /dev/null @@ -1,56 +0,0 @@ -- name: "Ensure databases server" - hosts: lovelace - roles: - - role: proxmox-infra-cloudinit-vm - vars: - vm: - name: "databases.vm.netsoc.co" - clone: "netsoc-ubuntu-server-{{ inventory_hostname }}" - net: - net0: "virtio,bridge=vmbr0,tag={{ vlan.infra }}" - net1: "virtio,bridge=vmbr0,tag={{ vlan.user }}" - disks: - virtio0: - resize: "20G" - virtio1: - pool: local-lvm - definition: "50,format=raw" - cores: 4 - memory: 2048 - description: - groups: - - vm - - databases - - ipaclients - host_vars: - ansible_ssh_private_key_file: "./keys/databases/id_rsa" - cloudinit: - drive_device: ide2 - userdata: | - #cloud-config - users: - - name: netsoc - gecos: Netsoc Management User - primary_group: netsoc - sudo: ALL=(ALL) NOPASSWD:ALL - ssh_authorized_keys: - - {{ lookup('file', './keys/databases/id_rsa.pub') }} - preserve_hostname: false - manage_etc_hosts: true - fqdn: databases.vm.netsoc.co - networkconfig: - version: 2 - ethernets: - ens18: "{{ interfaces.databases.net0 }}" - ens19: "{{ interfaces.databases.net1 }}" - wait_for_ssh_ip: "{{ interfaces.databases.net0.addresses[0] }}" - vars_files: - - vars/network.yml - - vars/proxmox.yml - - vars/secrets.yml - -- name: "Reload inventory to pull new VMs" - hosts: 127.0.0.1 - connection: local - tasks: - - meta: refresh_inventory diff --git a/create-docker-swarm.yml b/create-docker-swarm.yml deleted file mode 100644 index a34c2b09..00000000 --- a/create-docker-swarm.yml +++ /dev/null @@ -1,105 +0,0 @@ ---- - -- name: "Ensure Docker Nodes" - hosts: proxmox_hosts - roles: - # Manager VM - - role: proxmox-infra-cloudinit-vm - when: "ansible_play_hosts_all.index(inventory_hostname) < 3" - vars: - vm: - name: "manager{{ ansible_play_hosts_all.index(inventory_hostname) }}.vm.netsoc.co" - clone: "netsoc-ubuntu-server-{{ inventory_hostname }}" - description: - groups: - - vm - - docker_swarm - - docker_swarm_managers - - ipaclients - host_vars: - ansible_ssh_private_key_file: "./keys/docker_swarm/id_rsa" - net: - net0: "virtio,bridge=vmbr0,tag=30" - disks: - virtio0: - resize: "30G" - cores: 4 - memory: 4096 - cloudinit: - drive_device: ide2 - userdata: | - #cloud-config - users: - - name: netsoc - gecos: Netsoc Management User - primary_group: netsoc - sudo: ALL=(ALL) NOPASSWD:ALL - ssh_authorized_keys: - - "{{ lookup('file', './keys/docker_swarm/id_rsa.pub') }}" - preserve_hostname: false - manage_etc_hosts: true - fqdn: manager{{ ansible_play_hosts_all.index(inventory_hostname) }}.vm.netsoc.co - networkconfig: - version: 2 - ethernets: - ens18: - addresses: - - "{{ interfaces.managerN.net0.addresses[0] | ipmath(ansible_play_hosts_all.index(inventory_hostname)) }}/24" - gateway4: "{{ interfaces.managerN.net0.gateway4 }}" - nameservers: "{{ interfaces.managerN.net0.nameservers }}" - optional: true - wait_for_ssh_ip: "{{ interfaces.managerN.net0.addresses[0] | ipmath(ansible_play_hosts_all.index(inventory_hostname)) }}" - # Worker VM - - role: proxmox-infra-cloudinit-vm - when: "ansible_play_hosts_all.index(inventory_hostname) > 3" - vars: - vm: - name: "worker{{ ansible_play_hosts_all.index(inventory_hostname) }}.vm.netsoc.co" - clone: "netsoc-ubuntu-server-{{ inventory_hostname }}" - description: - groups: - - vm - - docker_swarm - - docker_workers - vars: - ansible_ssh_private_key_file: "./keys/docker_swarm/id_rsa" - net: - net0: "virtio,bridge=vmbr0,tag=30" - resize_disks: - virtio0: "20G" - cores: 4 - memory: 4096 - cloudinit: - cloudinit_device: ide2 - userdata: | - #cloud-config - users: - - name: netsoc - gecos: Netsoc Management User - primary_group: netsoc - sudo: ALL=(ALL) NOPASSWD:ALL - ssh_authorized_keys: - - "{{ lookup('file', './keys/docker_swarm/id_rsa.pub') }}" - preserve_hostname: false - manage_etc_hosts: true - fqdn: worker{{ ansible_play_hosts_all.index(inventory_hostname) }}.vm.netsoc.co - networkconfig: - version: 2 - ethernets: - ens18: - addresses: - - "{{ interfaces.workerN.net0.addresses[0] | ipmath(ansible_play_hosts_all.index(inventory_hostname)) }}/24" - gateway4: "{{ interfaces.workerN.net0.gateway4 }}" - nameservers: "{{ interfaces.workerN.net0.nameservers }}" - optional: true - wait_for_ssh_ip: "{{ interfaces.workerN.net0.addresses[0] | ipmath(ansible_play_hosts_all.index(inventory_hostname)) }}" - vars_files: - - vars/network.yml - - vars/proxmox.yml - - vars/secrets.yml - -- name: "Reload inventory to pull new VMs" - hosts: 127.0.0.1 - connection: local - tasks: - - meta: refresh_inventory \ No newline at end of file diff --git a/create-games.yml b/create-games.yml deleted file mode 100644 index 7f0ae41d..00000000 --- a/create-games.yml +++ /dev/null @@ -1,56 +0,0 @@ ---- - -- name: "Ensure games server" - hosts: lovelace - roles: - - role: proxmox-infra-cloudinit-vm - vars: - vm: - name: "games.vm.netsoc.co" - clone: "netsoc-ubuntu-server-{{ inventory_hostname }}" - net: - net0: "virtio,bridge=vmbr0,tag=30" - disks: - virtio0: - resize: "20G" - virtio1: - pool: local-lvm - definition: "50,format=raw" - cores: 4 - memory: 2048 - description: - groups: - - vm - - games - - ipaclients - host_vars: - ansible_ssh_private_key_file: "./keys/games/id_rsa" - cloudinit: - drive_device: ide2 - userdata: | - #cloud-config - users: - - name: netsoc - gecos: Netsoc Management User - primary_group: netsoc - sudo: ALL=(ALL) NOPASSWD:ALL - ssh_authorized_keys: - - {{ lookup('file', './keys/games/id_rsa.pub') }} - preserve_hostname: false - manage_etc_hosts: true - fqdn: games.vm.netsoc.co - networkconfig: - version: 2 - ethernets: - ens18: "{{ interfaces.games.net0 }}" - wait_for_ssh_ip: "{{ interfaces.games.net0.addresses[0] }}" - vars_files: - - vars/network.yml - - vars/proxmox.yml - - vars/secrets.yml - -- name: "Reload inventory to pull new VMs" - hosts: 127.0.0.1 - connection: local - tasks: - - meta: refresh_inventory diff --git a/create-infra-databases.yml b/create-infra-databases.yml new file mode 100644 index 00000000..fb8f8f7a --- /dev/null +++ b/create-infra-databases.yml @@ -0,0 +1,86 @@ +--- + +- name: "INFRA - Ensure databases server" + hosts: lovelace + roles: + - role: proxmox-cloudinit-vm + vars: + vm: + name: "databases.infra.netsoc.co" + template: + storage: local + image_url: "https://cloud-images.ubuntu.com/releases/focal/release-20200921.1/ubuntu-20.04-server-cloudimg-amd64.img" + image_hash: sha256:d18a9d2b890d3c1401e70a281cae44b61816aa669c4936f7a99c168e572ec8cb + cores: 4 + memory: 4096 + description: + groups: + - vm + - prometheus_base + - prometheus_docker + - promtail + - ipaclients + host_vars: + ansible_ssh_private_key_file: "./keys/infra/databases/id_rsa" + net: + net0: "virtio={{ interfaces.infra.databases.net0.match.macaddress }},tag={{ vlan.infra }},bridge={{ vmbr }}" + disks: + boot: + size: 30 + extra: + - size: 50 + cloudinit: + storage: local + force: yes + userdata: | + #cloud-config + preserve_hostname: false + manage_etc_hosts: true + fqdn: databases.infra.netsoc.co + packages: + - qemu-guest-agent + runcmd: + - [ systemctl, enable, qemu-guest-agent ] + - [ systemctl, start, qemu-guest-agent, --no-block ] + users: + - name: netsoc + gecos: Netsoc Management User + primary_group: netsoc + groups: netsoc + shell: /bin/bash + sudo: ALL=(ALL) NOPASSWD:ALL + ssh_authorized_keys: + - "{{ lookup('file', './keys/infra/databases/id_rsa.pub') }}" + apt: + preserve_sources_list: true + primary: + - arches: [default] + uri: http://ie.archive.ubuntu.com/ubuntu/ + security: + - uri: http://security.ubuntu.com/ubuntu + disk_setup: + /dev/vdb: + table_type: 'gpt' + layout: + - [100,83] # 100% Linux fs + overwrite: false + fs_setup: + - label: data-disk + filesystem: ext4 + device: '/dev/vdb1' + overwrite: false + mounts: + - [ vdb, /netsoc, auto ] + networkconfig: + version: 2 + ethernets: "{{ interfaces.infra.databases }}" + vars_files: + - vars/network.yml + - vars/secrets_mapping.yml + - vars/secrets.yml + +- name: "Reload inventory to pull new VMs" + hosts: 127.0.0.1 + connection: local + tasks: + - meta: refresh_inventory diff --git a/create-infra-games.yml b/create-infra-games.yml new file mode 100644 index 00000000..9de272b5 --- /dev/null +++ b/create-infra-games.yml @@ -0,0 +1,85 @@ +--- + +- name: "INFRA - Ensure games server" + hosts: lovelace + roles: + - role: proxmox-cloudinit-vm + vars: + vm: + name: "games.infra.netsoc.co" + template: + storage: local + image_url: "https://cloud-images.ubuntu.com/releases/focal/release-20200921.1/ubuntu-20.04-server-cloudimg-amd64.img" + image_hash: sha256:d18a9d2b890d3c1401e70a281cae44b61816aa669c4936f7a99c168e572ec8cb + cores: 4 + memory: 6144 + description: + groups: + - vm + - promtail + - prometheus_base + - prometheus_docker + host_vars: + ansible_ssh_private_key_file: "./keys/infra/games/id_rsa" + net: + net0: "virtio={{ interfaces.infra.games.net0.match.macaddress }},tag={{ vlan.infra }},bridge={{ vmbr }}" + disks: + boot: + size: 30 + extra: + - size: 45 + cloudinit: + storage: local + force: yes + userdata: | + #cloud-config + preserve_hostname: false + manage_etc_hosts: true + fqdn: games.infra.netsoc.co + packages: + - qemu-guest-agent + runcmd: + - [ systemctl, enable, qemu-guest-agent ] + - [ systemctl, start, qemu-guest-agent, --no-block ] + users: + - name: netsoc + gecos: Netsoc Management User + primary_group: netsoc + groups: netsoc + shell: /bin/bash + sudo: ALL=(ALL) NOPASSWD:ALL + ssh_authorized_keys: + - "{{ lookup('file', './keys/infra/games/id_rsa.pub') }}" + apt: + preserve_sources_list: true + primary: + - arches: [default] + uri: http://ie.archive.ubuntu.com/ubuntu/ + security: + - uri: http://security.ubuntu.com/ubuntu + disk_setup: + /dev/vdb: + table_type: 'gpt' + layout: + - [100,83] # 100% Linux fs + overwrite: false + fs_setup: + - label: data-disk + filesystem: ext4 + device: '/dev/vdb1' + overwrite: false + mounts: + - [ vdb, /netsoc, auto ] + networkconfig: + version: 2 + ethernets: "{{ interfaces.infra.games }}" + vars_files: + - vars/network.yml + - vars/secrets_mapping.yml + - vars/secrets.yml + +- name: "Reload inventory to pull new VMs" + hosts: 127.0.0.1 + connection: local + tasks: + - meta: refresh_inventory diff --git a/create-infra-minecraft.yml b/create-infra-minecraft.yml new file mode 100644 index 00000000..f7f5b191 --- /dev/null +++ b/create-infra-minecraft.yml @@ -0,0 +1,45 @@ +--- +- name: Provision Minecraft LXC Container + hosts: scalper + any_errors_fatal: true + roles: + - role: proxmox-lxc + vars: + lxc: + name: "minecraft.infra.netsoc.co" + storage: local + template: + storage: netsoc-cloud + image: "ubuntu-20.04-standard_20.04-1_amd64.tar.gz" + description: + groups: + - container + - promtail + - prometheus_base + - prometheus_docker + host_vars: + ansible_ssh_private_key_file: "./keys/infra/minecraft/id_rsa" + unprivileged: yes + cores: 8 + memory: 12288 + swap: 4096 + disks: + rootfs: + size: 60 + net: + net0: "name=eth0,ip={{ interfaces.infra.minecraft.net0.addresses[0] }},\ + hwaddr={{ interfaces.infra.minecraft.net0.match.macaddress }},\ + gw={{ interfaces.infra.minecraft.net0.gateway4 }},\ + mtu=1500,\ + tag={{ vlan.infra }},\ + bridge={{ vmbr }},\ + firewall=0" + features: "fuse=1,nesting=1,keyctl=1" + authorized_keys: "{{ lookup('file', '{{ playbook_dir }}/keys/infra/minecraft/id_rsa.pub') }}" + + vars_files: + - vars/network.yml + - vars/secrets_mapping.yml + - vars/secrets.yml + tags: + - always \ No newline at end of file diff --git a/create-infra-web.yml b/create-infra-web.yml new file mode 100644 index 00000000..4b64d230 --- /dev/null +++ b/create-infra-web.yml @@ -0,0 +1,87 @@ +--- + +- name: "INFRA - Ensure web server" + hosts: scalper + roles: + - role: proxmox-cloudinit-vm + vars: + vm: + name: "web.infra.netsoc.co" + storage: local + template: + storage: local + image_url: "https://cloud-images.ubuntu.com/releases/focal/release-20200921.1/ubuntu-20.04-server-cloudimg-amd64.img" + image_hash: sha256:d18a9d2b890d3c1401e70a281cae44b61816aa669c4936f7a99c168e572ec8cb + cores: 4 + memory: 12288 + description: + groups: + - vm + - web + - promtail + - prometheus_base + - prometheus_docker + host_vars: + ansible_ssh_private_key_file: "./keys/infra/web/id_rsa" + net: + net0: "virtio={{ interfaces.infra.web.net0.match.macaddress }},tag={{ vlan.infra }},bridge={{ vmbr }}" + disks: + boot: + size: 45 + extra: + - size: 45 + cloudinit: + storage: local + force: yes + userdata: | + #cloud-config + preserve_hostname: false + manage_etc_hosts: true + fqdn: web.infra.netsoc.co + packages: + - qemu-guest-agent + runcmd: + - [ systemctl, enable, qemu-guest-agent ] + - [ systemctl, start, qemu-guest-agent, --no-block ] + users: + - name: netsoc + gecos: Netsoc Management User + primary_group: netsoc + groups: netsoc + shell: /bin/bash + sudo: ALL=(ALL) NOPASSWD:ALL + ssh_authorized_keys: + - "{{ lookup('file', './keys/infra/web/id_rsa.pub') }}" + apt: + preserve_sources_list: true + primary: + - arches: [default] + uri: http://ie.archive.ubuntu.com/ubuntu/ + security: + - uri: http://security.ubuntu.com/ubuntu + disk_setup: + /dev/vdb: + table_type: 'gpt' + layout: + - [100,83] # 100% Linux fs + overwrite: false + fs_setup: + - label: data-disk + filesystem: ext4 + device: '/dev/vdb1' + overwrite: false + mounts: + - [ vdb, /netsoc, auto ] + networkconfig: + version: 2 + ethernets: "{{ interfaces.infra.web }}" + vars_files: + - vars/network.yml + - vars/secrets_mapping.yml + - vars/secrets.yml + +- name: "Reload inventory to pull new VMs" + hosts: 127.0.0.1 + connection: local + tasks: + - meta: refresh_inventory diff --git a/create-nfs.yml b/create-nfs.yml deleted file mode 100644 index 782fc332..00000000 --- a/create-nfs.yml +++ /dev/null @@ -1,54 +0,0 @@ -- name: "Ensure NFS server" - hosts: lovelace - roles: - - role: proxmox-infra-cloudinit-vm - vars: - vm: - name: "nfs.vm.netsoc.co" - clone: "netsoc-ubuntu-server-{{ inventory_hostname }}" - net: - net0: "virtio,bridge=vmbr0,tag=30" - disks: - virtio0: - resize: "20G" - virtio1: - pool: local-lvm - definition: "50,format=raw" - cores: 4 - memory: 2048 - description: - groups: - - vm - - nfs - - ipaclients - host_vars: - ansible_ssh_private_key_file: "./keys/nfs/id_rsa" - cloudinit: - drive_device: ide2 - userdata: | - #cloud-config - users: - - name: netsoc - gecos: Netsoc Management User - primary_group: netsoc - sudo: ALL=(ALL) NOPASSWD:ALL - ssh_authorized_keys: - - {{ lookup('file', './keys/nfs/id_rsa.pub') }} - preserve_hostname: false - manage_etc_hosts: true - fqdn: nfs.vm.netsoc.co - networkconfig: - version: 2 - ethernets: - ens18: "{{ interfaces.nfs.net0 }}" - wait_for_ssh_ip: "{{ interfaces.nfs.net0.addresses[0] }}" - vars_files: - - vars/network.yml - - vars/proxmox.yml - - vars/secrets.yml - -- name: "Reload inventory to pull new VMs" - hosts: 127.0.0.1 - connection: local - tasks: - - meta: refresh_inventory diff --git a/create-portal.yml b/create-portal.yml deleted file mode 100644 index bad7312f..00000000 --- a/create-portal.yml +++ /dev/null @@ -1,53 +0,0 @@ ---- - -- name: "Ensure Portal server" - hosts: lovelace - roles: - - role: proxmox-infra-cloudinit-vm - vars: - vm: - name: "portal.vm.netsoc.co" - clone: "netsoc-ubuntu-server-{{ inventory_hostname }}" - net: - net0: "virtio,bridge=vmbr0,tag=30" - disks: - virtio0: - resize: "20G" - cores: 4 - memory: 2048 - description: - groups: - - vm - - portal - - ipaclients - host_vars: - ansible_ssh_private_key_file: "./keys/portal/id_rsa" - cloudinit: - drive_device: ide2 - userdata: | - #cloud-config - users: - - name: netsoc - gecos: Netsoc Management User - primary_group: netsoc - sudo: ALL=(ALL) NOPASSWD:ALL - ssh_authorized_keys: - - {{ lookup('file', './keys/portal/id_rsa.pub') }} - preserve_hostname: false - manage_etc_hosts: true - fqdn: portal.vm.netsoc.co - networkconfig: - version: 2 - ethernets: - ens18: "{{ interfaces.portal.net0 }}" - wait_for_ssh_ip: "{{ interfaces.portal.net0.addresses[0] }}" - vars_files: - - vars/network.yml - - vars/proxmox.yml - - vars/secrets.yml - -- name: "Reload inventory to pull new VMs" - hosts: 127.0.0.1 - connection: local - tasks: - - meta: refresh_inventory diff --git a/create-web.yml b/create-web.yml deleted file mode 100644 index 7809137b..00000000 --- a/create-web.yml +++ /dev/null @@ -1,60 +0,0 @@ ---- - -- name: "Ensure Web Nodes" - hosts: proxmox_hosts - roles: - # Manager VM - - role: proxmox-infra-cloudinit-vm - when: "ansible_play_hosts_all.index(inventory_hostname) < 3" - vars: - vm: - name: "web{{ ansible_play_hosts_all.index(inventory_hostname) }}.vm.netsoc.co" - clone: "netsoc-ubuntu-server-{{ inventory_hostname }}" - description: - groups: - - vm - - web - - ipaclients - host_vars: - ansible_ssh_private_key_file: "./keys/web/id_rsa" - net: - net0: "virtio,bridge=vmbr0,tag=30" - disks: - virtio0: - resize: "30G" - cores: 4 - memory: 4096 - cloudinit: - drive_device: ide2 - userdata: | - #cloud-config - users: - - name: netsoc - gecos: Netsoc Management User - primary_group: netsoc - sudo: ALL=(ALL) NOPASSWD:ALL - ssh_authorized_keys: - - "{{ lookup('file', './keys/web/id_rsa.pub') }}" - preserve_hostname: false - manage_etc_hosts: true - fqdn: web{{ ansible_play_hosts_all.index(inventory_hostname) }}.vm.netsoc.co - networkconfig: - version: 2 - ethernets: - ens18: - addresses: - - "{{ interfaces.webN.net0.addresses[0] | ipmath(ansible_play_hosts_all.index(inventory_hostname)) }}/24" - gateway4: "{{ interfaces.webN.net0.gateway4 }}" - nameservers: "{{ interfaces.webN.net0.nameservers }}" - optional: true - wait_for_ssh_ip: "{{ interfaces.webN.net0.addresses[0] }}" - vars_files: - - vars/network.yml - - vars/proxmox.yml - - vars/secrets.yml - -- name: "Reload inventory to pull new VMs" - hosts: 127.0.0.1 - connection: local - tasks: - - meta: refresh_inventory \ No newline at end of file diff --git a/dev-hosts b/dev-hosts new file mode 100644 index 00000000..526798ad --- /dev/null +++ b/dev-hosts @@ -0,0 +1,7 @@ +[all:vars] +ansible_connection=ssh +ansible_user=root +ansible_ssh_pass=vagrant + +[dev] +server ansible_host=10.10.10.2 ansible_port=22 ansible_user=root diff --git a/dev-run.sh b/dev-run.sh new file mode 100755 index 00000000..96a1756d --- /dev/null +++ b/dev-run.sh @@ -0,0 +1,3 @@ +#!/bin/bash +export ANSIBLE_HOST_KEY_CHECKING=False +ansible-playbook -i dev-hosts ${@:1} \ No newline at end of file diff --git a/docs/bootstrapping.md b/docs/bootstrapping.md deleted file mode 100644 index c19e993b..00000000 --- a/docs/bootstrapping.md +++ /dev/null @@ -1,21 +0,0 @@ -Bootstrapping Order - - -Not the scope of this repo --- - -1. Setting up Proxmox cluster - -Scope of this repo --- - -2. Network config once joined into a Proxmox cluster -3. Build packer template for vyos -4. Create router -5. Build packer template for ubuntu -6. Create auth -7. Provision auth -8. Build nfs -9. Provision nfs -8. Build rest -9. Provision ther est \ No newline at end of file diff --git a/docs/infra.md b/docs/infra.md deleted file mode 100644 index ff94957c..00000000 --- a/docs/infra.md +++ /dev/null @@ -1,412 +0,0 @@ -# How UCC Netsoc Does Infrastructure - -This file contains documentation of the redesigned infrastructure for UCC Netsoc (2020/2021). It's ideally targeted at new SysAdmin's or anyone wanting to learn about how we operate - -## Historical Infrastructure - -**You can ignore this section if you wish, it's just to provide context if you come across old stuff we missed/have not yet migrated** - -Prior to 2020/2021, Netsoc ran a completely different setup on bare metal which consisted of 5 bare-metal servers & 2 virtual machines provided by UCC - -Bare-metal machines: - -* **leela** - * 84.39.234.51 - * Our main user server that any of our members can ssh into - * Hosted netsocadmin (v2) - * UCC Express & Motley -* **bigbertha** - * 84.39.234.50 - * CI/related -* **lovelace** - * 84.39.234.52 - * Game server hosting -* **boole** - * 84.39.234.54 - * Monitoring -* **feynman** - * 84.39.234.53 - * Root server for any user - -These machines are hosted in a rack in Cork International eXchange (CIX). -Many previous and current Netsoc members have worked at CIX and are familiar with the data center - -Our point-of-contact with CIX is Jerry McSweeney and noc@cix.ie, lovely chap - -Our UCC VMs: -* **elon / netsoc1.ucc.ie** - * 143.239.87.40 - * LDAP - * MySQL -* **tesla / netsoc2.ucc.ie** - * 143.239.87.41 - * I honestly can't remember, it's semi-perma borked - -We need to figure out our UCC point-of-contact - -The setup consisted of a Docker swarm all of our bare metal servers. - -We did not run a router, just a switch. As such each bare metal server was bound directly to their public IPs - -We decided it was time to completely manage our infrastructure with Infrastructure-As-Code as it would help preserve the server setup over time. We therefore migrated a large amount of our setup to be configured using Ansible in 2019/2020. - -## Core Infrastructure - -We run [Proxmox VE](https://pve.proxmox.com/), a system that abstracts KVM virtual machines and LXC containers into a common set of powerful tools. - -It's also got a _really_ nice web UI. Think of it like an open-source ESXi/vSphere - -Our setup consists of a cluster of Proxmox machines, there currently are as follows: - -* feynman - * Designated as our Ansible control server - * Designated as such because it's a pretty terrible server - * All Ansible playbooks that make changes must be run from here - * Each SysAdmin has a Linux account created on the server to allow them to do development work - * Fair warning: it's disks are slow af -* lovelace - -Servers that still need to become Proxmox cluster hosts (these still run the historical setups): - -* bigbertha -* leela -* boole - -We have not yet decided on what will be done to the UCC VMs. -We currently do _not_ plan on using Ceph (distributed storage) on our cluster. This is because Ceph requires a minimum quorum of 3 servers to operate redundantly. We may use it in the future - -### Short Intro to Ansible (for new SysAdmins) - -[Ansible](https://www.ansible.com/overview/how-ansible-works) is an incredibly powerful IT automation tool we use to configure and install software on servers - -* Servers to target are defined in a file (normally called `hosts`, or by a script), and given aliases and groups. - * Our `hosts` looks a little like this: - ``` - control - - [proxmox_master] - feynman - - [proxmox_hosts] - feynman - lovelace - ``` - * These hosts & groups can have `host_vars` and `group_vars` which apply to any server / server in that group respectively - * Here's an example of `host_vars` for `feynman` (`host_vars/feynman.yml`): - ``` - ansible_host: 10.0.10.53 - ansible_ssh_user: root - ansible_ssh_private_key_file: "/root/.ssh/id_rsa" - ansible_python_interpreter: "/usr/bin/python3" - ``` - * Here's an example of `group_vars` for a group called `vm` (`group_vars/vm.yml`): - ``` - ansible_ssh_common_args: '-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null' - ansible_python_interpreter: "/usr/bin/python3" - ansible_user: netsoc - ``` - * Not only can you make use of explicit variables specify info about the host for Ansible, you can specify your own and access them later -* A _playbook_ consists of a list of _plays_ to run on a host / group of hosts - * An _play_ could be a bunch of _tasks_ or _roles_ - * A _task_ is a call to an Ansible _module_ that does some functionality - * Example, to install the `jq` package: - ``` - apt: - name: jq - state: latest - update_cache: yes - ``` - * It's important to keep the Ansible module documentation open - * [Example](https://docs.ansible.com/ansible/latest/modules/apt_module.html) - * There are modules for *almost everything*, before implementing functionality using a script or shell commands try and see if it can be done using an existing module - * [An example list of some of the most common modules you may use](https://opensource.com/article/19/9/must-know-ansible-modules) - * A _role_ is a grouping of functionality - * It has lists of tasks, files, variables that can be specified when the role is ran - * Think of it almost like a script that accepts arguments - * Example of a role that installs and starts nginx: - ``` - roles/nginx/vars/defaults.yml: - start_on_boot: no - - roles/nginx/tasks/main.yml: - - name: Install nginx package - apt: - name: nginx - state: latest - update_cache: yes - - - name: Start Nginx service (and enable service start on boot if specified) - service: - name: nginx - enabled: "{{ start_on_boot }}" - state: started - ``` - * You could call the previous role as a _play_ in a playbook like so: - ``` - - name: "Ensure nginx on lovelace" - hosts: lovelace - roles: - - role: nginx - vars: - start_on_boot: yes - ``` - * This is the explicit var syntax that scopes the vars to the role, you can also scope the vars to the play - * Here is a list of tasks as a _play_: - ``` - - name: Setup server MOTD - hosts: portal - tasks: - - become: yes - copy: - content: "{{ lookup('file', './portal-banner.txt') }}" - dest: /etc/netsoc-banner - - become: yes - copy: - content: "{{ lookup('file', './portal-motd.txt') }}" - dest: /etc/netsoc-motd - - become: yes - shell: /bin/rm -rf /etc/update-motd.d/* - - become: yes - copy: - content: | - #!/bin/sh - cat /etc/netsoc-motd - mode: "0755" - dest: /etc/update-motd.d/00-netsoc-motd - - become: yes - copy: - content: "" - dest: /etc/legal - - become: yes - lineinfile: - regex: "^#PrintLastLog" - line: "PrintLastLog no" - path: /etc/ssh/sshd_config - - become: yes - lineinfile: - regex: "^#Banner none" - line: "Banner /etc/netsoc-banner" - path: /etc/ssh/sshd_config - - become: yes - service: - name: sshd - state: restarted - ``` - * Don't forget that tasks run after roles if you use them together in a play - * Ansible supports Jinja variable interpolation almost everywhere - * Don't forget to look at [filters](https://docs.ansible.com/ansible/latest/user_guide/playbooks_filters.html#list-filters) - * You can run a playbook by doing `ansible-playbook -i hosts playbook.yml` - * The playbook functionality is a complete IaC addition to Ansible, but you don't actually need to use it - * Ping every server: `ansible -i hosts all -m ping` - * Chmod a.txt to 600: `ansible -i hosts all -m file -a "dest=/srv/foo/a.txt mode=600"` -* Ansible also has a _vault_ for secrets - * This is like a yaml file full of variables we don't reveal, you can edit the vault and when you finish editing it Ansible will encrypt the file - * This lets us store our secrets in GitHub but not reveal them to anyone - * You can edit the vault by doing `ansible-vault edit vars/secrets.yml` - * When you run a playbook, you can enable vault by doing `ansible-playbook -i hosts playbook.yml --ask-vault-pass` - * This will decrypt every vault variable and prefix them with `vault_` - * We normally realias them with the files in `vars/` - * Example: - ``` - cloudflare_api_email: "{{ vault_cloudflare_api_email }}" - cloudflare_api_key: "{{ vault_cloudflare_api_key }}" - cloudflare_dns_api_token: "{{ vault_cloudflare_dns_api_token }}" - ``` - -* **[Keep all operations idempotent, this is the core philosophy to Ansible](https://docs.ansible.com/ansible/latest/reference_appendices/glossary.html#term-idempotency)** - -### How we use IaC (summary) - -* We can define and create a "template" VM that contains pre-installed tools and a base image - * Template VMs are created using [Hashicorp Packer](https://www.packer.io) - * We install the distro OS and then do further provisioning via Ansible/shell scripts - * We do not call the Packer executable directly, we instead use an Ansible role we created `packer-proxmox-template` - * Packer doesn't support saving the VM template to a distributed storage - * Not that we're using one, yet - * For a given template i.e `netsoc-centos-6`, we will first build the template on a specified server under the name `netsoc-centos-6-` - * The template is then dumped and copied to every other Proxmox server and hostname renamed - * When we want to create instances of the template, we clone on that server - * i.e for `netsoc-ubuntu-server`, we have `netsoc-ubuntu-server-lovelace` and `netsoc-ubuntu-server-feynman` - * See `template-netsoc-ubuntu-server.yml` - -* We can define and create VMs at will - * VM creation is done by our custom VM Ansible role `proxmox-infra-cloudinit-vm` - * We create a clone of a template VM defined previously - * It's expected that the template VM we cloned has cloud-init & qemu-guest-agent installed - * [cloud-init](https://cloudinit.readthedocs.io/en/latest/) is the de-facto industry standard for configuring Cloud VMs - * We use it to inject maintenance user info (ssh keys, etc) and network configuration into our VMs - * Note, the role we use accepts only _plain-text_ yaml, this is because not every field (userdata/instance data/network) only uses yaml. [Look here in the cloud-init docs](https://cloudinit.readthedocs.io/en/latest/topics/format.html) to see what I mean - * [qemu-guest-agent](https://pve.proxmox.com/wiki/Qemu-guest-agent) is a package that exposes the current network setup and stats to the KVM machine - * i.e. it let's us see what VMs are _actually_ binding to what static IPs we asked them to - * also used for some Proxmox related functionality - * We then modify the clone we created - * Set specifications: - * Cores, Memory, Network stuff - * Resize existing disks - * Set new disks - * **If you rerun the playbook, we will only recreate the disks if you explicitly say we should** - * Prevents loss of user data - * Set the description: - * All our IaC managed VMs are expected have descriptions containing YAML. - * We use this YAML later to "discover" info about any running VMs - * Example from (`create-auth.yml`): - ``` - groups: - - vm - - auth - vars: - ansible_ssh_private_key_file: ./keys/auth/id_rsa - ``` - * We will use this to pass info about running VMs to Ansible later - * Supply Cloud-Init metadata / userdata / network config - * If you're reading cloud-init docs, we use the [NoCloud data source](https://cloudinit.readthedocs.io/en/latest/topics/datasources/nocloud.html) - * We generally don't use metadata/instance metdata - * More targeted towards actual clouds like EC2 - * We use userdata to inject the Netsoc maintenance user and set the hostname (using [`#cloud-config`](https://cloudinit.readthedocs.io/en/latest/topics/examples.html)) - * Network config [`(we use v2)`](https://cloudinit.readthedocs.io/en/latest/topics/network-config-format-v2.html#network-config-v2) is used to tell the VM what static IP it should bind to, what DNS server is should use & what router it should send packets to - * Example from (`create-auth.yml`): - ``` - cloudinit: - drive_device: ide2 - metadata: "" - userdata: | - #cloud-config - users: - - name: netsoc - gecos: Netsoc Management User - primary_group: netsoc - sudo: ALL=(ALL) NOPASSWD:ALL - ssh_authorized_keys: - - {{ lookup('file', './keys/auth/id_rsa.pub') }} - preserve_hostname: false - manage_etc_hosts: true - fqdn: auth.vm.netsoc.co - networkconfig: | - version: 2 - ethernets: - 30a: - match: - name: ens18 - addresses: - - {{ ip_allocation.freeipa_base }} - gateway4: 10.0.30.1 - nameservers: - search: {{ ip_allocation.search }} - addresses: {{ ip_allocation.nameservers }} - ``` - * `drive_device` specifies what device the NoCloud CD-ROM drive is mounted on - * See `create-auth.yml` - -* We need to be able to discover every VM we have running in order to customize the base image we cloned further - * Proxmox has an API - * Description field was set with our previous Ansible-related groups and vars - * `qemu-guest-agent` will tell us what IPs the machines are running - * Ansible has a feature known as [custom inventory scripts](https://docs.ansible.com/ansible/latest/user_guide/intro_dynamic_inventory.html#dynamic-inventory) - * Ansible normally searches for machines to connect to in predefined files (i.e ./hosts, ./hosts.yml, ansible.cfg, etc...) - * A custom inventory script is a script that instead can be called to return the list of possible machines to connect to - * It's really common to use with Cloud providers (i.e discover every AWS EC2 instance you have running and run a command on them all) - * Our custom inventory script for Proxmox is `proxmox_inventory.py` - * Before you can use it, you must have loaded the environmental variables from the Ansible vault (these contain the API password) - * You can do this by running `source proxmox_secrets.sh` and entering the vault password - * You can now see we can set `host_vars` from the VM's description `vars` - * This is how we discover which ssh key in the NaC directory to use, and other info - * The inventory script will now work, try `ansible -i proxmox_inventory.py all -m ping` and it should be able to ping all the VMs - * Similarly you will see that `ansible-playbook -i proxmox_inventory.py ...` will use that inventory - * You can target the cluster hosts at the same time too by using `ansible-playbook -i hosts -i proxmox_inventory ...` - * If you want to get the json passed to Ansible for yourself, you can run `./proxmox_inventory.py --list` - -* We can then further provision that VM with tools that only it specifically needs - * See `provision-*.yml` - * i.e if the vm is databases.vm.netsoc.co, install MySQL - * They target the groups we specified in the description of the VM - * Don't forget you can target by name too, like `databases.vm.netsoc.co` - -* We can manage our router setup - * We have more VMs than we have public IP addresses, therefore we must make use of a router and a [NAT](https://www.reddit.com/r/explainlikeimfive/comments/1wqc30/eli5_how_does_nat_network_address_translation_work/) configuration - * We do not use a hardware router, instead we use a virtualized router called [VyOS](https://www.vyos.io/) - * We can map any port on any of our available IP addresses to any port on a VM - * We can use VLANs to serperate infra and user server traffic - * We currently only make (real) use of 1-2 VLANs - * The router has a prescence on every VLAN as 10.0.x.1 - * Send traffic to 10.0.x.1 when you're on VLAN x and it'l get routed to it's destination i.e other VMs on the same VLAN or the internet - * Currently in use VLANs: - * 10 - * 20 - * 30 - Internal infrastructure (the majority of VMs will be on this) - * 40 - User infrastructure (not currently in use-yet) - * 100 - DHCP for Packer - * All of this is configured via Ansible - * TODO(ocanty)-elaborate more on this, mloc too pls - * See `configure-router.yml` - * Watch these (excuse the cat meme, they'll be better than any lecture you'll ever get in college): - * [A Cat Explains the Internet](https://www.youtube.com/watch?v=jHyaFBsxy1s) - * [A Cat Explains Subnetting](https://www.youtube.com/watch?v=QgT1s2fOfiE) - * [A Cat Explains DNS](https://www.youtube.com/watch?v=4ZtFk2dtqv0) - -* We can manage our DNS records - * All (external) DNS records are hosted on Cloudflare and completely managed by the a playbook - * Internal DNS records are managed by FreeIPA - * See `configure-dns.yml` - -* All of this should tie into eachother - * We use `vars/ip_allocation.yml` to set IP allocations for VMs - * We can feed that to `create-*.yml` to create a VM that uses that IP - * We can feed that to `configure-router.yml` and create a port-mapping that maps an external port to that VM's IP - * We can then set a DNS record to point at the IP that the external port is on - -* All of this is stuck in time forever because git is awesome - -### Important policies - -* **All volatile data should be on a 2nd disk of the VM, not the boot disk** - * Configure your VMs tolerate the boot disk being completely destroyed - * i.e if we want to restore from a backup, we can delete the VM, run the playbook to create a new VM, detach the e,empty 2nd disk it created and attach the disk we backed up - * By defining a VM entirely by playbooks we can potentially save a LOT of disk space on backups - * Needs to be investigated - -* **Do NOT put a VM on a trunk port unless it's a router** - * Always give the VMs a NIC with a tagged VLAN - * If you want a prescence on multiple VLANs, attach multiple NICs - * If you give the VM with a NIC with no tagging, it will recieve ALL traffic. - * This is a huge security risk - -### Finally, our actual VM setup - -**IP allocations for these VMs can be found in `vars/ip_allocation.yml` and are subject to change** - -* auth.vm.netsoc.co - * Hosts a FreeIPA server on NIC 1 - * Container hostname: - * ipa.vm.netsoc.co - * LDAP for user accounts - * DNS server that serves *.vm.netsoc.co - * Kerberos - * Web UI - * Hosts Keycloak on NIC 2 - * Provides OAuth/OpenID Connect for users in LDAP - -**Every single other VM bar the router should be enrolled in the FreeIPA server** - -* nfs.vm.netsoc.co - * Provides an authenticated Kerberos NFS server - * Stores home directories and docker data - * ZFS is used on the data disk - * A script exists that periodically should scan FreeIPA and create zfs directories for users - -* databases.vm.netsoc.co - * Hosts MySQL database for infra on NIC 1 - * Hosts MYSQL databsae for users on NIC 2 - -* managerN.vm.netsoc.co, workerN.vm.netsoc.co - * Docker swarm managers and workers - * Hosts the following containers: - * Traefik (this reverse proxies the **majority** of our web services. It is **vital**) - -* router.vm.netsoc.co - * The VyOS router - * This is the only VM that should bind public IPs (when migrating from our old infra is done) - * Notable mappings: - * TODO - -* portal.vm.netsoc.co - * The user server \ No newline at end of file diff --git a/export-grafana-dashboards.yml b/export-grafana-dashboards.yml new file mode 100644 index 00000000..a760368c --- /dev/null +++ b/export-grafana-dashboards.yml @@ -0,0 +1,55 @@ +--- +- name: Export Grafana Dashboards + hosts: web.infra.netsoc.co + tasks: + - name: Get all Grafana dashboards + uri: + url: "{{ url }}/api/search?query=&starred=false&skipRecent=true&skipStarred=true&prevSort=null" + force_basic_auth: yes + user: admin + password: "{{ grafana.password }}" + register: dashboards + + - name: Export Grafana dashboards + community.grafana.grafana_dashboard: + state: export + grafana_url: "{{ url }}" + url_username: admin + url_password: "{{ grafana.password }}" + uid: "{{ item.uid }}" + path: "/netsoc/grafana/exports/{{ item.uri }}.json" + with_items: "{{ dashboards.json }}" + become: yes + + - name: Fetch dashboards to NaC/roles/grafana/files/data/dashboards + fetch: + src: "/netsoc/grafana/exports/{{ item.uri }}.json" + dest: "./roles/grafana/files/data/dashboards/{{ item.uri | basename }}.json" + flat: yes + with_items: "{{ dashboards.json }}" + become: yes + + vars_files: + - "vars/network.yml" + - "vars/secrets_mapping.yml" + - "vars/secrets.yml" + vars: + url: https://grafana.netsoc.co + +- name: Format Dashboards + hosts: localhost + tasks: + - name: Get dashboard files + become: no + find: + path: "{{ playbook_dir }}/roles/grafana/files/data/dashboards" + recurse: no + register: dashboards_dir + + - name: Format dashboard files + become: no + shell: "cat <<< $(jq .dashboard {{ item.path }} | jq '.id = null' ) > {{ item.path }}" + args: + executable: /bin/bash + with_items: "{{ dashboards_dir.files }}" + \ No newline at end of file diff --git a/group_vars/all.yml b/group_vars/all.yml new file mode 100644 index 00000000..125d26d4 --- /dev/null +++ b/group_vars/all.yml @@ -0,0 +1,5 @@ +dev_site: netsoc.dev +co_site: netsoc.co + +admins_gid: 420 +members_gid: 422 \ No newline at end of file diff --git a/group_vars/ipaclients.yml b/group_vars/ipaclients.yml deleted file mode 100644 index 42db091a..00000000 --- a/group_vars/ipaclients.yml +++ /dev/null @@ -1,6 +0,0 @@ -ipaadmin_password: "{{ freeipa.admin_password }}" -ipaserver_domain: "{{ freeipa.domain }}" -ipaserver_realm: "{{ freeipa.realm }}" -ipaclient_servers: - - ipa.vm.netsoc.co -ipaadmin_principal: "admin" \ No newline at end of file diff --git a/host_vars/feynman.yml b/host_vars/feynman.yml index baa9a322..4336e8c0 100644 --- a/host_vars/feynman.yml +++ b/host_vars/feynman.yml @@ -1,5 +1,6 @@ --- -ansible_host: 10.0.10.53 +ansible_host: 10.0.20.53 ansible_ssh_user: root -ansible_ssh_private_key_file: "/root/.ssh/id_rsa" +ansible_ssh_private_key_file: "./keys/feynman/id_rsa" + ansible_python_interpreter: "/usr/bin/python3" \ No newline at end of file diff --git a/host_vars/feynman_vm.yml b/host_vars/feynman_vm.yml new file mode 100644 index 00000000..cc5c62f0 --- /dev/null +++ b/host_vars/feynman_vm.yml @@ -0,0 +1,5 @@ +--- +ansible_host: 10.0.40.53 +ansible_ssh_user: netsoc +ansible_ssh_private_key_file: "./keys/feynman-vm/id_rsa" +ansible_python_interpreter: "/usr/bin/python3" \ No newline at end of file diff --git a/host_vars/leela.yml b/host_vars/leela.yml new file mode 100644 index 00000000..14935c82 --- /dev/null +++ b/host_vars/leela.yml @@ -0,0 +1,6 @@ +--- +ansible_host: 10.0.20.20 +ansible_ssh_port: 22 +ansible_ssh_user: root +ansible_ssh_private_key_file: "./keys/leela/id_rsa" +ansible_python_interpreter: "/usr/bin/python3" \ No newline at end of file diff --git a/host_vars/lovelace.yml b/host_vars/lovelace.yml index 6486a595..156faa00 100644 --- a/host_vars/lovelace.yml +++ b/host_vars/lovelace.yml @@ -1,5 +1,5 @@ --- -ansible_host: 10.0.10.52 +ansible_host: 10.0.20.30 ansible_ssh_user: root -ansible_ssh_private_key_file: "/root/.ssh/id_rsa" +ansible_ssh_private_key_file: "./keys/lovelace/id_rsa" ansible_python_interpreter: "/usr/bin/python3" \ No newline at end of file diff --git a/host_vars/lovelace_vm.yml b/host_vars/lovelace_vm.yml new file mode 100644 index 00000000..0b9d7cf2 --- /dev/null +++ b/host_vars/lovelace_vm.yml @@ -0,0 +1,5 @@ +--- +ansible_host: 10.0.20.30 +ansible_ssh_user: netsoc +ansible_ssh_private_key_file: "./keys/lovelace_vm/id_rsa" +ansible_python_interpreter: "/usr/bin/python3" \ No newline at end of file diff --git a/host_vars/scalper.yml b/host_vars/scalper.yml new file mode 100644 index 00000000..1dad0bc4 --- /dev/null +++ b/host_vars/scalper.yml @@ -0,0 +1,6 @@ +--- +ansible_host: 10.0.20.10 +ansible_ssh_port: 22 +ansible_ssh_user: root +ansible_ssh_private_key_file: "./keys/scalper/id_rsa" +ansible_python_interpreter: "/usr/bin/python3" \ No newline at end of file diff --git a/hosts b/hosts index 83908896..ebdf2f70 100644 --- a/hosts +++ b/hosts @@ -1,8 +1,28 @@ +# Please use IP addresses for each server +# This is done because DNS may not be configured when the playbook is ran +# +# Keep the ansible hostname as strictly the server name +# These are used to setup DNS records and related +# i.e only use "feynman", not "feynman.netsoc.co" + +# NEW NETSOC control +feynman +lovelace +leela +scalper [proxmox_master] feynman +[prometheus_base] +feynman +lovelace +leela +scalper + [proxmox_hosts] feynman lovelace +leela +scalper diff --git a/legacy_netsocadmin.yml b/legacy_netsocadmin.yml new file mode 100644 index 00000000..8ae529a3 --- /dev/null +++ b/legacy_netsocadmin.yml @@ -0,0 +1,8 @@ +--- +- name: Ensure Netsoc Admin + hosts: bigbertha + roles: + - netsocadmin2 + vars_files: + - vars/docker_registry.yml # traefik certs + - vars/secrets_legacy.yml \ No newline at end of file diff --git a/netsoc-cloud/templates/failsafe.yml b/netsoc-cloud/templates/failsafe.yml new file mode 100644 index 00000000..fa205450 --- /dev/null +++ b/netsoc-cloud/templates/failsafe.yml @@ -0,0 +1,8 @@ +# dies if it detects that there is proxmox stuff installed on those host +# i.e a dumbo ran it on the proxmox host + +- name: Test provisionee_host to ensure user is not an idiot and provisioning the proxmox host instead of the container (1/2) + shell: "! which pvesh" # errors if the pvesh binary exists + +- name: Test provisionee_host to ensure user is not an idiot and provisioning the proxmox host instead of the container (2/2) + shell: "! which pveam" # errors if the pveam binary exists \ No newline at end of file diff --git a/netsoc-cloud/templates/foundry-config-tool.go b/netsoc-cloud/templates/foundry-config-tool.go new file mode 100644 index 00000000..833ba51f --- /dev/null +++ b/netsoc-cloud/templates/foundry-config-tool.go @@ -0,0 +1,375 @@ +package main + +import ( + "context" + "fmt" + "log" + "net/http" + "os" + "os/exec" + "sync" + "text/template" + "time" +) + +const port = 80 + +const form = ` + + + + + +FoundryVTT Installer + + + + +
+
+

FoundryVTT Installer

+
+
+
+ +

To view your download URL

+
    +
  • Go to foundryvtt.com
  • +
  • Login and go to your profile
  • +
  • Select Purchased Licenses from the left column
  • +
  • Select the download version you would like, with the operating system set to Linux/NodeJS
  • +
  • Click on the Timed URL button, to copy the temporary download url to your clipboard
  • +
+ + + +
+
+
+ + +` + +const response = ` + + + + + +FoundryVTT Installer + + + + +
+
+

FoundryVTT Installer

+
+
+

Your FoundryVTT install should come up in a minute here +

Contact Netsoc SysAdmins on our Discord if you encounter any issues +

+ +` + +var dlURL string +var password string + +func main() { + httpServerExitDone := &sync.WaitGroup{} + httpServerExitDone.Add(1) + srv := startHTTPServer(httpServerExitDone) + + done := make(chan bool) + configureFunc := configure(done) + + http.HandleFunc("/", showForm) + http.HandleFunc("/config", configureFunc) + + <-done + + // Wait for server to shutdown and wait additional 10s for good measure + _ = srv.Shutdown(context.TODO()) + httpServerExitDone.Wait() + time.Sleep(10 * time.Second) + + // Commands to execute after web server shutdown + exec.Command("systemctl", "disable", "config_tool.service").Run() + docker_cmd := exec.Command("docker-compose", "up", "--detach") + docker_cmd.Dir = "/root/foundry" + docker_cmd.Run() +} + +func startHTTPServer(wg *sync.WaitGroup) *http.Server { + srv := &http.Server{Addr: fmt.Sprintf("0.0.0.0:%d", port)} + + go func() { + defer wg.Done() + + if err := srv.ListenAndServe(); err != http.ErrServerClosed { + log.Fatalf("ListenAndServe(): %v", err) + } + }() + + return srv +} + +/// Web Handler Funcs + +func showForm(w http.ResponseWriter, r *http.Request) { + t, _ := template.New("form").Parse(form) + t.Execute(w, nil) +} + +const secrets_json_template = `{ + "foundry_admin_key": "{{.Password}}", +}` + +const env_template = `FOUNDRY_RELEASE_URL={{.ReleaseUrl}}` + +func configure(done chan bool) func(http.ResponseWriter, *http.Request) { + return func(w http.ResponseWriter, r *http.Request) { + r.ParseForm() + dlURL = r.FormValue("dl_url") + password = r.FormValue("password") + + secretsfile, _ := os.Create("/root/foundry/secrets.json") + defer secretsfile.Close() + + tmplsecrets, _ := template.New("secrets").Parse(secrets_json_template) + tmplsecrets.Execute(secretsfile , map[string]interface{}{"Password": password}) + + envfile, _ := os.Create("/root/foundry/.env") + defer envfile.Close() + + envsecrets, _ := template.New("secrets").Parse(env_template) + envsecrets.Execute(envfile , map[string]interface{}{"ReleaseUrl": dlURL}) + + w.Write([]byte(response)) + done <- true + } +} diff --git a/netsoc-cloud/templates/ghost-cms-config-tool.go b/netsoc-cloud/templates/ghost-cms-config-tool.go new file mode 100644 index 00000000..93c27aec --- /dev/null +++ b/netsoc-cloud/templates/ghost-cms-config-tool.go @@ -0,0 +1,397 @@ +package main + +import ( + "context" + "fmt" + "html/template" + "log" + "net/http" + "os/exec" + "regexp" + "strings" + "sync" + "time" +) + +const port = 80 + +const form = ` + + + + + +GhostCMS Installer + + + + + +
+
+

GhostCMS installer

+
+
+
+
+

+ Ensure that the entered host is correctly configured as a Virtual Host in the Netsoc Cloud control panel +

+ Contact Netsoc SysAdmins via the UCC Netsoc Discord if you are unsure, having issues or require assistance! +

+
+
+
+ + +` +const response = ` + + + + + +GhostCMS Installer + + + + + +
+
+

GhostCMS installer

+
+
+

Installing GhostCMS for {{.Host}}

+

+ The administration page is available here
+ https://{{.Host}}/ghost
+ Do NOT forget to bookmark it, it is not linked on your site +

+ +

Contact Netsoc SysAdmins on our Discord if you encounter any issues +

+ +` + +var host string + +func main() { + httpServerExitDone := &sync.WaitGroup{} + httpServerExitDone.Add(1) + srv := startHTTPServer(httpServerExitDone) + + done := make(chan bool) + configureFunc := configure(done) + + http.HandleFunc("/", showForm) + http.HandleFunc("/config", configureFunc) + + <-done + + // Wait for server to shutdown and wait additional 10s for good measure + _ = srv.Shutdown(context.TODO()) + httpServerExitDone.Wait() + time.Sleep(10 * time.Second) + + // Commands to execute after web server shutdown + exec.Command("systemctl", "disable", "config_tool.service").Run() + exec.Command("docker", "run", "-d", "--name", "ghost", "-v", + "/ghost:/var/lib/ghost/content", "-e", fmt.Sprintf("url=https://%s", host), + "-p", "80:2368", "--restart", "always", "ghost").Run() +} + +func startHTTPServer(wg *sync.WaitGroup) *http.Server { + srv := &http.Server{Addr: fmt.Sprintf("0.0.0.0:%d", port)} + + go func() { + defer wg.Done() + + if err := srv.ListenAndServe(); err != http.ErrServerClosed { + log.Fatalf("ListenAndServe(): %v", err) + } + }() + + return srv +} + +/// Web Handler Funcs + +func showForm(w http.ResponseWriter, r *http.Request) { + t, _ := template.New("form").Parse(form) + t.Execute(w, nil) +} + +func configure(done chan bool) func(http.ResponseWriter, *http.Request) { + return func(w http.ResponseWriter, r *http.Request) { + r.ParseForm() + host = r.FormValue("host") + re := regexp.MustCompile(`https?:\/\/`) + host = re.ReplaceAllString(host, "") + host = strings.TrimSuffix(host, "/") + + t, _ := template.New("response").Parse(response) + t.Execute(w, map[string]interface{}{"Host": host}) + done <- true + } +} diff --git a/netsoc-cloud/templates/ubuntu-base.yml b/netsoc-cloud/templates/ubuntu-base.yml new file mode 100644 index 00000000..8c8c3498 --- /dev/null +++ b/netsoc-cloud/templates/ubuntu-base.yml @@ -0,0 +1,83 @@ +- import_tasks: "./netsoc-cloud/templates/failsafe.yml" + +- name: Fix locale spam + shell: + locale-gen en_US.UTF-8 + +- apt: + name: + - packagekit + - postfix + state: absent + purge: yes + autoremove: yes + +- name: Update all apt packages + apt: + name: "*" + state: latest + update_cache: yes + +- file: + path: /etc/machine-id + state: absent + +- file: + path: /var/lib/dbus/machine-id + state: absent + +- name: Delete installed SSH key on LXC + file: + path: /root/.ssh/id_rsa + state: absent + +- name: Delete installed host keys + shell: rm -f /etc/ssh/ssh_host* + args: + warn: false + +- name: Make SSHD override directories + file: + path: "{{ item }}" + state: directory + with_items: + - /lib/systemd/system/ssh.service.d + +- name: Install host key automator (generates host keys if they're missing) + copy: + dest: "{{ item }}" + content: | + [Service] + ExecStartPre= + ExecStart= + ExecStartPre=/usr/bin/ssh-keygen -A + ExecStart=/usr/sbin/sshd -D $SSHD_OPTS + with_items: + - /lib/systemd/system/ssh.service.d/override.conf + +- name: Daemon-reload + systemd: + name: sshd + daemon-reload: yes + +- name: Disable useless systemd services + shell: "systemctl disable {{ item }} && systemctl mask {{ item }}" + with_items: + - systemd-resolved # use resolv file + - accounts-daemon # desktop + +- name: Install /etc/resolv.conf (to replace systemd-resolved) + copy: + dest: /etc/resolv.conf + content: | + # --- BEGIN PVE --- + search netsoc.cloud + nameserver 1.1.1.1 + # --- END PVE --- + +- name: Add /usr/local/bin to PATH of root + lineinfile: + path: /root/.bashrc + regexp: | + ^PATH\=\$PATH\:\/usr\/local\/bin" + line: PATH=$PATH:/usr/local/bin \ No newline at end of file diff --git a/netsoc-cloud/templates/ubuntu-docker-bare.yml b/netsoc-cloud/templates/ubuntu-docker-bare.yml new file mode 100644 index 00000000..a75ae81e --- /dev/null +++ b/netsoc-cloud/templates/ubuntu-docker-bare.yml @@ -0,0 +1,78 @@ +- name: Ensure /etc/docker + file: + path: /etc/docker + state: directory + +- name: Ensure /etc/docker/daemon.json + copy: + dest: /etc/docker/daemon.json + content: | + { + "storage-driver": "fuse-overlayfs" + } + +- name: Ensure Docker dependencies + apt: + pkg: + - apt-transport-https + - ca-certificates + - curl + - software-properties-common + - fuse-overlayfs + - libfuse3-dev + - gnupg + state: latest + install_recommends: no + +- name: Ensure Docker GPG key + apt_key: + url: https://download.docker.com/linux/ubuntu/gpg + +- name: Ensure Docker APT repo + apt_repository: + repo: deb [arch=amd64] https://download.docker.com/linux/ubuntu {{ansible_distribution_release}} stable + +- name: Ensure Docker + apt: + name: docker-ce + state: latest + update_cache: yes + +- name: Ensure Docker Compose dependencies + apt: + name: python3-pip + state: latest + +- name: Ensure Docker Compose + pip: + name: docker-compose + state: latest + executable: pip3 + +- name: Ensure Docker Py + pip: + name: docker + state: latest + +- name: Create override folder for containerd + file: + path: /etc/systemd/system/containerd.service.d + state: directory + +- name: Stop LXC issues (stop loading kernel modules, this container will be unprivileged) + copy: + content: | + [Service] + ExecStartPre= + dest: /etc/systemd/system/containerd.service.d/override.conf + +- name: Reload Docker daemon + systemd: + state: reloaded + daemon_reload: yes + name: docker + +- name: Enable Docker daemon + service: + name: docker + enabled: yes diff --git a/netsoc-cloud/templates/ubuntu-docker.yml b/netsoc-cloud/templates/ubuntu-docker.yml new file mode 100644 index 00000000..1f007e8c --- /dev/null +++ b/netsoc-cloud/templates/ubuntu-docker.yml @@ -0,0 +1,3 @@ +- import_tasks: "./netsoc-cloud/templates/ubuntu-base.yml" +- import_tasks: "./netsoc-cloud/templates/ubuntu-docker-bare.yml" +- import_tasks: "./netsoc-cloud/templates/ubuntu-final.yml" \ No newline at end of file diff --git a/netsoc-cloud/templates/ubuntu-final.yml b/netsoc-cloud/templates/ubuntu-final.yml new file mode 100644 index 00000000..b7fa9248 --- /dev/null +++ b/netsoc-cloud/templates/ubuntu-final.yml @@ -0,0 +1,14 @@ +- name: Delete authorized ssh key + file: + path: /root/.ssh/authorized_keys + state: absent + +- name: Delete cloud-init status + file: + path: /etc/cloud + state: absent + +- name: Delete cloud-init netplan + file: + path: /etc/netplan/50-cloud-init.yml + state: absent diff --git a/netsoc-cloud/templates/ubuntu-foundry.yml b/netsoc-cloud/templates/ubuntu-foundry.yml new file mode 100644 index 00000000..08d90d0f --- /dev/null +++ b/netsoc-cloud/templates/ubuntu-foundry.yml @@ -0,0 +1,100 @@ +- import_tasks: "./netsoc-cloud/templates/ubuntu-base.yml" +- import_tasks: "./netsoc-cloud/templates/ubuntu-docker-bare.yml" + +- name: Pull FoundryVTT Image + community.general.docker_image: + name: felddy/foundryvtt:release + source: pull + +- name: Check Go on Host + shell: which go + register: result_go + delegate_to: localhost + +- name: Add Golang PPA + shell: | + echo -e '\n' | add-apt-repository ppa:longsleep/golang-backports + when: result_go.rc != 0 + delegate_to: localhost + +- name: Install golang + apt: + name: golang-go + update_cache: yes + when: result_go.rc != 0 + delegate_to: localhost + +- name: Build Config Tool + shell: + chdir: netsoc-cloud/templates/ + cmd: > + CGO_ENABLED=0 GOOS=linux GOARCH=amd64 + go build -a -tags netgo -ldflags='-extldflags=-static"' + -o /tmp/foundry-conf + foundry-config-tool.go + delegate_to: localhost + +- name: Copy config tool + copy: + src: "/tmp/foundry-conf" + dest: /srv/foundry-conf + mode: 0775 + +- name: Config Tool Service + copy: + dest: /etc/systemd/system/config_tool.service + content: | + [Unit] + Description=Netsoc FoundryVTT Config + + [Service] + Type=simple + ExecStart=/srv/foundry-conf + + [Install] + WantedBy=multi-user.target + +- name: Enable Config Tool + service: + name: config_tool + enabled: true + +- name: Make Foundry Folder + file: + path: /root/foundry + state: directory + +- name: Make Foundry Data Folder + file: + path: /root/foundry/data + state: directory + +- name: Copy over Foundry Docker Compose File + copy: + dest: /root/foundry/docker-compose.yml + content: | + --- + version: "3.8" + + secrets: + config_json: + file: secrets.json + + services: + foundry: + image: felddy/foundryvtt:release + hostname: my_foundry_host + init: true + volumes: + - /root/foundry/data:/data + environment: + - FOUNDRY_RELEASE_URL=${FOUNDRY_RELEASE_URL} + ports: + - target: 30000 + published: 80 + protocol: tcp + secrets: + - source: config_json + target: config.json" + +- import_tasks: "./netsoc-cloud/templates/ubuntu-final.yml" \ No newline at end of file diff --git a/netsoc-cloud/templates/ubuntu-ghostcms.yml b/netsoc-cloud/templates/ubuntu-ghostcms.yml new file mode 100644 index 00000000..8eb3e76f --- /dev/null +++ b/netsoc-cloud/templates/ubuntu-ghostcms.yml @@ -0,0 +1,62 @@ +- import_tasks: "./netsoc-cloud/templates/ubuntu-base.yml" +- import_tasks: "./netsoc-cloud/templates/ubuntu-docker-bare.yml" + +- name: Pull GhostCMS Image + community.general.docker_image: + name: ghost:4.16.0 + source: pull + +- name: Check Go on Host + shell: which go + register: result_go + delegate_to: localhost + +- name: Add Golang PPA + shell: | + echo -e '\n' | add-apt-repository ppa:longsleep/golang-backports + when: result_go.rc != 0 + delegate_to: localhost + +- name: Install golang + apt: + name: golang-go + update_cache: yes + when: result_go.rc != 0 + delegate_to: localhost + +- name: Build Config Tool + shell: + chdir: netsoc-cloud/templates/ + cmd: > + CGO_ENABLED=0 GOOS=linux GOARCH=amd64 + go build -a -tags netgo -ldflags='-extldflags=-static"' + -o /tmp/gcms-conf + ghost-cms-config-tool.go + delegate_to: localhost + +- name: Copy config tool + copy: + src: "/tmp/gcms-conf" + dest: /srv/gcms-conf + mode: 0775 + +- name: Config Tool Service + copy: + dest: /etc/systemd/system/config_tool.service + content: | + [Unit] + Description=Netsoc GhostCMS Host Config + + [Service] + Type=simple + ExecStart=/srv/gcms-conf + + [Install] + WantedBy=multi-user.target + +- name: Enable Config Tool + service: + name: config_tool + enabled: true + +- import_tasks: "./netsoc-cloud/templates/ubuntu-final.yml" \ No newline at end of file diff --git a/netsoc-cloud/templates/ubuntu-linuxtools.yml b/netsoc-cloud/templates/ubuntu-linuxtools.yml new file mode 100644 index 00000000..97caec04 --- /dev/null +++ b/netsoc-cloud/templates/ubuntu-linuxtools.yml @@ -0,0 +1,87 @@ +- import_tasks: "./netsoc-cloud/templates/ubuntu-base.yml" + +- name: Install Dependencies + shell: "apt-get install -y {{ item }}" + with_items: + - build-essential + - clang + - curl + - emacs + - gcc + - gdb + - git + - gnupg + - gradle + - jq + - htop + - iotop + - make + - maven + - mercurial + - mysql-client + - nano + - php7.4-cli + - protobuf-compiler + - ruby + - screen + - software-properties-common + - sqlite + - tmux + - vim + - python3-pip + +- name: Install Jupyter + pip: + name: jupyter + +- name: Install composer + shell: | + php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" + php -r "if (hash_file('sha384', 'composer-setup.php') === '756890a4488ce9024fc62c56153228907f1545c228516cbf63f885e036d37e9a59d27d63f46af1d4d07ee0f76181c7d3') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;" + php composer-setup.php + php -r "unlink('composer-setup.php');" + +- name: Add node PPA + shell: curl -sL https://deb.nodesource.com/setup_14.x | sudo -E bash - + +- name: Install nodejs + apt: + name: nodejs + update_cache: yes + +- name: Add golang PPA + shell: | + echo -e '\n' | add-apt-repository ppa:longsleep/golang-backports + +- name: Install golang + apt: + name: golang-go + update_cache: yes + +- name: Golang GOPATH (for stuff like gopls) + ansible.builtin.lineinfile: + path: /etc/bash.bashrc + regexp: '^export GOPATH=' + line: | + export GOPATH=$HOME/go + +- name: Add GOPATH to PATH + ansible.builtin.lineinfile: + path: /etc/bash.bashrc + regexp: '^export PATH=$PATH:$GOROOT/bin:$GOPATH/bin' + line: | + export PATH=$PATH:$GOROOT/bin:$GOPATH/bin + +- name: Install rustup + shell: curl https://sh.rustup.rs -sSf | sh -s -- -y + +- name: Install NVM + shell: curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.37.2/install.sh | bash + +- name: Install Helm + shell: curl -o- https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 | bash + + +- import_tasks: "./netsoc-cloud/templates/ubuntu-docker-bare.yml" + +- import_tasks: "./netsoc-cloud/templates/ubuntu-final.yml" diff --git a/netsoc-cloud/templates/ubuntu-wordpress.yml b/netsoc-cloud/templates/ubuntu-wordpress.yml new file mode 100644 index 00000000..bd18e3b2 --- /dev/null +++ b/netsoc-cloud/templates/ubuntu-wordpress.yml @@ -0,0 +1,400 @@ +- import_tasks: "./netsoc-cloud/templates/ubuntu-base.yml" + +- name: Install packages + package: + name: + - nginx + - mysql-server + - mysql-common + - php7.4-fpm + - php7.4-mysql + state: latest + +- name: Secure MySQL installation (does the same as mysql_secure_installation) and set root password to 'password' (changed later) + shell: | + mysql -e "ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'password';" && + mysql -ppassword -e "DELETE FROM mysql.user WHERE User='';" && + mysql -ppassword -e "DELETE FROM mysql.user WHERE User='root' AND Host NOT IN ('localhost', '127.0.0.1', '::1');" && + mysql -ppassword -e "DROP DATABASE IF EXISTS test;DELETE FROM mysql.db WHERE Db='test' OR Db='test_%';" && + mysql -ppassword -e "DROP DATABASE IF EXISTS wp_database; DROP USER IF EXISTS 'wp_user'@localhost;" && + mysql -ppassword -e "FLUSH PRIVILEGES"; + +- name: Tune MySQL performance to use low memory + copy: + dest: /etc/mysql/mysql.conf.d/mysqld.cnf + content: | + # + # The MySQL database server configuration file. + # + # One can use all long options that the program supports. + # Run program with --help to get a list of available options and with + # --print-defaults to see which it would actually understand and use. + # + # For explanations see + # http://dev.mysql.com/doc/mysql/en/server-system-variables.html + + # Here is entries for some specific programs + # The following values assume you have at least 32M ram + + [mysqld] + # + # * Basic Settings + # + user = mysql + # pid-file = /var/run/mysqld/mysqld.pid + # socket = /var/run/mysqld/mysqld.sock + # port = 3306 + # datadir = /var/lib/mysql + + performance_schema = off + + # If MySQL is running as a replication slave, this should be + # changed. Ref https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html#sysvar_tmpdir + # tmpdir = /tmp + # + # Instead of skip-networking the default is now to listen only on + # localhost which is more compatible and is not less secure. + bind-address = 127.0.0.1 + # + # * Fine Tuning + # + key_buffer_size = 16M + # max_allowed_packet = 64M + # thread_stack = 256K + + # thread_cache_size = -1 + + # This replaces the startup script and checks MyISAM tables if needed + # the first time they are touched + myisam-recover-options = BACKUP + + # max_connections = 151 + + # table_open_cache = 4000 + + # + # * Logging and Replication + # + # Both location gets rotated by the cronjob. + # + # Log all queries + # Be aware that this log type is a performance killer. + # general_log_file = /var/log/mysql/query.log + # general_log = 1 + # + # Error log - should be very few entries. + # + log_error = /var/log/mysql/error.log + # + # Here you can see queries with especially long duration + # slow_query_log = 1 + # slow_query_log_file = /var/log/mysql/mysql-slow.log + # long_query_time = 2 + # log-queries-not-using-indexes + # + # The following can be used as easy to replay backup logs or for replication. + # note: if you are setting up a replication slave, see README.Debian about + # other settings you may need to change. + # server-id = 1 + # log_bin = /var/log/mysql/mysql-bin.log + # binlog_expire_logs_seconds = 2592000 + max_binlog_size = 100M + # binlog_do_db = include_database_name + # binlog_ignore_db = include_database_name + +- name: PHP - Disable mail() + lineinfile: + path: /etc/php/7.4/fpm/php.ini + regexp: "^disable_functions =" + line: "disable_functions = mail,pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare," + +- name: PHP - Set cgi.fix_pathinfo=0 + lineinfile: + path: /etc/php/7.4/fpm/php.ini + regexp: "^cgi.fix_pathinfo|;cgi.fix_pathinfo" + line: cgi.fix_pathinfo=0 + +- name: PHP - Disable opcache + lineinfile: + path: /etc/php/7.4/fpm/php.ini + regexp: "^opcache.enable|;opcache.enable" + line: opcache.enable=0 + +- name: Restart PHP + service: + name: php7.4-fpm + state: restarted + +- name: Setup Nginx config + copy: + dest: /etc/nginx/sites-available/default + content: | + server { + listen 80 default_server; + listen [::]:80 default_server; + + root /var/www/html; + + # Add index.php to the list if you are using PHP + index index.php index.html index.htm index.nginx-debian.html; + + server_name _; + + client_max_body_size 100M; + + location = /favicon.ico { + log_not_found off; + access_log off; + } + + location = /robots.txt { + allow all; + log_not_found off; + access_log off; + } + + location / { + # First attempt to serve request as file, then + # as directory, then fall back to displaying a 404. + try_files $uri $uri/ /index.php$is_args$args; + } + + # Add trailing slash to */wp-admin requests. + rewrite /wp-admin$ $scheme://$host$uri/ permanent; + + # pass PHP scripts to FastCGI server + location ~ \.php$ { + include fastcgi_params; + fastcgi_intercept_errors on; + + # With php-fpm (or other unix sockets): + fastcgi_pass unix:/var/run/php/php7.4-fpm.sock; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + } + + location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ { + expires max; + log_not_found off; + } + + # deny access to .htaccess files, if Apache's document root + # concurs with nginx's one + # + location ~ /\.ht { + deny all; + } + } + +- name: Restart Nginx + service: + name: nginx + state: restarted + +- name: Download WordPress zip + unarchive: + src: https://wordpress.org/wordpress-5.5.3.tar.gz + dest: /var/www/ + remote_src: yes + +- name: Remove old html and replace with wordpress + shell: | + rm -r /var/www/html && + mv /var/www/wordpress /var/www/html && + chown -R www-data:www-data /var/www/html && + find /var/www/html/ -type d -exec chmod 755 {} \; && + find /var/www/html/ -type f -exec chmod 644 {} \; + args: + warn: false + +- name: Install WP-CLI + become: yes + shell: | + wget https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar -O /usr/local/bin/wp + chmod +x /usr/local/bin/wp + +- name: Install configurator script (we modify index.php of WordPress to automatically setup wp-config.php if it doesn't exist) + copy: + dest: /var/www/html/index.php + owner: www-data + group: www-data + mode: 0644 + content: !unsafe | + connect_error) { + die("Connection failed: " . $conn->connect_error); + } + + $dbPass = bin2hex(random_bytes(16)); + + if ($conn->query("create database if not exists wp_database") !== TRUE) { + die("Could not create database, contact SysAdmins" . $conn->error); + } + + if ($conn->query("create user if not exists 'wp_user'@'localhost' IDENTIFIED BY '" . $dbPass . "'") !== TRUE) { + die("Could not create database user, contact SysAdmins " . $conn->error); + } + + if ($conn->query("grant all privileges on wp_database.* TO 'wp_user'@'localhost'") !== TRUE) { + die("Could not grant privs to database user, contact SysAdmins " . $conn->error); + } + + if ($conn->query("FLUSH PRIVILEGES") !== TRUE) { + die("Could not flush privs, contact SysAdmins " . $conn->error); + } + + $config = <<<'EOD' + query("ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '" . bin2hex(random_bytes(16)) . "'") !== TRUE) { + die("Could not grant randomize root pw, contact SysAdmins " . $conn->error); + } + + mysqli_close($conn); + } + + + /** + * Tells WordPress to load the WordPress theme and output it. + * + * @var bool + */ + define( 'WP_USE_THEMES', true ); + + /** Loads the WordPress Environment and Template */ + require __DIR__ . '/wp-blog-header.php'; + +- import_tasks: "./netsoc-cloud/templates/ubuntu-final.yml" diff --git a/netsoc-cloud/templates/ubuntu.yml b/netsoc-cloud/templates/ubuntu.yml new file mode 100644 index 00000000..47d4c803 --- /dev/null +++ b/netsoc-cloud/templates/ubuntu.yml @@ -0,0 +1,3 @@ + +- import_tasks: "./netsoc-cloud/templates/ubuntu-base.yml" +- import_tasks: "./netsoc-cloud/templates/ubuntu-final.yml" \ No newline at end of file diff --git a/packer/netsoc-ubuntu-server/main.yml b/packer/netsoc-ubuntu-server/main.yml deleted file mode 100644 index f3914c37..00000000 --- a/packer/netsoc-ubuntu-server/main.yml +++ /dev/null @@ -1,20 +0,0 @@ ---- -- name: "Provision image" - hosts: default - become: true - roles: - - ansible-requirements - - apt-upgrade - - utf8-locale - - essential-utils - - docker - - shells - - apt-autoremove - - role: lvm-auto-extend - vars: - device: "/dev/vda" - lvm_extended_partition: "2" - lvm_pv_partition: "5" - lvm_vg_lv: "system-root" - - serial-console - - no-root-login diff --git a/packer/netsoc-ubuntu-server/packer.json b/packer/netsoc-ubuntu-server/packer.json deleted file mode 100644 index a62cd0bb..00000000 --- a/packer/netsoc-ubuntu-server/packer.json +++ /dev/null @@ -1,87 +0,0 @@ -{ - "description": "Generic Proxmox Template Packer file", - "variables": { - "vm_id": "", - "template_name": "", - "proxmox_api_url": "", - "proxmox_username": "", - "proxmox_password": "", - "proxmox_node": "", - "http_base_url": "", - "root_password": "" - }, - "sensitive-variables": [ - "proxmox_password", - "root_password" - ], - "provisioners": [ - { - "type": "ansible", - "playbook_file": "./main.yml" - } - ], - "builders": [ - { - "type": "proxmox", - "insecure_skip_tls_verify": true, - "proxmox_url": "{{ user `proxmox_api_url`}}", - "username": "{{ user `proxmox_username`}}", - "password": "{{ user `proxmox_password`}}", - "node": "{{ user `proxmox_node` }}", - - "vm_id": "{{ user `vm_id`}}", - "vm_name": "{{ user `vm_name`}}", - "template_name": "{{ user `template_name`}}", - "template_description": "Ubuntu Server for Netsoc", - - "iso_url": "http://cdimage.ubuntu.com/ubuntu/releases/bionic/release/ubuntu-18.04.4-server-amd64.iso", - "iso_checksum_type": "sha256", - "iso_checksum": "e2ecdace33c939527cbc9e8d23576381c493b071107207d2040af72595f8990b", - "iso_storage_pool": "local", - - "unmount_iso": "true", - - "boot_wait": "5s", - "http_directory": ".", - "boot_command": [ - "", - "", - "/install/vmlinuz", - " initrd=/install/initrd.gz", - " auto-install/enable=true", - " priority=critical", - " passwd/root-login=true", - " passwd/make-user=false", - " passwd/root-password={{ user `root_password`}}", - " passwd/root-password-again={{ user `root_password`}}", - " url={{ user `http_base_url`}}/preseed.cfg", - " --" - ], - - "ssh_username": "root", - "ssh_password": "{{ user `root_password`}}", - "ssh_timeout": "25m", - "cloud_init": true, - "cpu_type": "host", - "cores": "2", - "memory": "1024", - "os": "l26", - "network_adapters": [ - { - "model": "virtio", - "bridge": "vmbr1" - } - ], - "scsi_controller": "virtio-scsi-pci", - "disks": [ - { - "type": "virtio", - "disk_size": "8G", - "storage_pool": "local-lvm", - "storage_pool_type": "lvm", - "format": "raw" - } - ] - } - ] - } \ No newline at end of file diff --git a/packer/netsoc-ubuntu-server/preseed.cfg b/packer/netsoc-ubuntu-server/preseed.cfg deleted file mode 100644 index 37512478..00000000 --- a/packer/netsoc-ubuntu-server/preseed.cfg +++ /dev/null @@ -1,88 +0,0 @@ -#### Preseed file for Ubuntu 18.04 bionic -# Docs: - https://help.ubuntu.com/lts/installation-guide/amd64/apbs01.html -# - https://help.ubuntu.com/18.04/installation-guide/example-preseed.txt - -### Localization -# Locale sets language and country. -d-i debian-installer/locale string en_US.utf8 -# Keyboard selection. -d-i keyboard-configuration/xkb-keymap select us - -### Mirror settings -d-i mirror/country string manual -d-i mirror/http/hostname string ftp.heanet.ie -d-i mirror/http/directory string /pub/ubuntu - -### Clock and time zone setup -# Controls whether or not the hardware clock is set to UTC. -d-i clock-setup/utc boolean true -# see ls -R /usr/share/zoneinfo/ for valid values. -d-i time/zone string UTC - -d-i partman-auto-lvm/new_vg_name string system -d-i partman-auto/method string lvm -d-i partman-auto/disk string /dev/vda -d-i partman-auto/method string lvm -d-i partman-lvm/device_remove_lvm boolean true -d-i partman-lvm/device_remove_lvm_span boolean true -d-i partman-lvm/confirm boolean true -d-i partman-lvm/confirm_nooverwrite boolean true -d-i partman-auto/purge_lvm_from_device boolean true -d-i partman-auto/method string lvm - - -d-i partman-auto/expert_recipe string \ - boot-root :: \ - 300 300 300 ext4 \ - $primary } \ - $bootable{ } \ - method{ format } format{ } \ - use_filesystem{ } filesystem{ ext4 } \ - mountpoint{ /boot } \ - . \ - 500 10000 1000000000 ext4 \ - $lvmok{ } \ - lv_name{ root } \ - method{ format } format{ } \ - use_filesystem{ } filesystem{ ext4 } \ - mountpoint{ / } \ - . \ - 4000 4000 4000 linux-swap \ - $lvmok{ } \ - method{ swap } format{ } \ - lv_name{ swap } \ - . - -d-i partman-lvm/confirm_nooverwrite boolean true -d-i partman-lvm/confirm boolean true -d-i partman-partitioning/confirm_write_new_label boolean true -d-i partman/choose_partition select Finish -d-i partman/confirm_nooverwrite boolean true -d-i partman/confirm boolean true - -### Package selection -tasksel tasksel/first multiselect standard, server - -# Full upgrade packages after debootstrap and unattended upgrades -d-i pkgsel/upgrade select full-upgrade -d-i pkgsel/update-policy select unattended-upgrades - -# Individual additional packages to install -d-i pkgsel/include string openssh-server sudo qemu-guest-agent cloud-init -d-i pkgsel/install-language-support boolean false - - -# Do not report back on what software is installed, and what software is used -popularity-contest popularity-contest/participate boolean false - -### Boot loader installation -d-i grub-installer/bootdev string /dev/vda - -### Run custom commands during the installation -# Enable root login for ansible provisioner to work -d-i preseed/late_command string \ - sed -i 's/#PermitRootLogin prohibit-password/PermitRootLogin yes/' /target/etc/ssh/sshd_config; - -### Finishing up the installation -# Avoid that last message about the install being complete. -d-i finish-install/reboot_in_progress note diff --git a/packer/netsoc-ubuntu-server/roles/ansible-requirements/tasks/main.yml b/packer/netsoc-ubuntu-server/roles/ansible-requirements/tasks/main.yml deleted file mode 100644 index 51aaed5b..00000000 --- a/packer/netsoc-ubuntu-server/roles/ansible-requirements/tasks/main.yml +++ /dev/null @@ -1,20 +0,0 @@ ---- -- name: "Ensure pip installed" - become: yes - apt: - name: - - python-distutils-extra - - python3-apt - - python3-pip - state: latest - update_cache: yes - -- name: Ensure upgraded pip and ansible pip requirements - become: yes - pip: - name: - - pip - - jsondiff - - pymysql # needed for ansible mysql - state: latest - extra_args: --upgrade \ No newline at end of file diff --git a/packer/netsoc-ubuntu-server/roles/apt-autoremove/tasks/main.yml b/packer/netsoc-ubuntu-server/roles/apt-autoremove/tasks/main.yml deleted file mode 100644 index a45f1346..00000000 --- a/packer/netsoc-ubuntu-server/roles/apt-autoremove/tasks/main.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -- name: Remove unneeded APT dependencies - become: yes - apt: - autoremove: yes \ No newline at end of file diff --git a/packer/netsoc-ubuntu-server/roles/apt-upgrade/tasks/main.yml b/packer/netsoc-ubuntu-server/roles/apt-upgrade/tasks/main.yml deleted file mode 100644 index e648f8d3..00000000 --- a/packer/netsoc-ubuntu-server/roles/apt-upgrade/tasks/main.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -- name: Update and upgrade all packages to the latest version - apt: - upgrade: full - update_cache: yes \ No newline at end of file diff --git a/packer/netsoc-ubuntu-server/roles/essential-utils/tasks/main.yml b/packer/netsoc-ubuntu-server/roles/essential-utils/tasks/main.yml deleted file mode 100644 index 0d17fa29..00000000 --- a/packer/netsoc-ubuntu-server/roles/essential-utils/tasks/main.yml +++ /dev/null @@ -1,41 +0,0 @@ ---- - -- name: "Ensure Essential Utilities Installed" - apt: - name: - - iotop - - iftop - - htop - - git - - mysql-client - - tmux - - vim - - curl - - wget - - ncdu - - ranger - - ldnsutils - - nmap - - nano - - less - - mosh - - sudo - - sshfs - - freeipa-client - - oddjob-mkhomedir - - python3-apt - - python3-pip - - e2fsprogs - - apparmor-utils - - nfs-common - - autofs - - zfsutils-linux - state: latest - -- name: Ensure upgraded pip and ansible pip requirements - become: yes - pip: - name: - - pip - state: latest - extra_args: --upgrade \ No newline at end of file diff --git a/packer/netsoc-ubuntu-server/roles/lvm-auto-extend/tasks/main.yml b/packer/netsoc-ubuntu-server/roles/lvm-auto-extend/tasks/main.yml deleted file mode 100644 index 6e10f863..00000000 --- a/packer/netsoc-ubuntu-server/roles/lvm-auto-extend/tasks/main.yml +++ /dev/null @@ -1,34 +0,0 @@ ---- - -- name: "Install LVM Auto Extend Script" - become: yes - copy: - content: | - #!/bin/sh - parted ---pretend-input-tty {{ device }} resizepart {{ lvm_extended_partition }} 100% - parted ---pretend-input-tty {{ device }} resizepart {{ lvm_pv_partition }} 100% - pvresize {{ device }}{{ lvm_pv_partition }} - lvextend -r /dev/mapper/{{ lvm_vg_lv }} -l +100%FREE - - mode: u=rx,g=rx,o=r - dest: /opt/lvm_auto_resize.sh - -- name: "Install LVM Auto Extend Service" - become: yes - copy: - content: | - [Unit] - Description=LVM Auto Extend - - [Service] - Type=oneshot - ExecStart=/opt/lvm_auto_resize.sh - - [Install] - WantedBy=multi-user.target - dest: /etc/systemd/system/lvm-auto-extend.service - -- name: "Enable LVM Auto Extend Service" - systemd: - name: lvm-auto-extend - enabled: yes \ No newline at end of file diff --git a/packer/netsoc-ubuntu-server/roles/netsoc-dir/tasks/main.yml b/packer/netsoc-ubuntu-server/roles/netsoc-dir/tasks/main.yml deleted file mode 100644 index 659ce59c..00000000 --- a/packer/netsoc-ubuntu-server/roles/netsoc-dir/tasks/main.yml +++ /dev/null @@ -1,27 +0,0 @@ ---- -- name: "Create netsoc directory" - become: yes - file: - path: /netsoc/ - mode: 0770 - owner: root - group: root - state: directory - -- name: "Create /netsoc/docker-data directory" - become: yes - file: - path: /netsoc/docker-data - mode: 0770 - owner: root - group: root - state: directory - -- name: "Create /netsoc/certs directory" - become: yes - file: - path: /netsoc/certs - mode: 0770 - owner: root - group: root - state: directory \ No newline at end of file diff --git a/packer/netsoc-ubuntu-server/roles/no-root-login/tasks/main.yml b/packer/netsoc-ubuntu-server/roles/no-root-login/tasks/main.yml deleted file mode 100644 index c4ff93bb..00000000 --- a/packer/netsoc-ubuntu-server/roles/no-root-login/tasks/main.yml +++ /dev/null @@ -1,24 +0,0 @@ ---- - -- name: Fix from default value match - become: yes - lineinfile: - path: /etc/ssh/sshd_config - regexp: '^#PermitRootLogin prohibit-password' - line: PermitRootLogin no - owner: root - group: root - -- name: Fix from preseed value match - become: yes - lineinfile: - path: /etc/ssh/sshd_config - regexp: '^PermitRootLogin yes' - line: PermitRootLogin no - owner: root - group: root - -- name: Lock password - become: yes - command: - cmd: passwd -l root \ No newline at end of file diff --git a/packer/netsoc-ubuntu-server/roles/serial-console/tasks/main.yml b/packer/netsoc-ubuntu-server/roles/serial-console/tasks/main.yml deleted file mode 100644 index 3b047908..00000000 --- a/packer/netsoc-ubuntu-server/roles/serial-console/tasks/main.yml +++ /dev/null @@ -1,45 +0,0 @@ ---- - -- name: Ensure GRUB serial console enabled config - become: yes - blockinfile: - block: | - GRUB_TERMINAL="serial console gfxterm vga_text" - GRUB_SERIAL_COMMAND="serial --speed=115200 --unit=0 --word=8 --parity=no --stop=1" - path: /etc/default/grub - -- name: Ensure GRUB passes systemd serial tty activation to linux kernel config - become: yes - lineinfile: - path: /etc/default/grub - line: | - GRUB_CMDLINE_LINUX="console=tty0 console=lp0 console=ttyS0" - regexp: '^GRUB_CMDLINE_LINUX=""' - state: present - -- name: Ensure updated GRUB - become: yes - shell: update-grub - -- name: Create serial-getty@ttyS0.service.d - become: yes - file: - path: "/etc/systemd/system/serial-getty@ttyS0.service.d" - owner: root - group: root - state: directory - mode: '0775' - - -- name: Create serial-getty@ttyS0.service.d override to enable root auto login - become: yes - copy: - dest: "/etc/systemd/system/serial-getty@ttyS0.service.d/override.conf" - content: | - [Service] - ExecStart= - ExecStart=-/sbin/agetty -a root --noclear %I $TERM - -- name: Daemon-reload systemd - become: yes - command: systemctl daemon-reload \ No newline at end of file diff --git a/packer/netsoc-vyos-router/install.expect b/packer/netsoc-vyos-router/install.expect deleted file mode 100644 index a13a67ce..00000000 --- a/packer/netsoc-vyos-router/install.expect +++ /dev/null @@ -1,27 +0,0 @@ -#!/usr/bin/env expect - -spawn /bin/vbash -expect "vyos@vyos:~$" -send "install image\n" -expect "Would you like to continue" -send "Yes\n" -expect "Partition" -send "\n" -expect "Install the image on?" -send "\n" -expect "Continue?" -send "Yes\n" -expect "How big of a root" -send "\n" -expect "What would you like to name this image" -send "\n" -expect "Which one should I copy" -send "\n" -expect "Enter password for user 'vyos'" -send "vyos\n" -expect "Retype" -send "vyos\n" -expect "Which drive should GRUB" -send "\n" -expect "vyos@vyos" -send "exit\n" \ No newline at end of file diff --git a/packer/netsoc-vyos-router/packer.json b/packer/netsoc-vyos-router/packer.json deleted file mode 100644 index 1c741aab..00000000 --- a/packer/netsoc-vyos-router/packer.json +++ /dev/null @@ -1,86 +0,0 @@ - -{ - "description": "Generic Proxmox Template Packer file", - "variables": { - "proxmox_api_url": "https://localhost:8006/api2/json", - "proxmox_username": "root@pam", - "proxmox_password": "", - "proxmox_node": "", - "iso_file": "" - }, - "provisioners": [ - { - "type": "shell", - "scripts": ["./install.expect"] - }, - { - "type": "shell", - "inline": ["sudo reboot now"], - "expect_disconnect": true - }, - { - "pause_before": "20s", - "timeout": "40s", - "type": "file", - "source": "vyos-userdata-patched-cloud-init_20.1-365-gb987224b-1~bddeb_all.deb", - "destination": "/tmp/vyos-userdata-patched-cloud-init_20.1-365-gb987224b-1~bddeb_all.deb" - }, - { - "type": "shell", - "inline": ["sudo dpkg -i /tmp/vyos-userdata-patched-cloud-init_20.1-365-gb987224b-1~bddeb_all.deb", "sudo pip install paramiko"] - } - ], - "builders": [ - { - "type": "proxmox", - "proxmox_url": "{{ user `proxmox_api_url`}}", - "insecure_skip_tls_verify": true, - "username": "{{ user `proxmox_username`}}", - "password": "{{ user `proxmox_password`}}", - "node": "{{ user `proxmox_node` }}", - - "vm_id": "{{ user `vm_id`}}", - "vm_name": "{{ user `vm_name`}}", - "template_name": "{{ user `template_name`}}", - "template_description": "Vyos Router for Netsoc", - - "boot_wait": "10s", - "boot_command": [ - "", - "vyos", - "vyos", - "configure", - "set interfaces ethernet eth0 address dhcp", - "set service ssh port 22", - "commit", - "save" - ], - - "ssh_username": "vyos", - "ssh_password": "vyos", - "ssh_timeout": "25m", - - "unmount_iso": "true", - "iso_file": "local:iso/vyos-amd64-cloudinit.iso", - - "cores": "2", - "os": "l26", - - "network_adapters": [ - { - "model": "virtio", - "bridge": "vmbr1" - } - ], - - "disks": [ - { - "type": "virtio", - "disk_size": "5G", - "storage_pool": "local-lvm", - "storage_pool_type": "lvm" - } - ] - } - ] - } \ No newline at end of file diff --git a/packer/netsoc-vyos-router/vyos-userdata-patched-cloud-init_20.1-365-gb987224b-1~bddeb_all.deb b/packer/netsoc-vyos-router/vyos-userdata-patched-cloud-init_20.1-365-gb987224b-1~bddeb_all.deb deleted file mode 100644 index b0edeb48..00000000 Binary files a/packer/netsoc-vyos-router/vyos-userdata-patched-cloud-init_20.1-365-gb987224b-1~bddeb_all.deb and /dev/null differ diff --git a/portal-banner.txt b/portal-banner.txt deleted file mode 100644 index 4828a496..00000000 --- a/portal-banner.txt +++ /dev/null @@ -1,52 +0,0 @@ - - ▄███████████████████████████████████████████████████████████▄          -          ██  ██ -          ██ ........ .........      ██ -          ██ :████████: :█████████: ██ -          ██ ,:██████████:..............:███████████:.    ██       -          ██ :█████████████████████████████████████████:    ██       -          ██ :███████████████████████████████████████████:    ██       -          ██ :███████████████████████████████████████████:    ██       -          ██ :████████████████████████████████████████████:   ██       -          ██ :███████████████████████████████████████████:    ██       -          ██ :█████████████████████████████████████████████:   ██       -          ██ :███████████:██████:'''''':██████:████████████:   ██       -          ██ :███████████: ':██:' ':██:' :████████████:  ██        -          ██ :██████████: :███████████: ██ -          ██ :████████: '█████████:   ██       -          ██ :█████:' ':██████:    ██      -          ██ ''''' ''''''     ██     -          ██                ██ -          ▀███████████████████████████████████████████████████████████▀          -                                ██╙╙╙╙╙╙╙╙╙╙╙╙██                                 -                                ████████████████                                 -                       ▄▄▄▄▄▄▄██████████████████▄▄▄▄▄▄▄                         -                      ▄██████████████████████████████████▄                       -         ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄          -        ██                                                            ██         -       ██                                                              ██        -      ██                                                                ██       -     ▐████████████████████████████████████████████████████████████████████▌      -                                                                                 -                                                                                -   ██▄      ██  █████████  ██████████▌  ▄██████    ▄▄██████▄▄     ▄▄█████▄▄    -   ████▄    ██  ██▌            ██▌      ███        ██▀     ▀██   ███▀   ▀▀     -   ██ ▀██▄  ██  ███████▌       ██▌      █████▄▄   ███       ███ ▐██            -   ██   ▀██▄██  ██▌         ██▌           ███   ██▄     ▄██  ██▄           -   ██     ▀███  ███▄▄▄▄▄▄      ██▌     ███▄▄███    ███▄▄▄███     ███▄▄▄██▄    -   ▀▀       ▀▀  ▀▀▀▀▀▀▀▀▀      ▀▀        ▀▀▀▀         ▀▀▀▀           ▀▀▀▀      - - |--------------------------------------------------------------------------| - - -[ Welcome to PORTAL.NETSOC.CO ]- - UCC Netsoc's User Server - - -[ IMPORTANT ]- - if you had signed up to a previous version of netsocadmin - prior to the 17th July 2020, you will need to reset your password: - https://admin.netsoc.co/account/password-reset - - If you are new to Linux it is normal for the cursor to - not move when you type in your password - - > \ No newline at end of file diff --git a/portal-motd.txt b/portal-motd.txt deleted file mode 100644 index e55f5ba6..00000000 --- a/portal-motd.txt +++ /dev/null @@ -1,26 +0,0 @@ - - |--------------------------------------------------------------------------| - - -[ INFORMATION ]- - Most of our members hang out on our community Discord, - if you're new to college, have questions or are simply looking for craic: - https://discord.netsoc.co - - First time using Linux? Try out our tutorial: - https://tutorial.netsoc.co - - Want to know more about us / our services? - https://wiki.netsoc.co - - Want to help out with our backend infrastructure? - https://github.com/UCCNetsoc - or chat with the SysAdmins on our Discord! - - Your use of our services is in agreement to the Acceptable Usage Policy - (available by running the "aup" command). If you do not agree with the - Acceptable Usage Policy please cease use of our services immediately - - - UCC Netsoc - - |--------------------------------------------------------------------------| - diff --git a/provision-auth.yml b/provision-auth.yml deleted file mode 100644 index e2bda6fb..00000000 --- a/provision-auth.yml +++ /dev/null @@ -1,71 +0,0 @@ -- hosts: auth - become: yes - tasks: - # Because the Auth server also hosts the FreeIPA DNS server - # We configured it in create-auth.yml with cloudinit network config to use itself as it's DNS server - # However we haven't created the FreeIPA installation yet so we need to use a temporary nameserver - - shell: | - systemctl stop systemd-resolved - systemctl disable systemd-resolved - - copy: - content: | - nameserver 1.1.1.1 - dest: /etc/resolv.conf - -- name: "Ensure IPA server disk mounted and IPA server created" - hosts: auth - become: yes - roles: - - role: simple-disk - vars: - device: "/dev/vdb" - partition_size: "100%" - fstype: "ext4" - mount_path: "/mnt/data-disk" - mount_opts: "rw" - - role: freeipa-server-docker - vars: - mount: "/mnt/data-disk/freeipa" - interface_address: "{{ interfaces.auth.net0.addresses[0] }}" - vars_files: - - "vars/freeipa.yml" - - "vars/network.yml" - - "vars/secrets.yml" - -- hosts: auth - become: yes - tasks: - # Restore DNS to point at FreeIcaPA localhost DNS - # allows cloud-init to remain working - - copy: - content: | - nameserver {{ interfaces.auth.net0.addresses[0] | ipmath(0) }} - dest: /etc/resolv.conf - vars_files: - - "vars/network.yml" - -- name: "Enroll in IPA server" - hosts: auth - roles: - - role: freeipa-client - vars: - client: - addresses: - - "{{ ansible_default_ipv4.address }}" - vars_files: - - "vars/freeipa.yml" - - "vars/network.yml" - - "vars/secrets.yml" - -- name: "Setup Keycloak" - hosts: auth - roles: - - role: keycloak-docker - vars: - mount: "/mnt/data-disk/keycloak" - realm: "{{ keycloak_freeipa_realm }}" - vars_files: - - "vars/keycloak.yml" - - "vars/keycloak_freeipa_realm.yml" - - "vars/freeipa.yml" - - "vars/secrets.yml" \ No newline at end of file diff --git a/provision-databases.yml b/provision-databases.yml deleted file mode 100644 index 2397cb9e..00000000 --- a/provision-databases.yml +++ /dev/null @@ -1,39 +0,0 @@ - -- name: "Enroll in IPA server" - hosts: databases - roles: - - role: freeipa-client - vars: - client: - addresses: "{{ interfaces.databases.net0.addresses }}" - vars_files: - - "vars/freeipa.yml" - - "vars/network.yml" - - "vars/secrets.yml" - -- name: "Setup Data Disk & MySQL infra, user" - hosts: databases - roles: - - role: simple-disk - vars: - device: "/dev/vdb" - partition_size: "100%" - fstype: "ext4" - mount_path: "/mnt/data-disk" - mount_opts: "rw" - - role: mysql-server-docker - vars: - container_name: mysql-infra - ip: "{{ interfaces.databases.net0.addresses[0] | ipaddr('address') }}" - root_password: "{{ mysql.infra.root_password }}" - mount: "/mnt/data-disk/mysql-infra" - - role: mysql-server-docker - vars: - container_name: mysql-user - ip: "{{ interfaces.databases.net1.addresses[0] | ipaddr('address') }}" - root_password: "{{ mysql.user.root_password }}" - mount: "/mnt/data-disk/mysql-user" - vars_files: - - "vars/mysql.yml" - - "vars/network.yml" - - "vars/secrets.yml" \ No newline at end of file diff --git a/provision-dev-env-container-templates.yml b/provision-dev-env-container-templates.yml new file mode 100644 index 00000000..38fac771 --- /dev/null +++ b/provision-dev-env-container-templates.yml @@ -0,0 +1,293 @@ +- name: Setup + become: yes + hosts: dev + tasks: + - name: Random number to avoid collisions + set_fact: + uuid: '{{ 999999999999999 | random | to_uuid }}' + - name: Configure LXC to use a bridge + copy: + content: USE_LXC_BRIDGE="true" + dest: /etc/default/lxc-net + mode: 0774 + - name: Start lxc-net service + service: + name: lxc-net + state: started + - name: Make /tmp/{{uuid}} dir + file: + state: directory + path: '/tmp/{{ uuid }}/lxc' + - name: Configure general container settings + copy: + content: | + lxc.net.0.type = veth + lxc.net.0.link = lxcbr0 + lxc.net.0.flags = up + lxc.net.0.hwaddr = 00:16:3e:xx:xx:xx + dest: /etc/lxc/default.conf + mode: 0774 + - name: Output Directories Vars + set_fact: + packer_output: '/tmp/{{ uuid }}/output' + template_output: '/tmp/{{ uuid }}/templates' + - name: Ensure Output Dirs + file: + path: '{{ item }}' + state: directory + loop: + - '{{ packer_output }}' + - '{{ template_output }}' + - name: Install depenendencies + apt: + name: + - python3-pip + - git + - lxc-pve-dev + - pkg-config + - dnsmasq + - cloud-guest-utils + - name: Grow sda3 + command: growpart /dev/sda 3 + ignore_errors: yes + - name: Resize sda3 + command: pvresize /dev/sda3 + ignore_errors: yes + - name: Resize root partition + command: lvresize -l +100%FREE /dev/pve/root + ignore_errors: yes + - name: Resize root fs + command: resize2fs /dev/mapper/pve-root + ignore_errors: yes + - name: Disable dnsmasq + systemd: + name: dnsmasq + enabled: no + state: stopped + - name: python3 lxc bindings + pip: + name: git+https://github.com/lxc/python3-lxc + executable: pip3 + - name: python3 ansible + pip: + name: ansible + executable: pip3 + - name: Restart lxc-net + systemd: + name: lxc-net + state: restarted + roles: + - packer + tags: + - always + +- name: Delegate to Dev VM + become: yes + hosts: dev + tasks: + - name: Copy provisioning files + copy: + src: ./lxc/ + dest: '/tmp/{{ uuid }}/lxc/' + tags: + - always + +# Additional base templates can be found here http://uk.images.linuxcontainers.org +- name: Templates + hosts: dev + become: yes + tasks: + - name: Ghost CMS Ubuntu + command: + cmd: > + packer build + -var "name={{ name }}" + -var "dist={{ dist }}" + -var "rel={{ rel }}" + -var "playbook={{ playbook }}" + -var "packer_output={{ packer_output }}" + -var "uuid={{ uuid }}" + /tmp/{{ uuid }}/lxc/packer.json + vars: + name: ghostcms + dist: ubuntu + rel: focal + playbook: ghostcms-ubuntu + tags: + - ghostcms-ubuntu + - name: nginx Ubuntu + command: + cmd: > + packer build + -var "name={{ name }}" + -var "dist={{ dist }}" + -var "rel={{ rel }}" + -var "playbook={{ playbook }}" + -var "packer_output={{ packer_output }}" + -var "uuid={{ uuid }}" + /tmp/{{ uuid }}/lxc/packer.json + vars: + name: nginx + dist: ubuntu + rel: focal + playbook: nginx-ubuntu + tags: + - nginx-ubuntu + - name: MEAN Ubuntu + command: + cmd: > + packer build + -var "name={{ name }}" + -var "dist={{ dist }}" + -var "rel={{ rel }}" + -var "playbook={{ playbook }}" + -var "packer_output={{ packer_output }}" + -var "uuid={{ uuid }}" + /tmp/{{ uuid }}/lxc/packer.json + vars: + name: mean + dist: ubuntu + rel: focal + playbook: mean-ubuntu + tags: + - mean-ubuntu + - name: Game Servers Ubuntu + command: + cmd: > + packer build + -var "name={{ name }}" + -var "dist={{ dist }}" + -var "rel={{ rel }}" + -var "playbook={{ playbook }}" + -var "packer_output={{ packer_output }}" + -var "uuid={{ uuid }}" + /tmp/{{ uuid }}/lxc/packer.json + vars: + name: gameservers + dist: ubuntu + rel: focal + playbook: linuxgsm-ubuntu + tags: + - linuxgsm-ubuntu + - name: Devtools Ubuntu + command: + cmd: > + packer build + -var "name={{ name }}" + -var "dist={{ dist }}" + -var "rel={{ rel }}" + -var "playbook={{ playbook }}" + -var "packer_output={{ packer_output }}" + -var "uuid={{ uuid }}" + /tmp/{{ uuid }}/lxc/packer.json + vars: + name: devtools + dist: ubuntu + rel: focal + playbook: devtools-ubuntu + tags: + - devtools-ubuntu + - name: LEMP Ubuntu + command: + cmd: > + packer build + -var "name={{ name }}" + -var "dist={{ dist }}" + -var "rel={{ rel }}" + -var "playbook={{ playbook }}" + -var "packer_output={{ packer_output }}" + -var "uuid={{ uuid }}" + /tmp/{{ uuid }}/lxc/packer.json + vars: + name: lemp + dist: ubuntu + rel: focal + playbook: lemp-ubuntu + tags: + - lemp-ubuntu + - name: Wordpress Ubuntu + command: + cmd: > + packer build + -var "name={{ name }}" + -var "dist={{ dist }}" + -var "rel={{ rel }}" + -var "playbook={{ playbook }}" + -var "packer_output={{ packer_output }}" + -var "uuid={{ uuid }}" + /tmp/{{ uuid }}/lxc/packer.json + vars: + name: wordpress + dist: ubuntu + rel: focal + playbook: wordpress-ubuntu + tags: + - wordpress-ubuntu + - name: Node Ubuntu + command: + cmd: > + packer build + -var "name={{ name }}" + -var "dist={{ dist }}" + -var "rel={{ rel }}" + -var "playbook={{ playbook }}" + -var "packer_output={{ packer_output }}" + -var "uuid={{ uuid }}" + /tmp/{{ uuid }}/lxc/packer.json + vars: + name: node + dist: ubuntu + rel: focal + playbook: node-ubuntu + tags: + - node-ubuntu + +# Packer exports containers as rootfs.tar.gz with the following structure +# rootfs/ +# - bin +# - boot +# - etc... +# Proxmox expects bin,boot,etc... without parent rootfs dir +# As such we must extract rootfs and then compress just its contents +- name: Fix Archives + become: yes + hosts: dev + tasks: + - name: Get all templates + find: + pattern: 'rootfs.tar.gz' + path: '{{ packer_output }}' + recurse: yes + register: files + - name: Extract + shell: + cmd: 'tar --preserve-permissions --numeric-owner -xzf {{ item.path }} -C {{ item.path | dirname }}' + warn: false + loop: '{{ files.files }}' + - name: Compress + shell: + cmd: "tar -czf {{ template_output }}/netsoc-{{ item.path.split('/')[-2] }}.tar.gz -C {{ item.path | dirname }}/rootfs ." + warn: false + loop: '{{ files.files }}' + tags: + - always + +- name: Copy Templates to Proxmox + become: yes + hosts: dev + tasks: + - name: Copy templates + command: 'mv {{ template_output }}/* /var/lib/vz/template/cache/' + tags: + - always + +- name: Cleanup + become: yes + hosts: dev + tasks: + - name: Tidy up directory + file: + path: '/tmp/{{ uuid }}' + state: absent + tags: + - always diff --git a/provision-docker-swarm-services.yml b/provision-docker-swarm-services.yml deleted file mode 100644 index 6073f02a..00000000 --- a/provision-docker-swarm-services.yml +++ /dev/null @@ -1,118 +0,0 @@ -# Setup Traefik -- name: "Ensure Traefik directory and file config" - hosts: docker_swarm_managers - tasks: - - name: Ensure Traefik file config dir on NFS - become: yes - file: - path: "{{ item }}" - mode: '0770' - state: directory - with_items: # do not use recurse: yes because the /nfs mount could have failed - - /nfs/docker/traefik - - /nfs/docker/traefik/file_config - - - set_fact: - file_config: - http: - routers: - ipa: - entrypoints: - - web-secure - rule: Host(`ipa.netsoc.co`) - middlewares: - - ipa-rewrite - service: ipa - tls: - certResolver: letsencrypt - - discord-router: - entrypoints: - - web-secure - rule: Host(`discord.netsoc.co`) - middlewares: - - discord-redirect - service: unused - tls: - certResolver: letsencrypt - esports-router: - entrypoints: - - web-secure - rule: Host(`esports.netsoc.co`) - middlewares: - - esports-redirect - service: unused - tls: - certResolver: letsencrypt - - middlewares: - discord-redirect: - redirectRegex: - regex: ^(.*) - replacement: 'https://discordapp.com/invite/qPUmuYw' - esports-redirect: - redirectRegex: - regex: ^(.*) - replacement: 'https://discordapp.com/invite/pDUv6Uj' - ipa-rewrite: - headers: - customRequestHeaders: - Host: ipa.vm.netsoc.co - Referer: https://ipa.vm.netsoc.co/ipa - services: - ipa: - loadBalancer: - servers: - - url: "https://ipa.vm.netsoc.co" - unused: - loadBalancer: - servers: - - url: 'https://google.com' - - - name: Write Traefik config - become: yes - copy: - content: "{{ file_config | from_yaml }}" - dest: /nfs/docker/traefik/file_config/config.yml - -- name: "Ensure Traefik loadbalancer running" - hosts: docker_swarm_managers - roles: - - role: traefik - vars: - mount: "/nfs/docker/traefik" - dashboard_domain: traefik.netsoc.co - dashboard_basicauth: netsoc:$$2y$$05$$1Rro44k9JKujdml4I.JAe.tx2iQEnKj4ykoD3Q50Adk5Q.lOu1CsG - config: - log: - level: DEBUG - accessLog: {} - entrypoints: - web: - address: ':80' - web-secure: - address: ':443' - serversTransport: - insecureSkipVerify: true - certificatesResolvers: - letsencrypt: - acme: - email: netsoc@uccsocieties.ie - storage: /traefik/acme.json - dnsChallenge: - provider: cloudflare - delayBeforeCheck: 0 - providers: - file: - directory: /traefik/file_config/ - watch: true - docker: - swarmMode: true - exposedByDefault: false - api: - dashboard: true - insecure: true - vars_files: - - vars/network.yml - - vars/cloudflare.yml - - vars/secrets.yml \ No newline at end of file diff --git a/provision-docker-swarm.yml b/provision-docker-swarm.yml deleted file mode 100644 index b3a21ce5..00000000 --- a/provision-docker-swarm.yml +++ /dev/null @@ -1,54 +0,0 @@ -- name: "Enroll in IPA server" - hosts: docker_swarm - roles: - - role: freeipa-client - vars: - client: - addresses: - - "{{ ansible_default_ipv4.address }}" - vars_files: - - "vars/freeipa.yml" - - "vars/network.yml" - - "vars/secrets.yml" - -- name: Setup NFS client and NFS mount requirements - hosts: docker_swarm - roles: - - role: nfs-client-requirements - - role: autofs-automount - vars: - src: nfs.vm.netsoc.co:/ - mount: /nfs - opts: fstype=nfs4,rw,vers=4.2,sec=krb5p,hard,bg - vars_files: - - "vars/idmap.yml" - - "vars/freeipa.yml" - - "vars/secrets.yml" - -- name: "Ensure nfs directories" - hosts: nfs - become: yes - tasks: - - file: - path: "/nfs/{{ item }}" - state: directory - recurse: yes - with_items: - - "docker/" - -- name: "Ensure Docker Swarm created" - hosts: docker_swarm_managers - roles: - - role: docker-swarm-create - when: "ansible_play_hosts_all.index(inventory_hostname) == 0" - - role: docker-swarm-enroll-manager - when: "ansible_play_hosts_all.index(inventory_hostname) > 0" - vars: - swarm_creator: "{{ groups['docker_swarm_managers'][0] }}" - -- name: "Ensure Docker Swarm workers enrolled" - hosts: docker_swarm_workers - roles: - - docker-swarm-enroll-worker - vars: - swarm_creator: "{{ groups['docker_swarm_managers'][0] }}" \ No newline at end of file diff --git a/provision-infra-all-prometheus-exporters.yml b/provision-infra-all-prometheus-exporters.yml new file mode 100644 index 00000000..efcf9e98 --- /dev/null +++ b/provision-infra-all-prometheus-exporters.yml @@ -0,0 +1,37 @@ +--- + +- name: Create Proxmox Auditor + hosts: control + become: yes + tasks: + - name: Check for existing Auditor + shell: + cmd: "pveum user list --output-format=json | jq .[].userid | grep {{auditor.username}}@pve" + register: output + changed_when: output.rc != 0 + failed_when: output.rc != 1 and output.rc != 0 + - name: Create Auditor + when: output.rc != 0 + shell: "pveum useradd {{auditor.username}}@pve" + - name: Set Auditor Password + when: output.rc != 0 + shell: "printf '%s\n%s\n' {{auditor.password}} {{auditor.password}} | pveum passwd {{auditor.username}}@pve" + - name: Give Auditor user PVEAuditor role + when: output.rc != 0 + shell: "pveum aclmod / -user {{auditor.username}}@pve -role PVEAuditor" + vars_files: + - vars/secrets_mapping.yml + - vars/secrets.yml + tags: + - provision + +- name: Install Exporters on Servers + hosts: prometheus_base + roles: + - prometheus-exporter + vars_files: + - vars/secrets_mapping.yml + - vars/secrets.yml + tags: + - provision + - exporters \ No newline at end of file diff --git a/provision-infra-all-promtail.yml b/provision-infra-all-promtail.yml new file mode 100644 index 00000000..989f3f90 --- /dev/null +++ b/provision-infra-all-promtail.yml @@ -0,0 +1,93 @@ +--- + +- name: PROMTAIL + hosts: promtail + become: yes + tasks: + - name: PROMTAIL - Ensure build dependencies + apt: + name: unzip + state: present + + - name : PROMTAIL - Set config + copy: + dest: /netsoc/promtail.yml + mode: 0777 + content: | + server: + http_listen_port: 9080 + grpc_listen_port: 0 + log_level: "info" + + positions: + filename: /tmp/positions.yaml + + clients: + - url: http://loki.netsoc.co/loki/api/v1/push + basic_auth: + username: {{ loki.username }} + password: {{ loki.password }} + + scrape_configs: + - job_name: syslog + static_configs: + - targets: + - localhost + labels: + job: "syslog-{{ inventory_hostname }}" + __path__: /var/log/syslog + - job_name: varlogs + static_configs: + - targets: + - localhost + labels: + job: "varlogs-{{ inventory_hostname }}" + __path__: /var/log/*.log + - job_name: ipalogs + static_configs: + - targets: + - localhost + labels: + job: "ipalogs-{{ inventory_hostname }}" + __path__: /netsoc/ipa/var/log/* + + - name: PROMTAIL - Install + unarchive: + src: https://github.com/grafana/loki/releases/download/v2.0.0/promtail-linux-amd64.zip + dest: /usr/local/bin + remote_src: yes + + - name: PROMTAIL - Install systemd service + copy: + dest: /etc/systemd/system/promtail.service + mode: 0777 + content: | + [Unit] + Description=Promtail service + After=network.target + + [Service] + Type=simple + User=root + ExecStart=/usr/local/bin/promtail-linux-amd64 -config.file /netsoc/promtail.yml + + [Install] + WantedBy=multi-user.target + + - name: PROMTAIL - Enable and start service + systemd: + state: started + enabled: yes + daemon_reload: yes + name: promtail + + - name: PROMTAIL - Restart service + systemd: + state: restarted + enabled: yes + name: promtail + + vars_files: + - vars/secrets_mapping.yml + - vars/secrets.yml + - vars/network.yml diff --git a/provision-infra-databases-export-keycloak-freeipa-realm.yml b/provision-infra-databases-export-keycloak-freeipa-realm.yml new file mode 100644 index 00000000..66dbd8dd --- /dev/null +++ b/provision-infra-databases-export-keycloak-freeipa-realm.yml @@ -0,0 +1,27 @@ +# Export keycloak realm to ./keycloak-realm-exported.json +- name: "Exporting Keycloak realm to ./vars/keycloak-realm-exported.json" + hosts: databases.infra.netsoc.co + become: yes + tasks: + - shell: | # pretty bad way of doing this but who cares + rm -f /netsoc/keycloak/realm/freeipa-realm-exported.json + docker restart auth_keycloak_1 + sleep 20s + docker exec -d auth_keycloak_1 /opt/jboss/keycloak/bin/standalone.sh -Djboss.socket.binding.port-offset=10000 -Dkeycloak.migration.action=export -Dkeycloak.migration.provider=singleFile -Dkeycloak.migration.realmName=freeipa -Dkeycloak.migration.usersExportStrategy=REALM_FILE -Dkeycloak.migration.file=/tmp/realm/freeipa-realm-exported.json + sleep 30s + docker restart auth_keycloak_1 + args: + executable: /bin/bash + ignore_errors: yes + - fetch: + src: /netsoc/keycloak/realm/freeipa-realm-exported.json + dest: ./vars/keycloak-realm-exported.json + flat: yes + - shell: + rm /netsoc/keycloak/realm/freeipa-realm-exported.json + +- name: Encrypt vault + hosts: localhost + tasks: + - shell: + cmd: ansible-vault encrypt --vault-password-file ./_vault_pass ./vars/keycloak-realm-exported.json \ No newline at end of file diff --git a/provision-infra-databases.yml b/provision-infra-databases.yml new file mode 100644 index 00000000..d8d3e37f --- /dev/null +++ b/provision-infra-databases.yml @@ -0,0 +1,322 @@ +--- +- name: "INITIAL SETUP" + hosts: databases.infra.netsoc.co + become: yes + roles: + - ansible-requirements + - utf8-locale + - docker + tasks: + - name: "Make /netsoc only readable by root" + file: + path: "/netsoc" + owner: root + group: root + mode: '1770' + tags: + - initial + +- name: "DATABASES - MySQL/PG" + hosts: databases.infra.netsoc.co + become: yes + tasks: + - name: MYSQL/PG/PROM - Ensure directories exist + file: + path: "/netsoc/{{ item }}" + owner: root + group: root + mode: '0755' + state: directory + with_items: + - mysql + - pg + + - name: PG - Install psycopg2 (needed for ansible pg driver) + apt: + name: python3-psycopg2 + state: present + + - name: MYSQL/PG - Remember Compose definition + set_fact: + definition: + version: "3.5" + services: + mysql: + hostname: "mysql.databases.infra.netsoc.co" + command: --default-authentication-plugin=mysql_native_password + image: mysql:8.0 + restart: always + environment: + MYSQL_ROOT_PASSWORD: "{{ mysql.infra.root_password }}" + volumes: + - "/netsoc/mysql:/var/lib/mysql" + ports: + - "3306:3306" + pg: + hostname: "pg.databases.netsoc.co" + image: postgres:12.3 + restart: always + environment: + POSTGRES_PASSWORD: "{{ postgres.infra.postgres_password }}" + volumes: + - "/netsoc/pg:/var/lib/postgresql/data" + ports: + - "5432:5432" + + - name: MYSQL/PG - Setup services + docker_compose: + project_name: databases + recreate: smart + remove_orphans: yes + state: present + definition: "{{ definition }}" + vars_files: + - "vars/network.yml" + - "vars/secrets_mapping.yml" + - "vars/secrets.yml" + tags: + - provision + +- name: "DATABASES - Prometheus" + hosts: databases.infra.netsoc.co + become: yes + tasks: + - name: PROM - Ensure directories exist + file: + path: "/netsoc/{{ item }}" + owner: root + group: root + mode: '0755' + state: directory + with_items: + - prometheus + - blackbox_exporter + - pve + roles: + - role: prometheus-server + vars: + prometheus_dir: "/netsoc/prometheus" + blackbox_exporter_dir: "/netsoc/blackbox_exporter" + pve_dir: "/netsoc/pve" + vars_files: + - "vars/network.yml" + - "vars/secrets_mapping.yml" + - "vars/secrets.yml" + tags: + - provision + - prometheus + +- name: "DATABASES - FreeIPA/Keycloak" + hosts: databases.infra.netsoc.co + become: yes + tasks: + - name: IPA - Ensure IPA directory exists + file: + path: "/netsoc/ipa" + owner: root + group: root + # Needs to be 775 as this folder is accessed internally by a dirsrv user + # https://github.com/freeipa/freeipa-container/issues/281 + mode: '0755' + state: directory + + - name: KEYCLOAK - Ensure Keycloak directory exists + file: + path: "/netsoc/keycloak" + owner: root + group: root + # Uses UIDs interally too + mode: '0777' + state: directory + + - name: KEYCLOAK - Ensure Keycloak directories exists + file: + path: "/netsoc/keycloak/{{ item }}" + owner: root + group: root + # Uses UIDs interally too + mode: '0777' + state: directory + with_items: + - realm + + - name: KEYCLOAK - Ensure realm file + copy: + src: "./vars/keycloak-realm-exported.json" + dest: "/netsoc/keycloak/realm/realm.json" + mode: 0755 + + - name: IPA/KEYCLOAK - Remember Compose definition + set_fact: + definition: + version: "3.5" + services: + keycloak: + image: uccnetsoc/keycloak:9.0.3-themed + environment: + DB_VENDOR: h2 + KEYCLOAK_USER: "{{ keycloak.username }}" + KEYCLOAK_PASSWORD: "{{ keycloak.password }}" + KEYCLOAK_IMPORT: "/tmp/realm/realm.json" + restart: always + ports: + - "8443:8443" + volumes: + - "/netsoc/keycloak/realm:/tmp/realm/" + - "/etc/localtime:/etc/localtime:ro" + ipa: + image: freeipa/freeipa-server:centos-8-4.8.4 + command: > + --unattended + --realm={{ ipa.realm }} + --domain={{ ipa.domain }} + --ds-password={{ ipa.ds_password }} + --admin-password={{ ipa.admin_password }} + --setup-dns + --forwarder=1.1.1.1 + --forward-policy=only + --ssh-trust-dns + hostname: "{{ ipa.server }}" + dns: 127.0.0.1 + environment: + IPA_SERVER_HOSTNAME: "{{ ipa.server }}" + IPA_SERVER_IP: "{{ ansible_default_ipv4.address }}" + ports: + - "80:80" # http + - "443:443" # https + - "389:389" # ldap + - "636:636" # ldaps + - "88:88" # kerberos + - "464:464" # kpasswd + - "749:749" # kpasswd + - "123:123" # ntp + - "{{ ansible_default_ipv4.address }}:53:53/tcp" # dns + - "{{ ansible_default_ipv4.address }}:53:53/udp" + volumes: + - "/sys/fs/cgroup:/sys/fs/cgroup:ro" + - "/etc/machine-id:/etc/machine-id" + - "/netsoc/ipa:/data:Z" + restart: always + tmpfs: + - "/run" + - "/tmp" + sysctls: + # Fixes: + # DEBUG The ipa-server-install command failed, exception: + # RuntimeError: IPv6 stack is enabled in the kernel but there is no interface that has ::1 address assigned. + # Add ::1 address resolution to "lo" interface. You might need to enable IPv6 on the interface "lo" in sysctl.conf. + net.ipv6.conf.lo.disable_ipv6: 0 + + - name: IPA/KEYCLOAK - Setup services + docker_compose: + project_name: auth + recreate: always + pull: yes + remove_orphans: yes + state: present + definition: "{{ definition }}" + + - name: IPA - Wait for IPA install to finish (8-12 minutes, check /netsoc/ipa/var/log/ipa-server-configure-first.log if time out) + wait_for: + path: "/netsoc/ipa/var/log/ipaserver-install.log" + search_regex: "The ipa-server-install command" + timeout: 1200 # 20 minutes + + - name: IPA - Check install status + become: yes + shell: "grep -i 'The ipa-server-install command was successful' /netsoc/ipa/var/log/ipaserver-install.log" + + - name: IPA - Ensure HTTP redirect disabler (disables some of their apache config and lets us reverse proxy IPA WebUI) + become: yes + copy: + content: | + # VERSION 6 - DO NOT REMOVE THIS LINE + + # ORIGINAL + # RewriteEngine on + + # # By default forward all requests to /ipa. If you don't want IPA + # # to be the default on your web server comment this line out. + # RewriteRule ^/$ https://ipa.infra.netsoc.co/ipa/ui [L,NC,R=301] + + # # Redirect to the fully-qualified hostname. Not redirecting to secure + # # port so configuration files can be retrieved without requiring SSL. + # RewriteCond %{HTTP_HOST} !^ipa.vm.netsoc.co$ [NC] + # RewriteRule ^/ipa/(.*) http://ipa.infra.netsoc.co/ipa/$1 [L,R=301] + + # # Redirect to the secure port if not displaying an error or retrieving + # # configuration. + # RewriteCond %{SERVER_PORT} !^443$ + # RewriteCond %{REQUEST_URI} !^/ipa/(errors|config|crl) + # RewriteCond %{REQUEST_URI} !^/ipa/[^\?]+(\.js|\.css|\.png|\.gif|\.ico|\.woff|\.svg|\.ttf|\.eot)$ + # RewriteRule ^/ipa/(.*) https://ipa.infra.netsoc.co/ipa/$1 [L,R=301,NC] + + # # Rewrite for plugin index, make it like it's a static file + # RewriteRule ^/ipa/ui/js/freeipa/plugins.js$ /ipa/wsgi/plugins.py [PT] + + # MODIFIED + RewriteEngine on + + # By default forward all requests to /ipa. If you don't want IPA + # to be the default on your web server comment this line out. + RewriteRule ^/$ /ipa/ui [L,NC,R=301] + + # Redirect to the fully-qualified hostname. Not redirecting to secure + # port so configuration files can be retrieved without requiring SSL. + #RewriteCond %{HTTP_HOST} !^ipa.vm.netsoc.co$ [NC] + #RewriteRule ^/ipa/(.*) http://ipa.infra.netsoc.co/ipa/$1 [L,R=301] + + # Redirect to the secure port if not displaying an error or retrieving + # configuration. + #RewriteCond %{SERVER_PORT} !^443$ + #RewriteCond %{REQUEST_URI} !^/ipa/(errors|config|crl) + #RewriteCond %{REQUEST_URI} !^/ipa/[^\?]+(\.js|\.css|\.png|\.gif|\.ico|\.woff|\.svg|\.ttf|\.eot)$ + #RewriteRule ^/ipa/(.*) https://ipa.infra.netsoc.co/ipa/$1 [L,R=301,NC] + + # Rewrite for plugin index, make it like it's a static file + RewriteRule ^/ipa/ui/js/freeipa/plugins.js$ /ipa/wsgi/plugins.py [PT] + dest: "/netsoc/ipa/etc/httpd/conf.d/ipa-rewrite.conf" + + - set_fact: + recursive_dns_trusted_network: + - 10.0.0.0/8 + - 172.16.0.0/12 + - 192.168.0.0/16 + + - name: IPA - Insert trusted network ACLs for DNS + blockinfile: + path: "/netsoc/ipa/etc/named.conf" + insertbefore: "BOF" + marker: "# Trusted Network For Recursive DNS Queries - {mark}" + block: | + acl "trusted_network" { + {% for trusted in recursive_dns_trusted_network %} + {{ trusted }}; + {% endfor %} + }; + + - name: IPA - Modify IPA /etc/named to support queries from intralan + blockinfile: + path: "/netsoc/ipa/etc/named.conf" + insertafter: "options" + marker: "# Enable Trusted Network For Recursive DNS Queries - {mark}" + block: | + allow-recursion { trusted_network; }; + allow-query-cache { trusted_network; }; + + - name: IPA - Restart + docker_compose: + project_name: auth + restarted: yes + state: present + services: + - ipa + definition: "{{ definition }}" + vars_files: + - "vars/network.yml" + - "vars/secrets_mapping.yml" + - "vars/secrets.yml" + tags: + - provision + - freeipa + - keycloak diff --git a/provision-infra-games.yml b/provision-infra-games.yml new file mode 100644 index 00000000..eb76f83a --- /dev/null +++ b/provision-infra-games.yml @@ -0,0 +1,27 @@ +--- +- name: "INITIAL SETUP" + hosts: games.infra.netsoc.co + become: yes + roles: + - ansible-requirements + - utf8-locale + - docker + tasks: + - name: "Make /netsoc only readable by root" + file: + path: "/netsoc" + owner: root + group: root + mode: '1770' + tags: + - initial + +- name: Ensure Minecraft Servers + hosts: games.infra.netsoc.co + roles: + - role: minecraft + vars: + mount: "/netsoc/minecraft" + tags: + - minecraft + diff --git a/provision-infra-minecraft.yml b/provision-infra-minecraft.yml new file mode 100644 index 00000000..aa7debae --- /dev/null +++ b/provision-infra-minecraft.yml @@ -0,0 +1,84 @@ +--- +- name: MINECRAFT - INITIAL SETUP + hosts: minecraft.infra.netsoc.co + become: yes + roles: + - ansible-requirements + - utf8-locale + - docker + tags: + - init + +- name: MINECRAFT - SETUP SERVER + hosts: minecraft.infra.netsoc.co + become: yes + tasks: + - name: Rember Manifest Map + set_fact: + manifest: "{{ lookup('file', '{{ playbook_dir }}/roles/minecraft/files/manifest.json') | from_json }}" + tags: + - server + + - name: Ensure directories exist + file: + path: '/{{ item }}' + owner: root + group: root + mode: '0777' + state: directory + with_items: + - data + - 'data/mods' + + - name: Ensure server icon + copy: + src: '{{ playbook_dir }}/roles/minecraft/files/server-icon.png' + dest: /data/server-icon.png + + - name: Ensure server.properties + copy: + src: '{{ playbook_dir }}/roles/minecraft/files/server.properties' + dest: /data/server.properties + + - name: Download Mods + get_url: + dest: '/data/mods' + url: "{{ lookup('url', 'https://addons-ecs.forgesvc.net/api/v2/addon/{{item.projectID}}/file/{{item.fileID}}/download-url') | replace(' ', '%20') }}" + force: no + loop: '{{ manifest.files }}' + + - name: Remember Compose definition + set_fact: + minecraft_definition: + version: '3.8' + services: + minecraft: + container_name: minecraft + image: itzg/minecraft-server:java17 + ports: + - '1194:25565/tcp' + - '19565:19565' + restart: always + volumes: + - '/data:/data' + environment: + EULA: 'TRUE' + TYPE: FORGE + MEMORY: 10G + VERSION: '{{ manifest.minecraft.version }}' + tags: + - server + + - name: Setup compose + docker_compose: + project_name: minecraft + recreate: always + restarted: yes + pull: yes + remove_orphans: yes + state: present + definition: '{{ minecraft_definition }}' + tags: + - server + tags: + - minecraft diff --git a/provision-infra-web.yml b/provision-infra-web.yml new file mode 100644 index 00000000..4b9f0e11 --- /dev/null +++ b/provision-infra-web.yml @@ -0,0 +1,1610 @@ +--- +- name: 'INITIAL SETUP' + hosts: web.infra.netsoc.co + become: yes + roles: + - ansible-requirements + - utf8-locale + - docker + tasks: + - name: 'Make /netsoc only readable by root' + file: + path: '/netsoc' + owner: root + group: root + mode: '1770' + tags: + - initial + +# We don't do this on the web host because ansible needs a python driver installed on a system that uses these +- name: 'WIKI (DATABASES) - Create databases for services' + hosts: databases.infra.netsoc.co + become: yes + tasks: + - name: WIKI - Ensure database + postgresql_db: + name: '{{ wikijs.postgres.db }}' + state: present + login_host: '{{ databases.infra.postgres }}' + login_password: '{{ postgres.infra.postgres_password }}' + + - name: WIKI - Ensure user + postgresql_user: + name: '{{ wikijs.postgres.username }}' + password: '{{ wikijs.postgres.password }}' + login_host: '{{ databases.infra.postgres }}' + login_password: '{{ postgres.infra.postgres_password }}' + no_log: true + + - name: WIKI - Ensure user has access to database + postgresql_privs: + db: '{{ wikijs.postgres.db }}' + role: '{{ wikijs.postgres.username }}' + objs: ALL_IN_SCHEMA + privs: SELECT,INSERT,UPDATE,DELETE + login_host: '{{ databases.infra.postgres }}' + login_password: '{{ postgres.infra.postgres_password }}' + vars_files: + - 'vars/network.yml' + - 'vars/secrets_mapping.yml' + - 'vars/secrets.yml' + tags: + - provision + - wiki + +- name: 'TRAEFIK' + hosts: web.infra.netsoc.co + become: yes + tasks: + - name: TRAEFIK - Ensure directories exist + file: + path: '/netsoc/{{ item }}' + owner: root + group: root + mode: '0755' + state: directory + with_items: + - traefik + - traefik/file_config + + - name: TRAEFIK - Ensure Docker network + become: yes + docker_network: + name: traefik + attachable: yes + + - name: TRAEFIK & NETSOC CLOUD - Load Netsoc Cloud config + set_fact: + netsoc_cloud_config: "{{ lookup('file', './vars/netsoc_cloud_api_config.yml') | from_yaml }}" + + - name: TRAEFIK & NETSOC CLOUD - Generate entrypoints for web + Netsoc Cloud + set_fact: + text_traefik_entrypoints: | + web: + address: ':80' + web-secure: + address: ':443' + metrics: + address: ':8082' + {% for i in range(netsoc_cloud_config.proxmox.network.port_forward.range[0],netsoc_cloud_config.proxmox.network.port_forward.range[1]+1) %} + netsoc-cloud-{{i}}-tcp: + address: ':{{i}}/tcp' + netsoc-cloud-{{i}}-udp: + address: ':{{i}}/udp' + {% endfor %} + + - name: TRAEFIK - Remember static config + set_fact: + traefik_static_config: + log: + level: INFO + format: 'json' + accessLog: + format: 'json' + entrypoints: '{{ text_traefik_entrypoints | from_yaml }}' + metrics: + prometheus: + entrypoint: metrics + serversTransport: + insecureSkipVerify: true + certificatesResolvers: + letsencrypt-tls: + acme: + email: netsoc@uccsocieties.ie + storage: /traefik/acme.json + tlsChallenge: {} + letsencrypt-dns: + acme: + email: netsoc@uccsocieties.ie + storage: /traefik/acme-cf.json + dnsChallenge: + provider: cloudflare + delayBeforeCheck: 10 + resolvers: + - '1.1.1.1:53' + - '1.0.0.1:53' + providers: + file: + directory: /traefik/file_config/ + watch: true + docker: + exposedByDefault: false + http: # cloud http config + endpoint: + - 'https://api.netsoc.cloud/v1/proxmox/traefik-config?key={{ netsoc_cloud_config.proxmox.network.traefik.config_key }}' + pollInterval: 20s + pollTimeout: 10s + api: + dashboard: true + insecure: true + + - name: TRAEFIK - Remember file config + set_fact: + traefik_file_config: + http: + routers: + leela-fallback: + entrypoints: + - web-secure + rule: PathPrefix(`/`) # matches everything + service: leela-https + priority: 1 # last possible match + tls: + certResolver: letsencrypt-tls + # leela-fallback-evan: + # entrypoints: + # - web-secure + # rule: Host(`iamevan.me`) + # service: leela-https + # tls: + # certResolver: letsencrypt-tls + # leela-fallback-evan2: + # entrypoints: + # - web-secure + # rule: Host(`www.iamevan.me`) + # service: leela-https + # tls: + # certResolver: letsencrypt-tls + leela-fallback-https: + entrypoints: + - web-secure + rule: >- + Host(`cardinaldesign.io`, + `colm.cf`, + `colm.design`, + `ghostking.rip`, + `ghostkingisdead.com`, + `hau.su`, + `hausurecords.com`, + `kaizokucon.ie`, + `l.hausurecords.com`, + `olwen.ie`, + `reeling.party`, + `ultimateeastcoastusatrip.ie`, + `www.cardinaldesign.io`, + `www.colm.design`, + `www.ghostking.rip`, + `www.ghostkingisdead.com`, + `www.hausurecords.com`, + `www.olwen.ie`, + `www.reeling.party`, + `www.ultimateeastcoastusatrip.ie`) + service: leela-https + tls: + certResolver: letsencrypt-tls + leela-fallback-http: + entrypoints: + - web-secure + rule: >- + Host( + `vune.ie`, + `www.vune.ie`, + `dsn.ie`, + `refund.noahsc.xyz`, + `www.silentmovies.media`, + `silentmovies.media`, + `ultimateeastcoastusatrip.ie`) + service: leela-http + tls: + certResolver: letsencrypt-tls + leela-fallback-user-sites: + entrypoints: + - web-secure + rule: HostRegexp(`{subdomain:[a-zA-Z0-9-]+}.netsoc.co`, `www.{subdomain:[a-zA-Z0-9-]+}.netsoc.co`) + service: leela-http + priority: 2 + tls: + certResolver: letsencrypt-dns + domains: + - main: 'netsoc.co' + sans: + - '*.netsoc.co' + # student-media: + # entrypoints: + # - web-secure + # rule: Host(`motley.ie`,`www.motley.ie`,`www.uccexpress.ie`,`uccexpress.ie`) + # service: studentmedia-https + # tls: + # certResolver: letsencrypt-tls + control: + entrypoints: + - web-secure + rule: Host(`proxmox.netsoc.co`) + service: control-https + tls: + certResolver: letsencrypt-tls + ipa: + entrypoints: + - web-secure + rule: Host(`ipa.netsoc.co`) + middlewares: + - ipa-rewrite + service: ipa + tls: + certResolver: letsencrypt-dns + keycloak: + entrypoints: + - web-secure + rule: Host(`keycloak.netsoc.co`) + service: keycloak + tls: + certResolver: letsencrypt-dns + discord-router: + entrypoints: + - web-secure + rule: Host(`discord.netsoc.co`) + middlewares: + - discord-redirect + service: unused + tls: + certResolver: letsencrypt-dns + constitution-router: + entrypoints: + - web-secure + rule: Host(`constitution.netsoc.co`) + middlewares: + - constitution-redirect + service: unused + tls: + certResolver: letsencrypt-dns + esports-router: + entrypoints: + - web-secure + rule: Host(`esports.netsoc.co`) + middlewares: + - esports-redirect + service: unused + tls: + certResolver: letsencrypt-dns + prometheus: + entrypoints: + - web-secure + rule: Host(`prometheus.netsoc.co`) + middlewares: + - prometheus-auth + service: prometheus + tls: + certResolver: letsencrypt-dns + mentorships-router: + entrypoints: + - web-secure + rule: Host(`mentorships.netsoc.co`) + middlewares: + - mentorships-redirect + service: unused + tls: + certResolver: letsencrypt-dns + minecraft-router: + entrypoints: + - web-secure + rule: Host(`minecraft.netsoc.co`) + middlewares: + - minecraft-redirect + service: unused + tls: + certResolver: letsencrypt-dns + tutorial-router: + entrypoints: + - web-secure + rule: Host(`tutorial.netsoc.co`) + middlewares: + - tutorial-redirect + service: unused + tls: + certResolver: letsencrypt-dns + hlm-router: + entrypoints: + - web-secure + rule: Host(`hlm.netsoc.co`) + middlewares: + - hlm-redirect + service: unused + tls: + certResolver: letsencrypt-dns + middlewares: + discord-redirect: + redirectRegex: + regex: ^(.*) + replacement: 'https://discord.gg/zHkxHYjdqH' + constitution-redirect: + redirectRegex: + regex: ^(.*) + replacement: 'https://wiki.netsoc.co/en/about/constitution' + permanent: true + minecraft-redirect: + redirectRegex: + regex: ^(.*) + replacement: 'https://wiki.netsoc.co/en/services/minecraft' + permanent: true + esports-redirect: + redirectRegex: + regex: ^(.*) + replacement: 'https://discordapp.com/invite/pDUv6Uj' + mentorships-redirect: + redirectRegex: + regex: ^(.*) + replacement: 'https://wiki.netsoc.co/en/technology/mentorships' + ipa-rewrite: + headers: + customRequestHeaders: + Host: ipa.infra.netsoc.co + Referer: https://ipa.infra.netsoc.co/ipa/ + hlm-redirect: + redirectRegex: + regex: ^(.*) + replacement: 'https://hlm.netsoc.cloud' + prometheus-auth: + basicAuth: + users: + - "{{ prometheus.username }}:{{ prometheus.password | password_hash('bcrypt') }}" + tutorial-redirect: + redirectRegex: + regex: ^(.*) + replacement: 'https://wiki.netsoc.co/en/services/tutorial' + permanent: true + services: + ipa: + loadBalancer: + servers: + - url: 'https://{{ databases.infra.ipa }}' + keycloak: + loadBalancer: + servers: + - url: 'https://{{ databases.infra.keycloak }}:8443' + prometheus: + loadBalancer: + servers: + - url: 'http://{{ databases.infra.prometheus }}:9090' + unused: + loadBalancer: + servers: + - url: 'https://google.com' + leela-https: + loadBalancer: + servers: + - url: 'https://10.0.30.135' + studentmedia-https: + loadBalancer: + servers: + - url: 'https://netsoc2.ucc.ie' + control-https: + loadBalancer: + servers: + - url: 'https://10.0.30.20:8006' + leela-http: + loadBalancer: + servers: + - url: 'http://10.0.30.135' + + - name: TRAEFIK - Write static config + copy: + content: '{{ traefik_static_config | from_yaml }}' + dest: /netsoc/traefik/config.yml + + - name: TRAEFIK - Write file config + copy: + content: '{{ traefik_file_config | from_yaml }}' + dest: /netsoc/traefik/file_config/config.yml + + - name: TRAEFIK - Write Cloudflare DNS token + copy: + content: '{{ cloudflare.api.dns_api_token }}' + dest: /netsoc/traefik/cloudflare_dns_api_token.txt + + - name: TRAEFIK - Remember Compose definition + set_fact: + traefik_definition: + version: '3.8' + networks: + traefik: + external: true + services: + server: + restart: always + image: traefik:v2.3.2 + command: traefik --configFile=/traefik/config.yml --log.format=json + volumes: + - '/var/run/docker.sock:/var/run/docker.sock' + - '/netsoc/traefik:/traefik/:shared' + environment: + CLOUDFLARE_DNS_API_TOKEN_FILE: '/traefik/cloudflare_dns_api_token.txt' + network_mode: 'host' + labels: + # global redirect to https + traefik.enable: 'true' + traefik.docker.network: 'traefik' + traefik.http.routers.https-redirect.entrypoints: 'web' + traefik.http.routers.https-redirect.rule: 'HostRegexp(`{any:.*}`)' + traefik.http.routers.https-redirect.middlewares: 'https-redirect' + traefik.http.middlewares.https-redirect.redirectscheme.scheme: 'https' + traefik.http.middlewares.https-redirect.redirectscheme.port: '443' + traefik.http.middlewares.https-redirect.redirectscheme.permanent: 'true' + + # passworded dashboard + traefik.http.routers.dashboard.entrypoints: 'web-secure' + traefik.http.routers.dashboard.rule: 'Host(`traefik.netsoc.co`)' + traefik.http.routers.dashboard.tls.certResolver: 'letsencrypt-dns' + traefik.http.routers.dashboard.service: 'dashboard-service' + traefik.http.services.dashboard-service.loadbalancer.server.port: '8080' + traefik.http.middlewares.dashboard-auth.basicauth.users: "{{ traefik.username }}:{{ traefik.password | password_hash('bcrypt') | replace('$', '$$') }}" + traefik.http.routers.dashboard.middlewares: 'dashboard-auth@docker' + logging: + options: + max-size: '500M' + max-file: '5' + + - name: TRAEFIK - Setup compose + docker_compose: + project_name: traefik + pull: yes + recreate: always + restarted: yes + remove_orphans: yes + state: present + definition: '{{ traefik_definition }}' + vars_files: + - 'vars/network.yml' + - 'vars/secrets_mapping.yml' + - 'vars/secrets.yml' + tags: + - provision + - traefik + - netsoc-cloud + +- name: 'STATIC WEBSITES' + hosts: web.infra.netsoc.co + become: yes + tasks: + - name: STATIC WEBSITES - Remember Compose definition + set_fact: + static_websites_definition: + version: '3.8' + networks: + traefik: + external: true + services: + netsoc.co: + image: ghcr.io/uccnetsoc/netsoc.co:latest + networks: + traefik: + labels: + traefik.enable: 'true' + traefik.http.routers.website.rule: 'Host(`netsoc.co`, `www.netsoc.co`)' + traefik.http.routers.website.entrypoints: 'web-secure' + traefik.http.routers.website.tls.certResolver: 'letsencrypt-dns' + traefik.http.services.website-service.loadbalancer.server.port: '80' + traefik.http.routers.website.service: 'website-service' + traefik.http.middlewares.rk-redirect.redirectregex.regex: '^(http|https)://netsoc.co/(r(?:[^k].*)|[^r].*)?$$' + traefik.http.middlewares.rk-redirect.redirectregex.replacement: 'https://netsoc.co/rk/$${2}' + traefik.http.middlewares.rk-redirect.redirectregex.permanent: 'true' + traefik.http.middlewares.rk-strip.stripprefix.prefixes: '/rk' + traefik.http.middlewares.www-redirect.redirectregex.regex: '^(http|https)://www.netsoc.co/(.*)' + traefik.http.middlewares.www-redirect.redirectregex.replacement: '^(http|https)://netsoc.co/$${2}' + traefik.http.middlewares.www-redirect.redirectregex.permanent: 'true' + traefik.http.routers.website.middlewares: 'rk-redirect@docker,rk-strip@docker,www-redirect@docker' + traefik.docker.network: 'traefik' + restart: always + blog: + image: ghost:5.8.3-alpine + networks: + traefik: + environment: + url: 'https://blog.netsoc.co/' + mail__transport: SMTP + mail__from: 'noreply@blog.netosc.co' + mail__options__service: Mailgun + mail__options__host: "{{ blog.smtp.hostname }}" + mail__options__port: "{{ blog.smtp.port }}" + mail__options__secureConnection: 'false' + mail__options__auth__user: "{{ blog.smtp.username }}" + mail__options__auth__pass: "{{ blog.smtp.password }}" + labels: + traefik.enable: 'true' + traefik.http.routers.blog.rule: 'Host(`blog.netsoc.co`)' + traefik.http.routers.blog.entrypoints: 'web-secure' + traefik.http.routers.blog.tls.certResolver: 'letsencrypt-dns' + traefik.http.services.blog-service.loadbalancer.server.port: '2368' + traefik.http.routers.blog.service: 'blog-service' + traefik.docker.network: 'traefik' + volumes: + - /netsoc/blog:/var/lib/ghost/content + restart: always + robots-disallow: + image: wikiwi/robots-disallow + networks: + traefik: + labels: + traefik.enable: 'true' + traefik.http.routers.proxmox.rule: 'Host(`proxmox.netsoc.co`) && Path(`/robots.txt`)' + traefik.http.routers.proxmox.entrypoints: 'web-secure' + traefik.http.routers.proxmox.tls.certResolver: 'letsencrypt-dns' + traefik.http.services.proxmox-service.loadbalancer.server.port: '8080' + traefik.http.routers.proxmox.service: 'proxmox-service' + traefik.docker.network: 'traefik' + + - name: STATIC WEBSITES - Setup compose + docker_compose: + project_name: static_websites + remove_orphans: yes + pull: yes + state: present + definition: '{{ static_websites_definition }}' + vars_files: + - 'vars/network.yml' + - 'vars/secrets_mapping.yml' + - 'vars/secrets.yml' + tags: + - provision + - static-websites + +- name: 'WIKI' + hosts: web.infra.netsoc.co + become: yes + tasks: + - name: WIKI - Remember Compose definition + set_fact: + wiki_definition: + version: '3.8' + networks: + traefik: + external: true + services: + instance: + image: requarks/wiki:2.5 + environment: + # like this for future use + DB_TYPE: 'postgres' + DB_HOST: "{{ interfaces.infra.databases.net0.addresses[0] | ipaddr('address') }}" + DB_PORT: '{{ wikijs.postgres.port | default(5432) }}' + DB_USER: '{{ wikijs.postgres.username }}' + DB_PASS: '{{ wikijs.postgres.password }}' + DB_NAME: '{{ wikijs.postgres.db }}' + networks: + traefik: + labels: + traefik.enable: 'true' + traefik.http.routers.wiki.rule: 'Host(`wiki.netsoc.co`)' + traefik.http.routers.wiki.entrypoints: 'web-secure' + traefik.http.routers.wiki.tls.certResolver: 'letsencrypt-dns' + traefik.http.services.wiki.loadbalancer.server.port: '3000' + traefik.http.routers.wiki.service: 'wiki' + traefik.docker.network: 'traefik' + restart: always + + - name: WIKI - Setup compose + docker_compose: + project_name: wiki + recreate: smart + restarted: yes + remove_orphans: yes + state: present + definition: '{{ wiki_definition }}' + vars_files: + - 'vars/network.yml' + - 'vars/secrets_mapping.yml' + - 'vars/secrets.yml' + tags: + - provision + - wiki + +- name: 'DISCORD BOT (DATABASES) - Create databases for services' + hosts: databases.infra.netsoc.co + become: yes + tasks: + - name: DISCORD BOT - Ensure MySQL Database + run_once: true + postgresql_db: + name: '{{ netsocbot.sql_database }}' + login_host: '{{ databases.infra.postgres }}' + login_password: '{{ postgres.infra.postgres_password }}' + state: present + + - name: DISCORD BOT - Ensure Bot MySQL User + run_once: true + postgresql_user: + name: '{{ netsocbot.sql_user }}' + password: '{{ netsocbot.sql_password }}' + login_host: '{{ databases.infra.postgres }}' + login_password: '{{ postgres.infra.postgres_password }}' + state: present + no_log: true + vars_files: + - 'vars/network.yml' + - 'vars/secrets_mapping.yml' + - 'vars/secrets.yml' + tags: + - provision + - discord-bot + +- name: 'PLAUSIBLE - Databases' + hosts: databases.infra.netsoc.co + become: yes + tasks: + - name: PLAUSIBLE - Ensure database + postgresql_db: + name: '{{ plausible.postgres.db }}' + state: present + login_host: '{{ databases.infra.postgres }}' + login_password: '{{ postgres.infra.postgres_password }}' + - name: PLAUSIBLE - Ensure user + postgresql_user: + name: '{{ plausible.postgres.user }}' + password: '{{ plausible.postgres.pass }}' + login_host: '{{ databases.infra.postgres }}' + login_password: '{{ postgres.infra.postgres_password }}' + no_log: true + - name: PLAUSIBLE - Ensure user has access to database + postgresql_privs: + db: '{{ plausible.postgres.db }}' + role: '{{ plausible.postgres.user }}' + objs: ALL_IN_SCHEMA + privs: SELECT,INSERT,UPDATE,DELETE + login_host: '{{ databases.infra.postgres }}' + login_password: '{{ postgres.infra.postgres_password }}' + - name: PLAUSIBLE - Ensure user has CREATE access + postgresql_privs: + db: '{{ plausible.postgres.db }}' + role: '{{ plausible.postgres.user }}' + privs: CREATE + type: database + login_host: '{{ databases.infra.postgres }}' + login_password: '{{ postgres.infra.postgres_password }}' + vars_files: + - 'vars/network.yml' + - 'vars/secrets_mapping.yml' + - 'vars/secrets.yml' + tags: + - provision + - plausible + +- name: 'PLAUSIBLE' + hosts: web.infra.netsoc.co + become: yes + tasks: + - name: PLAUSIBLE - Ensure directories exist + file: + path: '/netsoc/{{ item }}' + owner: root + group: root + mode: '0755' + state: directory + with_items: + - plausible + - name: PLAUSIBLE - Ensure Plausible config file + copy: + dest: /netsoc/plausible/clickhouse-config.xml + mode: 0777 + content: | + + + warning + true + + + + + + + + + + + - name: PLAUSIBLE - Ensure Plausible User config file + copy: + dest: /netsoc/plausible/clickhouse-user-config.xml + mode: 0777 + content: | + + + + 0 + 0 + + + + - name: PLAUSIBLE - Remember Compose definition + set_fact: + plausible_definition: + version: '3.8' + networks: + traefik: + external: true + services: + instance: + image: plausible/analytics + restart: always + command: sh -c "sleep 10 && /entrypoint.sh db createdb && /entrypoint.sh db migrate && /entrypoint.sh db init-admin && /entrypoint.sh run" + environment: + ADMIN_USER_NAME: root + ADMIN_USER_EMAIL: netsoc@uccsocieties.ie + ADMIN_USER_PWD: '{{ plausible.password }}' + DATABASE_URL: 'postgress://{{ plausible.postgres.user }}:{{ plausible.postgres.pass }}@{{ databases.infra.postgres }}/{{ plausible.postgres.db }}' + CLICKHOUSE_DATABASE_URL: 'http://plausible_plausible_events_db_1:8123/plausible_events_db' + SECRET_KEY_BASE: '{{ plausible.key_base }}' + BASE_URL: 'https://analytics.netsoc.co' + labels: + traefik.enable: 'true' + traefik.http.routers.plausible.rule: 'Host(`analytics.netsoc.co`)' + traefik.http.routers.plausible.entrypoints: 'web-secure' + traefik.http.routers.plausible.tls.certResolver: 'letsencrypt-dns' + traefik.http.services.plausible-service.loadbalancer.server.port: '8000' + traefik.http.routers.plausible.service: 'plausible-service' + traefik.docker.network: 'traefik' + depends_on: + - plausible_events_db + plausible_events_db: + image: yandex/clickhouse-server:21.3.2.5 + restart: always + volumes: + - event-data:/var/lib/clickhouse + - /netsoc/plausible/clickhouse-config.xml:/etc/clickhouse-server/config.d/logging.xml:ro + - /netsoc/plausible/clickhouse-user-config.xml:/etc/clickhouse-server/users.d/logging.xml:ro + ulimits: + nofile: + soft: 262144 + hard: 262144 + + volumes: + event-data: + driver: local + + - name: PLAUSIBLE - Setup compose + docker_compose: + project_name: plausible + recreate: smart + restarted: yes + remove_orphans: yes + state: present + definition: '{{ plausible_definition }}' + vars_files: + - 'vars/network.yml' + - 'vars/secrets_mapping.yml' + - 'vars/secrets.yml' + tags: + - provision + - plausible + +- name: 'DISCORD BOT' + hosts: web.infra.netsoc.co + become: yes + tasks: + - name: DISCORD BOT - Remember Compose definition + set_fact: + discord_bot_definition: + version: '3.8' + networks: + traefik: + external: true + services: + instance: + image: ghcr.io/uccnetsoc/discord-bot:latest + restart: always + networks: + traefik: + environment: + DISCORD_TOKEN: '{{ netsocbot.discord_token }}' + DISCORD_ROLES: '631196785913888768,855884858794442783' + DISCORD_PUBLIC_SERVER: '248421213628530688' + DISCORD_PUBLIC_CHANNEL: '494539080885993472' + DISCORD_PUBLIC_GENERAL: '248421213628530688' + DISCORD_PUBLIC_CORONA: '691756092379627621' + DISCORD_PUBLIC_WELCOME: 'Welcome to the UCC Netsoc Discord server %s!,Hey %s! Welcome to the Netsoc Discord Server!,Welcome %s!' + DISCORD_COMMITTEE_SERVER: '824315212768346152' + DISCORD_COMMITTEE_CHANNEL: '847973898900471859' + BOT_PREFIX: '!' + SENDGRID_TOKEN: '{{ sendgrid.apikey }}' + TWITTER_KEY: '{{ netsocbot.twitter_key }}' + TWITTER_SECRET: '{{ netsocbot.twitter_secret }}' + TWITTER_ACCESS_KEY: '{{ netsocbot.twitter_access_key }}' + TWITTER_ACCESS_SECRET: '{{ netsocbot.twitter_access_secret }}' + SQL_HOST: '{{ databases.infra.postgres }}' + SQL_PORT: 5432 + SQL_USERNAME: '{{ netsocbot.sql_user }}' + SQL_PASSWORD: '{{ netsocbot.sql_password }}' + FREEIMAGE_KEY: '{{ netsocbot.freeimage_key }}' + FACEBOOK_APPID: '{{ netsocbot.fb.appid }}' + FACEBOOK_APP_SECRET: '{{ netsocbot.fb.appsecret }}' + FACEBOOK_PAGEID: '{{ netsocbot.fb.pageid }}' + FACEBOOK_PAGE_ACCESS_TOKEN: '{{ netsocbot.fb.accesstoken }}' + SCHEDULE_ENABLE: 'False' + MINECRAFT_HOST: "{{ interfaces.infra.minecraft.net0.addresses[0] | ipaddr('address') }}:1194" + SHORTEN_HOST: 'http://shortener_instance_1:8080/api' + SHORTEN_PUBLIC_HOST: 'https://netsoc.co/go' + SHORTEN_USERNAME: '{{ shortener.username }}' + SHORTEN_PASSWORD: '{{ shortener.password }}' + GOOGLE_CALENDAR_PUBLIC_ICS: 'https://calendar.google.com/calendar/ical/c_1rid5k8ahaiosmdhn8pkahf2og%40group.calendar.google.com/public/basic.ics' + GOOGLE_CALENDAR_COMMITTEE_ICS: '{{ netsocbot.google_calendar_committee_ics }}' + GOOGLE_CALENDAR_IMAGE_DEFAULT: 'https://raw.githubusercontent.com/UCCNetsoc/wiki/master/assets/logo-hires.png' + labels: + traefik.enable: 'true' + traefik.http.routers.netsocbot.rule: 'Host(`bot.netsoc.co`)' + traefik.http.routers.netsocbot.entrypoints: 'web-secure' + traefik.http.routers.netsocbot.tls.certResolver: 'letsencrypt-dns' + traefik.http.services.netsocbot-service.loadbalancer.server.port: '80' + traefik.http.routers.netsocbot.service: 'netsocbot-service' + traefik.docker.network: 'traefik' + + - name: DISCORD BOT - Setup compose + docker_compose: + project_name: discord_bot + remove_orphans: yes + recreate: always + pull: yes + state: present + definition: '{{ discord_bot_definition }}' + vars_files: + - 'vars/network.yml' + - 'vars/secrets_mapping.yml' + - 'vars/secrets.yml' + tags: + - provision + - discord-bot + +- name: 'whodis' + hosts: web.infra.netsoc.co + become: yes + tasks: + - name: whodis - Remember Compose definition + set_fact: + whodis_definition: + version: '3.8' + networks: + traefik: + external: true + services: + instance: + image: ghcr.io/uccnetsoc/whodis:latest + restart: always + networks: + traefik: + environment: + DISCORD_TOKEN: '{{ whodis.discord_token }}' + DISCORD_APP_ID: '{{ whodis.discord_app_id }}' + DISCORD_BOT_INVITE: '{{ whodis.discord_bot_invite }}' + DISCORD_GUILD_MEMBERS_WELCOME: '{"248421213628530688": "Some channels are hidden by default so head over to <#769360801332461569> to get access to them."}' + API_URL: 'https://whodis.netsoc.co' + API_PORT: '8080' + API_SECRET: '{{ whodis.api_secret }}' + OAUTH_GOOGLE_ID: '{{ whodis.oauth_google_id }}' + OAUTH_GOOGLE_SECRET: '{{ whodis.oauth_google_secret }}' + labels: + traefik.enable: 'true' + traefik.http.routers.whodis.rule: 'Host(`whodis.netsoc.co`)' + traefik.http.routers.whodis.entrypoints: 'web-secure' + traefik.http.routers.whodis.tls.certResolver: 'letsencrypt-dns' + traefik.http.routers.whodis.service: 'whodis-service' + traefik.http.services.whodis-service.loadbalancer.server.port: '8080' + traefik.docker.network: 'traefik' + + - name: whodis - Setup compose + docker_compose: + project_name: whodis + remove_orphans: yes + recreate: always + pull: yes + state: present + definition: '{{ whodis_definition }}' + vars_files: + - 'vars/network.yml' + - 'vars/secrets_mapping.yml' + - 'vars/secrets.yml' + tags: + - provision + - whodis + +- name: 'NETSOC CLOUD' + hosts: web.infra.netsoc.co + become: yes + tasks: + - name: NETSOC CLOUD - Ensure directories exist + file: + path: '/netsoc/{{ item }}' + owner: root + group: root + mode: '0755' + state: directory + with_items: + - cloud + + - name: NETSOC CLOUD - Ensure config file + copy: + src: './vars/netsoc_cloud_api_config.yml' + dest: /netsoc/cloud/config.yaml + owner: root + group: root + mode: 0770 + + - name: NETSOC CLOUD - Remember Compose definition + set_fact: + netsoc_cloud_definition: + version: '3.8' + networks: + traefik: + external: true + services: + api: + image: ghcr.io/uccnetsoc/cloud-api:latest + entrypoint: /start.sh + restart: always + networks: + traefik: + volumes: + - '/netsoc/cloud/config.yaml:/config.yml' + environment: + WORKERS_PER_CORE: 4 + labels: + traefik.enable: 'true' + traefik.http.routers.netsoc-cloud-api.entrypoints: web-secure + traefik.http.routers.netsoc-cloud-api.rule: Host(`api.netsoc.cloud`) + traefik.http.routers.netsoc-cloud-api.tls.certResolver: letsencrypt-dns + traefik.http.routers.netsoc-cloud-api.service: netsoc-cloud-api + traefik.http.services.netsoc-cloud-api.loadbalancer.server.port: '80' + traefik.docker.network: traefik + ui: + image: ghcr.io/uccnetsoc/cloud-ui:latest + restart: always + networks: + traefik: + labels: + traefik.enable: 'true' + traefik.http.routers.netsoc-cloud-ui.entrypoints: web-secure + traefik.http.routers.netsoc-cloud-ui.rule: Host(`netsoc.cloud`) + traefik.http.routers.netsoc-cloud-ui.tls.certResolver: letsencrypt-dns + traefik.http.routers.netsoc-cloud-ui.tls.domains[0].main: 'netsoc.cloud' + traefik.http.routers.netsoc-cloud-ui.tls.domains[0].sans: '*.netsoc.cloud' + traefik.http.routers.netsoc-cloud-ui.service: netsoc-cloud-ui + traefik.http.services.netsoc-cloud-ui.loadbalancer.server.port: '80' + traefik.docker.network: traefik + + - name: NETSOC CLOUD - Setup compose + docker_compose: + project_name: netsoc_cloud + recreate: always + restarted: yes + pull: yes + remove_orphans: yes + state: present + definition: '{{ netsoc_cloud_definition }}' + vars_files: + - 'vars/network.yml' + - 'vars/secrets_mapping.yml' + - 'vars/secrets.yml' + tags: + - provision + - netsoc-cloud + - netsoc-cloud-api + - netsoc-cloud-ui + +- name: NETSOC CLOUD - WEBSSH2 + hosts: web.infra.netsoc.co + become: yes + tasks: + - name: WEBSSH2 - Ensure directories exist + file: + path: '/netsoc/{{ item }}' + owner: root + group: root + mode: '0755' + state: directory + with_items: + - webssh2 + + - name: WEBSSH2 & NETSOC CLOUD - Load Netsoc Cloud config + set_fact: + netsoc_cloud_config: "{{ lookup('file', './vars/netsoc_cloud_api_config.yml') | from_yaml }}" + + - name: WEBSSH2 - Ensure config file + copy: + dest: '/netsoc/webssh2/config.json' + content: | + { + "listen": { + "ip": "0.0.0.0", + "port": 2222 + }, + "user": { + "name": null, + "password": null, + "privatekey": null + }, + "ssh": { + "host": null, + "port": 22, + "localAddress": null, + "localPort": null, + "term": "xterm-color", + "readyTimeout": 20000, + "keepaliveInterval": 120000, + "keepaliveCountMax": 10, + "allowedSubnets": [ + "{{ netsoc_cloud_config.proxmox.network.network }}" + ] + }, + "terminal": { + "cursorBlink": true, + "scrollback": 10000, + "tabStopWidth": 8, + "bellStyle": "sound" + }, + "header": { + "text": null, + "background": "green" + }, + "session": { + "name": "SSH | Netsoc Cloud", + "secret": "{{ lookup('password', '/dev/null chars=ascii_lowercase,digits length=32') }}" + }, + "options": { + "challengeButton": true, + "allowreauth": true + }, + "algorithms": { + "kex": [ + "ecdh-sha2-nistp256", + "ecdh-sha2-nistp384", + "ecdh-sha2-nistp521", + "diffie-hellman-group-exchange-sha256", + "diffie-hellman-group14-sha1" + ], + "cipher": [ + "aes128-ctr", + "aes192-ctr", + "aes256-ctr", + "aes128-gcm", + "aes128-gcm@openssh.com", + "aes256-gcm", + "aes256-gcm@openssh.com", + "aes256-cbc" + ], + "hmac": [ + "hmac-sha2-256", + "hmac-sha2-512", + "hmac-sha1" + ], + "compress": [ + "none", + "zlib@openssh.com", + "zlib" + ] + }, + "serverlog": { + "client": false, + "server": false + }, + "accesslog": false, + "verify": false, + "safeShutdownDuration": 300 + } + + - name: WEBSSH2 - Remember Compose definition + set_fact: + webssh2_definition: + version: '3.8' + networks: + traefik: + external: true + services: + instance: + image: ghcr.io/uccnetsoc/webssh2:latest + networks: + traefik: + volumes: + - '/netsoc/webssh2/config.json:/usr/src/config.json' + labels: + traefik.enable: 'true' + traefik.http.routers.webssh2.rule: 'Host(`ssh.netsoc.cloud`)' + traefik.http.routers.webssh2.entrypoints: 'web-secure' + traefik.http.routers.webssh2.tls.certResolver: 'letsencrypt-dns' + traefik.http.services.webssh2-service.loadbalancer.server.port: '2222' + traefik.http.routers.webssh2.service: 'webssh2-service' + traefik.docker.network: 'traefik' + restart: always + + - name: WEBSSH2 - Setup compose + docker_compose: + project_name: webssh2 + remove_orphans: yes + recreate: always + restarted: yes + pull: yes + state: present + definition: '{{ webssh2_definition }}' + vars_files: + - 'vars/network.yml' + - 'vars/secrets_mapping.yml' + - 'vars/secrets.yml' + tags: + - webssh2 + - provision + - netsoc-cloud + +- name: NETSOC CLOUD - MONSTAFTP + hosts: web.infra.netsoc.co + become: yes + tasks: + - name: WEBSSH2 - Ensure directories exist + file: + path: '/netsoc/{{ item }}' + owner: root + group: root + mode: '0755' + state: directory + with_items: + - monstaftp + + - name: MONSTAFTP - Write config + copy: + dest: /netsoc/monstaftp/settings.json + content: | + { + "language": "en_us", + "resumeSessionInfoDisplaySeconds": 0, + "hideProUpgradeMessages": true, + "connectionRestrictions": { + "types": ["sftp"] + } + } + + - name: MONSTAFTP - Remember Compose definition + set_fact: + monstaftp_definition: + version: '3.8' + networks: + traefik: + external: true + services: + instance: + image: cardonaje/monstaftp-docker:latest + networks: + traefik: + volumes: + - '/netsoc/monstaftp/settings.json:/var/www/mftp/settings/settings.json' + labels: + traefik.enable: 'true' + traefik.http.routers.monstaftp.rule: 'Host(`sftp.netsoc.cloud`)' + traefik.http.routers.monstaftp.entrypoints: 'web-secure' + traefik.http.routers.monstaftp.tls.certResolver: 'letsencrypt-dns' + traefik.http.services.monstaftp-service.loadbalancer.server.port: '80' + traefik.http.routers.monstaftp.service: 'monstaftp-service' + traefik.docker.network: 'traefik' + restart: on-failure + + - name: MONSTAFTP - Setup compose + docker_compose: + project_name: monstaftp + remove_orphans: yes + recreate: always + restarted: yes + pull: yes + state: present + definition: '{{ monstaftp_definition }}' + vars_files: + - 'vars/network.yml' + - 'vars/secrets_mapping.yml' + - 'vars/secrets.yml' + tags: + - monstaftp + - provision + - netsoc-cloud + +- name: 'LOKI' + hosts: web.infra.netsoc.co + become: yes + tasks: + - name: LOKI - Ensure directories exist + file: + path: '/netsoc/{{ item }}' + owner: root + group: root + + mode: '0777' + state: directory + with_items: + - loki + - promtail + + - name: LOKI - Ensure Loki config file + copy: + dest: /netsoc/loki/config.yaml + mode: 0777 + content: | + auth_enabled: false + server: + http_listen_port: 3100 + ingester: + lifecycler: + address: 127.0.0.1 + ring: + kvstore: + store: inmemory + replication_factor: 1 + final_sleep: 0s + chunk_idle_period: 5m + chunk_retain_period: 30s + max_transfer_retries: 0 + schema_config: + configs: + - from: 2018-04-15 + store: boltdb + object_store: filesystem + schema: v11 + index: + prefix: index_ + period: 360h + storage_config: + boltdb: + directory: /loki/chunks + filesystem: + directory: /loki/chunks + limits_config: + enforce_metric_name: false + reject_old_samples: true + reject_old_samples_max_age: 360h + chunk_store_config: + max_look_back_period: 0s + table_manager: + retention_deletes_enabled: false + retention_period: 0s + + - name: LOKI - Ensure Promtail config file + copy: + dest: /netsoc/promtail/config.yaml + mode: 0777 + content: | + server: + http_listen_port: 9080 + grpc_listen_port: 0 + log_level: "info" + + positions: + filename: /tmp/positions.yaml + + clients: + - url: http://loki:3100/loki/api/v1/push + + scrape_configs: + - job_name: containers + pipeline_stages: + - docker: + file_sd_configs: + - files: + - /promtail/targets.yaml + relabel_configs: + - source_labels: [__address__] + target_label: container_id + - source_labels: [container_id] + target_label: __path__ + replacement: /var/lib/docker/containers/$1*/*.log + + - name: LOKI - Setup targets + shell: "docker ps --format '- targets: [\"{{ '{{' }}.ID{{ '}}' }}\"]\\n labels:\\n container_name: \"{{ '{{' }}.Names{{ '}}' }}\"' | sed -e '/`docker ps -aqf \"name=loki_promtail_1\"`/,+3d' | sed -e '/`docker ps -aqf \"name=loki_loki_1\"`/,+3d'> /netsoc/promtail/targets.yaml" + + - name: LOKI - Remember Compose definition + set_fact: + loki_definition: + version: '3.8' + networks: + loki: + traefik: + external: true + services: + loki: + command: -config.file=/loki/config.yaml + hostname: loki + deploy: + resources: + limits: + memory: 500M + image: grafana/loki:2.0.0 + networks: + loki: + volumes: + - '/netsoc/loki:/loki' + restart: always + labels: + traefik.enable: 'true' + traefik.http.routers.loki.rule: 'Host(`loki.netsoc.co`)' + traefik.http.routers.loki.entrypoints: 'web-secure' + traefik.http.routers.loki.tls.certResolver: 'letsencrypt-dns' + traefik.http.services.loki.loadbalancer.server.port: '3100' + traefik.http.routers.loki.service: 'loki' + traefik.http.middlewares.loki-auth.basicauth.users: '{{ loki.username }}:{{ loki.hash }}' + traefik.http.routers.loki.middlewares: 'loki-auth@docker' + traefik.docker.network: 'traefik' + + promtail: + image: grafana/promtail:2.0.0 + volumes: + - /var/lib/docker:/var/lib/docker + - /netsoc/promtail/:/promtail + command: -config.file=/promtail/config.yaml + restart: always + networks: + loki: + + # grafana: + # image: grafana/grafana:latest + # labels: + # traefik.enable: "true" + # traefik.http.routers.grafana.rule: "Host(`grafana.netsoc.co`)" + # traefik.http.routers.grafana.entrypoints: "web-secure" + # traefik.http.routers.grafana.tls.certResolver: "letsencrypt-dns" + # traefik.http.services.grafana.loadbalancer.server.port: "3000" + # traefik.http.routers.grafana.service: "grafana" + # traefik.docker.network: "traefik" + # networks: + # - loki + # - traefik + + - name: LOKI - Setup compose + docker_compose: + project_name: loki + recreate: always + restarted: yes + remove_orphans: yes + state: present + definition: '{{ loki_definition }}' + vars_files: + - 'vars/network.yml' + - 'vars/secrets_mapping.yml' + - 'vars/secrets.yml' + tags: + - provision + - loki + +- name: Grafana + become: yes + hosts: web.infra.netsoc.co + roles: + - grafana + vars: + host: grafana.netsoc.co + keycloak_host: keycloak.netsoc.co + vars_files: + - 'vars/network.yml' + - 'vars/secrets_mapping.yml' + - 'vars/secrets.yml' + tags: + - provision + - grafana + +- name: Grafana Dashboards + become: yes + hosts: web.infra.netsoc.co + tasks: + - name: Copy Dashboards + synchronize: + archive: no + recursive: yes + delete: yes + src: roles/grafana/files/data/dashboards/ + dest: /netsoc/grafana/data/dashboards/ + tags: + - dashboards + - grafana + +- name: Shortener Databases + hosts: databases.infra.netsoc.co + become: yes + tasks: + - name: Shortener - Ensure database + postgresql_db: + name: '{{ shortener.postgres.db }}' + state: present + login_host: '{{ databases.infra.postgres }}' + login_password: '{{ postgres.infra.postgres_password }}' + + - name: Shortener - Ensure user + postgresql_user: + name: '{{ shortener.postgres.user }}' + password: '{{ shortener.postgres.pass }}' + login_host: '{{ databases.infra.postgres }}' + login_password: '{{ postgres.infra.postgres_password }}' + no_log: true + + - name: Shortener - Ensure user has access to database + postgresql_privs: + db: '{{ shortener.postgres.db }}' + role: '{{ shortener.postgres.user }}' + objs: ALL_IN_SCHEMA + privs: SELECT,INSERT,UPDATE,DELETE + login_host: '{{ databases.infra.postgres }}' + login_password: '{{ postgres.infra.postgres_password }}' + vars_files: + - 'vars/network.yml' + - 'vars/secrets_mapping.yml' + - 'vars/secrets.yml' + tags: + - provision + - shortener + +- name: 'Shortener' + hosts: web.infra.netsoc.co + become: yes + tasks: + - name: Shortener - Remember Compose definition + set_fact: + shortener_definition: + version: '3.8' + networks: + traefik: + external: true + services: + instance: + image: uccnetsoc/shortener:latest + environment: + DB_HOST: "{{ interfaces.infra.databases.net0.addresses[0] | ipaddr('address') }}" + DB_PORT: '5432' + DB_USER: '{{ shortener.postgres.user }}' + DB_PASS: '{{ shortener.postgres.pass }}' + DB_NAME: '{{ shortener.postgres.db }}' + SHORTENER_USER: '{{ shortener.username }}' + SHORTENER_PASSWORD: '{{ shortener.password }}' + networks: + traefik: + labels: + traefik.enable: 'true' + traefik.http.routers.shortener.rule: 'Host(`netsoc.co`) && PathPrefix(`/go/`)' + traefik.http.middlewares.go-strip.stripprefix.prefixes: '/go' + traefik.http.routers.shortener.entrypoints: 'web-secure' + traefik.http.routers.shortener.tls.certResolver: 'letsencrypt-dns' + traefik.http.services.shortener.loadbalancer.server.port: '8080' + traefik.http.routers.shortener.service: 'shortener' + traefik.docker.network: 'traefik' + traefik.http.routers.shortener.middlewares: 'go-strip@docker,www-redirect@docker' + restart: always + - name: Shortener - Setup compose + docker_compose: + project_name: shortener + pull: yes + recreate: smart + restarted: yes + remove_orphans: yes + state: present + definition: '{{ shortener_definition }}' + vars_files: + - 'vars/network.yml' + - 'vars/secrets_mapping.yml' + - 'vars/secrets.yml' + tags: + - provision + - shortener + +- name: 'Student Media - Motley' + hosts: web.infra.netsoc.co + become: yes + tasks: + - name: 'Student Media - Remember Motley definition' + set_fact: + motley_definition: + version: '3.5' + networks: + traefik: + external: true + motley: + services: + motleydb: + image: mariadb:10.4.8 + volumes: + - /netsoc/student-media/motley/database:/var/lib/mysql + restart: always + networks: + motley: + motleywp: + networks: + motley: + traefik: + depends_on: + - motleydb + image: wordpress:php7.4 + restart: always + volumes: + - /netsoc/student-media/motley/wordpress:/var/www/html + labels: + traefik.enable: "true" + traefik.http.routers.motley.rule: "Host(`www.motley.ie`, `motley.ie`)" + traefik.http.routers.motley.entrypoints: "web-secure" + traefik.http.routers.motley.tls.certResolver: "letsencrypt-tls" + traefik.http.services.motley-service.loadbalancer.server.port: "80" + traefik.http.routers.motley.service: "motley-service" + traefik.docker.network: "traefik" + - name: 'Motley - Setup compose' + docker_compose: + project_name: motley + recreate: smart + restarted: yes + remove_orphans: yes + state: present + definition: '{{ motley_definition }}' + vars_files: + - 'vars/network.yml' + - 'vars/secrets_mapping.yml' + - 'vars/secrets.yml' + tags: + - provision + - student_media + - motley + +- name: 'Student Media - UCCExpress' + hosts: web.infra.netsoc.co + become: yes + tasks: + - name: 'Student Media - Remember UCCExpress definition' + set_fact: + uccexpress_definition: + version: '3.5': + services: + uccexpressdb: + image: mariadb:10.4.8 + volumes: + - /netsoc/student-media/uccexpress/database:/var/lib/mysql + restart: always + networks: + uccexpress: + uccexpresswp: + depends_on: + - uccexpressdb + networks: + traefik: + image: wordpress:php7.4 + restart: always + volumes: + - /netsoc/student-media/uccexpress/wordpress:/var/www/html + labels: + traefik.enable: "true" + traefik.http.routers.uccexpress.rule: "Host(`www.uccexpress.ie`, `uccexpress.ie`)" + traefik.http.routers.uccexpress.entrypoints: "web-secure" + traefik.http.routers.uccexpress.tls.certResolver: "letsencrypt-tls" + traefik.http.services.uccexpress-service.loadbalancer.server.port: "80" + traefik.http.routers.uccexpress.service: "uccexpress-service" + traefik.docker.network: "traefik" + - name: 'UCCExpress - Setup compose' + docker_compose: + project_name: uccexpress + pull: yes + recreate: smart + restarted: yes + remove_orphans: yes + state: present + definition: '{{ uccexpress_definition }}' + vars_files: + - 'vars/network.yml' + - 'vars/secrets_mapping.yml' + - 'vars/secrets.yml' + tags: + - provision + - student_media + - uccexpress + + + + + +- name: 'LOKI TARGETS' # Keep this at the bottom of the file at all times. + hosts: web.infra.netsoc.co + become: yes + tasks: + - name: LOKI TARGETS - Setup targets + shell: "docker ps --format '- targets: [\"{{ '{{' }}.ID{{ '}}' }}\"]\\n labels:\\n container_name: \"{{ '{{' }}.Names{{ '}}' }}\"' | sed -e '/`docker ps -aqf \"name=loki_promtail_1\"`/,+3d' | sed -e '/`docker ps -aqf \"name=loki_loki_1\"`/,+3d' > /netsoc/promtail/targets.yaml" + tags: + - always diff --git a/provision-nfs.yml b/provision-nfs.yml deleted file mode 100644 index 18fe3880..00000000 --- a/provision-nfs.yml +++ /dev/null @@ -1,107 +0,0 @@ -- name: "Enroll in IPA server" - hosts: nfs - roles: - - role: freeipa-client - vars: - client: - addresses: - - "{{ ansible_default_ipv4.address }}" - vars_files: - - "vars/freeipa.yml" - - "vars/network.yml" - - "vars/secrets.yml" - -- name: "Ensure data disk made with snapshotting" - hosts: nfs - become: yes - roles: - - role: zfs-auto-snapshot - - role: simple-zfs - vars: - pool: nfs - mount: /nfs - device: /dev/vdb - fs: - - home/users - - docker - snapshot: - monthly: true - weekly: true - daily: true - hourly: false - frequent: false - tasks: - - become: yes - file: - path: /nfs - mode: 0777 - state: directory - -# - name: "Setup ZFS dataset user home directory generator" -# hosts: nfs -# become: yes -# tasks: -# - copy: -# content | -# #!/bin/bash - -# printf "[$(date -u)] Starting user home directory dataset creator\n" -# printf "[$(date -u)] Creating nfs/home dataset\n" -# zfs create nfs/home - -# printf "[$(date -u)] Creating nfs/home/users dataset\n" -# zfs create nfs/home/users - -# while true -# do -# echo "SomePass" | kinit admin - -# all_users=$(ipa user-find --all | awk '/User login/{ print $3 }') - -# printf "\n[$(date -u)] Scanning IPA users (with home dirs in /home/users/*) to find users missing home directories\n" - -# for user in $all_users do -# printf "[$(date -u)] Checking $user...\n" -# uid=$(getent passwd $user | cut -d ":" -f 3) -# gid=$(getent passwd $user | cut -d ":" -f 4) -# home=$(getent passwd $user | cut -d ":" -f 6) - -# if [ ! -d "/nfs/home/users/$user" ] && [[ $home == "/home/users/$user" ]]; then -# printf "[$(date -u)] $user ($uid:$gid) does not have a zfs home directory, setting them up now\n" -# zfs create nfs/home/users/$user -# chown root:$uid /nfs/home/users/$user -# chmod 770 /nfs/home/users/$user -# cp -a /etc/skel/. /nfs/home/users/$user/. -# chown $uid:$uid -R /nfs/home/users/$user/* -# else -# printf "[$(date -u)] $user does not have a home directory pointed to /home/users/$user, ignoring\n" -# fi -# done -# printf "[$(date -u)] Scanning complete\n" -# sleep 10 -# done - -# This has the side effect of setting up an IPA service and keytab for the NFS server too -# as the NFS server shares the same hostname, when we create it below,3 it will mount the same keytab file -- name: Setup NFS client requirements - hosts: nfs - roles: - - role: nfs-client-requirements - vars_files: - - "vars/idmap.yml" - - "vars/freeipa.yml" - - "vars/secrets.yml" - -- name: "Ensure server" - hosts: nfs - become: yes - roles: - - role: nfs4-server-krb5 - vars: - exports: | - /nfs 10.0.{{ subnets.infra }}.0/24(fsid=0,rw,sync,crossmnt,no_root_squash,sec=krb5p:krb5i:krb5) - vars_files: - - vars/idmap.yml - - vars/network.yml - - \ No newline at end of file diff --git a/provision-portal.yml b/provision-portal.yml deleted file mode 100644 index 7a9b26b3..00000000 --- a/provision-portal.yml +++ /dev/null @@ -1,66 +0,0 @@ -- name: "Enroll in IPA server" - hosts: portal - roles: - - role: freeipa-client - vars: - client: - addresses: - - "{{ ansible_default_ipv4.address }}" - vars_files: - - "vars/freeipa.yml" - - "vars/network.yml" - - "vars/secrets.yml" - -- name: Setup NFS client and NFS mount requirements - hosts: portal - roles: - - role: nfs-client-requirements - - role: autofs-automount - vars: - src: nfs.vm.netsoc.co:/home/users - mount: /home/users - opts: fstype=nfs4,rw,vers=4.2,sec=krb5p,hard,bg - vars_files: - - "vars/idmap.yml" - - "vars/freeipa.yml" - - "vars/secrets.yml" - -- name: Setup server MOTD - hosts: portal - tasks: - - become: yes - copy: - content: "{{ lookup('file', './portal-banner.txt') }}" - dest: /etc/netsoc-banner - - become: yes - copy: - content: "{{ lookup('file', './portal-motd.txt') }}" - dest: /etc/netsoc-motd - - become: yes - shell: /bin/rm -rf /etc/update-motd.d/* - - become: yes - copy: - content: | - #!/bin/sh - cat /etc/netsoc-motd - mode: "0755" - dest: /etc/update-motd.d/00-netsoc-motd - - become: yes - copy: - content: "" - dest: /etc/legal - - become: yes - lineinfile: - regex: "^#PrintLastLog" - line: "PrintLastLog no" - path: /etc/ssh/sshd_config - - become: yes - lineinfile: - regex: "^#Banner none" - line: "Banner /etc/netsoc-banner" - path: /etc/ssh/sshd_config - - become: yes - service: - name: sshd - state: restarted - diff --git a/provision-proxmox-templates.yml b/provision-proxmox-templates.yml new file mode 100644 index 00000000..ac827217 --- /dev/null +++ b/provision-proxmox-templates.yml @@ -0,0 +1,210 @@ +- name: Add Provisionee host + hosts: scalper + tasks: + - add_host: + name: provisionee + tags: + - always + +- name: Provision Netsoc Cloud templates + hosts: scalper, provisionee + gather_facts: no + any_errors_fatal: true + roles: + - role: proxmox-templates + vars: + proxmox_host: scalper + provisionee_host: provisionee + templates: + - lxc: + name: "ubuntu.container.template.netsoc.cloud" + storage: netsoc-cloud + template: + storage: netsoc-cloud + image: "ubuntu-20.04-standard_20.04-1_amd64.tar.gz" + description: + title: "Ubuntu Server 20.04.1 LTS" + subtitle: "An easy to use server distro" + description: | + Ubuntu is a Linux distribution based on Debian mostly composed of free and open-source software. + Ubuntu is officially released in three editions: Desktop, Server, and Core for Internet of things devices and robots. + All the editions can run on the computer alone, or in a virtual machine + logo_url: https://raw.githubusercontent.com/UCCNetsoc/cloud/master/ui/public/img/templates/ubuntu.png + wake_on_request: no + unprivileged: yes + cores: 1 + memory: 512 + swap: 512 + disks: + rootfs: + size: 10 + net: + net0: "name=eth0,ip=dhcp,tag={{ vlan.dhcp }},bridge={{ vmbr }},firewall=1" + features: "fuse=1,nesting=1,keyctl=1" + tasks: "./netsoc-cloud/templates/ubuntu.yml" + - lxc: + name: "ubuntu-docker.container.template.netsoc.cloud" + storage: netsoc-cloud + template: + storage: netsoc-cloud + image: "ubuntu-20.04-standard_20.04-1_amd64.tar.gz" + description: + title: "Docker (on Ubuntu 20.04)" + subtitle: "Get started using your own containers in seconds" + description: | + Docker is a Linux container management toolkit with a “social” aspect, letting users publish container images and consume those published by others. + Containers are isolated from one another and bundle their own software, libraries and configuration files; they can communicate with each other through well-defined channels. + logo_url: https://raw.githubusercontent.com/UCCNetsoc/cloud/master/ui/public/img/templates/docker.png + wake_on_request: no + unprivileged: yes + cores: 2 + memory: 512 + swap: 512 + disks: + rootfs: + size: 10 + net: + net0: "name=eth0,ip=dhcp,tag={{ vlan.dhcp }},bridge={{ vmbr }},firewall=1" + features: "fuse=1,nesting=1,keyctl=1" + tasks: "./netsoc-cloud/templates/ubuntu-docker.yml" + - lxc: + name: "ubuntu-linuxtools.container.template.netsoc.cloud" + storage: netsoc-cloud + template: + storage: netsoc-cloud + image: "ubuntu-20.04-standard_20.04-1_amd64.tar.gz" + description: + title: "Linux Tools (on Ubuntu Server 20.04)" + subtitle: "Docker, Git and support for most programming languages" + description: | + Build to your heart's desires with this fully equipped machine: + + * Docker + * Git, Mercurial + * Emacs, Nano, Vim, Neovim + * Tmux, Screen + * Make, Maven, Gradle + * C/C++ (clang, gcc) + * Python, pip, Jupyter/IPython + * Java + * PHP (composer) + * Ruby + * NodeJS, NPM, NVM + * Go + * Rust + logo_url: https://raw.githubusercontent.com/UCCNetsoc/cloud/master/ui/public/img/templates/linux-tools.png + wake_on_request: no + unprivileged: yes + cores: 2 + memory: 512 + swap: 512 + disks: + rootfs: + size: 10 + net: + net0: "name=eth0,ip=dhcp,tag={{ vlan.dhcp }},bridge={{ vmbr }},firewall=1" + features: "fuse=1,nesting=1,keyctl=1" + tasks: "./netsoc-cloud/templates/ubuntu-linuxtools.yml" + - lxc: + name: "ubuntu-wordpress.container.template.netsoc.cloud" + storage: netsoc-cloud + template: + storage: netsoc-cloud + image: "ubuntu-20.04-standard_20.04-1_amd64.tar.gz" + description: + title: "WordPress" + subtitle: "The most popular blog and CMS system" + description: | + WordPress is a free and open-source content management system (CMS) written in PHP and paired with a MySQL or MariaDB database. + logo_url: https://raw.githubusercontent.com/UCCNetsoc/cloud/master/ui/public/img/templates/wordpress.png + wake_on_request: no + unprivileged: yes + cores: 1 + memory: 512 + swap: 512 + disks: + rootfs: + size: 10 + net: + net0: "name=eth0,ip=dhcp,tag={{ vlan.dhcp }},bridge={{ vmbr }},firewall=1" + features: "fuse=1,nesting=1,keyctl=1" + tasks: "./netsoc-cloud/templates/ubuntu-wordpress.yml" + - lxc: + name: "ubuntu-ghostcms.container.template.netsoc.cloud" + storage: netsoc-cloud + template: + storage: netsoc-cloud + image: "ubuntu-20.04-standard_20.04-1_amd64.tar.gz" + description: + title: "GhostCMS" + subtitle: "The world's most popular modern professional publishing platform" + description: | + Used by Apple, SkyNews, Buffer, OpenAI, and thousands more. + logo_url: https://raw.githubusercontent.com/UCCNetsoc/cloud/master/ui/public/img/templates/ghost.png + wake_on_request: no + unprivileged: yes + cores: 1 + memory: 512 + swap: 512 + disks: + rootfs: + size: 10 + net: + net0: "name=eth0,ip=dhcp,tag={{ vlan.dhcp }},bridge={{ vmbr }},firewall=1" + features: "fuse=1,nesting=1,keyctl=1" + tasks: "./netsoc-cloud/templates/ubuntu-ghostcms.yml" + - lxc: + name: "ubuntu-foundry.container.template.netsoc.cloud" + storage: netsoc-cloud + template: + storage: netsoc-cloud + image: "ubuntu-20.04-standard_20.04-1_amd64.tar.gz" + description: + title: "FoundryVTT" + subtitle: "Popular online Virtual Table Top" + description: | + Play DND and other Tabletop RPGs using the hugely customisable FoundryVTT + logo_url: https://foundryvtt.com/static/assets/icons/fvtt.png + wake_on_request: no + unprivileged: yes + cores: 2 + memory: 512 + swap: 512 + disks: + rootfs: + size: 10 + net: + net0: "name=eth0,ip=dhcp,tag={{ vlan.dhcp }},bridge={{ vmbr }},firewall=1" + features: "fuse=1,nesting=1,keyctl=1" + tasks: "./netsoc-cloud/templates/ubuntu-foundry.yml" + - vm: + name: "ubuntu.vps.template.netsoc.cloud" + storage: netsoc-cloud + template: + storage: netsoc-cloud + image_url: https://cloud-images.ubuntu.com/releases/focal/release-20200921.1/ubuntu-20.04-server-cloudimg-amd64.img + image_hash: sha256:d18a9d2b890d3c1401e70a281cae44b61816aa669c4936f7a99c168e572ec8cb + description: + title: "Ubuntu Server 20.04.1 LTS" + subtitle: "An easy to use server distro" + description: | + Ubuntu is a Linux distribution based on Debian mostly composed of free and open-source software. + Ubuntu is officially released in three editions: Desktop, Server, and Core for Internet of things devices and robots. + All the editions can run on the computer alone, or in a virtual machine + logo_url: https://raw.githubusercontent.com/UCCNetsoc/cloud/master/ui/public/img/templates/ubuntu.png + wake_on_request: no + cores: 1 + memory: 1024 + disks: + boot: + size: 10 + net: + net0: "model=virtio,tag={{ vlan.dhcp }},bridge={{ vmbr }},firewall=1" + cloudinit: + storage: "netsoc-cloud" + vars_files: + - vars/network.yml + - vars/secrets_mapping.yml + - vars/secrets.yml + tags: + - always diff --git a/provision-router.yml b/provision-router.yml index ae29fcd2..bfde24c3 100644 --- a/provision-router.yml +++ b/provision-router.yml @@ -1,39 +1,364 @@ -# --- -- hosts: router - tasks: - - set_fact: - dnat_base: 9000 - dnat: - - destination: - address: "84.39.234.53" - port: "80,443" - translation: - address: "{{ network.managerN.docker.net0.addresses[0] | ipmath(0) }}" - port: "80" - dnat_lines: [] - - # Build list of rules to apply from NAT table - - set_fact: - dnat_lines: | - {{ dnat_lines }} + [ - 'set nat destination rule {{ dnat_base + 1 + item }} destination address {{ dnat[item].destination.address }}', - 'set nat destination rule {{ dnat_base + 1 + item }} destination port {{ dnat[item].destination.port }}', - 'set nat destination rule {{ dnat_base + 1 + item }} translation address {{ dnat[item].translation.port }}', - 'set nat destination rule {{ dnat_base + 1 + item }} inbound-interface eth0.10' - ] - loop: "{{ range(0, len(dnat)) | list }}" - - debug: - msg: "{{ dnat_lines }}" - - # - name: "Provision router" - # vyos_config: - # - lines: - # loop: "{{ range(nat_rule_base+1, nat_rule_base+1+nat_rule_count)|list }}" - vars_files: - - vars/network.yml +# Can't run util next CIX trip, talk to canty # - name: "Provision router" # hosts: router +# vars_files: +# - vars/network.yml # tasks: -# \ No newline at end of file +# - set_fact: +# config_path: "/tmp/router-config-{{ 100000000000 | random }}.boot" +# # Base config, don't touch this without talking to canty pls +# - copy: +# dest: "{{ config_path }}" +# content: | +# firewall { +# all-ping enable +# broadcast-ping disable +# config-trap disable +# ipv6-receive-redirects disable +# ipv6-src-route disable +# ip-src-route disable +# log-martians enable +# name infra-user { +# default-action accept +# } +# name infra-wan { +# default-action accept +# } +# name user-infra { +# default-action accept +# } +# name user-wan { +# default-action accept +# } +# name vmhost-wan { +# default-action accept +# } +# name wan-infra { +# default-action accept +# } +# name wan-user { +# default-action accept +# } +# name wan-vmhost { +# default-action accept +# } +# receive-redirects disable +# send-redirects enable +# source-validation disable +# syn-cookies enable +# twa-hazards-protection disable +# } +# interfaces { +# ethernet eth0 { +# vif 10 { +# address 10.0.0.99/24 +# address 84.39.234.53/29 +# address 84.39.234.52/29 +# } +# vif 20 { +# address 10.0.20.1/24 +# } +# vif 30 { +# address 10.0.30.1/24 +# } +# vif 40 { +# address 10.0.40.1/24 +# } +# vif 90 { +# address 10.0.90.1/24 +# } +# } +# loopback lo { +# } +# } +# nat { +# destination { +# rule 800 { +# destination { +# address 84.39.234.53 +# port 80,443 +# } +# inbound-interface eth0.10 +# protocol tcp +# translation { +# address {{ interfaces.managerN.net0.addresses[0] | ipaddr('address') }} +# } +# } +# rule 801 { +# destination { +# address 84.39.234.53 +# port 80,443 +# } +# inbound-interface eth0.30 +# protocol tcp +# translation { +# address {{ interfaces.managerN.net0.addresses[0] | ipaddr('address') }} +# } +# } +# rule 802 { +# destination { +# address 84.39.234.52 +# port 22 +# } +# inbound-interface eth0.10 +# protocol tcp +# translation { +# address {{ interfaces.portal.net0.addresses[0] | ipaddr('address') }} +# } +# } +# rule 803 { +# destination { +# address 84.39.234.52 +# port 22 +# } +# inbound-interface eth0.30 +# protocol tcp +# translation { +# address {{ interfaces.portal.net0.addresses[0] | ipaddr('address') }} +# } +# } +# rule 900 { +# destination { +# address 84.39.234.53 +# port 8006 +# } +# inbound-interface eth0.10 +# protocol tcp +# translation { +# address 10.0.20.53 +# } +# } +# rule 901 { +# destination { +# address 84.39.234.53 +# port 2222 +# } +# inbound-interface eth0.10 +# protocol tcp +# translation { +# address 10.0.20.53 +# port 22 +# } +# } +# rule 902 { +# destination { +# address 84.39.234.53 +# port 8007 +# } +# inbound-interface eth0.10 +# protocol tcp +# translation { +# address 10.0.20.52 +# port 8006 +# } +# } +# rule 903 { +# destination { +# address 84.39.234.53 +# port 2223 +# } +# inbound-interface eth0.10 +# protocol tcp +# translation { +# address 10.0.20.52 +# port 22 +# } +# } +# rule 904 { +# destination { +# address 84.39.234.53 +# port 1194 +# } +# inbound-interface eth0.10 +# protocol tcp +# translation { +# address {{ interfaces.games.net0.addresses[0] | ipaddr('address') }} +# port 1194 +# } +# } +# } +# source { +# rule 10 { +# outbound-interface eth0.30 +# source { +# address 10.0.30.0/24 +# } +# destination { +# address 10.0.30.0/24 +# } +# translation { +# address masquerade +# } +# } +# rule 100 { +# outbound-interface eth0.10 +# source { +# address 10.0.20.0/24 +# } +# translation { +# address masquerade +# } +# } +# rule 101 { +# outbound-interface eth0.10 +# source { +# address 10.0.40.0/24 +# } +# translation { +# address 84.39.234.53 +# } +# } +# rule 102 { +# outbound-interface eth0.10 +# source { +# address 10.0.30.0/24 +# } +# translation { +# address 84.39.234.53 +# } +# } +# rule 901 { +# outbound-interface eth0.10 +# source { +# address 10.0.200.0/24 +# } +# translation { +# address 84.39.234.53 +# } +# } +# } +# } +# protocols { +# static { +# route 0.0.0.0/0 { +# next-hop 84.39.234.49 { +# distance 1 +# } +# } +# } +# } +# service { +# ssh { +# listen-address 10.0.90.1 +# port 22 +# } +# } +# system { +# config-management { +# commit-revisions 100 +# } +# console { +# device ttyS0 { +# speed 115200 +# } +# } +# host-name router.vm.netsoc.co +# login { +# user vyos { +# authentication { +# encrypted-password '$6$Z3O/fMz9g4zCWys$DiujfJa4GEAlgj8C0WQlAmTTdlqCWFLkMLq5Bq1aBTGusQeyhS7H5K6sLINHmx1qg1BYyF36oPtoCEz/ZZiVJ.' +# plaintext-password "" +# } +# level admin +# } +# } +# ntp { +# server 0.pool.ntp.org { +# } +# server 1.pool.ntp.org { +# } +# server 2.pool.ntp.org { +# } +# } +# syslog { +# global { +# facility all { +# level info +# } +# facility protocols { +# level debug +# } +# } +# } +# time-zone UTC +# } +# zone-policy { +# zone infra { +# default-action drop +# description "Infrastructure traffic" +# from user { +# firewall { +# name user-infra +# } +# } +# from wan { +# firewall { +# name wan-infra +# } +# } +# interface eth0.30 +# } +# zone mgmt { +# default-action drop +# description "Management traffic" +# interface eth0.90 +# } +# zone user { +# default-action drop +# description "User VM traffic" +# from infra { +# firewall { +# name infra-user +# } +# } +# from wan { +# firewall { +# name wan-user +# } +# } +# interface eth0.40 +# } +# zone vmhost { +# default-action drop +# description "VM host traffic" +# from wan { +# firewall { +# name wan-vmhost +# } +# } +# interface eth0.20 +# } +# zone wan { +# default-action drop +# description "WAN traffic" +# from infra { +# firewall { +# name infra-wan +# } +# } +# from user { +# firewall { +# name user-wan +# } +# } +# from vmhost { +# firewall { +# name vmhost-wan +# } +# } + +# interface eth0.10 +# } +# } + +# /* Warning: Do not remove the following line. */ +# /* === vyatta-config-version: "broadcast-relay@1:cluster@1:config-management@1:conntrack@1:conntrack-sync@1:dhcp-relay@2:dhcp-server@5:dns-forwarding@2:firewall@5:interfaces@3:ipsec@5:l2tp@1:mdns@1:nat@4:ntp@1:pptp@1:qos@1:quagga@4:snmp@1:ssh@1:system@11:vrrp@2:vyos-accel-ppp@2:wanloadbalance@3:webgui@1:webproxy@2:zone-policy@1" === */ +# /* Release version: 1.2-rolling-201911230217 */ +# - vyos_config: +# save: no +# src: "{{ config_path }}" +# register: result +# - debug: +# msg: "{{ result }}" diff --git a/provision-web.yml b/provision-web.yml deleted file mode 100644 index 78448b37..00000000 --- a/provision-web.yml +++ /dev/null @@ -1,30 +0,0 @@ -- name: "Enroll in IPA server" - hosts: web - roles: - - role: freeipa-client - vars: - client: - addresses: - - "{{ ansible_default_ipv4.address }}" - vars_files: - - "vars/freeipa.yml" - - "vars/network.yml" - - "vars/secrets.yml" - -- name: Setup NFS client and NFS mount requirements - hosts: web - roles: - - role: nfs-client-requirements - - role: autofs-automount - vars: - src: nfs.vm.netsoc.co:/home/users - mount: /home/users - opts: fstype=nfs4,rw,vers=4.2,sec=krb5p,hard,bg - vars_files: - - "vars/idmap.yml" - - "vars/freeipa.yml" - - "vars/secrets.yml" - -# - name: "Ensure Nginx Unit" -# roles: - diff --git a/proxmox_inventory.py b/proxmox_inventory.py index 61b35568..2b84c497 100755 --- a/proxmox_inventory.py +++ b/proxmox_inventory.py @@ -18,11 +18,19 @@ from proxmoxer import ProxmoxAPI, ResourceException +FILTERED_GROUPS = {"netsoc_cloud_vps", "netsoc_cloud_instance"} + +CONTAINER_SUFFIX = ".infra.netsoc.co" + if not 'PM_PASS' in os.environ: print("You need to run source ./proxmox_secrets.sh first") quit(-1) -proxmox = ProxmoxAPI("localhost", user=os.environ['PM_USER'], password=os.environ['PM_PASS'], verify_ssl=False) +host = "localhost" +if 'PM_HOST' in os.environ: + host = os.environ['PM_HOST'] + +proxmox = ProxmoxAPI(host, user=os.environ['PM_USER'], password=os.environ['PM_PASS'], verify_ssl=False) # If you're maintaining this script for future use # Here is a good tutorial on Ansible custom inventories @@ -36,6 +44,75 @@ } for node in proxmox.nodes.get(): + for con in proxmox.nodes(node['node']).lxc.get(): + if not con['name'].endswith(CONTAINER_SUFFIX): + continue + + # Get the config off the container + vm_config = proxmox.nodes(node['node']).lxc(con['vmid']).get('config') + + # We need to discover it's local 10.x.x.x IP + # so that we can ssh into the machine via ansible + ssh_ip = '' + + if con['status'] == 'running': + # Request the IPs that the VM is exposing via it's guest agent + try: + config = proxmox.nodes(node['node']).lxc(f"{con['vmid']}/config").get() + try: + macaddress = config["net0"].split("=")[5].split(',')[0] + except Exception as e: + macaddress = None + + try: + ssh_ip = config["net0"].split("=")[6].split(',')[0] + ssh_ip = ssh_ip[:-3] + except Exception as e: + continue + + except ResourceException: + # If the agent isn't running on the machine, ignore that machine + continue + pass + + + inventory['_meta']['hostvars'][con['name']] = { + "ansible_host": ssh_ip, + "ansible_ssh_user": "root" + } + + ssh_ip = '' + + # Parse yaml from vm description + if 'description' in vm_config: + desc_config = yaml.safe_load(vm_config['description']) + + if type(desc_config) == dict: + # Groups + filtered = False + if 'groups' in desc_config: + for group in desc_config['groups']: + if group in FILTERED_GROUPS: + filtered = True + continue + if group not in inventory: + inventory[group] = { + 'hosts': [ ], + 'host_vars': { + # group specific vars would be in here if specific + } + } + inventory[group]['hosts'].append(con['name']) + + # Host-specific vars + if filtered: + del inventory['_meta']['hostvars'][con['name']] + elif 'host_vars'in desc_config: + inventory['_meta']['hostvars'][con['name']] = { + **inventory['_meta']['hostvars'][con['name']], + **desc_config['host_vars'] + } + for vm in proxmox.nodes(node['node']).qemu.get(): # Get the config off the VM vm_config = proxmox.nodes(node['node']).qemu(vm['vmid']).get('config') @@ -47,40 +124,45 @@ if vm['status'] == 'running': # Request the IPs that the VM is exposing via it's guest agent try: + config = proxmox.nodes(node['node']).qemu(f"{vm['vmid']}/config").get() + try: + macaddress = config["net0"].split("=")[1].split(',')[0] + except Exception as e: + macaddress = None + ifaces = proxmox.nodes(node['node']).qemu(vm['vmid']).agent.get('network-get-interfaces') for iface in ifaces['result']: - if 'ip-addresses' in iface: - for ipinfo in iface['ip-addresses']: - # prefer ips with private subnets - if ipinfo['ip-address'].split('.')[0] == '10': - ssh_ip = ipinfo['ip-address'] - break + #print(iface) + if 'hardware-address' in iface and iface['hardware-address'].lower() == macaddress.lower(): + + if 'ip-addresses' in iface and len(iface['ip-addresses']) > 0: + ssh_ip = iface['ip-addresses'][0]['ip-address'] + break except ResourceException: # If the agent isn't running on the machine, ignore that machine continue pass - inventory['_meta']['hostvars'][vm['name']] = { - "ansible_host": ssh_ip + "ansible_host": ssh_ip, + "ansible_ssh_user": "netsoc" } + ssh_ip = '' + # Parse yaml from vm description if 'description' in vm_config: desc_config = yaml.safe_load(vm_config['description']) if type(desc_config) == dict: - # Host-specific vars - if 'host_vars'in desc_config: - inventory['_meta']['hostvars'][vm['name']] = { - **inventory['_meta']['hostvars'][vm['name']], - **desc_config['host_vars'] - } - # Groups + filtered = False if 'groups' in desc_config: for group in desc_config['groups']: + if group in FILTERED_GROUPS: + filtered = True + continue if group not in inventory: inventory[group] = { 'hosts': [ ], @@ -88,9 +170,17 @@ # group specific vars would be in here if specific } } - inventory[group]['hosts'].append(vm['name']) + # Host-specific vars + if filtered: + del inventory['_meta']['hostvars'][vm['name']] + elif 'host_vars'in desc_config: + inventory['_meta']['hostvars'][vm['name']] = { + **inventory['_meta']['hostvars'][vm['name']], + **desc_config['host_vars'] + } + if __name__ == '__main__': parser = OptionParser() diff --git a/proxmox_secrets.sh b/proxmox_secrets.sh index 6b2e7c67..f6c8e582 100755 --- a/proxmox_secrets.sh +++ b/proxmox_secrets.sh @@ -8,7 +8,7 @@ parse_yaml() { local s='[[:space:]]*' w='[a-zA-Z0-9_]*' fs=$(echo @|tr @ '\034') sed -ne "s|^\($s\)\($w\)$s:$s\"\(.*\)\"$s\$|\1$fs\2$fs\3|p" \ -e "s|^\($s\)\($w\)$s:$s\(.*\)$s\$|\1$fs\2$fs\3|p" $1 | - awk -F$fs '{ + awk -F$fs '$3 !~ /\(/{ indent = length($1)/2; vname[indent] = $2; for (i in vname) {if (i > indent) {delete vname[i]}} @@ -16,16 +16,33 @@ parse_yaml() { vn=""; for (i=0; i ./_secrets.yml + +if [[ -z "${VAULT_PASS}" ]]; then + echo -n "Vault password: " + read -s vault_pass + echo "$vault_pass" > ./_vault_pass + export VAULT_PASS=$vault_pass +else + echo "$VAULT_PASS" > ./_vault_pass +fi + +echo "" +ansible-vault edit vars/secrets.yml --vault-password-file ./_vault_pass > ./_secrets.yml eval $(parse_yaml _secrets.yml "yaml_") rm _secrets.yml +rm _vault_pass export EDITOR=$editor export PM_USER=$yaml_vault_proxmox_username export PM_PASS=$yaml_vault_proxmox_password +for f in *.sh; do + alias "${f::-3}"="$(pwd)/$f" +done + +echo "All .sh scripts in NaC are global. EG: 'run provision-infra-web.yml' maps to './run.sh provision-infra-web.yml'" diff --git a/pyvenv.cfg b/pyvenv.cfg index 7104627c..7eaf9358 100644 --- a/pyvenv.cfg +++ b/pyvenv.cfg @@ -1,8 +1,8 @@ home = /usr implementation = CPython -version_info = 2.7.16.final.0 +version_info = 3.7.3.final.0 virtualenv = 20.0.17 include-system-site-packages = false base-prefix = /usr base-exec-prefix = /usr -base-executable = /usr/bin/python2.7 +base-executable = /usr/bin/python3 diff --git a/requirements.txt b/requirements.txt index cee7fb6f..071b45db 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,6 @@ -ansible==2.9.10 +ansible==2.10.5 +ansible-base==2.10.5 +bcrypt==3.1.7 certifi==2020.6.20 cffi==1.14.0 chardet==3.0.4 @@ -9,12 +11,20 @@ idna==2.10 importlib-resources==3.0.0 ipaddress==1.0.23 Jinja2==2.11.2 +jmespath==0.10.0 jq==1.0.2 MarkupSafe==1.1.1 netaddr==0.8.0 +packaging==20.8 +paramiko==2.7.1 +passlib==1.7.2 pathlib2==2.3.5 -proxmoxer==1.1.1 +proxmoxer==1.2.0 pycparser==2.20 +PyNaCl==1.4.0 +pyparsing==2.4.7 +python-consul==1.1.0 +git+https://github.com/lxc/python3-lxc@master#egg=python3-lxc PyYAML==5.3.1 requests==2.24.0 scandir==1.10.0 diff --git a/requirements.yml b/requirements.yml index 0cfb7313..14c697a4 100644 --- a/requirements.yml +++ b/requirements.yml @@ -1,3 +1,8 @@ ---- collections: - - freeipa.ansible_freeipa \ No newline at end of file +- name: community.general +- name: ansible.posix +- name: community.grafana + +roles: +- src: cloudalchemy.node-exporter + version: 0.21.3 diff --git a/roles/ansible-requirements/README.md b/roles/ansible-requirements/README.md new file mode 100644 index 00000000..c4e6f55b --- /dev/null +++ b/roles/ansible-requirements/README.md @@ -0,0 +1,6 @@ +Ansible Requirements +========= + +For debian based systems. + +Installs Python 2.7, Python 3 then gathers facts \ No newline at end of file diff --git a/roles/ansible-requirements/tasks/main.yml b/roles/ansible-requirements/tasks/main.yml new file mode 100644 index 00000000..75f879c6 --- /dev/null +++ b/roles/ansible-requirements/tasks/main.yml @@ -0,0 +1,29 @@ +--- +# tasks file for ansible-requirements + +- name: Ensure Python 3 + become: yes + raw: test -e /usr/bin/python3 || (apt -y update && apt install -y python3) + register: result + changed_when: "result.rc != 0" + +- name: Gather facts + setup: + +- name: "Ensure pip installed" + become: yes + apt: + name: + - python-distutils-extra + - python3-pip + state: latest + +- name: Ensure upgraded pip and ansible pip requirements + become: yes + pip: + name: + - pip + - jsondiff + - pymysql + state: latest + extra_args: --upgrade diff --git a/roles/ansible/tasks/main.yml b/roles/ansible/tasks/main.yml index 2e9f89da..c12c885b 100644 --- a/roles/ansible/tasks/main.yml +++ b/roles/ansible/tasks/main.yml @@ -11,7 +11,7 @@ - name: Ensure python3-distutils apt: name: python3-distutils - + - name: Ensure pip installed apt: name: python3-pip @@ -21,14 +21,8 @@ pip: name: - pip - - ansible + - ansible==2.10.5 - proxmoxer - netaddr state: latest extra_args: --upgrade - -- name: Ensure Galaxy roles - command: ansible-galaxy collection install {{ item }} - with_items: - - freeipa.ansible_freeipa - ignore_errors: yes diff --git a/roles/auditd/files/audit.rules b/roles/auditd/files/audit.rules new file mode 100644 index 00000000..1700f0c4 --- /dev/null +++ b/roles/auditd/files/audit.rules @@ -0,0 +1,243 @@ +## https://github.com/Neo23x0/auditd/blob/master/audit.rules + +# Remove Pre-existing rules +-D + +# Buffer Size -- Large in case of stress events +-b 16,384 + +# Failure mode (0-silent, 1-print error msg, 2-panic) +-f 1 + +## rules + +## Kernel parameters +-w /etc/sysctl.conf -p wa -k sysctl + +## Kernel module loading and unloading +-a always,exit -F perm=x -F auid!=-1 -F path=/sbin/insmod -k modules +-a always,exit -F perm=x -F auid!=-1 -F path=/sbin/modprobe -k modules +-a always,exit -F perm=x -F auid!=-1 -F path=/sbin/rmmod -k modules +-a always,exit -F arch=b64 -S finit_module -S init_module -S delete_module -F auid!=-1 -k modules +-a always,exit -F arch=b32 -S finit_module -S init_module -S delete_module -F auid!=-1 -k modules +## Modprobe configuration +-w /etc/modprobe.conf -p wa -k modprobe + +## KExec usage (all actions) +-a always,exit -F arch=b64 -S kexec_load -k KEXEC +-a always,exit -F arch=b32 -S sys_kexec_load -k KEXEC + +## Special files +-a exit,always -F arch=b32 -S mknod -S mknodat -k specialfiles +-a exit,always -F arch=b64 -S mknod -S mknodat -k specialfiles + +## Mount operations (only attributable) +-a always,exit -F arch=b64 -S mount -S umount2 -F auid!=-1 -k mount +-a always,exit -F arch=b32 -S mount -S umount -S umount2 -F auid!=-1 -k mount + +# Change swap (only attributable) +-a always,exit -F arch=b64 -S swapon -S swapoff -F auid!=-1 -k swap +-a always,exit -F arch=b32 -S swapon -S swapoff -F auid!=-1 -k swap + +## Time +-a exit,always -F arch=b32 -S adjtimex -S settimeofday -S clock_settime -k time +-a exit,always -F arch=b64 -S adjtimex -S settimeofday -S clock_settime -k time +### Local time zone +-w /etc/localtime -p wa -k localtime + +## Stunnel +-w /usr/sbin/stunnel -p x -k stunnel + +## Cron configuration & scheduled jobs +-w /etc/cron.allow -p wa -k cron +-w /etc/cron.deny -p wa -k cron +-w /etc/cron.d/ -p wa -k cron +-w /etc/cron.daily/ -p wa -k cron +-w /etc/cron.hourly/ -p wa -k cron +-w /etc/cron.monthly/ -p wa -k cron +-w /etc/cron.weekly/ -p wa -k cron +-w /etc/crontab -p wa -k cron +-w /var/spool/cron/crontabs/ -k cron + +## User, group, password databases +-w /etc/group -p wa -k etcgroup +-w /etc/passwd -p wa -k etcpasswd +-w /etc/gshadow -k etcgroup +-w /etc/shadow -k etcpasswd +-w /etc/security/opasswd -k opasswd + +## Sudoers file changes +-w /etc/sudoers -p wa -k actions +-w /etc/sudoers.d/ -p wa -k actions + +## Passwd +-w /usr/bin/passwd -p x -k passwd_modification + +## Tools to change group identifiers +-w /usr/sbin/groupadd -p x -k group_modification +-w /usr/sbin/groupmod -p x -k group_modification +-w /usr/sbin/addgroup -p x -k group_modification +-w /usr/sbin/useradd -p x -k user_modification +-w /usr/sbin/usermod -p x -k user_modification +-w /usr/sbin/adduser -p x -k user_modification + +## Login configuration and information +-w /etc/login.defs -p wa -k login +-w /etc/securetty -p wa -k login +-w /var/log/faillog -p wa -k login +-w /var/log/lastlog -p wa -k login +-w /var/log/tallylog -p wa -k login + +## Network Environment +### Changes to hostname +-a always,exit -F arch=b32 -S sethostname -S setdomainname -k network_modifications +-a always,exit -F arch=b64 -S sethostname -S setdomainname -k network_modifications +## Successful IPv4 Connections +-a always,exit -F arch=b64 -S connect -F a2=16 -F success=1 -F key=network_connect_4 +-a always,exit -F arch=b32 -S connect -F a2=16 -F success=1 -F key=network_connect_4 +## Successful IPv6 Connections +-a always,exit -F arch=b64 -S connect -F a2=28 -F success=1 -F key=network_connect_6 +-a always,exit -F arch=b32 -S connect -F a2=28 -F success=1 -F key=network_connect_6 +### Changes to other files +-w /etc/hosts -p wa -k network_modifications +-w /etc/sysconfig/network -p wa -k network_modifications +-w /etc/network/ -p wa -k network +-a always,exit -F dir=/etc/NetworkManager/ -F perm=wa -k network_modifications +### Changes to issue +-w /etc/issue -p wa -k etcissue +-w /etc/issue.net -p wa -k etcissue + +## System startup scripts +-w /etc/inittab -p wa -k init +-w /etc/init.d/ -p wa -k init +-w /etc/init/ -p wa -k init + +## Library search paths +-w /etc/ld.so.conf -p wa -k libpath + +## Systemwide library preloads (LD_PRELOAD) +-w /etc/ld.so.preload -p wa -k systemwide_preloads + +## Pam configuration +-w /etc/pam.d/ -p wa -k pam +-w /etc/security/limits.conf -p wa -k pam +-w /etc/security/pam_env.conf -p wa -k pam +-w /etc/security/namespace.conf -p wa -k pam +-w /etc/security/namespace.init -p wa -k pam + +## Postfix configuration +-w /etc/aliases -p wa -k mail +-w /etc/postfix/ -p wa -k mail + +## SSH configuration +-w /etc/ssh/sshd_config -k sshd + +# Systemd +-w /bin/systemctl -p x -k systemd +-w /etc/systemd/ -p wa -k systemd + +## SELinux events that modify the system's Mandatory Access Controls (MAC) +-w /etc/selinux/ -p wa -k mac_policy + +## Critical elements access failures +-a exit,always -F arch=b64 -S open -F dir=/etc -F success=0 -k unauthedfileaccess +-a exit,always -F arch=b64 -S open -F dir=/bin -F success=0 -k unauthedfileaccess +-a exit,always -F arch=b64 -S open -F dir=/sbin -F success=0 -k unauthedfileaccess +-a exit,always -F arch=b64 -S open -F dir=/usr/bin -F success=0 -k unauthedfileaccess +-a exit,always -F arch=b64 -S open -F dir=/usr/sbin -F success=0 -k unauthedfileaccess +-a exit,always -F arch=b64 -S open -F dir=/var -F success=0 -k unauthedfileaccess +-a exit,always -F arch=b64 -S open -F dir=/home -F success=0 -k unauthedfileaccess +-a exit,always -F arch=b64 -S open -F dir=/srv -F success=0 -k unauthedfileaccess + +## Process ID change (switching accounts) applications +-w /bin/su -p x -k priv_esc +-w /usr/bin/sudo -p x -k priv_esc +-w /etc/sudoers -p rw -k priv_esc + +## Power state +-w /sbin/shutdown -p x -k power +-w /sbin/poweroff -p x -k power +-w /sbin/reboot -p x -k power +-w /sbin/halt -p x -k power + +## Session initiation information +-w /var/run/utmp -p wa -k session +-w /var/log/btmp -p wa -k session +-w /var/log/wtmp -p wa -k session + +## Discretionary Access Control (DAC) modifications +-a always,exit -F arch=b32 -S chmod -F auid>=500 -F auid!=4294967295 -k perm_mod +-a always,exit -F arch=b32 -S chown -F auid>=500 -F auid!=4294967295 -k perm_mod +-a always,exit -F arch=b32 -S fchmod -F auid>=500 -F auid!=4294967295 -k perm_mod +-a always,exit -F arch=b32 -S fchmodat -F auid>=500 -F auid!=4294967295 -k perm_mod +-a always,exit -F arch=b32 -S fchown -F auid>=500 -F auid!=4294967295 -k perm_mod +-a always,exit -F arch=b32 -S fchownat -F auid>=500 -F auid!=4294967295 -k perm_mod +-a always,exit -F arch=b32 -S fremovexattr -F auid>=500 -F auid!=4294967295 -k perm_mod +-a always,exit -F arch=b32 -S fsetxattr -F auid>=500 -F auid!=4294967295 -k perm_mod +-a always,exit -F arch=b32 -S lchown -F auid>=500 -F auid!=4294967295 -k perm_mod +-a always,exit -F arch=b32 -S lremovexattr -F auid>=500 -F auid!=4294967295 -k perm_mod +-a always,exit -F arch=b32 -S lsetxattr -F auid>=500 -F auid!=4294967295 -k perm_mod +-a always,exit -F arch=b32 -S removexattr -F auid>=500 -F auid!=4294967295 -k perm_mod +-a always,exit -F arch=b32 -S setxattr -F auid>=500 -F auid!=4294967295 -k perm_mod +-a always,exit -F arch=b64 -S chmod -F auid>=500 -F auid!=4294967295 -k perm_mod +-a always,exit -F arch=b64 -S chown -F auid>=500 -F auid!=4294967295 -k perm_mod +-a always,exit -F arch=b64 -S fchmod -F auid>=500 -F auid!=4294967295 -k perm_mod +-a always,exit -F arch=b64 -S fchmodat -F auid>=500 -F auid!=4294967295 -k perm_mod +-a always,exit -F arch=b64 -S fchown -F auid>=500 -F auid!=4294967295 -k perm_mod +-a always,exit -F arch=b64 -S fchownat -F auid>=500 -F auid!=4294967295 -k perm_mod +-a always,exit -F arch=b64 -S fremovexattr -F auid>=500 -F auid!=4294967295 -k perm_mod +-a always,exit -F arch=b64 -S fsetxattr -F auid>=500 -F auid!=4294967295 -k perm_mod +-a always,exit -F arch=b64 -S lchown -F auid>=500 -F auid!=4294967295 -k perm_mod +-a always,exit -F arch=b64 -S lremovexattr -F auid>=500 -F auid!=4294967295 -k perm_mod +-a always,exit -F arch=b64 -S lsetxattr -F auid>=500 -F auid!=4294967295 -k perm_mod +-a always,exit -F arch=b64 -S removexattr -F auid>=500 -F auid!=4294967295 -k perm_mod +-a always,exit -F arch=b64 -S setxattr -F auid>=500 -F auid!=4294967295 -k perm_mod + + +## Suspicious activity +-w /usr/bin/wget -p x -k susp_activity +-w /usr/bin/curl -p x -k susp_activity +-w /usr/bin/base64 -p x -k susp_activity +-w /bin/nc -p x -k susp_activity +-w /bin/netcat -p x -k susp_activity +-w /usr/bin/ncat -p x -k susp_activity +-w /usr/bin/ssh -p x -k susp_activity +-w /usr/bin/scp -p x -k susp_activity +-w /usr/bin/sftp -p x -k susp_activity +-w /usr/bin/ftp -p x -k susp_activity +-w /usr/bin/socat -p x -k susp_activity +-w /usr/bin/wireshark -p x -k susp_activity +-w /usr/bin/tshark -p x -k susp_activity +-w /usr/bin/rawshark -p x -k susp_activity +-w /usr/bin/rdesktop -p x -k susp_activity +-w /usr/bin/nmap -p x -k susp_activity + +## Added to catch netcat on Ubuntu +-w /bin/nc.openbsd -p x -k susp_activity +-w /bin/nc.traditional -p x -k susp_activity + +## Sbin suspicious activity +-w /sbin/iptables -p x -k sbin_susp +-w /sbin/ip6tables -p x -k sbin_susp +-w /sbin/ifconfig -p x -k sbin_susp +-w /usr/sbin/arptables -p x -k sbin_susp +-w /usr/sbin/ebtables -p x -k sbin_susp +-w /usr/sbin/nft -p x -k sbin_susp +-w /usr/sbin/tcpdump -p x -k sbin_susp +-w /usr/sbin/traceroute -p x -k sbin_susp + +## Injection +### These rules watch for code injection by the ptrace facility. +### This could indicate someone trying to do something bad or just debugging +-a always,exit -F arch=b32 -S ptrace -k tracing +-a always,exit -F arch=b64 -S ptrace -k tracing +-a always,exit -F arch=b32 -S ptrace -F a0=0x4 -k code_injection +-a always,exit -F arch=b64 -S ptrace -F a0=0x4 -k code_injection +-a always,exit -F arch=b32 -S ptrace -F a0=0x5 -k data_injection +-a always,exit -F arch=b64 -S ptrace -F a0=0x5 -k data_injection +-a always,exit -F arch=b32 -S ptrace -F a0=0x6 -k register_injection +-a always,exit -F arch=b64 -S ptrace -F a0=0x6 -k register_injection + +## Privilege Abuse +### The purpose of this rule is to detect when an admin may be abusing power by looking in user's home dir. +-a always,exit -F dir=/home -F uid=0 -F auid>=1000 -F auid!=4294967295 -C auid!=obj_uid -k power_abuse diff --git a/roles/auditd/tasks/main.yml b/roles/auditd/tasks/main.yml new file mode 100644 index 00000000..66e4319d --- /dev/null +++ b/roles/auditd/tasks/main.yml @@ -0,0 +1,18 @@ +--- +- name: Ensure auditd installed + become: yes + apt: + name: auditd + +- name: Ensure rules file + become: yes + copy: + src: "files/audit.rules" + dest: "/etc/audit/rules.d/audit.rules" + +- name: Ensure auditd running + become: yes + systemd: + state: started + masked: no + name: auditd diff --git a/roles/autofs-automount/tasks/main.yml b/roles/autofs-automount/tasks/main.yml deleted file mode 100644 index 2724909e..00000000 --- a/roles/autofs-automount/tasks/main.yml +++ /dev/null @@ -1,25 +0,0 @@ -- become: yes - apt: - name: autofs - state: latest - -- become: yes - lineinfile: - path: /etc/auto.master - regexp: "^{{ mount }}" - line: "/- /etc/auto.{{ range(0, 500000000) | random(seed=mount) }} --timeout 60" - - -# https://andrewaadland.me/2017-06-18-autofs-nfs-and-archlinux-key-not-found-in-map-sources/ -- become: yes - copy: - content: | - {{ mount }} -{{ opts }} {{ src }} - dest: "/etc/auto.{{ range(0, 500000000) | random(seed=mount) }}" - -- name: Enable and restart service autofs - become: yes - service: - name: autofs - enabled: yes - state: restarted \ No newline at end of file diff --git a/roles/backups-hosts/tasks/main.yml b/roles/backups-hosts/tasks/main.yml new file mode 100644 index 00000000..5e105c80 --- /dev/null +++ b/roles/backups-hosts/tasks/main.yml @@ -0,0 +1,1201 @@ +--- +- name: "Ensure duplicity dependencies on each proxmox host" + become: yes + apt: + name: + - python-requests + - python-requests-oauthlib + +- name: "Ensure duplicity-backup.sh on each system" + become: yes + copy: + content: | + #!/usr/bin/env bash + # + # Copyright (c) 2008-2010 Damon Timm. + # Copyright (c) 2010 Mario Santagiuliana. + # Copyright (c) 2012-2018 Marc Gallet. + # + # This program is free software: you can redistribute it and/or modify it under + # the terms of the GNU General Public License as published by the Free Software + # Foundation, either version 3 of the License, or (at your option) any later + # version. + # + # This program is distributed in the hope that it will be useful, but WITHOUT + # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + # details. + # + # You should have received a copy of the GNU General Public License along with + # this program. If not, see . + # + # MORE ABOUT THIS SCRIPT AVAILABLE IN THE README AND AT: + # + # http://zertrin.org/projects/duplicity-backup/ (for this version) + # http://damontimm.com/code/dt-s3-backup (for the original program by Damon Timm) + # + # Latest code available at: + # http://github.com/zertrin/duplicity-backup.sh + # + # List of contributors: + # https://github.com/zertrin/duplicity-backup.sh/graphs/contributors + # + # ---------------------------------------------------------------------------- # + + # Default config file (don't forget to copy duplicity-backup.conf.example to + # match that path) + # + # NOTE: It is RECOMMENDED to use the command line option -c to specify the + # location of the config file. The CONFIG variable here is only used for + # fallback purposes (look for the file named 'duplicity-backup.conf' in + # the same folder as the script, if the option -c is not given). + # It is DEPRECATED to edit this. + + CONFIG="duplicity-backup.conf" + + ############################################################## + # Script Happens Below This Line - Shouldn't Require Editing # + ############################################################## + + DBSH_VERSION="v1.6.0" + + # make a backup of stdout and stderr for later + exec 6>&1 + exec 7>&2 + + # ------------------------------------------------------------ + + usage(){ + echo "USAGE: + $(basename "$0") [options] + + Options: + -c, --config CONFIG_FILE specify the config file to use + + -b, --backup runs an incremental backup + -f, --full forces a full backup + -v, --verify verifies the backup + -e, --cleanup cleanup the backup (eg. broken sessions), by default using + duplicity --force flag, use --dry-run to actually log what + will be cleaned up without removing (see man duplicity + > ACTIONS > cleanup for details) + -l, --list-current-files lists the files currently backed up in the archive + -s, --collection-status show all the backup sets in the archive + + --restore [PATH] restores the entire backup to [path] + --restore-file [FILE_TO_RESTORE] [DESTINATION] + restore a specific file + --restore-dir [DIR_TO_RESTORE] [DESTINATION] + restore a specific directory + + -t, --time TIME specify the time from which to restore or list files + (see duplicity man page for the format) + + --backup-script automatically backup the script and secret key(s) to + the current working directory + + -q, --quiet silence most of output messages, except errors and output + that are intended for interactive usage. Silenced output + is still logged in the logfile. + + -n, --dry-run perform a trial run with no changes made + -d, --debug echo duplicity commands to logfile + -V, --version print version information about this script and duplicity + -h, --help print this help and exit + + CURRENT SCRIPT VARIABLES: + ======================== + DEST (backup destination) = ${DEST} + INCLIST (directories included) = ${INCLIST[*]:0} + EXCLIST (directories excluded) = ${EXCLIST[*]:0} + ROOT (root directory of backup) = ${ROOT} + LOGFILE (log file path) = ${LOGFILE} + " >&6 + USAGE=1 + } + + DUPLICITY="$(command -v duplicity)" + + if [ ! -x "${DUPLICITY}" ]; then + echo "ERROR: duplicity not installed, that's gotta happen first!" >&2 + exit 1 + fi + + DUPLICITY_VERSION=$(${DUPLICITY} --version) + DUPLICITY_VERSION=${DUPLICITY_VERSION//[^0-9\.]/} + + version_compare() { + if [[ $1 =~ ^([0-9]+\.?)+$ && $2 =~ ^([0-9]+\.?)+$ ]]; then + # shellcheck disable=SC2206 + local l=(${1//./ }) r=(${2//./ }) s=${#l[@]}; [[ ${#r[@]} -gt ${#l[@]} ]] && s=${#r[@]} + + for i in $(seq 0 $((s - 1))); do + [[ ${l[$i]} -gt ${r[$i]} ]] && return 1 + [[ ${l[$i]} -lt ${r[$i]} ]] && return 2 + done + + return 0 + else + echo "Invalid version number given" + exit 1 + fi + } + + # set a flag if duplicity's version is lower than 0.7, for usage later in the script + version_compare "${DUPLICITY_VERSION}" 0.7 + case $? in 2) LT07=1;; *) LT07=0;; esac + + version(){ + echo "duplicity-backup.sh ${DBSH_VERSION}" + echo "duplicity ${DUPLICITY_VERSION}" + exit 0 + } + + # Some expensive argument parsing that allows the script to + # be insensitive to the order of appearance of the options + # and to handle correctly option parameters that are optional + while getopts ":c:t:bfvelsqndhV-:" opt; do + case $opt in + # parse long options (a bit tricky because builtin getopts does not + # manage long options and I don't want to impose GNU getopt dependancy) + -) + case "${OPTARG}" in + # --restore [restore dest] + restore) + COMMAND=${OPTARG} + # We try to find the optional value [restore dest] + if [ -n "${!OPTIND:0:1}" ] && [ ! "${!OPTIND:0:1}" = "-" ]; then + RESTORE_DEST=${!OPTIND} + OPTIND=$(( OPTIND + 1 )) # we found it, move forward in arg parsing + fi + ;; + # --restore-file [file to restore] [restore dest] + # --restore-dir [path to restore] [restore dest] + restore-file|restore-dir) + COMMAND=${OPTARG} + # We try to find the first optional value [file to restore] + if [ -n "${!OPTIND:0:1}" ] && [ ! "${!OPTIND:0:1}" = "-" ]; then + FILE_TO_RESTORE=${!OPTIND} + OPTIND=$(( OPTIND + 1 )) # we found it, move forward in arg parsing + else + continue # no value for the restore-file option, skip the rest + fi + # We try to find the second optional value [restore dest] + if [ -n "${!OPTIND:0:1}" ] && [ ! "${!OPTIND:0:1}" = "-" ]; then + RESTORE_DEST=${!OPTIND} + OPTIND=$(( OPTIND + 1 )) # we found it, move forward in arg parsing + fi + ;; + config) # set the config file from the command line + # We try to find the config file + if [ -n "${!OPTIND:0:1}" ] && [ ! "${!OPTIND:0:1}" = "-" ]; then + CONFIG=${!OPTIND} + OPTIND=$(( OPTIND + 1 )) # we found it, move forward in arg parsing + fi + ;; + time) # set the restore time from the command line + # We try to find the restore time + if [ -n "${!OPTIND:0:1}" ] && [ ! "${!OPTIND:0:1}" = "-" ]; then + TIME=${!OPTIND} + OPTIND=$(( OPTIND + 1 )) # we found it, move forward in arg parsing + fi + ;; + quiet) + QUIET=1 + ;; + dry-run) + DRY_RUN="--dry-run" + ;; + debug) + ECHO=$(command -v echo) + ;; + help) + usage + exit 0 + ;; + version) + version + ;; + *) + COMMAND=${OPTARG} + ;; + esac + ;; + # here are parsed the short options + c) CONFIG=${OPTARG};; # set the config file from the command line + t) TIME=${OPTARG};; # set the restore time from the command line + b) COMMAND="backup";; + f) COMMAND="full";; + v) COMMAND="verify";; + e) COMMAND="cleanup";; + l) COMMAND="list-current-files";; + s) COMMAND="collection-status";; + q) QUIET=1;; + n) DRY_RUN="--dry-run";; # dry run + d) ECHO=$(command -v echo);; # debug + h) + usage + exit 0 + ;; + V) version;; + :) + echo "Option -${OPTARG} requires an argument." >&2 + COMMAND="" + ;; + \?) + echo "Invalid option: -${OPTARG}" >&2 + COMMAND="" + ;; + esac + done + #echo "Options parsed. COMMAND=${COMMAND}" # for debugging + + + # ---------------- Read config file if specified ----------------- + + if [ -n "${CONFIG}" ] && [ -f "${CONFIG}" ]; + then + # shellcheck source=duplicity-backup.conf.example + . "${CONFIG}" + else + echo "ERROR: can't find config file! (${CONFIG})" >&2 + usage + exit 1 + fi + + # ----------------------- Setup logging --------------------------- + + # Setup logging as soon as possible, in order to be able to perform i/o redirection + + [[ ${LOGDIR} = "/home/foobar_user_name/logs/test2/" ]] && config_sanity_fail "LOGDIR must be configured" + + # Ensure a trailing slash always exists in the log directory name + LOGDIR="${LOGDIR%/}/" + + LOGFILE="${LOGDIR}${LOG_FILE}" + + if [ ! -d "${LOGDIR}" ]; then + echo "Attempting to create log directory ${LOGDIR} ..." + if ! mkdir -p "${LOGDIR}"; then + echo "Log directory ${LOGDIR} could not be created by this user: ${USER}" >&2 + echo "Aborting..." >&2 + exit 1 + else + echo "Directory ${LOGDIR} successfully created." + fi + echo "Attempting to change owner:group of ${LOGDIR} to ${LOG_FILE_OWNER} ..." + if ! chown "${LOG_FILE_OWNER}" "${LOGDIR}"; then + echo "User ${USER} could not change the owner:group of ${LOGDIR} to ${LOG_FILE_OWNER}" >&2 + echo "Aborting..." >&2 + exit 1 + else + echo "Directory ${LOGDIR} successfully changed to owner:group of ${LOG_FILE_OWNER}" + fi + elif [ ! -w "${LOGDIR}" ]; then + echo "Log directory ${LOGDIR} is not writeable by this user: ${USER}" >&2 + echo "Aborting..." >&2 + exit 1 + fi + + # -------------------- Setup I/O redirections -------------------- + # Magic from + # http://superuser.com/questions/86915/force-bash-script-to-use-tee-without-piping-from-the-command-line + # + # ##### Redirection matrix in the case when quiet mode is ON ##### + # + # QUIET mode ON | shown on screen | not shown on screen + # ---------------+-----------------+---------------------- + # logged | fd2, fd3 | fd1, fd5 + # not logged | fd4 | - + # + # ##### Redirection matrix in the case when quiet mode is OFF ##### + # + # QUIET mode OFF | shown on screen | not shown on screen + # ---------------+-----------------+---------------------- + # logged | fd1, fd2, fd3 | fd5 + # not logged | fd4 | - + # + # fd1 is stdout and is always logged but only shown if not QUIET + # fd2 is stderr and is always shown on screen and logged + # fd3 is like stdout but always shown on screen (for interactive prompts) + # fd4 is always shown on screen but never logged (for the usage text) + # fd5 is never shown on screen but always logged (for delimiters in the log) + # + + # fd2 and fd3 are always logged and shown on screen via tee + # for fd2 (original stderr) the output of tee needs to be redirected to stderr + exec 2> >(tee -ia "${LOGFILE}" >&2) + # create fd3 as a redirection to stdout and the logfile via tee + exec 3> >(tee -ia "${LOGFILE}") + + # create fd4 as a copy of stdout, but that won't be redirected to tee + # so that it is always shown and never logged + exec 4>&1 + + # create fd5 as a direct redirection to the logfile + # so that the content is never shown on screen but always logged + exec 5>> "${LOGFILE}" + + # finally we modify stdout (fd1) to always being logged (like fd3 and fd5) + # but only being shown on screen if quiet mode is not active + if [[ ${QUIET} == 1 ]]; then + # Quiet mode: stdout not shown on screen but still logged via fd5 + exec 1>&5 + else + # Normal mode: stdout shown on screen and logged via fd3 + exec 1>&3 + fi + + # tests for debugging the magic + #echo "redirected to fd1" + #echo "redirected to fd2" >&2 + #echo "redirected to fd3" >&3 + #echo "redirected to fd4" >&4 + #echo "redirected to fd5" >&5 + + # ------------------------- Setting up variables ------------------------ + + if [ -n "${DRY_RUN}" ]; then + STATIC_OPTIONS="${DRY_RUN} ${STATIC_OPTIONS}" + fi + + if [ -n "${STORAGECLASS}" ]; then + STATIC_OPTIONS="${STATIC_OPTIONS} ${STORAGECLASS}" + fi + + SIGN_PASSPHRASE=${PASSPHRASE} + + export AWS_ACCESS_KEY_ID + export AWS_SECRET_ACCESS_KEY + export GS_ACCESS_KEY_ID + export GS_SECRET_ACCESS_KEY + export SWIFT_USERNAME + export SWIFT_PASSWORD + export SWIFT_AUTHURL + export SWIFT_AUTHVERSION + export SWIFT_TENANTNAME + export SWIFT_REGIONNAME + export DPBX_ACCESS_TOKEN + export PASSPHRASE + export SIGN_PASSPHRASE + + if [[ -n "${FTP_PASSWORD}" ]]; then + export FTP_PASSWORD + fi + + if [[ -n "${TMPDIR}" ]]; then + export TMPDIR + fi + + # File to use as a lock. The lock is used to insure that only one instance of + # the script is running at a time. + LOCKFILE=${LOGDIR}backup.lock + + if [ "${ENCRYPTION}" = "yes" ]; then + ENCRYPT="--gpg-options \"${GPG_OPTIONS}\"" + if [ -n "${GPG_ENC_KEY}" ] && [ -n "${GPG_SIGN_KEY}" ]; then + if [ "${HIDE_KEY_ID}" = "yes" ]; then + ENCRYPT="${ENCRYPT} --hidden-encrypt-key=${GPG_ENC_KEY}" + if [ "${COMMAND}" != "restore" ] && [ "${COMMAND}" != "restore-file" ] && [ "${COMMAND}" != "restore-dir" ]; then + ENCRYPT="${ENCRYPT} --sign-key=${GPG_SIGN_KEY}" + fi + else + ENCRYPT="${ENCRYPT} --encrypt-key=${GPG_ENC_KEY} --sign-key=${GPG_SIGN_KEY}" + fi + if [ -n "${SECRET_KEYRING}" ]; then + KEYRING="--secret-keyring ${SECRET_KEYRING}" + ENCRYPT="${ENCRYPT} --encrypt-secret-keyring=${SECRET_KEYRING}" + fi + elif [ -n "${PASSPHRASE}" ]; then + ENCRYPT="" + fi + elif [ "${ENCRYPTION}" = "no" ]; then + ENCRYPT="--no-encryption" + fi + + NO_GSCMD="WARNING: gsutil not found in PATH, remote file \ + size information unavailable." + NO_GSCMD_CFG="WARNING: gsutil is not configured, run 'gsutil config' \ + in order to retrieve remote file size information. Remote file \ + size information unavailable." + + NO_S3CMD="WARNING: s3cmd not found in PATH, remote file \ + size information unavailable." + NO_S3CMD_CFG="WARNING: s3cmd is not configured, run 's3cmd --configure' \ + in order to retrieve remote file size information. Remote file \ + size information unavailable." + + NO_B2CMD="WARNING: b2 not found in PATH, remote file size information \ + unavailable. Is the python-b2 package installed?" + + README_TXT="In case you've long forgotten, this is a backup script that you used to backup some files (most likely remotely at Amazon S3). In order to restore these files, you first need to import your GPG private(s) key(s) (if you haven't already). The key(s) is/are in this directory and the following command(s) should do the trick:\n\nIf you were using the same key for encryption and signature:\n gpg --allow-secret-key-import --import duplicity-backup-encryption-and-sign-secret.key.txt\nOr if you were using two separate keys for encryption and signature:\n gpg --allow-secret-key-import --import duplicity-backup-encryption-secret.key.txt\n gpg --allow-secret-key-import --import duplicity-backup-sign-secret.key.txt\n\nAfter your key(s) has/have been succesfully imported, you should be able to restore your files.\n\nGood luck!" + + if [ "$(echo "${DEST}" | cut -c 1,2)" = "gs" ]; then + DEST_IS_GS=true + GSCMD="$(command -v gsutil)" + if [ ! -x "${GSCMD}" ]; then + echo "${NO_GSCMD}"; GSCMD_AVAIL=false + elif [ ! -f "${HOME}/.boto" ]; then + echo "${NO_GSCMD_CFG}"; GSCMD_AVAIL=false + else + GSCMD_AVAIL=true + GSCMD="${GSCMD}" + fi + else + DEST_IS_GS=false + fi + + if [ "$(echo "${DEST}" | cut -c 1,2)" = "s3" ]; then + DEST_IS_S3=true + S3CMD="$(command -v s3cmd)" + if [ ! -x "${S3CMD}" ]; then + echo "${NO_S3CMD}"; S3CMD_AVAIL=false + elif [ -z "${S3CMD_CONF_FILE}" ] && [ ! -f "${HOME}/.s3cfg" ]; then + S3CMD_CONF_FOUND=false + echo "${NO_S3CMD_CFG}"; S3CMD_AVAIL=false + elif [ -n "${S3CMD_CONF_FILE}" ] && [ ! -f "${S3CMD_CONF_FILE}" ]; then + S3CMD_CONF_FOUND=false + echo "${S3CMD_CONF_FILE} not found, check S3CMD_CONF_FILE variable in duplicity-backup's configuration!"; + echo "${NO_S3CMD_CFG}"; + S3CMD_AVAIL=false + else + S3CMD_AVAIL=true + S3CMD_CONF_FOUND=true + if [ -n "${S3CMD_CONF_FILE}" ] && [ -f "${S3CMD_CONF_FILE}" ]; then + # if conf file specified and it exists then add it to the command line for s3cmd + S3CMD="${S3CMD} -c ${S3CMD_CONF_FILE}" + fi + fi + else + DEST_IS_S3=false + fi + + if [ "$(echo "${DEST}" | cut -c 1,4)" = "dpbx" ]; then + DEST_IS_DPBX=true + else + DEST_IS_DPBX=false + fi + + if [ "$(echo "${DEST}" | cut -c 1,2)" = "b2" ]; then + DEST_IS_B2=true + B2CMD="$(command -v b2)" + if [ ! -x "${B2CMD}" ]; then + echo "${NO_B2CMD}"; B2CMD_AVAIL=false + fi + else + DEST_IS_B2=false + fi + + config_sanity_fail() + { + EXPLANATION=$1 + CONFIG_VAR_MSG="Oops!! ${0} was unable to run!\nWe are missing one or more important variables in the configuration file.\nCheck your configuration because it appears that something has not been set yet." + echo -e "${CONFIG_VAR_MSG}\n ${EXPLANATION}." >&2 + echo -e "--------------------- END ---------------------\n" >&5 + exit 1 + } + + check_variables () + { + [[ ${ROOT} = "" ]] && config_sanity_fail "ROOT must be configured" + [[ ${DEST} = "" || ${DEST} = "s3+http://backup-foobar-bucket/backup-folder/" ]] && config_sanity_fail "DEST must be configured" + [[ ${INCLIST[0]} = "/home/foobar_user_name/Documents/" ]] && config_sanity_fail "INCLIST must be configured" + [[ ${EXCLIST[0]} = "/home/foobar_user_name/Documents/foobar-to-exclude" ]] && config_sanity_fail "EXCLIST must be configured" + [[ ( ${ENCRYPTION} = "yes" && (${GPG_ENC_KEY} = "foobar_gpg_key" || \ + ${GPG_SIGN_KEY} = "foobar_gpg_key" || \ + ${PASSPHRASE} = "foobar_gpg_passphrase")) ]] && \ + config_sanity_fail "ENCRYPTION is set to 'yes', but GPG_ENC_KEY, GPG_SIGN_KEY, or PASSPHRASE have not been configured" + [[ ( ${DEST_IS_S3} = true && (${AWS_ACCESS_KEY_ID} = "foobar_aws_key_id" || ${AWS_SECRET_ACCESS_KEY} = "foobar_aws_access_key" )) ]] && \ + config_sanity_fail "An s3 DEST has been specified, but AWS_ACCESS_KEY_ID or AWS_SECRET_ACCESS_KEY have not been configured" + [[ ( ${DEST_IS_GS} = true && (${GS_ACCESS_KEY_ID} = "foobar_gcs_key_id" || ${GS_SECRET_ACCESS_KEY} = "foobar_gcs_secret_id" )) ]] && \ + config_sanity_fail "A Google Cloud Storage DEST has been specified, but GS_ACCESS_KEY_ID or GS_SECRET_ACCESS_KEY have not been configured" + [[ ( ${DEST_IS_DPBX} = true && (${DPBX_ACCESS_TOKEN} = "foobar_dropbox_access_token" )) ]] && \ + config_sanity_fail "A Dropbox DEST has been specified, but DPBX_ACCESS_TOKEN has not been configured" + [[ -n "${INCEXCFILE}" && ! -f ${INCEXCFILE} ]] && config_sanity_fail "The specified INCEXCFILE ${INCEXCFILE} does not exists" + } + + mailcmd_sendmail() { + # based on http://linux.die.net/man/8/sendmail.sendmail + echo -e "From: ${EMAIL_FROM}\nSubject: ${EMAIL_SUBJECT}\n" | cat - "${LOGFILE}" | ${MAILCMD} "${EMAIL_TO}" + } + mailcmd_ssmtp() { + # based on http://linux.die.net/man/8/ssmtp + echo -e "From: ${EMAIL_FROM}\nSubject: ${EMAIL_SUBJECT}\n" | cat - "${LOGFILE}" | ${MAILCMD} "${EMAIL_TO}" + } + mailcmd_msmtp() { + # based on http://manpages.ubuntu.com/manpages/precise/en/man1/msmtp.1.html + echo -e "Subject: ${EMAIL_SUBJECT}\n" | cat - "${LOGFILE}" | ${MAILCMD} -f "${EMAIL_FROM}" -- "${EMAIL_TO}" + } + mailcmd_bsd_mailx() { + # based on http://man.he.net/man1/bsd-mailx + ${MAILCMD} -s "${EMAIL_SUBJECT}" -a "From: ${EMAIL_FROM}" "${EMAIL_TO}" < "${LOGFILE}" + } + mailcmd_heirloom_mailx() { + # based on http://heirloom.sourceforge.net/mailx/mailx.1.html + ${MAILCMD} -s "${EMAIL_SUBJECT}" -S from="${EMAIL_FROM}" "${EMAIL_TO}" < "${LOGFILE}" + } + mailcmd_nail() { + # based on http://linux.die.net/man/1/nail + ${MAILCMD} -s "${EMAIL_SUBJECT}" -r "${EMAIL_FROM}" "${EMAIL_TO}" < "${LOGFILE}" + } + mailcmd_else() { + ${MAILCMD} "${EMAIL_SUBJECT}" "${EMAIL_FROM}" "${EMAIL_TO}" < "${LOGFILE}" + } + + email_logfile() + { + if [ -n "${EMAIL_TO}" ]; then + + MAILCMD=$(command -v "${MAIL}") + MAILCMD_REALPATH=$(readlink -e "${MAILCMD}") + MAILCMD_BASENAME=${MAILCMD_REALPATH##*/} + + if [ ! -x "${MAILCMD}" ]; then + echo -e "Email couldn't be sent. ${MAIL} not available." >&2 + else + EMAIL_SUBJECT=${EMAIL_SUBJECT:="duplicity-backup ${BACKUP_STATUS:-"ERROR"} (${HOSTNAME}) ${LOG_FILE}"} + case ${MAIL} in + ssmtp) + mailcmd_ssmtp;; + msmtp) + mailcmd_msmtp;; + mail|mailx) + case ${MAILCMD_BASENAME} in + bsd-mailx|mail.mailutils) + mailcmd_bsd_mailx;; + heirloom-mailx) + mailcmd_heirloom_mailx;; + s-nail) + mailcmd_nail;; + *) + mailcmd_else;; + esac + ;; + sendmail) + mailcmd_sendmail;; + nail) + mailcmd_nail;; + *) + mailcmd_else;; + esac + + echo -e "Email notification sent to ${EMAIL_TO} using ${MAIL}" + fi + fi + } + + send_notification() + { + if [ -n "${NOTIFICATION_SERVICE}" ]; then + echo "-----------[ Notification Request ]-----------" + NOTIFICATION_CONTENT="duplicity-backup ${BACKUP_STATUS:-"ERROR"} [${HOSTNAME}] - \`${LOGFILE}\`" + + if [ "${NOTIFICATION_SERVICE}" = "slack" ]; then + curl -X POST -H 'Content-type: application/json' --data "{\"text\": \"${NOTIFICATION_CONTENT}\", \"channel\": \"${SLACK_CHANNEL}\", \"username\": \"${SLACK_USERNAME}\", \"icon_emoji\": \":${SLACK_EMOJI}:\"}" "${SLACK_HOOK_URL}" + elif [ "${NOTIFICATION_SERVICE}" = "ifttt" ]; then + curl -X POST -H 'Content-type: application/json' --data "{\"value1\": \"${NOTIFICATION_CONTENT}\", \"value2\": \"${IFTTT_VALUE2}\"}" "${IFTTT_HOOK_URL}" + elif [ "${NOTIFICATION_SERVICE}" = "pushover" ]; then + curl -s \ + -F "token=${PUSHOVER_TOKEN}" \ + -F "user=${PUSHOVER_USER}" \ + -F "message=${NOTIFICATION_CONTENT}" \ + https://api.pushover.net/1/messages + elif [ "${NOTIFICATION_SERVICE}" = "telegram" ]; then + curl -s --max-time 10 -d "chat_id=${TELEGRAM_CHATID}&disable_web_page_preview=1&text=${NOTIFICATION_CONTENT}" "https://api.telegram.org/bot${TELEGRAM_KEY}/sendMessage" >/dev/null + fi + + echo -e "\n----------------------------------------------\n" + + if [ "${NOTIFICATION_SERVICE}" = "slack" ]; then + echo -e "Slack notification sent to channel ${SLACK_CHANNEL}" + elif [ "${NOTIFICATION_SERVICE}" = "ifttt" ]; then + echo -e "IFTTT notification sent to Maker channel event ${IFTTT_EVENT}" + elif [ "${NOTIFICATION_SERVICE}" = "pushover" ]; then + echo -e "Pushover notification sent" + elif [ "${NOTIFICATION_SERVICE}" = "telegram" ]; then + echo -e "Telegram notification sent" + fi + fi + } + + get_lock() + { + echo "Attempting to acquire lock ${LOCKFILE}" >&5 + if ( set -o noclobber; echo "$$" > "${LOCKFILE}" ) 2> /dev/null; then + # The lock succeeded. Create a signal handler to remove the lock file when the process terminates. + trap 'EXITCODE=$?; echo "Removing lock. Exit code: ${EXITCODE}" >> ${LOGFILE}; rm -f "${LOCKFILE}"' EXIT + echo "successfully acquired lock." >&5 + else + # Write lock acquisition errors to log file and stderr + echo "lock failed, could not acquire ${LOCKFILE}" >&2 + echo "lock held by $(cat "${LOCKFILE}")" >&2 + email_logfile + send_notification + exit 2 + fi + } + + get_source_file_size() + { + echo "-----------[ Source Disk Use Information ]-----------" + + # FIXME: doesn't work properly with include/exclude-filelists (issue #101) + + # Patches to support spaces in paths- + # Remove space as a field separator temporarily + OLDIFS=$IFS + IFS=$(echo -en "\t\n") + + case $(uname) in + FreeBSD|Darwin|DragonFly) + DUEXCFLAG="-I -" + ;; + OpenBSD) + echo "WARNING: OpenBSD du does not support exclusion, sizes may be off" + DUEXCFLAG="" + ;; + *) + DUEXCFLAG="--exclude-from=-" + ;; + esac + + # always exclude /proc + DUEXCLIST="/proc\n" + + for exclude in "${EXCLIST[@]}"; do + DUEXCLIST="${DUEXCLIST}${exclude}\n" + done + + # if INCLIST is not set or empty, add ROOT to it to be able to calculate disk usage + if [ ${#INCLIST[@]} -eq 0 ]; then + DUINCLIST=("${ROOT}") + else + DUINCLIST=("${INCLIST[@]}") + fi + + for include in "${DUINCLIST[@]}"; do + # shellcheck disable=SC2216 + echo -e "${DUEXCLIST}" | \ + du -hs ${DUEXCFLAG} "${include}" | \ + awk '{ FS="\t"; $0=$0; print $1"\t"$2 }' + done + + echo + + # Restore IFS + IFS=$OLDIFS + } + + get_remote_file_size() + { + echo "---------[ Destination Disk Use Information ]--------" + FRIENDLY_TYPE_NAME="" + dest_type=$(echo "${DEST}" | cut -c 1,2) + case $dest_type in + "ss") + FRIENDLY_TYPE_NAME="SSH" + + TMPDEST="${DEST#*://*/}" + TMPDEST="${DEST%/${TMPDEST}}" + ssh_opt=$(echo "${STATIC_OPTIONS}" |awk -vo="--ssh-options=" '{s=index($0,o); if (s) {s=substr($0,s+length(o)); m=substr(s,0,1); for (i=2; i < length(s); i++) { if (substr(s,i,1) == m && substr(s,i-1,1) != "\\\\") break; } print substr(s,2,i-2)}}') + + SIZE=$(${TMPDEST%://*} "${ssh_opt}" "${TMPDEST#*//}" du -hs "${DEST#${TMPDEST}/}" | awk '{print $1}') + EMAIL_SUBJECT="${EMAIL_SUBJECT} ${SIZE} $(${TMPDEST%://*} "${ssh_opt}" "${TMPDEST#*//}" df -hP "${DEST#${TMPDEST}/}" | awk '{tmp=$5 " used"}END{print tmp}')" + ;; + "fi") + FRIENDLY_TYPE_NAME="File" + TMPDEST="${DEST#file://*}" + SIZE=$(du -hs "${TMPDEST}" | awk '{print $1}') + ;; + "gs") + FRIENDLY_TYPE_NAME="Google Cloud Storage" + if ${GSCMD_AVAIL} ; then + #TMPDEST=$(echo "${DEST}" | sed -e "s/\/*$//" ) + TMPDEST=${DEST//\/*$/} + SIZE=$(gsutil du -hs "${TMPDEST}" | awk '{print $1$2}') + fi + ;; + "s3") + FRIENDLY_TYPE_NAME="Amazon S3" + if ${S3CMD_AVAIL} ; then + TMPDEST=$(echo "${DEST}" | cut -f 3- -d /) + dest_scheme=$(echo "${DEST}" | cut -f -1 -d :) + if [ "$dest_scheme" = "s3" ]; then + # Strip off the host name, too. + TMPDEST=$(echo "${TMPDEST}" | cut -f 2- -d /) + fi + SIZE=$(${S3CMD} du -H s3://"${TMPDEST}" | awk '{print $1}') + else + if ! ${S3CMD_CONF_FOUND} ; then + SIZE="-s3cmd config not found-" + else + SIZE="-s3cmd not found in PATH-" + fi + fi + ;; + "b2") + FRIENDLY_TYPE_NAME="Backblaze B2" + if ${B2CMD_AVAIL}; then + if [[ -n ${FTP_PASSWORD} ]]; then + APP_KEY=${FTP_PASSWORD} + else + APP_KEY=$(echo "${DEST}" | cut -d":" -f 3 | cut -d"@" -f 1) + fi + ACC_ID=$(echo "${DEST}" | cut -d"/" -f 3 | cut -d"@" -f 1 | cut -d ":" -f 1) + BUCKET=$(echo "${DEST}" | cut -d"@" -f2 | cut -d"/" -f1) + if [[ -z ${APP_KEY} ]] || [[ -z ${ACC_ID} ]]; then + SIZE="-b2 authentication wrong-" + return + fi + if [[ -z ${BUCKET} ]]; then + SIZE="-b2 bucket wrong-" + return + fi + if [[ $(${B2CMD} authorize-account "${ACC_ID}" "${APP_KEY}" >/dev/null 2>&1) -ne 0 ]]; then + SIZE="-b2 authentication wrong-" + return + fi + SIZE=$(${B2CMD} ls --long "${BUCKET}" | awk '{ print $5 }' | paste -sd+ | bc | numfmt --to=iec) + else + SIZE="-b2 not found in PATH-" + fi + ;; + *) + # not yet available for the other backends + FRIENDLY_TYPE_NAME="" + ;; + esac + + if [[ ${FRIENDLY_TYPE_NAME} ]] ; then + echo -e "${SIZE}\t${FRIENDLY_TYPE_NAME} type backend" + else + echo "Destination disk use information is currently only available for the following storage backends:" + echo "File, SSH, Amazon S3, Google Cloud and Backblaze B2" + fi + echo + } + + include_exclude() + { + # Changes to handle spaces in directory names and filenames + # and wrapping the files to include and exclude in quotes. + OLDIFS=$IFS + IFS=$(echo -en "\t\n") + + # Exclude device files? + if [ -n "${EXDEVICEFILES}" ] && [ "${EXDEVICEFILES}" -ne 0 ]; then + TMP=" --exclude-device-files" + EXCLUDE=${EXCLUDE}${TMP} + fi + + for include in "${INCLIST[@]}" + do + if [[ -n "$include" ]]; then + TMP=" --include='$include'" + INCLUDE=${INCLUDE}${TMP} + fi + done + + for exclude in "${EXCLIST[@]}" + do + if [[ -n "$exclude" ]]; then + TMP=" --exclude '$exclude'" + EXCLUDE=${EXCLUDE}${TMP} + fi + done + + # Include/Exclude globbing filelist + if [ "${INCEXCFILE}" != '' ]; then + if [ ${LT07} -eq 1 ]; then + TMP=" --include-globbing-filelist '${INCEXCFILE}'" + else + TMP=" --include-filelist '${INCEXCFILE}'" + fi + INCLUDE=${INCLUDE}${TMP} + fi + + # INCLIST and globbing filelist is empty so every file needs to be saved + if [ ${#INCLIST[@]} -eq 0 ] && [ "${INCEXCFILE}" == '' ]; then + EXCLUDEROOT='' + else + EXCLUDEROOT="--exclude=**" + fi + + + # Restore IFS + IFS=$OLDIFS + } + + duplicity_cleanup() + { + echo "----------------[ Duplicity Cleanup ]----------------" + if [[ "${CLEAN_UP_TYPE}" != "none" && -n ${CLEAN_UP_TYPE} && -n ${CLEAN_UP_VARIABLE} ]]; then + { + eval "${ECHO}" "${DUPLICITY}" "${CLEAN_UP_TYPE}" "${CLEAN_UP_VARIABLE}" "${STATIC_OPTIONS}" --force \ + "${ENCRYPT}" \ + "${DEST}" + } || { + BACKUP_ERROR=1 + } + echo + fi + if [ -n "${REMOVE_INCREMENTALS_OLDER_THAN}" ] && [[ ${REMOVE_INCREMENTALS_OLDER_THAN} =~ ^[0-9]+$ ]]; then + { + eval "${ECHO}" "${DUPLICITY}" remove-all-inc-of-but-n-full "${REMOVE_INCREMENTALS_OLDER_THAN}" \ + "${STATIC_OPTIONS}" --force \ + "${ENCRYPT}" \ + "${DEST}" + } || { + BACKUP_ERROR=1 + } + echo + fi + } + + duplicity_backup() + { + { + eval "${ECHO}" "${DUPLICITY}" "${OPTION}" "${VERBOSITY}" "${STATIC_OPTIONS}" \ + "${ENCRYPT}" \ + "${EXCLUDE}" \ + "${INCLUDE}" \ + "${EXCLUDEROOT}" \ + "${ROOT}" "${DEST}" + } || { + BACKUP_ERROR=1 + } + } + + duplicity_cleanup_failed() + { + { + eval "${ECHO}" "${DUPLICITY}" "${OPTION}" "${VERBOSITY}" "${STATIC_OPTIONS}" \ + "${ENCRYPT}" \ + "${DEST}" + } || { + BACKUP_ERROR=1 + } + } + + setup_passphrase() + { + if [ -n "${GPG_ENC_KEY}" ] && [ -n "${GPG_SIGN_KEY}" ] && [ "${GPG_ENC_KEY}" != "${GPG_SIGN_KEY}" ]; then + echo -n "Please provide the passphrase for decryption (GPG key 0x${GPG_ENC_KEY}): " >&3 + builtin read -s -r ENCPASSPHRASE + echo -ne "\n" >&3 + PASSPHRASE=${ENCPASSPHRASE} + export PASSPHRASE + fi + } + + get_file_sizes() + { + get_source_file_size + get_remote_file_size + } + + backup_this_script() + { + if [ "$(echo "${0}" | cut -c 1)" = "." ]; then + SCRIPTFILE=$(echo "${0}" | cut -c 2-) + SCRIPTPATH=$(pwd)${SCRIPTFILE} + else + SCRIPTPATH=$(command -v "${0}") + fi + TMPDIR=duplicity-backup-$(date +%Y-%m-%d) + TMPFILENAME=${TMPDIR}.tar.gpg + README=${TMPDIR}/README + + echo "You are backing up: " >&3 + echo " 1. ${SCRIPTPATH}" >&3 + + if [ -n "${GPG_ENC_KEY}" ] && [ -n "${GPG_SIGN_KEY}" ]; then + if [ "${GPG_ENC_KEY}" = "${GPG_SIGN_KEY}" ]; then + echo " 2. GPG Secret encryption and sign key: ${GPG_ENC_KEY}" >&3 + else + echo " 2. GPG Secret encryption key: ${GPG_ENC_KEY} and GPG secret sign key: ${GPG_SIGN_KEY}" >&3 + fi + else + echo " 2. GPG Secret encryption and sign key: none (symmetric encryption)" >&3 + fi + + if [ -n "${CONFIG}" ] && [ -f "${CONFIG}" ]; + then + echo " 3. Config file: ${CONFIG}" >&3 + fi + + if [ -n "${INCEXCFILE}" ] && [ -f "${INCEXCFILE}" ]; + then + echo " 4. Include/Exclude globbing file: ${INCEXCFILE}" >&3 + fi + + echo "Backup tarball will be encrypted and saved to: $(pwd)/${TMPFILENAME}" >&3 + echo >&3 + echo ">> Are you sure you want to do that ('yes' to continue)?" >&3 + read -r ANSWER + if [ "${ANSWER}" != "yes" ]; then + echo "You said << ${ANSWER} >> so I am exiting now." >&3 + echo -e "--------------------- END ---------------------\n" >&5 + exit 1 + fi + + mkdir -p "${TMPDIR}" + cp "${SCRIPTPATH}" "${TMPDIR}"/ + + if [ -n "${CONFIG}" ] && [ -f "${CONFIG}" ]; + then + cp "${CONFIG}" "${TMPDIR}"/ + fi + + if [ -n "${INCEXCFILE}" ] && [ -f "${INCEXCFILE}" ]; + then + cp "${INCEXCFILE}" "${TMPDIR}"/ + fi + + if [ -n "${GPG_ENC_KEY}" ] && [ -n "${GPG_SIGN_KEY}" ]; then + GPG_TTY=$(tty) + export GPG_TTY + if [ "${GPG_ENC_KEY}" = "${GPG_SIGN_KEY}" ]; then + # shellcheck disable=SC2086 + gpg -a --export-secret-keys ${KEYRING} ${GPG_ENC_KEY} > "${TMPDIR}"/duplicity-backup-encryption-and-sign-secret.key.txt + else + # shellcheck disable=SC2086 + gpg -a --export-secret-keys ${KEYRING} ${GPG_ENC_KEY} > "${TMPDIR}"/duplicity-backup-encryption-secret.key.txt + # shellcheck disable=SC2086 + gpg -a --export-secret-keys ${KEYRING} ${GPG_SIGN_KEY} > "${TMPDIR}"/duplicity-backup-sign-secret.key.txt + fi + fi + + echo -e "${README_TXT}" > "${README}" + echo "Encrypting tarball, choose a password you'll remember..." >&3 + tar -cf - "${TMPDIR}" | gpg -aco "${TMPFILENAME}" + rm -Rf "${TMPDIR}" + echo -e "\nIMPORTANT!!" >&3 + echo ">> To restore these files, run the following (remember your password):" >&3 + echo "gpg -d ${TMPFILENAME} | tar -xf -" >&3 + echo -e "\nYou may want to write the above down and save it with the file." >&3 + } + + # ################################################## + # #### end of functions definition #### + # ################################################## + + check_variables + + echo -e "-------- START DUPLICITY-BACKUP SCRIPT for ${HOSTNAME} --------\n" >&5 + + echo -e "-------[ Program versions ]-------" + echo -e "duplicity-backup.sh ${DBSH_VERSION}" + echo -e "duplicity ${DUPLICITY_VERSION}" + echo -e "----------------------------------\n" + + get_lock + + INCLUDE= + EXCLUDE= + EXCLUDEROOT= + + case "${COMMAND}" in + "backup-script") + backup_this_script + exit 0 + ;; + + "full") + OPTION="full" + include_exclude + duplicity_backup + duplicity_cleanup + get_file_sizes + ;; + + "verify") + OLDROOT=${ROOT} + ROOT=${DEST} + DEST=${OLDROOT} + OPTION="verify" + + echo -e "-------[ Verifying Source & Destination ]-------\n" + include_exclude + setup_passphrase + echo -e "Attempting to verify now ...\n" >&3 + duplicity_backup + echo + + OLDROOT=${ROOT} + ROOT=${DEST} + DEST=${OLDROOT} + + get_file_sizes + + echo -e "Verify complete.\n" >&3 + ;; + + "cleanup") + OPTION="cleanup" + + if [ -z "${DRY_RUN}" ]; then + STATIC_OPTIONS="${STATIC_OPTIONS} --force" + fi + + echo -e "-------[ Cleaning up Destination ]-------\n" + setup_passphrase + duplicity_cleanup_failed + + echo -e "Cleanup complete." + ;; + + "restore") + ROOT=${DEST} + OPTION="restore" + if [ -n "${TIME}" ]; then + STATIC_OPTIONS="${STATIC_OPTIONS} --time ${TIME}" + fi + + if [[ ! "${RESTORE_DEST}" ]]; then + echo "Please provide a destination path (eg, /home/user/dir):" >&3 + read -r -e NEWDESTINATION + DEST=${NEWDESTINATION} + echo ">> You will restore from ${ROOT} to ${DEST}" >&3 + echo "Are you sure you want to do that ('yes' to continue)?" >&3 + read -r ANSWER + if [[ "${ANSWER}" != "yes" ]]; then + echo "You said << ${ANSWER} >> so I am exiting now." >&3 + echo -e "User aborted restore process ...\n" >&2 + echo -e "--------------------- END ---------------------\n" >&5 + exit 1 + fi + else + DEST=${RESTORE_DEST} + fi + + setup_passphrase + echo "Attempting to restore now ..." >&3 + duplicity_backup + ;; + + "restore-file"|"restore-dir") + ROOT=${DEST} + OPTION="restore" + + if [ -n "${TIME}" ]; then + STATIC_OPTIONS="${STATIC_OPTIONS} --time ${TIME}" + fi + + if [[ ! "${FILE_TO_RESTORE}" ]]; then + echo "Which file or directory do you want to restore?" >&3 + echo "(give the path relative to the root of the backup eg, mail/letter.txt):" >&3 + read -r -e FILE_TO_RESTORE + echo + fi + + if [[ "${RESTORE_DEST}" ]]; then + DEST=${RESTORE_DEST} + else + DEST=$(basename "${FILE_TO_RESTORE}") + fi + + echo -e "YOU ARE ABOUT TO..." >&3 + echo -e ">> RESTORE: ${FILE_TO_RESTORE}" >&3 + echo -e ">> TO: ${DEST}" >&3 + echo -e "\nAre you sure you want to do that ('yes' to continue)?" >&3 + read -r ANSWER + if [ "${ANSWER}" != "yes" ]; then + echo "You said << ${ANSWER} >> so I am exiting now." >&3 + echo -e "User aborted restore process ...\n" >&2 + echo -e "--------------------- END ---------------------\n" >&5 + exit 1 + fi + + FILE_TO_RESTORE="'${FILE_TO_RESTORE}'" + DEST="'${DEST}'" + + setup_passphrase + echo "Restoring now ..." >&3 + #use INCLUDE variable without creating another one + INCLUDE="--file-to-restore ${FILE_TO_RESTORE}" + duplicity_backup + ;; + + "list-current-files") + OPTION="list-current-files" + + if [ -n "${TIME}" ]; then + STATIC_OPTIONS="${STATIC_OPTIONS} --time ${TIME}" + fi + + eval \ + "${DUPLICITY}" "${OPTION}" "${VERBOSITY}" "${STATIC_OPTIONS}" \ + ${ENCRYPT} \ + "${DEST}" + ;; + + "collection-status") + OPTION="collection-status" + + eval \ + "${DUPLICITY}" "${OPTION}" "${VERBOSITY}" "${STATIC_OPTIONS}" \ + ${ENCRYPT} \ + "${DEST}" + ;; + + "backup") + include_exclude + duplicity_backup + duplicity_cleanup + get_file_sizes + ;; + + *) + echo -e "[Only show $(basename "$0") usage options]\n" + usage + ;; + esac + + echo -e "--------- END DUPLICITY-BACKUP SCRIPT ---------\n" >&5 + + if [ "${USAGE}" ]; then + exit 0 + fi + + if [ "${BACKUP_ERROR}" ]; then + BACKUP_STATUS="ERROR" + else + BACKUP_STATUS="OK" + fi + + # send email + [[ ${BACKUP_ERROR} || ! "$EMAIL_FAILURE_ONLY" = "yes" ]] && email_logfile + + # send notification + [[ ${BACKUP_ERROR} || ! "$NOTIFICATION_FAILURE_ONLY" = "yes" ]] && send_notification + + # remove old logfiles + # stops them from piling up infinitely + [[ -n "${REMOVE_LOGS_OLDER_THAN}" ]] && find "${LOGDIR}" -type f -mtime +"${REMOVE_LOGS_OLDER_THAN}" -delete + + if [ "${ECHO}" ]; then + echo "TEST RUN ONLY: Check the logfile for command output." + fi + + unset AWS_ACCESS_KEY_ID + unset AWS_SECRET_ACCESS_KEY + unset GS_ACCESS_KEY_ID + unset GS_SECRET_ACCESS_KEY + unset SWIFT_USERNAME + unset SWIFT_PASSWORD + unset SWIFT_AUTHURL + unset SWIFT_AUTHVERSION + unset DPBX_ACCESS_TOKEN + unset PASSPHRASE + unset SIGN_PASSPHRASE + unset FTP_PASSWORD + + # restore stdout and stderr to their original values + # and close the other fd + exec 1>&6 2>&7 3>&- 4>&- 5>&- 6>&- 7>&- + + # vim: set tabstop=2 shiftwidth=2 sts=2 autoindent smartindent: + + dest: "/usr/bin/duplicity-backup.sh" + mode: '0755' \ No newline at end of file diff --git a/roles/docker-swarm-create/tasks/main.yml b/roles/docker-swarm-create/tasks/main.yml deleted file mode 100644 index 6b0f1758..00000000 --- a/roles/docker-swarm-create/tasks/main.yml +++ /dev/null @@ -1,31 +0,0 @@ ---- -- name: "Check if host enrolled as manager" - become: yes - shell: "docker node ls" # Will return an non-zero error code if the swarm does not exist - register: swarm_ls - changed_when: "swarm_ls.rc != 0" - ignore_errors: true - -# Skipped if swarm exists -- name: "Ensure swarm initialized" - become: yes - shell: "docker swarm init --advertise-addr={{ ansible_host }}:2377" - when: swarm_ls.rc != 0 # Don't create the swarm if the previous docker node ls returned zero - -- name: "Ensure known manager token" - become: yes - shell: "docker swarm join-token --quiet manager" - register: swarm_manager_token_result - -- name: "Ensure known manager token fact" - set_fact: - swarm_manager_token: "{{ swarm_manager_token_result.stdout }}" - -- name: "Ensure known worker token" - become: yes - shell: "docker swarm join-token --quiet worker" - register: swarm_worker_token_result - -- name: "Ensure known worker token fact" - set_fact: - swarm_worker_token: "{{ swarm_worker_token_result.stdout }}" \ No newline at end of file diff --git a/roles/docker-swarm-enroll-manager/tasks/main.yml b/roles/docker-swarm-enroll-manager/tasks/main.yml deleted file mode 100644 index 2be79eac..00000000 --- a/roles/docker-swarm-enroll-manager/tasks/main.yml +++ /dev/null @@ -1,14 +0,0 @@ ---- - -- name: "Check if host enrolled as manager" - become: yes - shell: "docker node ls" # Will return an non-zero error code if the swarm does not exist - register: swarm_ls - changed_when: "swarm_ls.rc != 0" - ignore_errors: true - -# Skipped if swarm exists -- name: "Ensure this host enrolled as manager" - become: yes - shell: "docker swarm join --token {{ hostvars[swarm_creator]['swarm_manager_token'] }} {{ hostvars[swarm_creator].ansible_host }}:2377" - when: swarm_ls.rc != 0 # Don't create the swarm if the previous docker node ls returned zero \ No newline at end of file diff --git a/roles/docker-swarm-enroll-worker/tasks/main.yml b/roles/docker-swarm-enroll-worker/tasks/main.yml deleted file mode 100644 index a8a2fbdc..00000000 --- a/roles/docker-swarm-enroll-worker/tasks/main.yml +++ /dev/null @@ -1,7 +0,0 @@ ---- - -# Skipped if swarm exists -- name: "Ensure this host enrolled as worker" - become: yes - shell: "docker swarm join --token {{ hostvars[swarm_creator]['swarm_worker_token'] }} {{ hostvars[swarm_creator].ansible_host }}:2377" - ignore_errors: true \ No newline at end of file diff --git a/packer/netsoc-ubuntu-server/roles/docker/files/daemon.json b/roles/docker/files/daemon.json similarity index 100% rename from packer/netsoc-ubuntu-server/roles/docker/files/daemon.json rename to roles/docker/files/daemon.json diff --git a/packer/netsoc-ubuntu-server/roles/docker/tasks/main.yml b/roles/docker/tasks/main.yml similarity index 89% rename from packer/netsoc-ubuntu-server/roles/docker/tasks/main.yml rename to roles/docker/tasks/main.yml index b169a9f3..8480ddd4 100644 --- a/packer/netsoc-ubuntu-server/roles/docker/tasks/main.yml +++ b/roles/docker/tasks/main.yml @@ -52,17 +52,16 @@ name: docker-compose state: latest +- name: Ensure Docker Py + become: yes + pip: + name: docker + state: latest + + - name: Reload Docker daemon become: yes systemd: state: restarted daemon_reload: no - name: docker - -- name: Adding netsoc user to Docker group - become: yes - user: - name: "netsoc" - shell: "/bin/bash" - groups: "docker" - append: "yes" \ No newline at end of file + name: docker \ No newline at end of file diff --git a/roles/fail2ban/README.md b/roles/fail2ban/README.md new file mode 100644 index 00000000..b3786f9a --- /dev/null +++ b/roles/fail2ban/README.md @@ -0,0 +1,4 @@ +fail2ban +======== + +Installs fail2ban from APT, and sets it enabled & running in systemd \ No newline at end of file diff --git a/roles/fail2ban/files/jail.local b/roles/fail2ban/files/jail.local new file mode 100644 index 00000000..c4bf39d6 --- /dev/null +++ b/roles/fail2ban/files/jail.local @@ -0,0 +1,4 @@ +[DEFAULT] +# eduroam +ignoreip = 143.239.0.0/16 +maxretry = 8 diff --git a/roles/fail2ban/tasks/main.yml b/roles/fail2ban/tasks/main.yml new file mode 100644 index 00000000..950de1ba --- /dev/null +++ b/roles/fail2ban/tasks/main.yml @@ -0,0 +1,21 @@ +--- +- name: "Ensure fail2ban installed" + become: yes + apt: + name: + - fail2ban + state: latest + update_cache: yes + +- name: "Ensure fail2ban config customizations" + become: yes + copy: + src: "files/jail.local" + dest: "/etc/fail2ban/jail.local" + +- name: "Ensure fail2ban service enabled & running" + become: yes + systemd: + name: fail2ban + enabled: true + state: started \ No newline at end of file diff --git a/roles/fluentd/tasks/main.yml b/roles/fluentd/tasks/main.yml new file mode 100644 index 00000000..e69de29b diff --git a/roles/freeipa-server-docker/defaults/main.yml b/roles/freeipa-server-docker/defaults/main.yml deleted file mode 100644 index 4105582d..00000000 --- a/roles/freeipa-server-docker/defaults/main.yml +++ /dev/null @@ -1 +0,0 @@ -ip: "0.0.0.0" \ No newline at end of file diff --git a/roles/freeipa-server-docker/files/ipa-rewrite.conf b/roles/freeipa-server-docker/files/ipa-rewrite.conf deleted file mode 100644 index 88cf3465..00000000 --- a/roles/freeipa-server-docker/files/ipa-rewrite.conf +++ /dev/null @@ -1,45 +0,0 @@ -# VERSION 6 - DO NOT REMOVE THIS LINE - -# ORIGINAL -# RewriteEngine on - -# # By default forward all requests to /ipa. If you don't want IPA -# # to be the default on your web server comment this line out. -# RewriteRule ^/$ https://ipa.vm.netsoc.co/ipa/ui [L,NC,R=301] - -# # Redirect to the fully-qualified hostname. Not redirecting to secure -# # port so configuration files can be retrieved without requiring SSL. -# RewriteCond %{HTTP_HOST} !^ipa.vm.netsoc.co$ [NC] -# RewriteRule ^/ipa/(.*) http://ipa.vm.netsoc.co/ipa/$1 [L,R=301] - -# # Redirect to the secure port if not displaying an error or retrieving -# # configuration. -# RewriteCond %{SERVER_PORT} !^443$ -# RewriteCond %{REQUEST_URI} !^/ipa/(errors|config|crl) -# RewriteCond %{REQUEST_URI} !^/ipa/[^\?]+(\.js|\.css|\.png|\.gif|\.ico|\.woff|\.svg|\.ttf|\.eot)$ -# RewriteRule ^/ipa/(.*) https://ipa.vm.netsoc.co/ipa/$1 [L,R=301,NC] - -# # Rewrite for plugin index, make it like it's a static file -# RewriteRule ^/ipa/ui/js/freeipa/plugins.js$ /ipa/wsgi/plugins.py [PT] - -# MODIFIED -RewriteEngine on - -# By default forward all requests to /ipa. If you don't want IPA -# to be the default on your web server comment this line out. -RewriteRule ^/$ /ipa/ui [L,NC,R=301] - -# Redirect to the fully-qualified hostname. Not redirecting to secure -# port so configuration files can be retrieved without requiring SSL. -#RewriteCond %{HTTP_HOST} !^ipa.vm.netsoc.co$ [NC] -#RewriteRule ^/ipa/(.*) http://ipa.vm.netsoc.co/ipa/$1 [L,R=301] - -# Redirect to the secure port if not displaying an error or retrieving -# configuration. -#RewriteCond %{SERVER_PORT} !^443$ -#RewriteCond %{REQUEST_URI} !^/ipa/(errors|config|crl) -#RewriteCond %{REQUEST_URI} !^/ipa/[^\?]+(\.js|\.css|\.png|\.gif|\.ico|\.woff|\.svg|\.ttf|\.eot)$ -#RewriteRule ^/ipa/(.*) https://ipa.vm.netsoc.co/ipa/$1 [L,R=301,NC] - -# Rewrite for plugin index, make it like it's a static file -RewriteRule ^/ipa/ui/js/freeipa/plugins.js$ /ipa/wsgi/plugins.py [PT] \ No newline at end of file diff --git a/roles/freeipa-server-docker/tasks/main.yml b/roles/freeipa-server-docker/tasks/main.yml deleted file mode 100644 index db7c9c2d..00000000 --- a/roles/freeipa-server-docker/tasks/main.yml +++ /dev/null @@ -1,115 +0,0 @@ ---- - -- name: Ensure freeipa/data dir - become: yes - file: - path: "{{ mount }}/data" - owner: root - group: root - # needs to 775 as this folder is accessed internally by a dirsrv user - # https://github.com/freeipa/freeipa-container/issues/281 - mode: 0777 - state: directory - recurse: yes - -- name: Ensure freeipa/mods dir - become: yes - file: - path: "{{ mount }}/mods" - owner: root - group: root - mode: 0777 - state: directory - recurse: yes - -- name: Ensure HTTP redirect disabler - become: yes - copy: - src: "files/ipa-rewrite.conf" - dest: "{{ mount }}/mods/ipa-rewrite.conf" - -- set_fact: - ip: "{{ interface_address | ipmath(0) }}" # removes subnet mask - -- name: Ensure FreeIPA server container - become: yes - docker_container: - name: freeipa_server - state: started - recreate: yes - image: freeipa/freeipa-server - command: > - --unattended - --realm={{ freeipa.realm }} - --domain={{ freeipa.domain }} - --ds-password={{ freeipa.ds_password }} - --admin-password={{ freeipa.admin_password }} - --setup-dns - --forwarder=1.1.1.1 - --forward-policy=only - --ssh-trust-dns - restart: yes - etc_hosts: - '{ "{{ freeipa.server }}": "{{ ip }}" }' - env: # environment: - IPA_SERVER_HOSTNAME: "{{ freeipa.server }}" - IPA_SERVER_IP: "{{ ip }}" - ports: - - "{{ ip }}:80:80" # http - - "{{ ip }}:443:443" # https - - "{{ ip }}:389:389" # ldap - - "{{ ip }}:636:636" # ldaps - - "{{ ip }}:88:88" # kerberos - - "{{ ip }}:464:464" # kpasswd - - "{{ ip }}:749:749" # kpasswd - - "{{ ip }}:123:123" # ntp - - "{{ ip }}:53:53/tcp" # dns - - "{{ ip }}:53:53/udp" - volumes: - - "/sys/fs/cgroup:/sys/fs/cgroup:ro" - - "/etc/machine-id:/etc/machine-id" - - "{{ mount }}/data/:/data:Z" - - "{{ mount }}/mods/ipa-rewrite.conf:/etc/httpd/conf.d/ipa-rewrite.conf:Z" - tmpfs: - - "/run" - - "/tmp" - sysctls: - # Fixes: - # DEBUG The ipa-server-install command failed, exception: - # RuntimeError: IPv6 stack is enabled in the kernel but there is no interface that has ::1 address assigned. - # Add ::1 address resolution to "lo" interface. You might need to enable IPv6 on the interface "lo" in sysctl.conf. - net.ipv6.conf.lo.disable_ipv6: 0 - -- name: "Wait for install to finish (8-12 minutes, check {{ mount }}/data/var/log/ipa-server-configure-first.log if time out)" - become: yes - wait_for: - path: "{{ mount }}/data/var/log/ipaserver-install.log" - search_regex: "The ipa-server-install command was successful" - timeout: 1200 # 20 minutes - -- name: Insert trusted network ACLs - blockinfile: - path: "{{ mount }}/data/etc/named.conf" - insertbefore: "BOF" - marker: "# Trusted Network For Recursive DNS Queries - {mark}" - block: | - acl "trusted_network" { - {{ interface_address | ipaddr('network') }}/{{ interface_address | ipaddr('prefix') }}; - }; - - -- name: Modify /data/etc/named to support queries from intralan - blockinfile: - path: "{{ mount }}/data/etc/named.conf" - insertafter: "options" - marker: "# Enable Trusted Network For Recursive DNS Queries - {mark}" - block: | - allow-recursion { trusted_network; }; - allow-query-cache { trusted_network; }; - -- name: Restart IPA - command: docker restart freeipa_server - -- name: "Wait" - pause: - seconds: 20 \ No newline at end of file diff --git a/roles/grafana/files/data/dashboards/container-logs.json b/roles/grafana/files/data/dashboards/container-logs.json new file mode 100644 index 00000000..49652272 --- /dev/null +++ b/roles/grafana/files/data/dashboards/container-logs.json @@ -0,0 +1,202 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": "-- Grafana --", + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": true, + "gnetId": null, + "graphTooltip": 0, + "id": 54, + "iteration": 1634949765684, + "links": [], + "panels": [ + { + "datasource": "Loki", + "gridPos": { + "h": 32, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 2, + "options": { + "dedupStrategy": "exact", + "enableLogDetails": true, + "showLabels": false, + "showTime": true, + "sortOrder": "Descending", + "wrapLogMessage": true + }, + "pluginVersion": "8.0.1", + "targets": [ + { + "expr": "{container_name=\"$containerName\"} |= \"$query\" |~ \"(?i)level=$level\" | container_name!=\"discord_bot_instance_1\" and container_name!=\"traefik_server_1\" and container_name!=\"whodis_instance_1\" and level!=\"\"", + "refId": "A" + }, + { + "expr": "{container_name=\"$containerName\"} |= \"$query\" | container_name!=\"discord_bot_instance_1\" and container_name!=\"traefik_server_1\" and container_name!=\"whodis_instance_1\"and level=\"\"", + "hide": false, + "refId": "D" + }, + { + "expr": "{container_name=\"$containerName\"} |= \"$query\" |~ \"(?i)\\\"level\\\":\\\"$level\" | json | line_format \"{{.level}}\\t location=\\\"{{._file}}:{{._line}}\\\"\\t command=\\\"{{.command}}\\\" user=\\\"{{.user}}\\\"\\t message=\\\"{{.message}}\\\"\" | command!=\"\" and (container_name=\"discord_bot_instance_1\" or container_name=\"whodis_instance_1\")", + "hide": false, + "refId": "B" + }, + { + "expr": "{container_name=\"$containerName\"} |= \"$query\" |~ \"(?i)\\\"level\\\":\\\"$level\" | json | line_format \"{{.level}}\\t location=\\\"{{._file}}:{{._line}}\\\"\\t message=\\\"{{.message}}\\\"\" | command=\"\" and (container_name=\"discord_bot_instance_1\" or container_name=\"whodis_instance_1\")", + "hide": false, + "refId": "C" + }, + { + "expr": "{container_name=\"$containerName\"} |= \"$query\" | json | line_format \"client_addr=\\\"{{.ClientAddr}}\\\"\\t method=\\\"{{.RequestMethod}}\\\"\\t url=\\\"{{.RequestHost}}{{.RequestPath}}\\\"\\t service=\\\"{{.ServiceName}}\\\"\\t return_status=\\\"{{.OriginStatus}}\\\"\" | level=\"info\" and container_name=\"traefik_server_1\"", + "hide": false, + "refId": "E" + }, + { + "expr": "{container_name=\"$containerName\"} |= \"$query\" | json | level=\"\" and (container_name=\"discord_bot_instance_1\" or container_name=\"whodis_instance_1\")", + "hide": false, + "refId": "F" + } + ], + "title": "Logs", + "transparent": true, + "type": "logs" + } + ], + "refresh": "1m", + "schemaVersion": 30, + "style": "dark", + "tags": [], + "templating": { + "list": [ + { + "allValue": null, + "current": { + "selected": true, + "text": "discord_bot_instance_1", + "value": "discord_bot_instance_1" + }, + "datasource": null, + "definition": "label_values(container_processes{instance=\"web.infra.netsoc.co\"}, name)", + "description": null, + "error": null, + "hide": 0, + "includeAll": false, + "label": "Container Name", + "multi": false, + "name": "containerName", + "options": [], + "query": { + "query": "label_values(container_processes{instance=\"web.infra.netsoc.co\"}, name)", + "refId": "StandardVariableQuery" + }, + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "sort": 0, + "type": "query" + }, + { + "current": { + "selected": false, + "text": "", + "value": "" + }, + "description": null, + "error": null, + "hide": 0, + "label": "Query", + "name": "query", + "options": [ + { + "selected": true, + "text": "", + "value": "" + } + ], + "query": "", + "skipUrlSync": false, + "type": "textbox" + }, + { + "allValue": null, + "current": { + "selected": false, + "text": [ + "" + ], + "value": [ + "" + ] + }, + "description": null, + "error": null, + "hide": 0, + "includeAll": false, + "label": "Log Level", + "multi": true, + "name": "level", + "options": [ + { + "selected": true, + "text": "TRACE", + "value": "TRACE" + }, + { + "selected": false, + "text": "DEBUG", + "value": "DEBUG" + }, + { + "selected": false, + "text": "INFO", + "value": "INFO" + }, + { + "selected": false, + "text": "WARN", + "value": "WARN" + }, + { + "selected": false, + "text": "ERROR", + "value": "ERROR" + }, + { + "selected": false, + "text": "FATAL", + "value": "FATAL" + }, + { + "selected": false, + "text": "PANIC", + "value": "PANIC" + } + ], + "query": "TRACE, DEBUG, INFO, WARN, ERROR, FATAL, PANIC", + "queryValue": "", + "skipUrlSync": false, + "type": "custom" + } + ] + }, + "time": { + "from": "now-24h", + "to": "now" + }, + "timepicker": {}, + "timezone": "", + "title": "Container Logs", + "uid": "B89jFmz7k", + "version": 15 +} \ No newline at end of file diff --git a/roles/grafana/files/data/dashboards/discord-bot.json b/roles/grafana/files/data/dashboards/discord-bot.json new file mode 100644 index 00000000..975a8da3 --- /dev/null +++ b/roles/grafana/files/data/dashboards/discord-bot.json @@ -0,0 +1,724 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": "-- Grafana --", + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": true, + "gnetId": null, + "graphTooltip": 0, + "id": null, + "links": [], + "panels": [ + { + "datasource": "Loki", + "fieldConfig": { + "defaults": { + "custom": { + "align": null, + "displayMode": "auto", + "filterable": false + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "container_id" + }, + "properties": [ + { + "id": "custom.width", + "value": 108 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "ts" + }, + "properties": [ + { + "id": "custom.width", + "value": 146 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "message" + }, + "properties": [ + { + "id": "custom.width", + "value": 245 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "level" + }, + "properties": [ + { + "id": "custom.width", + "value": 63 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "line" + }, + "properties": [ + { + "id": "custom.width", + "value": 76 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "body" + }, + "properties": [ + { + "id": "custom.width", + "value": 73 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "command" + }, + "properties": [ + { + "id": "custom.width", + "value": 83 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "guild_id" + }, + "properties": [ + { + "id": "custom.width", + "value": 29 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "author_id" + }, + "properties": [ + { + "id": "custom.width", + "value": 57 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "channel_id" + }, + "properties": [ + { + "id": "custom.width", + "value": 70 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "file" + }, + "properties": [ + { + "id": "custom.width", + "value": 36 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "error" + }, + "properties": [ + { + "id": "custom.width", + "value": 55 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "username" + }, + "properties": [ + { + "id": "custom.width", + "value": 39 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "uuid" + }, + "properties": [ + { + "id": "custom.width", + "value": 19 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "expected_code" + }, + "properties": [ + { + "id": "custom.width", + "value": 187 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "user" + }, + "properties": [ + { + "id": "custom.width", + "value": 80 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "received_code" + }, + "properties": [ + { + "id": "custom.width", + "value": 112 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "channel_name" + }, + "properties": [ + { + "id": "custom.width", + "value": 111 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "email" + }, + "properties": [ + { + "id": "custom.width", + "value": 261 + } + ] + } + ] + }, + "gridPos": { + "h": 14, + "w": 23, + "x": 0, + "y": 0 + }, + "id": 2, + "options": { + "showHeader": true, + "sortBy": [ + { + "desc": true, + "displayName": "ts" + } + ] + }, + "pluginVersion": "8.0.1", + "repeat": null, + "targets": [ + { + "expr": "{container_name=\"discord_bot_instance_1\"} | json", + "legendFormat": "command", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Discord Bot Commands", + "transformations": [ + { + "id": "labelsToFields", + "options": {} + }, + { + "id": "organize", + "options": { + "excludeByName": { + "_file": false, + "_function": true, + "_line": false, + "api_announcement_query_limit": true, + "api_event_query_limit": true, + "api_port": true, + "api_public_message_cutoff": true, + "arcGis_Country": true, + "arcGis_CountryCode": true, + "arcGis_Date": true, + "arcGis_NewConfirmed": true, + "arcGis_NewDeaths": true, + "arcGis_NewRecovered": true, + "arcGis_Slug": true, + "arcGis_TotalConfirmed": true, + "arcGis_TotalDeaths": true, + "arcGis_TotalRecovered": true, + "bot_prefix": true, + "bot_quote_default_message_weight": true, + "bot_version": true, + "container_id": true, + "container_name": true, + "corona_default": true, + "corona_webhook": true, + "discord_channels_private_events": true, + "discord_channels_public_announcements": true, + "discord_channels_public_general": true, + "discord_charlimit": true, + "discord_committee_channel": true, + "discord_committee_server": true, + "discord_public_channel": true, + "discord_public_corona": true, + "discord_public_general": true, + "discord_public_server": true, + "discord_public_welcome": true, + "discord_roles": true, + "discord_servers_committee": true, + "discord_servers_public": true, + "discord_token": true, + "error": false, + "facebook_app_secret": true, + "facebook_appid": true, + "facebook_page_access_token": true, + "facebook_pageid": true, + "filename": true, + "freeimage_key": true, + "guild_id": false, + "id": true, + "line": true, + "minecraft_host": true, + "mysql_password": true, + "mysql_url": true, + "mysql_username": true, + "netsoc_sites": true, + "prom_dbname": true, + "prom_port": true, + "schedule_enable": true, + "sendgrid_token": true, + "sql_host": true, + "sql_password": true, + "sql_port": true, + "sql_username": true, + "stream": true, + "time": true, + "ts": false, + "tsNs": true, + "twitter_access_key": true, + "twitter_access_secret": true, + "twitter_key": true, + "twitter_secret": true, + "user_id": true, + "username": true, + "uuid": true + }, + "indexByName": { + "_file": 62, + "_function": 8, + "_line": 63, + "api_announcement_query_limit": 40, + "api_event_query_limit": 20, + "api_port": 47, + "api_public_message_cutoff": 51, + "arcGis_Country": 72, + "arcGis_CountryCode": 73, + "arcGis_Date": 69, + "arcGis_NewConfirmed": 70, + "arcGis_NewDeaths": 67, + "arcGis_NewRecovered": 68, + "arcGis_Slug": 66, + "arcGis_TotalConfirmed": 64, + "arcGis_TotalDeaths": 71, + "arcGis_TotalRecovered": 65, + "author_id": 57, + "body": 54, + "bot_prefix": 14, + "bot_quote_default_message_weight": 26, + "bot_version": 48, + "channel_id": 59, + "channel_name": 56, + "command": 53, + "container_id": 5, + "container_name": 4, + "corona_default": 41, + "corona_webhook": 15, + "discord_channels_private_events": 27, + "discord_channels_public_announcements": 52, + "discord_channels_public_general": 35, + "discord_charlimit": 21, + "discord_committee_channel": 28, + "discord_committee_server": 49, + "discord_public_channel": 50, + "discord_public_corona": 36, + "discord_public_general": 22, + "discord_public_server": 16, + "discord_public_welcome": 11, + "discord_roles": 17, + "discord_servers_committee": 42, + "discord_servers_public": 37, + "discord_token": 38, + "email": 75, + "error": 60, + "expected_code": 79, + "facebook_app_secret": 12, + "facebook_appid": 24, + "facebook_page_access_token": 43, + "facebook_pageid": 23, + "filename": 6, + "freeimage_key": 25, + "guild_id": 58, + "id": 9, + "level": 1, + "line": 61, + "message": 2, + "minecraft_host": 18, + "mysql_password": 31, + "mysql_url": 29, + "mysql_username": 44, + "netsoc_sites": 19, + "prom_dbname": 32, + "prom_port": 33, + "received_code": 78, + "schedule_enable": 39, + "sendgrid_token": 45, + "stream": 3, + "time": 7, + "ts": 0, + "tsNs": 10, + "twitter_access_key": 13, + "twitter_access_secret": 30, + "twitter_key": 34, + "twitter_secret": 46, + "user": 55, + "user_id": 74, + "username": 76, + "uuid": 77 + }, + "renameByName": { + "_file": "file", + "_line": "line" + } + } + } + ], + "transparent": true, + "type": "table" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": null, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 14 + }, + "hiddenSeries": false, + "id": 4, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.1", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "members_joined", + "format": "time_series", + "instant": false, + "interval": "", + "intervalFactor": 1, + "legendFormat": "members_joined", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Members Joined", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": null, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 9, + "w": 11, + "x": 12, + "y": 14 + }, + "hiddenSeries": false, + "id": 6, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.1", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "message_count{channel=\"248421213628530688\",server=\"248421213628530688\"}", + "interval": "", + "legendFormat": "general", + "refId": "A" + }, + { + "expr": "message_count{channel=\"494539080885993472\",server=\"248421213628530688\"}", + "interval": "", + "legendFormat": "announcements", + "refId": "B" + }, + { + "expr": "message_count{channel=\"691756092379627621\",server=\"248421213628530688\"}", + "interval": "", + "legendFormat": "corona", + "refId": "C" + }, + { + "expr": "message_count{channel=\"248422864062119947\",server=\"248421213628530688\"}", + "interval": "", + "legendFormat": "tech-chat", + "refId": "D" + }, + { + "expr": "message_count{channel=\"763012234636034069\",server=\"248421213628530688\"}", + "interval": "", + "legendFormat": "programming", + "refId": "E" + }, + { + "expr": "message_count{channel=\"248421871199059971\",server=\"248421213628530688\"}", + "interval": "", + "legendFormat": "general-gaming", + "refId": "F" + }, + { + "expr": "message_count{channel=\"689518089536143362\",server=\"248421213628530688\"}", + "interval": "", + "legendFormat": "minecraft", + "refId": "G" + }, + { + "expr": "message_count{channel=\"684009440441008128\",server=\"248421213628530688\"}", + "interval": "", + "legendFormat": "politics", + "refId": "H" + }, + { + "expr": "message_count{channel=\"571834322596659208\",server=\"248421213628530688\"}", + "interval": "", + "legendFormat": "memes", + "refId": "I" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Text Channel Activity (From 26/1/2021)", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + } + ], + "schemaVersion": 30, + "style": "dark", + "tags": [], + "templating": { + "list": [] + }, + "time": { + "from": "now-30d", + "to": "now" + }, + "timepicker": {}, + "timezone": "", + "title": "Discord Bot", + "uid": "discord-bot", + "version": 2 +} diff --git a/roles/grafana/files/data/dashboards/home.json b/roles/grafana/files/data/dashboards/home.json new file mode 100644 index 00000000..ec8fc756 --- /dev/null +++ b/roles/grafana/files/data/dashboards/home.json @@ -0,0 +1,161 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": "-- Grafana --", + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": true, + "gnetId": null, + "graphTooltip": 0, + "id": null, + "links": [], + "panels": [ + { + "datasource": null, + "gridPos": { + "h": 3, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 1, + "type": "welcome" + }, + { + "datasource": "-- Grafana --", + "gridPos": { + "h": 5, + "w": 12, + "x": 0, + "y": 3 + }, + "id": 8, + "options": { + "folderId": null, + "maxItems": 10, + "query": "", + "showHeadings": true, + "showRecentlyViewed": false, + "showSearch": true, + "showStarred": false, + "tags": [ + "public" + ] + }, + "pluginVersion": "8.0.1", + "targets": [ + { + "queryType": "randomWalk", + "refId": "A" + } + ], + "title": "Public Panels", + "type": "dashlist" + }, + { + "datasource": null, + "gridPos": { + "h": 19, + "w": 12, + "x": 12, + "y": 3 + }, + "id": 6, + "options": { + "alertName": "", + "dashboardAlerts": false, + "dashboardTitle": "", + "folderId": null, + "maxItems": 10, + "showOptions": "current", + "sortOrder": 1, + "stateFilter": { + "alerting": false, + "execution_error": false, + "no_data": false, + "ok": false, + "paused": false, + "pending": false + }, + "tags": [] + }, + "pluginVersion": "8.0.1", + "title": "Alerts", + "type": "alertlist" + }, + { + "datasource": null, + "gridPos": { + "h": 14, + "w": 12, + "x": 0, + "y": 8 + }, + "id": 3, + "links": [], + "options": { + "folderId": 0, + "maxItems": 30, + "query": "", + "showHeadings": true, + "showRecentlyViewed": true, + "showSearch": false, + "showStarred": true, + "tags": [] + }, + "pluginVersion": "8.0.1", + "tags": [], + "title": "Dashboards", + "type": "dashlist" + } + ], + "schemaVersion": 30, + "style": "dark", + "tags": [], + "templating": { + "list": [] + }, + "time": { + "from": "now-6h", + "to": "now" + }, + "timepicker": { + "hidden": true, + "refresh_intervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ], + "time_options": [ + "5m", + "15m", + "1h", + "6h", + "12h", + "24h", + "2d", + "7d", + "30d" + ], + "type": "timepicker" + }, + "timezone": "browser", + "title": "Home", + "uid": "mzD8GEknz", + "version": 5 +} diff --git a/roles/grafana/files/data/dashboards/job-logs.json b/roles/grafana/files/data/dashboards/job-logs.json new file mode 100644 index 00000000..911a41d5 --- /dev/null +++ b/roles/grafana/files/data/dashboards/job-logs.json @@ -0,0 +1,81 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": "-- Grafana --", + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": true, + "gnetId": null, + "graphTooltip": 0, + "id": null, + "iteration": 1633807412238, + "links": [], + "panels": [ + { + "datasource": "Loki", + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 0 + }, + "id": 2, + "options": { + "dedupStrategy": "none", + "enableLogDetails": true, + "showLabels": false, + "showTime": false, + "sortOrder": "Descending", + "wrapLogMessage": false + }, + "title": "Logs", + "type": "logs" + } + ], + "schemaVersion": 30, + "style": "dark", + "tags": [], + "templating": { + "list": [ + { + "current": { + "selected": false, + "text": "", + "value": "" + }, + "description": null, + "error": null, + "hide": 0, + "label": "Query", + "name": "query", + "options": [ + { + "selected": true, + "text": "", + "value": "" + } + ], + "query": "", + "skipUrlSync": false, + "type": "textbox" + } + ] + }, + "time": { + "from": "now-6h", + "to": "now" + }, + "timepicker": {}, + "timezone": "", + "title": "Job Logs", + "uid": "hje1JEk7k", + "version": 2 +} diff --git a/roles/grafana/files/data/dashboards/minecraft-player-stats.json b/roles/grafana/files/data/dashboards/minecraft-player-stats.json new file mode 100644 index 00000000..13bdffd3 --- /dev/null +++ b/roles/grafana/files/data/dashboards/minecraft-player-stats.json @@ -0,0 +1,281 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": "-- Grafana --", + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": true, + "gnetId": null, + "graphTooltip": 0, + "id": null, + "iteration": 1633808368911, + "links": [], + "panels": [ + { + "datasource": null, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "m" + }, + "overrides": [] + }, + "gridPos": { + "h": 14, + "w": 12, + "x": 0, + "y": 0 + }, + "id": 2, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "text": {}, + "textMode": "auto" + }, + "pluginVersion": "8.0.1", + "targets": [ + { + "exemplar": true, + "expr": "sum_over_time(mc_player_list{name=\"$player\"}[1000d:1m])", + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "title": "Total Hours Played", + "transparent": true, + "type": "stat" + }, + { + "datasource": null, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "fillOpacity": 100, + "lineWidth": 0 + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "bool_on_off" + }, + "overrides": [] + }, + "gridPos": { + "h": 14, + "w": 12, + "x": 12, + "y": 0 + }, + "id": 4, + "options": { + "alignValue": "left", + "legend": { + "displayMode": "hidden", + "placement": "bottom" + }, + "mergeValues": true, + "rowHeight": 0.26, + "showValue": "auto", + "tooltip": { + "mode": "single" + } + }, + "repeat": null, + "targets": [ + { + "exemplar": true, + "expr": "mc_player_list{name=\"$player\"}", + "interval": "", + "legendFormat": "$player", + "refId": "A" + } + ], + "title": "Sessions", + "transparent": true, + "type": "state-timeline" + }, + { + "cacheTimeout": null, + "datasource": null, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 45, + "gradientMode": "opacity", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineStyle": { + "fill": "solid" + }, + "lineWidth": 1, + "pointSize": 1, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "m" + }, + "overrides": [] + }, + "gridPos": { + "h": 12, + "w": 24, + "x": 0, + "y": 14 + }, + "id": 6, + "links": [], + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "8.0.1", + "targets": [ + { + "exemplar": true, + "expr": "count_over_time(mc_player_list{name=\"$player\"}[1000d:1m])", + "interval": "", + "legendFormat": "Total Playtime for $player", + "refId": "A" + } + ], + "title": "Total Playtime over time", + "transparent": true, + "type": "timeseries" + } + ], + "schemaVersion": 30, + "style": "dark", + "tags": [ + "public" + ], + "templating": { + "list": [ + { + "allValue": null, + "current": { + "selected": false, + "text": "Feynnmann", + "value": "Feynnmann" + }, + "datasource": null, + "definition": "label_values(mc_player_list, name)", + "description": null, + "error": null, + "hide": 0, + "includeAll": false, + "label": "Player", + "multi": false, + "name": "player", + "options": [], + "query": { + "query": "label_values(mc_player_list, name)", + "refId": "StandardVariableQuery" + }, + "refresh": 2, + "regex": "", + "skipUrlSync": false, + "sort": 0, + "type": "query" + } + ] + }, + "time": { + "from": "now-2d", + "to": "now" + }, + "timepicker": {}, + "timezone": "", + "title": "Minecraft Player Stats", + "uid": "dFyzXavnz", + "version": 2 +} diff --git a/roles/grafana/files/data/dashboards/minecraft.json b/roles/grafana/files/data/dashboards/minecraft.json new file mode 100644 index 00000000..b6d91403 --- /dev/null +++ b/roles/grafana/files/data/dashboards/minecraft.json @@ -0,0 +1,625 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": "-- Grafana --", + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": true, + "gnetId": null, + "graphTooltip": 0, + "id": null, + "links": [], + "panels": [ + { + "datasource": null, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 17, + "gradientMode": "opacity", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineStyle": { + "fill": "solid" + }, + "lineWidth": 2, + "pointSize": 5, + "scaleDistribution": { + "log": 2, + "type": "log" + }, + "showPoints": "always", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "decimals": 0, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 0 + }, + "id": 4, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "count(mc_player_list) ", + "interval": "", + "legendFormat": "Players Online", + "refId": "A" + } + ], + "title": "Concurrent Players", + "type": "timeseries" + }, + { + "datasource": null, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "custom": { + "fillOpacity": 70, + "lineWidth": 0 + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "bool_on_off" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 0 + }, + "id": 6, + "options": { + "alignValue": "left", + "legend": { + "displayMode": "list", + "placement": "bottom" + }, + "mergeValues": true, + "rowHeight": 0.9, + "showValue": "auto", + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "8.0.1", + "targets": [ + { + "exemplar": true, + "expr": "mc_player_list", + "interval": "", + "legendFormat": "{{ name }}", + "refId": "A" + } + ], + "title": "Players Online Timeline", + "type": "state-timeline" + }, + { + "datasource": null, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "left", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "decbytes" + }, + "overrides": [] + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 8 + }, + "id": 2, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "sum(jvm_memory_bytes_max)", + "interval": "", + "legendFormat": "Max Memory", + "refId": "A" + }, + { + "exemplar": true, + "expr": "sum(jvm_memory_bytes_used)", + "hide": false, + "interval": "", + "legendFormat": "Memory used", + "refId": "B" + }, + { + "exemplar": true, + "expr": "jvm_memory_bytes_committed{area=\"heap\"}", + "hide": false, + "interval": "", + "legendFormat": "Committed Memory", + "refId": "C" + } + ], + "title": "JVM Memory Usage", + "type": "timeseries" + }, + { + "datasource": null, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 86, + "gradientMode": "opacity", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 2, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "percentunit" + }, + "overrides": [] + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 8 + }, + "id": 12, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "(pve_cpu_usage_ratio{id=\"lxc/3242451\"})", + "interval": "", + "intervalFactor": 4, + "legendFormat": "CPU usage", + "refId": "A" + } + ], + "title": "CPU Usage", + "type": "timeseries" + }, + { + "datasource": null, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 17 + }, + "id": 16, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "targets": [ + { + "exemplar": true, + "expr": "mc_world_chunks_loaded", + "format": "time_series", + "instant": false, + "interval": "", + "legendFormat": "{{name}}", + "refId": "A" + } + ], + "title": "Chunks Loaded", + "type": "timeseries" + }, + { + "datasource": null, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 17 + }, + "id": 14, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "text": {}, + "textMode": "auto" + }, + "pluginVersion": "8.0.1", + "targets": [ + { + "exemplar": true, + "expr": "pve_cpu_usage_limit{id=\"lxc/3242451\"}", + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "title": "vCore Count", + "type": "stat" + }, + { + "datasource": null, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 4, + "x": 8, + "y": 25 + }, + "id": 8, + "options": { + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showThresholdLabels": false, + "showThresholdMarkers": true, + "text": {} + }, + "pluginVersion": "8.0.1", + "targets": [ + { + "exemplar": true, + "expr": "count(mc_player_list) or vector(0)", + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "title": "Currently Online", + "type": "gauge" + }, + { + "datasource": null, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 4, + "x": 12, + "y": 25 + }, + "id": 10, + "options": { + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showThresholdLabels": false, + "showThresholdMarkers": true, + "text": {} + }, + "pluginVersion": "8.0.1", + "targets": [ + { + "exemplar": true, + "expr": "count(avg_over_time(mc_player_list[7d])) or vector(0)", + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "title": "Unique Players over last 7 days", + "type": "gauge" + } + ], + "refresh": "1m", + "schemaVersion": 30, + "style": "dark", + "tags": [ + "public" + ], + "templating": { + "list": [] + }, + "time": { + "from": "now-24h", + "to": "now" + }, + "timepicker": {}, + "timezone": "", + "title": "Minecraft", + "uid": "eIDN5BNnk", + "version": 4 +} diff --git a/roles/grafana/files/data/dashboards/netsoc-cloud-api.json b/roles/grafana/files/data/dashboards/netsoc-cloud-api.json new file mode 100644 index 00000000..c2d64eb9 --- /dev/null +++ b/roles/grafana/files/data/dashboards/netsoc-cloud-api.json @@ -0,0 +1,129 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": "-- Grafana --", + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": true, + "gnetId": null, + "graphTooltip": 0, + "id": null, + "links": [], + "panels": [ + { + "datasource": "Loki", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "custom": { + "align": "auto", + "displayMode": "auto", + "filterable": false + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "Time" + }, + "properties": [ + { + "id": "custom.width", + "value": 150 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Request" + }, + "properties": [ + { + "id": "custom.width", + "value": 820 + } + ] + } + ] + }, + "gridPos": { + "h": 12, + "w": 17, + "x": 0, + "y": 0 + }, + "id": 2, + "options": { + "frameIndex": 0, + "showHeader": true, + "sortBy": [] + }, + "pluginVersion": "8.0.1", + "targets": [ + { + "expr": "{container_name=\"netsoc_cloud_api_1\", stream=\"stdout\"}", + "refId": "A" + } + ], + "title": "Cloud API Logs", + "transformations": [ + { + "id": "organize", + "options": { + "excludeByName": { + "Time ns": true + }, + "indexByName": {}, + "renameByName": { + "Time": "", + "id": "Request ID", + "line {container_id=\"ab6e182d536c\", container_name=\"netsoc_cloud_api_1\", filename=\"/var/lib/docker/containers/ab6e182d536ce9ad410b300db1c0ba2a197afa70d6fdbb36a05c0359ad730a9e/ab6e182d536ce9ad410b300db1c0ba2a197afa70d6fdbb36a05c0359ad730a9e-json.log\", stream=\"stdout\"}": "Request" + } + } + } + ], + "type": "table" + } + ], + "schemaVersion": 30, + "style": "dark", + "tags": [], + "templating": { + "list": [] + }, + "time": { + "from": "now-7d", + "to": "now" + }, + "timepicker": {}, + "timezone": "", + "title": "Netsoc Cloud API", + "uid": "bv4qTYgnz", + "version": 2 +} diff --git a/roles/grafana/files/data/dashboards/netsoc-infra.json b/roles/grafana/files/data/dashboards/netsoc-infra.json new file mode 100644 index 00000000..23beb3ac --- /dev/null +++ b/roles/grafana/files/data/dashboards/netsoc-infra.json @@ -0,0 +1,162 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": "-- Grafana --", + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": true, + "gnetId": null, + "graphTooltip": 0, + "id": null, + "links": [], + "panels": [ + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": null, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 0 + }, + "hiddenSeries": false, + "id": 4, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.1", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "container_cpu_load_average_10s", + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Panel Title", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "datasource": "Loki", + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 8 + }, + "id": 2, + "options": { + "dedupStrategy": "none", + "enableLogDetails": true, + "showLabels": false, + "showTime": false, + "sortOrder": "Descending", + "wrapLogMessage": false + }, + "pluginVersion": "7.3.3", + "targets": [ + { + "expr": "{container_name=\"traefik_server_1\"}", + "legendFormat": "", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Traefik", + "transformations": [ + { + "id": "filterByRefId", + "options": {} + } + ], + "type": "logs" + } + ], + "schemaVersion": 30, + "style": "dark", + "tags": [], + "templating": { + "list": [] + }, + "time": { + "from": "now-6h", + "to": "now" + }, + "timepicker": {}, + "timezone": "", + "title": "Netsoc Infra", + "uid": "netsoc-infra", + "version": 2 +} diff --git a/roles/grafana/files/data/dashboards/node-exporter.json b/roles/grafana/files/data/dashboards/node-exporter.json new file mode 100644 index 00000000..9ab1e2d3 --- /dev/null +++ b/roles/grafana/files/data/dashboards/node-exporter.json @@ -0,0 +1,14357 @@ +{ + "annotations": { + "list": [ + { + "$$hashKey": "object:1058", + "builtIn": 1, + "datasource": "-- Grafana --", + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "description": "Get going fast with this Prometheus dashboard + free Grafana Cloud trial with Prometheus even faster. https://grafana.com/products/cloud", + "editable": true, + "gnetId": 1860, + "graphTooltip": 0, + "id": null, + "iteration": 1633807400300, + "links": [], + "panels": [ + { + "collapsed": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": {}, + "overrides": [] + }, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 261, + "panels": [], + "repeat": null, + "title": "Quick CPU / Mem / Disk", + "type": "row" + }, + { + "cacheTimeout": null, + "datasource": "Prometheus", + "description": "Busy state of all CPU cores together", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [ + { + "options": { + "match": "null", + "result": { + "text": "N/A" + } + }, + "type": "special" + } + ], + "max": 100, + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "rgba(50, 172, 45, 0.97)", + "value": null + }, + { + "color": "rgba(237, 129, 40, 0.89)", + "value": 85 + }, + { + "color": "rgba(245, 54, 54, 0.9)", + "value": 95 + } + ] + }, + "unit": "percent" + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 3, + "x": 0, + "y": 1 + }, + "id": 20, + "links": [], + "options": { + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showThresholdLabels": false, + "showThresholdMarkers": true, + "text": {} + }, + "pluginVersion": "8.0.1", + "targets": [ + { + "expr": "(((count(count(node_cpu_seconds_total{instance=\"$node\",job=\"$job\"}) by (cpu))) - avg(sum by (mode)(irate(node_cpu_seconds_total{mode='idle',instance=\"$node\",job=\"$job\"}[5m])))) * 100) / count(count(node_cpu_seconds_total{instance=\"$node\",job=\"$job\"}) by (cpu))", + "hide": false, + "intervalFactor": 1, + "legendFormat": "", + "refId": "A", + "step": 900 + } + ], + "title": "CPU Busy", + "type": "gauge" + }, + { + "cacheTimeout": null, + "datasource": "Prometheus", + "description": "Busy state of all CPU cores together (5 min average)", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [ + { + "options": { + "match": "null", + "result": { + "text": "N/A" + } + }, + "type": "special" + } + ], + "max": 100, + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "rgba(50, 172, 45, 0.97)", + "value": null + }, + { + "color": "rgba(237, 129, 40, 0.89)", + "value": 85 + }, + { + "color": "rgba(245, 54, 54, 0.9)", + "value": 95 + } + ] + }, + "unit": "percent" + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 3, + "x": 3, + "y": 1 + }, + "id": 155, + "links": [], + "options": { + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showThresholdLabels": false, + "showThresholdMarkers": true, + "text": {} + }, + "pluginVersion": "8.0.1", + "targets": [ + { + "expr": "avg(node_load5{instance=\"$node\",job=\"$job\"}) / count(count(node_cpu_seconds_total{instance=\"$node\",job=\"$job\"}) by (cpu)) * 100", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "refId": "A", + "step": 900 + } + ], + "title": "Sys Load (5m avg)", + "type": "gauge" + }, + { + "cacheTimeout": null, + "datasource": "Prometheus", + "description": "Busy state of all CPU cores together (15 min average)", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [ + { + "options": { + "match": "null", + "result": { + "text": "N/A" + } + }, + "type": "special" + } + ], + "max": 100, + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "rgba(50, 172, 45, 0.97)", + "value": null + }, + { + "color": "rgba(237, 129, 40, 0.89)", + "value": 85 + }, + { + "color": "rgba(245, 54, 54, 0.9)", + "value": 95 + } + ] + }, + "unit": "percent" + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 3, + "x": 6, + "y": 1 + }, + "id": 19, + "links": [], + "options": { + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showThresholdLabels": false, + "showThresholdMarkers": true, + "text": {} + }, + "pluginVersion": "8.0.1", + "targets": [ + { + "expr": "avg(node_load15{instance=\"$node\",job=\"$job\"}) / count(count(node_cpu_seconds_total{instance=\"$node\",job=\"$job\"}) by (cpu)) * 100", + "hide": false, + "intervalFactor": 1, + "refId": "A", + "step": 900 + } + ], + "title": "Sys Load (15m avg)", + "type": "gauge" + }, + { + "cacheTimeout": null, + "datasource": "Prometheus", + "description": "Non available RAM memory", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "decimals": 0, + "mappings": [], + "max": 100, + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "rgba(50, 172, 45, 0.97)", + "value": null + }, + { + "color": "rgba(237, 129, 40, 0.89)", + "value": 80 + }, + { + "color": "rgba(245, 54, 54, 0.9)", + "value": 90 + } + ] + }, + "unit": "percent" + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 3, + "x": 9, + "y": 1 + }, + "hideTimeOverride": false, + "id": 16, + "links": [], + "options": { + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showThresholdLabels": false, + "showThresholdMarkers": true, + "text": {} + }, + "pluginVersion": "8.0.1", + "targets": [ + { + "expr": "((node_memory_MemTotal_bytes{instance=\"$node\",job=\"$job\"} - node_memory_MemFree_bytes{instance=\"$node\",job=\"$job\"}) / (node_memory_MemTotal_bytes{instance=\"$node\",job=\"$job\"} )) * 100", + "format": "time_series", + "hide": true, + "intervalFactor": 1, + "refId": "A", + "step": 900 + }, + { + "expr": "100 - ((node_memory_MemAvailable_bytes{instance=\"$node\",job=\"$job\"} * 100) / node_memory_MemTotal_bytes{instance=\"$node\",job=\"$job\"})", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "refId": "B", + "step": 900 + } + ], + "title": "RAM Used", + "type": "gauge" + }, + { + "cacheTimeout": null, + "datasource": "Prometheus", + "description": "Used Swap", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [ + { + "options": { + "match": "null", + "result": { + "text": "N/A" + } + }, + "type": "special" + } + ], + "max": 100, + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "rgba(50, 172, 45, 0.97)", + "value": null + }, + { + "color": "rgba(237, 129, 40, 0.89)", + "value": 10 + }, + { + "color": "rgba(245, 54, 54, 0.9)", + "value": 25 + } + ] + }, + "unit": "percent" + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 3, + "x": 12, + "y": 1 + }, + "id": 21, + "links": [], + "options": { + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showThresholdLabels": false, + "showThresholdMarkers": true, + "text": {} + }, + "pluginVersion": "8.0.1", + "targets": [ + { + "expr": "((node_memory_SwapTotal_bytes{instance=\"$node\",job=\"$job\"} - node_memory_SwapFree_bytes{instance=\"$node\",job=\"$job\"}) / (node_memory_SwapTotal_bytes{instance=\"$node\",job=\"$job\"} )) * 100", + "intervalFactor": 1, + "refId": "A", + "step": 900 + } + ], + "title": "SWAP Used", + "type": "gauge" + }, + { + "cacheTimeout": null, + "datasource": "Prometheus", + "description": "Used Root FS", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [ + { + "options": { + "match": "null", + "result": { + "text": "N/A" + } + }, + "type": "special" + } + ], + "max": 100, + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "rgba(50, 172, 45, 0.97)", + "value": null + }, + { + "color": "rgba(237, 129, 40, 0.89)", + "value": 80 + }, + { + "color": "rgba(245, 54, 54, 0.9)", + "value": 90 + } + ] + }, + "unit": "percent" + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 3, + "x": 15, + "y": 1 + }, + "id": 154, + "links": [], + "options": { + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showThresholdLabels": false, + "showThresholdMarkers": true, + "text": {} + }, + "pluginVersion": "8.0.1", + "targets": [ + { + "expr": "100 - ((node_filesystem_avail_bytes{instance=\"$node\",job=\"$job\",mountpoint=\"/\",fstype!=\"rootfs\"} * 100) / node_filesystem_size_bytes{instance=\"$node\",job=\"$job\",mountpoint=\"/\",fstype!=\"rootfs\"})", + "format": "time_series", + "intervalFactor": 1, + "refId": "A", + "step": 900 + } + ], + "title": "Root FS Used", + "type": "gauge" + }, + { + "cacheTimeout": null, + "datasource": "Prometheus", + "description": "Total number of CPU cores", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "gridPos": { + "h": 2, + "w": 2, + "x": 18, + "y": 1 + }, + "id": 14, + "interval": null, + "links": [], + "maxDataPoints": 100, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "text": {}, + "textMode": "auto" + }, + "pluginVersion": "8.0.1", + "targets": [ + { + "expr": "count(count(node_cpu_seconds_total{instance=\"$node\",job=\"$job\"}) by (cpu))", + "interval": "", + "intervalFactor": 1, + "legendFormat": "", + "refId": "A", + "step": 900 + } + ], + "title": "CPU Cores", + "type": "stat" + }, + { + "cacheTimeout": null, + "datasource": "Prometheus", + "description": "System uptime", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "decimals": 1, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "s" + }, + "overrides": [] + }, + "gridPos": { + "h": 2, + "w": 4, + "x": 20, + "y": 1 + }, + "hideTimeOverride": true, + "id": 15, + "interval": null, + "links": [], + "maxDataPoints": 100, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "text": {}, + "textMode": "auto" + }, + "pluginVersion": "8.0.1", + "targets": [ + { + "expr": "node_time_seconds{instance=\"$node\",job=\"$job\"} - node_boot_time_seconds{instance=\"$node\",job=\"$job\"}", + "intervalFactor": 2, + "refId": "A", + "step": 1800 + } + ], + "title": "Uptime", + "type": "stat" + }, + { + "cacheTimeout": null, + "datasource": "Prometheus", + "description": "Total RootFS", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "decimals": 0, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "rgba(50, 172, 45, 0.97)", + "value": null + }, + { + "color": "rgba(237, 129, 40, 0.89)", + "value": 70 + }, + { + "color": "rgba(245, 54, 54, 0.9)", + "value": 90 + } + ] + }, + "unit": "bytes" + }, + "overrides": [] + }, + "gridPos": { + "h": 2, + "w": 2, + "x": 18, + "y": 3 + }, + "id": 23, + "interval": null, + "links": [], + "maxDataPoints": 100, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "text": {}, + "textMode": "auto" + }, + "pluginVersion": "8.0.1", + "targets": [ + { + "expr": "node_filesystem_size_bytes{instance=\"$node\",job=\"$job\",mountpoint=\"/\",fstype!=\"rootfs\"}", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "refId": "A", + "step": 900 + } + ], + "title": "RootFS Total", + "type": "stat" + }, + { + "cacheTimeout": null, + "datasource": "Prometheus", + "description": "Total RAM", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "decimals": 0, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "bytes" + }, + "overrides": [] + }, + "gridPos": { + "h": 2, + "w": 2, + "x": 20, + "y": 3 + }, + "id": 75, + "interval": null, + "links": [], + "maxDataPoints": 100, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "text": {}, + "textMode": "auto" + }, + "pluginVersion": "8.0.1", + "targets": [ + { + "expr": "node_memory_MemTotal_bytes{instance=\"$node\",job=\"$job\"}", + "intervalFactor": 1, + "refId": "A", + "step": 900 + } + ], + "title": "RAM Total", + "type": "stat" + }, + { + "cacheTimeout": null, + "datasource": "Prometheus", + "description": "Total SWAP", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "decimals": 0, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "bytes" + }, + "overrides": [] + }, + "gridPos": { + "h": 2, + "w": 2, + "x": 22, + "y": 3 + }, + "id": 18, + "interval": null, + "links": [], + "maxDataPoints": 100, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "text": {}, + "textMode": "auto" + }, + "pluginVersion": "8.0.1", + "targets": [ + { + "expr": "node_memory_SwapTotal_bytes{instance=\"$node\",job=\"$job\"}", + "intervalFactor": 1, + "refId": "A", + "step": 900 + } + ], + "title": "SWAP Total", + "type": "stat" + }, + { + "collapsed": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": {}, + "overrides": [] + }, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 5 + }, + "id": 263, + "panels": [], + "repeat": null, + "title": "Basic CPU / Mem / Net / Disk", + "type": "row" + }, + { + "aliasColors": { + "Busy": "#EAB839", + "Busy Iowait": "#890F02", + "Busy other": "#1F78C1", + "Idle": "#052B51", + "Idle - Waiting for something to happen": "#052B51", + "guest": "#9AC48A", + "idle": "#052B51", + "iowait": "#EAB839", + "irq": "#BF1B00", + "nice": "#C15C17", + "softirq": "#E24D42", + "steal": "#FCE2DE", + "system": "#508642", + "user": "#5195CE" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "decimals": 2, + "description": "Basic CPU info", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 4, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 6 + }, + "hiddenSeries": false, + "id": 77, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "sideWidth": 250, + "sort": null, + "sortDesc": null, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "maxPerRow": 6, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": true, + "pluginVersion": "8.0.1", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "Busy Iowait", + "color": "#890F02" + }, + { + "alias": "Idle", + "color": "#7EB26D" + }, + { + "alias": "Busy System", + "color": "#EAB839" + }, + { + "alias": "Busy User", + "color": "#0A437C" + }, + { + "alias": "Busy Other", + "color": "#6D1F62" + } + ], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sum by (instance)(irate(node_cpu_seconds_total{mode=\"system\",instance=\"$node\",job=\"$job\"}[5m])) * 100", + "format": "time_series", + "hide": false, + "intervalFactor": 2, + "legendFormat": "Busy System", + "refId": "A", + "step": 240 + }, + { + "expr": "sum by (instance)(irate(node_cpu_seconds_total{mode='user',instance=\"$node\",job=\"$job\"}[5m])) * 100", + "format": "time_series", + "hide": false, + "intervalFactor": 2, + "legendFormat": "Busy User", + "refId": "B", + "step": 240 + }, + { + "expr": "sum by (instance)(irate(node_cpu_seconds_total{mode='iowait',instance=\"$node\",job=\"$job\"}[5m])) * 100", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Busy Iowait", + "refId": "C", + "step": 240 + }, + { + "expr": "sum by (instance)(irate(node_cpu_seconds_total{mode=~\".*irq\",instance=\"$node\",job=\"$job\"}[5m])) * 100", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Busy IRQs", + "refId": "D", + "step": 240 + }, + { + "expr": "sum (irate(node_cpu_seconds_total{mode!='idle',mode!='user',mode!='system',mode!='iowait',mode!='irq',mode!='softirq',instance=\"$node\",job=\"$job\"}[5m])) * 100", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Busy Other", + "refId": "E", + "step": 240 + }, + { + "expr": "sum by (mode)(irate(node_cpu_seconds_total{mode='idle',instance=\"$node\",job=\"$job\"}[5m])) * 100", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Idle", + "refId": "F", + "step": 240 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "CPU Basic", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": "", + "logBase": 1, + "max": "100", + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { + "Apps": "#629E51", + "Buffers": "#614D93", + "Cache": "#6D1F62", + "Cached": "#511749", + "Committed": "#508642", + "Free": "#0A437C", + "Hardware Corrupted - Amount of RAM that the kernel identified as corrupted / not working": "#CFFAFF", + "Inactive": "#584477", + "PageTables": "#0A50A1", + "Page_Tables": "#0A50A1", + "RAM_Free": "#E0F9D7", + "SWAP Used": "#BF1B00", + "Slab": "#806EB7", + "Slab_Cache": "#E0752D", + "Swap": "#BF1B00", + "Swap Used": "#BF1B00", + "Swap_Cache": "#C15C17", + "Swap_Free": "#2F575E", + "Unused": "#EAB839" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "decimals": 2, + "description": "Basic memory usage", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 4, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 6 + }, + "hiddenSeries": false, + "id": 78, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "sideWidth": 350, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "maxPerRow": 6, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.1", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "RAM Total", + "color": "#E0F9D7", + "fill": 0, + "stack": false + }, + { + "alias": "RAM Cache + Buffer", + "color": "#052B51" + }, + { + "alias": "RAM Free", + "color": "#7EB26D" + }, + { + "alias": "Avaliable", + "color": "#DEDAF7", + "fill": 0, + "stack": false + } + ], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "node_memory_MemTotal_bytes{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "hide": false, + "intervalFactor": 2, + "legendFormat": "RAM Total", + "refId": "A", + "step": 240 + }, + { + "expr": "node_memory_MemTotal_bytes{instance=\"$node\",job=\"$job\"} - node_memory_MemFree_bytes{instance=\"$node\",job=\"$job\"} - (node_memory_Cached_bytes{instance=\"$node\",job=\"$job\"} + node_memory_Buffers_bytes{instance=\"$node\",job=\"$job\"})", + "format": "time_series", + "hide": false, + "intervalFactor": 2, + "legendFormat": "RAM Used", + "refId": "B", + "step": 240 + }, + { + "expr": "node_memory_Cached_bytes{instance=\"$node\",job=\"$job\"} + node_memory_Buffers_bytes{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "RAM Cache + Buffer", + "refId": "C", + "step": 240 + }, + { + "expr": "node_memory_MemFree_bytes{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "RAM Free", + "refId": "D", + "step": 240 + }, + { + "expr": "(node_memory_SwapTotal_bytes{instance=\"$node\",job=\"$job\"} - node_memory_SwapFree_bytes{instance=\"$node\",job=\"$job\"})", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "SWAP Used", + "refId": "E", + "step": 240 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Memory Basic", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "bytes", + "label": "", + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { + "Recv_bytes_eth2": "#7EB26D", + "Recv_bytes_lo": "#0A50A1", + "Recv_drop_eth2": "#6ED0E0", + "Recv_drop_lo": "#E0F9D7", + "Recv_errs_eth2": "#BF1B00", + "Recv_errs_lo": "#CCA300", + "Trans_bytes_eth2": "#7EB26D", + "Trans_bytes_lo": "#0A50A1", + "Trans_drop_eth2": "#6ED0E0", + "Trans_drop_lo": "#E0F9D7", + "Trans_errs_eth2": "#BF1B00", + "Trans_errs_lo": "#CCA300", + "recv_bytes_lo": "#0A50A1", + "recv_drop_eth0": "#99440A", + "recv_drop_lo": "#967302", + "recv_errs_eth0": "#BF1B00", + "recv_errs_lo": "#890F02", + "trans_bytes_eth0": "#7EB26D", + "trans_bytes_lo": "#0A50A1", + "trans_drop_eth0": "#99440A", + "trans_drop_lo": "#967302", + "trans_errs_eth0": "#BF1B00", + "trans_errs_lo": "#890F02" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "description": "Basic network info per interface", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 4, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 13 + }, + "hiddenSeries": false, + "id": 74, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "hideEmpty": false, + "hideZero": false, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "sort": "current", + "sortDesc": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.1", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "/.*trans.*/", + "transform": "negative-Y" + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "irate(node_network_receive_bytes_total{instance=\"$node\",job=\"$job\"}[5m])*8", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "recv {{device}}", + "refId": "A", + "step": 240 + }, + { + "expr": "irate(node_network_transmit_bytes_total{instance=\"$node\",job=\"$job\"}[5m])*8", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "trans {{device}} ", + "refId": "B", + "step": 240 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Network Traffic Basic", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "bps", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "pps", + "label": "", + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "decimals": 3, + "description": "Disk space used of all filesystems mounted", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 4, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 13 + }, + "height": "", + "hiddenSeries": false, + "id": 152, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "sort": "current", + "sortDesc": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "maxPerRow": 6, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.1", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "100 - ((node_filesystem_avail_bytes{instance=\"$node\",job=\"$job\",device!~'rootfs'} * 100) / node_filesystem_size_bytes{instance=\"$node\",job=\"$job\",device!~'rootfs'})", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{mountpoint}}", + "refId": "A", + "step": 240 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Disk Space Used Basic", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "percent", + "label": null, + "logBase": 1, + "max": "100", + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "collapsed": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": {}, + "overrides": [] + }, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 20 + }, + "id": 265, + "panels": [], + "repeat": null, + "title": "CPU / Memory / Net / Disk", + "type": "row" + }, + { + "aliasColors": { + "Idle - Waiting for something to happen": "#052B51", + "guest": "#9AC48A", + "idle": "#052B51", + "iowait": "#EAB839", + "irq": "#BF1B00", + "nice": "#C15C17", + "softirq": "#E24D42", + "steal": "#FCE2DE", + "system": "#508642", + "user": "#5195CE" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "decimals": 2, + "description": "", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 4, + "fillGradient": 0, + "gridPos": { + "h": 12, + "w": 12, + "x": 0, + "y": 21 + }, + "hiddenSeries": false, + "id": 3, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "sideWidth": 250, + "sort": null, + "sortDesc": null, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "maxPerRow": 6, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": true, + "pluginVersion": "8.0.1", + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sum by (mode)(irate(node_cpu_seconds_total{mode=\"system\",instance=\"$node\",job=\"$job\"}[5m])) * 100", + "format": "time_series", + "interval": "10s", + "intervalFactor": 2, + "legendFormat": "System - Processes executing in kernel mode", + "refId": "A", + "step": 20 + }, + { + "expr": "sum by (mode)(irate(node_cpu_seconds_total{mode='user',instance=\"$node\",job=\"$job\"}[5m])) * 100", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "User - Normal processes executing in user mode", + "refId": "B", + "step": 240 + }, + { + "expr": "sum by (mode)(irate(node_cpu_seconds_total{mode='nice',instance=\"$node\",job=\"$job\"}[5m])) * 100", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Nice - Niced processes executing in user mode", + "refId": "C", + "step": 240 + }, + { + "expr": "sum by (mode)(irate(node_cpu_seconds_total{mode='idle',instance=\"$node\",job=\"$job\"}[5m])) * 100", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Idle - Waiting for something to happen", + "refId": "D", + "step": 240 + }, + { + "expr": "sum by (mode)(irate(node_cpu_seconds_total{mode='iowait',instance=\"$node\",job=\"$job\"}[5m])) * 100", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Iowait - Waiting for I/O to complete", + "refId": "E", + "step": 240 + }, + { + "expr": "sum by (mode)(irate(node_cpu_seconds_total{mode='irq',instance=\"$node\",job=\"$job\"}[5m])) * 100", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Irq - Servicing interrupts", + "refId": "F", + "step": 240 + }, + { + "expr": "sum by (mode)(irate(node_cpu_seconds_total{mode='softirq',instance=\"$node\",job=\"$job\"}[5m])) * 100", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Softirq - Servicing softirqs", + "refId": "G", + "step": 240 + }, + { + "expr": "sum by (mode)(irate(node_cpu_seconds_total{mode='steal',instance=\"$node\",job=\"$job\"}[5m])) * 100", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Steal - Time spent in other operating systems when running in a virtualized environment", + "refId": "H", + "step": 240 + }, + { + "expr": "sum by (mode)(irate(node_cpu_seconds_total{mode='guest',instance=\"$node\",job=\"$job\"}[5m])) * 100", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Guest - Time spent running a virtual CPU for a guest operating system", + "refId": "I", + "step": 240 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "CPU", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": "percentage", + "logBase": 1, + "max": "100", + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { + "Apps": "#629E51", + "Buffers": "#614D93", + "Cache": "#6D1F62", + "Cached": "#511749", + "Committed": "#508642", + "Free": "#0A437C", + "Hardware Corrupted - Amount of RAM that the kernel identified as corrupted / not working": "#CFFAFF", + "Inactive": "#584477", + "PageTables": "#0A50A1", + "Page_Tables": "#0A50A1", + "RAM_Free": "#E0F9D7", + "Slab": "#806EB7", + "Slab_Cache": "#E0752D", + "Swap": "#BF1B00", + "Swap - Swap memory usage": "#BF1B00", + "Swap_Cache": "#C15C17", + "Swap_Free": "#2F575E", + "Unused": "#EAB839", + "Unused - Free memory unassigned": "#052B51" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "decimals": 2, + "description": "", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 4, + "fillGradient": 0, + "gridPos": { + "h": 12, + "w": 12, + "x": 12, + "y": 21 + }, + "hiddenSeries": false, + "id": 24, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "sideWidth": 350, + "sort": null, + "sortDesc": null, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "maxPerRow": 6, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.1", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "/.*Hardware Corrupted - *./", + "stack": false + } + ], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "node_memory_MemTotal_bytes{instance=\"$node\",job=\"$job\"} - node_memory_MemFree_bytes{instance=\"$node\",job=\"$job\"} - node_memory_Buffers_bytes{instance=\"$node\",job=\"$job\"} - node_memory_Cached_bytes{instance=\"$node\",job=\"$job\"} - node_memory_Slab_bytes{instance=\"$node\",job=\"$job\"} - node_memory_PageTables_bytes{instance=\"$node\",job=\"$job\"} - node_memory_SwapCached_bytes{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "hide": false, + "intervalFactor": 2, + "legendFormat": "Apps - Memory used by user-space applications", + "refId": "A", + "step": 240 + }, + { + "expr": "node_memory_PageTables_bytes{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "hide": false, + "intervalFactor": 2, + "legendFormat": "PageTables - Memory used to map between virtual and physical memory addresses", + "refId": "B", + "step": 240 + }, + { + "expr": "node_memory_SwapCached_bytes{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "SwapCache - Memory that keeps track of pages that have been fetched from swap but not yet been modified", + "refId": "C", + "step": 240 + }, + { + "expr": "node_memory_Slab_bytes{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "hide": false, + "intervalFactor": 2, + "legendFormat": "Slab - Memory used by the kernel to cache data structures for its own use (caches like inode, dentry, etc)", + "refId": "D", + "step": 240 + }, + { + "expr": "node_memory_Cached_bytes{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "hide": false, + "intervalFactor": 2, + "legendFormat": "Cache - Parked file data (file content) cache", + "refId": "E", + "step": 240 + }, + { + "expr": "node_memory_Buffers_bytes{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "hide": false, + "intervalFactor": 2, + "legendFormat": "Buffers - Block device (e.g. harddisk) cache", + "refId": "F", + "step": 240 + }, + { + "expr": "node_memory_MemFree_bytes{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "hide": false, + "intervalFactor": 2, + "legendFormat": "Unused - Free memory unassigned", + "refId": "G", + "step": 240 + }, + { + "expr": "(node_memory_SwapTotal_bytes{instance=\"$node\",job=\"$job\"} - node_memory_SwapFree_bytes{instance=\"$node\",job=\"$job\"})", + "format": "time_series", + "hide": false, + "intervalFactor": 2, + "legendFormat": "Swap - Swap space used", + "refId": "H", + "step": 240 + }, + { + "expr": "node_memory_HardwareCorrupted_bytes{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "hide": false, + "intervalFactor": 2, + "legendFormat": "Hardware Corrupted - Amount of RAM that the kernel identified as corrupted / not working", + "refId": "I", + "step": 240 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Memory Stack", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "bytes", + "label": "bytes", + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { + "receive_packets_eth0": "#7EB26D", + "receive_packets_lo": "#E24D42", + "transmit_packets_eth0": "#7EB26D", + "transmit_packets_lo": "#E24D42" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 4, + "fillGradient": 0, + "gridPos": { + "h": 12, + "w": 12, + "x": 0, + "y": 33 + }, + "hiddenSeries": false, + "id": 84, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.1", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "$$hashKey": "object:5871", + "alias": "/.*Trans.*/", + "transform": "negative-Y" + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "irate(node_network_receive_bytes_total{instance=\"$node\",job=\"$job\"}[5m])*8", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{device}} - Receive", + "refId": "A", + "step": 240 + }, + { + "expr": "irate(node_network_transmit_bytes_total{instance=\"$node\",job=\"$job\"}[5m])*8", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{device}} - Transmit", + "refId": "B", + "step": 240 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Network Traffic", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:5884", + "format": "bps", + "label": "bits out (-) / in (+)", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "$$hashKey": "object:5885", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "decimals": 3, + "description": "", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 4, + "fillGradient": 0, + "gridPos": { + "h": 12, + "w": 12, + "x": 12, + "y": 33 + }, + "height": "", + "hiddenSeries": false, + "id": 156, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "sort": "current", + "sortDesc": false, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "maxPerRow": 6, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.1", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "node_filesystem_size_bytes{instance=\"$node\",job=\"$job\",device!~'rootfs'} - node_filesystem_avail_bytes{instance=\"$node\",job=\"$job\",device!~'rootfs'}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{mountpoint}}", + "refId": "A", + "step": 240 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Disk Space Used", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "bytes", + "label": "bytes", + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "description": "", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 12, + "w": 12, + "x": 0, + "y": 45 + }, + "hiddenSeries": false, + "id": 229, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "hideZero": true, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "maxPerRow": 6, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.1", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "/.*Read.*/", + "transform": "negative-Y" + }, + { + "alias": "/.*sda_.*/", + "color": "#7EB26D" + }, + { + "alias": "/.*sdb_.*/", + "color": "#EAB839" + }, + { + "alias": "/.*sdc_.*/", + "color": "#6ED0E0" + }, + { + "alias": "/.*sdd_.*/", + "color": "#EF843C" + }, + { + "alias": "/.*sde_.*/", + "color": "#E24D42" + }, + { + "alias": "/.*sda1.*/", + "color": "#584477" + }, + { + "alias": "/.*sda2_.*/", + "color": "#BA43A9" + }, + { + "alias": "/.*sda3_.*/", + "color": "#F4D598" + }, + { + "alias": "/.*sdb1.*/", + "color": "#0A50A1" + }, + { + "alias": "/.*sdb2.*/", + "color": "#BF1B00" + }, + { + "alias": "/.*sdb2.*/", + "color": "#BF1B00" + }, + { + "alias": "/.*sdb3.*/", + "color": "#E0752D" + }, + { + "alias": "/.*sdc1.*/", + "color": "#962D82" + }, + { + "alias": "/.*sdc2.*/", + "color": "#614D93" + }, + { + "alias": "/.*sdc3.*/", + "color": "#9AC48A" + }, + { + "alias": "/.*sdd1.*/", + "color": "#65C5DB" + }, + { + "alias": "/.*sdd2.*/", + "color": "#F9934E" + }, + { + "alias": "/.*sdd3.*/", + "color": "#EA6460" + }, + { + "alias": "/.*sde1.*/", + "color": "#E0F9D7" + }, + { + "alias": "/.*sdd2.*/", + "color": "#FCEACA" + }, + { + "alias": "/.*sde3.*/", + "color": "#F9E2D2" + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "irate(node_disk_reads_completed_total{instance=\"$node\",job=\"$job\",device=~\"$diskdevices\"}[5m])", + "intervalFactor": 4, + "legendFormat": "{{device}} - Reads completed", + "refId": "A", + "step": 480 + }, + { + "expr": "irate(node_disk_writes_completed_total{instance=\"$node\",job=\"$job\",device=~\"$diskdevices\"}[5m])", + "intervalFactor": 2, + "legendFormat": "{{device}} - Writes completed", + "refId": "B", + "step": 240 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Disk IOps", + "tooltip": { + "shared": false, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "iops", + "label": "IO read (-) / write (+)", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { + "io time": "#890F02" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "decimals": 3, + "description": "", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 4, + "fillGradient": 0, + "gridPos": { + "h": 12, + "w": 12, + "x": 12, + "y": 45 + }, + "hiddenSeries": false, + "id": 42, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "sort": null, + "sortDesc": null, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "maxPerRow": 6, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.1", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "/.*read*./", + "transform": "negative-Y" + }, + { + "alias": "/.*sda.*/", + "color": "#7EB26D" + }, + { + "alias": "/.*sdb.*/", + "color": "#EAB839" + }, + { + "alias": "/.*sdc.*/", + "color": "#6ED0E0" + }, + { + "alias": "/.*sdd.*/", + "color": "#EF843C" + }, + { + "alias": "/.*sde.*/", + "color": "#E24D42" + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "irate(node_disk_read_bytes_total{instance=\"$node\",job=\"$job\",device=~\"$diskdevices\"}[5m])", + "format": "time_series", + "hide": false, + "intervalFactor": 2, + "legendFormat": "{{device}} - Successfully read bytes", + "refId": "A", + "step": 240 + }, + { + "expr": "irate(node_disk_written_bytes_total{instance=\"$node\",job=\"$job\",device=~\"$diskdevices\"}[5m])", + "format": "time_series", + "hide": false, + "intervalFactor": 2, + "legendFormat": "{{device}} - Successfully written bytes", + "refId": "B", + "step": 240 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "I/O Usage Read / Write", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": false, + "values": [] + }, + "yaxes": [ + { + "format": "bytes", + "label": "bytes read (-) / write (+)", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "ms", + "label": "", + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { + "io time": "#890F02" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "decimals": 3, + "description": "", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 4, + "fillGradient": 0, + "gridPos": { + "h": 12, + "w": 12, + "x": 0, + "y": 57 + }, + "hiddenSeries": false, + "id": 127, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "sort": null, + "sortDesc": null, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "maxPerRow": 6, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.1", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "irate(node_disk_io_time_seconds_total{instance=\"$node\",job=\"$job\",device=~\"$diskdevices\"} [5m])", + "format": "time_series", + "hide": false, + "intervalFactor": 2, + "legendFormat": "{{device}} - Time spent doing I/Os", + "refId": "A", + "step": 240 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "I/O Usage Times", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": false, + "values": [] + }, + "yaxes": [ + { + "format": "s", + "label": "time", + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "s", + "label": "", + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "collapsed": true, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": {}, + "overrides": [] + }, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 69 + }, + "id": 266, + "panels": [ + { + "aliasColors": { + "Apps": "#629E51", + "Buffers": "#614D93", + "Cache": "#6D1F62", + "Cached": "#511749", + "Committed": "#508642", + "Free": "#0A437C", + "Hardware Corrupted - Amount of RAM that the kernel identified as corrupted / not working": "#CFFAFF", + "Inactive": "#584477", + "PageTables": "#0A50A1", + "Page_Tables": "#0A50A1", + "RAM_Free": "#E0F9D7", + "Slab": "#806EB7", + "Slab_Cache": "#E0752D", + "Swap": "#BF1B00", + "Swap_Cache": "#C15C17", + "Swap_Free": "#2F575E", + "Unused": "#EAB839" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "decimals": 2, + "fieldConfig": { + "defaults": { + "custom": {}, + "links": [] + }, + "overrides": [] + }, + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 0, + "y": 8 + }, + "hiddenSeries": false, + "id": 136, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "sideWidth": 350, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "maxPerRow": 2, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.3.6", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "node_memory_Inactive_bytes{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Inactive - Memory which has been less recently used. It is more eligible to be reclaimed for other purposes", + "refId": "A", + "step": 4 + }, + { + "expr": "node_memory_Active_bytes{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Active - Memory that has been used more recently and usually not reclaimed unless absolutely necessary", + "refId": "B", + "step": 4 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Memory Active / Inactive", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "bytes", + "label": "bytes", + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { + "Apps": "#629E51", + "Buffers": "#614D93", + "Cache": "#6D1F62", + "Cached": "#511749", + "Committed": "#508642", + "Free": "#0A437C", + "Hardware Corrupted - Amount of RAM that the kernel identified as corrupted / not working": "#CFFAFF", + "Inactive": "#584477", + "PageTables": "#0A50A1", + "Page_Tables": "#0A50A1", + "RAM_Free": "#E0F9D7", + "Slab": "#806EB7", + "Slab_Cache": "#E0752D", + "Swap": "#BF1B00", + "Swap_Cache": "#C15C17", + "Swap_Free": "#2F575E", + "Unused": "#EAB839" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "decimals": 2, + "fieldConfig": { + "defaults": { + "custom": {}, + "links": [] + }, + "overrides": [] + }, + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 12, + "y": 8 + }, + "hiddenSeries": false, + "id": 135, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "sideWidth": 350, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "maxPerRow": 6, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.3.6", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "/.*Committed_AS - *./" + }, + { + "alias": "/.*CommitLimit - *./", + "color": "#BF1B00", + "fill": 0 + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "node_memory_Committed_AS_bytes{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Committed_AS - Amount of memory presently allocated on the system", + "refId": "A", + "step": 4 + }, + { + "expr": "node_memory_CommitLimit_bytes{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "CommitLimit - Amount of memory currently available to be allocated on the system", + "refId": "B", + "step": 4 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Memory Commited", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "bytes", + "label": "bytes", + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { + "Apps": "#629E51", + "Buffers": "#614D93", + "Cache": "#6D1F62", + "Cached": "#511749", + "Committed": "#508642", + "Free": "#0A437C", + "Hardware Corrupted - Amount of RAM that the kernel identified as corrupted / not working": "#CFFAFF", + "Inactive": "#584477", + "PageTables": "#0A50A1", + "Page_Tables": "#0A50A1", + "RAM_Free": "#E0F9D7", + "Slab": "#806EB7", + "Slab_Cache": "#E0752D", + "Swap": "#BF1B00", + "Swap_Cache": "#C15C17", + "Swap_Free": "#2F575E", + "Unused": "#EAB839" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "decimals": 2, + "fieldConfig": { + "defaults": { + "custom": {}, + "links": [] + }, + "overrides": [] + }, + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 0, + "y": 18 + }, + "hiddenSeries": false, + "id": 191, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "sideWidth": 350, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "maxPerRow": 6, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.3.6", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "node_memory_Inactive_file_bytes{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "hide": false, + "intervalFactor": 2, + "legendFormat": "Inactive_file - File-backed memory on inactive LRU list", + "refId": "A", + "step": 4 + }, + { + "expr": "node_memory_Inactive_anon_bytes{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "hide": false, + "intervalFactor": 2, + "legendFormat": "Inactive_anon - Anonymous and swap cache on inactive LRU list, including tmpfs (shmem)", + "refId": "B", + "step": 4 + }, + { + "expr": "node_memory_Active_file_bytes{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "hide": false, + "intervalFactor": 2, + "legendFormat": "Active_file - File-backed memory on active LRU list", + "refId": "C", + "step": 4 + }, + { + "expr": "node_memory_Active_anon_bytes{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "hide": false, + "intervalFactor": 2, + "legendFormat": "Active_anon - Anonymous and swap cache on active least-recently-used (LRU) list, including tmpfs", + "refId": "D", + "step": 4 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Memory Active / Inactive Detail", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "bytes", + "label": "bytes", + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "bytes", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { + "Active": "#99440A", + "Buffers": "#58140C", + "Cache": "#6D1F62", + "Cached": "#511749", + "Committed": "#508642", + "Dirty": "#6ED0E0", + "Free": "#B7DBAB", + "Inactive": "#EA6460", + "Mapped": "#052B51", + "PageTables": "#0A50A1", + "Page_Tables": "#0A50A1", + "Slab_Cache": "#EAB839", + "Swap": "#BF1B00", + "Swap_Cache": "#C15C17", + "Total": "#511749", + "Total RAM": "#052B51", + "Total RAM + Swap": "#052B51", + "Total Swap": "#614D93", + "VmallocUsed": "#EA6460" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "decimals": 2, + "fieldConfig": { + "defaults": { + "custom": {}, + "links": [] + }, + "overrides": [] + }, + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 12, + "y": 18 + }, + "hiddenSeries": false, + "id": 130, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "sideWidth": null, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "maxPerRow": 2, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.3.6", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "node_memory_Writeback_bytes{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Writeback - Memory which is actively being written back to disk", + "refId": "A", + "step": 4 + }, + { + "expr": "node_memory_WritebackTmp_bytes{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "WritebackTmp - Memory used by FUSE for temporary writeback buffers", + "refId": "B", + "step": 4 + }, + { + "expr": "node_memory_Dirty_bytes{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Dirty - Memory which is waiting to get written back to the disk", + "refId": "C", + "step": 4 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Memory Writeback and Dirty", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "bytes", + "label": "bytes", + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { + "Apps": "#629E51", + "Buffers": "#614D93", + "Cache": "#6D1F62", + "Cached": "#511749", + "Committed": "#508642", + "Free": "#0A437C", + "Hardware Corrupted - Amount of RAM that the kernel identified as corrupted / not working": "#CFFAFF", + "Inactive": "#584477", + "PageTables": "#0A50A1", + "Page_Tables": "#0A50A1", + "RAM_Free": "#E0F9D7", + "Slab": "#806EB7", + "Slab_Cache": "#E0752D", + "Swap": "#BF1B00", + "Swap_Cache": "#C15C17", + "Swap_Free": "#2F575E", + "Unused": "#EAB839" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "decimals": 2, + "fieldConfig": { + "defaults": { + "custom": {}, + "links": [] + }, + "overrides": [] + }, + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 0, + "y": 28 + }, + "hiddenSeries": false, + "id": 138, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "sideWidth": 350, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "maxPerRow": 6, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.3.6", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "$$hashKey": "object:4131", + "alias": "ShmemHugePages - Memory used by shared memory (shmem) and tmpfs allocated with huge pages", + "fill": 0 + }, + { + "$$hashKey": "object:4138", + "alias": "ShmemHugePages - Memory used by shared memory (shmem) and tmpfs allocated with huge pages", + "fill": 0 + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "node_memory_Mapped_bytes{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Mapped - Used memory in mapped pages files which have been mmaped, such as libraries", + "refId": "A", + "step": 4 + }, + { + "expr": "node_memory_Shmem_bytes{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Shmem - Used shared memory (shared between several processes, thus including RAM disks)", + "refId": "B", + "step": 4 + }, + { + "expr": "node_memory_ShmemHugePages_bytes{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "ShmemHugePages - Memory used by shared memory (shmem) and tmpfs allocated with huge pages", + "refId": "C", + "step": 4 + }, + { + "expr": "node_memory_ShmemPmdMapped_bytes{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "ShmemPmdMapped - Ammount of shared (shmem/tmpfs) memory backed by huge pages", + "refId": "D", + "step": 4 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Memory Shared and Mapped", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:4106", + "format": "bytes", + "label": "bytes", + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "$$hashKey": "object:4107", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { + "Active": "#99440A", + "Buffers": "#58140C", + "Cache": "#6D1F62", + "Cached": "#511749", + "Committed": "#508642", + "Dirty": "#6ED0E0", + "Free": "#B7DBAB", + "Inactive": "#EA6460", + "Mapped": "#052B51", + "PageTables": "#0A50A1", + "Page_Tables": "#0A50A1", + "Slab_Cache": "#EAB839", + "Swap": "#BF1B00", + "Swap_Cache": "#C15C17", + "Total": "#511749", + "Total RAM": "#052B51", + "Total RAM + Swap": "#052B51", + "Total Swap": "#614D93", + "VmallocUsed": "#EA6460" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "decimals": 2, + "fieldConfig": { + "defaults": { + "custom": {}, + "links": [] + }, + "overrides": [] + }, + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 12, + "y": 28 + }, + "hiddenSeries": false, + "id": 131, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "sideWidth": null, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "maxPerRow": 2, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.3.6", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "node_memory_SUnreclaim_bytes{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "SUnreclaim - Part of Slab, that cannot be reclaimed on memory pressure", + "refId": "A", + "step": 4 + }, + { + "expr": "node_memory_SReclaimable_bytes{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "SReclaimable - Part of Slab, that might be reclaimed, such as caches", + "refId": "B", + "step": 4 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Memory Slab", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "bytes", + "label": "bytes", + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { + "Active": "#99440A", + "Buffers": "#58140C", + "Cache": "#6D1F62", + "Cached": "#511749", + "Committed": "#508642", + "Dirty": "#6ED0E0", + "Free": "#B7DBAB", + "Inactive": "#EA6460", + "Mapped": "#052B51", + "PageTables": "#0A50A1", + "Page_Tables": "#0A50A1", + "Slab_Cache": "#EAB839", + "Swap": "#BF1B00", + "Swap_Cache": "#C15C17", + "Total": "#511749", + "Total RAM": "#052B51", + "Total RAM + Swap": "#052B51", + "VmallocUsed": "#EA6460" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "decimals": 2, + "fieldConfig": { + "defaults": { + "custom": {}, + "links": [] + }, + "overrides": [] + }, + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 0, + "y": 38 + }, + "hiddenSeries": false, + "id": 70, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "sideWidth": null, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "maxPerRow": 6, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.3.6", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "node_memory_VmallocChunk_bytes{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "hide": false, + "intervalFactor": 2, + "legendFormat": "VmallocChunk - Largest contigious block of vmalloc area which is free", + "refId": "A", + "step": 4 + }, + { + "expr": "node_memory_VmallocTotal_bytes{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "hide": false, + "intervalFactor": 2, + "legendFormat": "VmallocTotal - Total size of vmalloc memory area", + "refId": "B", + "step": 4 + }, + { + "expr": "node_memory_VmallocUsed_bytes{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "hide": false, + "intervalFactor": 2, + "legendFormat": "VmallocUsed - Amount of vmalloc area which is used", + "refId": "C", + "step": 4 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Memory Vmalloc", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "bytes", + "label": "bytes", + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { + "Apps": "#629E51", + "Buffers": "#614D93", + "Cache": "#6D1F62", + "Cached": "#511749", + "Committed": "#508642", + "Free": "#0A437C", + "Hardware Corrupted - Amount of RAM that the kernel identified as corrupted / not working": "#CFFAFF", + "Inactive": "#584477", + "PageTables": "#0A50A1", + "Page_Tables": "#0A50A1", + "RAM_Free": "#E0F9D7", + "Slab": "#806EB7", + "Slab_Cache": "#E0752D", + "Swap": "#BF1B00", + "Swap_Cache": "#C15C17", + "Swap_Free": "#2F575E", + "Unused": "#EAB839" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "decimals": 2, + "fieldConfig": { + "defaults": { + "custom": {}, + "links": [] + }, + "overrides": [] + }, + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 12, + "y": 38 + }, + "hiddenSeries": false, + "id": 159, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "sideWidth": 350, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "maxPerRow": 6, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.3.6", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "node_memory_Bounce_bytes{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Bounce - Memory used for block device bounce buffers", + "refId": "A", + "step": 4 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Memory Bounce", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "bytes", + "label": "bytes", + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { + "Active": "#99440A", + "Buffers": "#58140C", + "Cache": "#6D1F62", + "Cached": "#511749", + "Committed": "#508642", + "Dirty": "#6ED0E0", + "Free": "#B7DBAB", + "Inactive": "#EA6460", + "Mapped": "#052B51", + "PageTables": "#0A50A1", + "Page_Tables": "#0A50A1", + "Slab_Cache": "#EAB839", + "Swap": "#BF1B00", + "Swap_Cache": "#C15C17", + "Total": "#511749", + "Total RAM": "#052B51", + "Total RAM + Swap": "#052B51", + "VmallocUsed": "#EA6460" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "decimals": 2, + "fieldConfig": { + "defaults": { + "custom": {}, + "links": [] + }, + "overrides": [] + }, + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 0, + "y": 48 + }, + "hiddenSeries": false, + "id": 129, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "sideWidth": null, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "maxPerRow": 6, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.3.6", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "/.*Inactive *./", + "transform": "negative-Y" + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "node_memory_AnonHugePages_bytes{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "AnonHugePages - Memory in anonymous huge pages", + "refId": "A", + "step": 4 + }, + { + "expr": "node_memory_AnonPages_bytes{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "AnonPages - Memory in user pages not backed by files", + "refId": "B", + "step": 4 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Memory Anonymous", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "bytes", + "label": "bytes", + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { + "Apps": "#629E51", + "Buffers": "#614D93", + "Cache": "#6D1F62", + "Cached": "#511749", + "Committed": "#508642", + "Free": "#0A437C", + "Hardware Corrupted - Amount of RAM that the kernel identified as corrupted / not working": "#CFFAFF", + "Inactive": "#584477", + "PageTables": "#0A50A1", + "Page_Tables": "#0A50A1", + "RAM_Free": "#E0F9D7", + "Slab": "#806EB7", + "Slab_Cache": "#E0752D", + "Swap": "#BF1B00", + "Swap_Cache": "#C15C17", + "Swap_Free": "#2F575E", + "Unused": "#EAB839" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "decimals": 2, + "fieldConfig": { + "defaults": { + "custom": {}, + "links": [] + }, + "overrides": [] + }, + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 12, + "y": 48 + }, + "hiddenSeries": false, + "id": 160, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "sideWidth": 350, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "maxPerRow": 2, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.3.6", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "node_memory_KernelStack_bytes{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "KernelStack - Kernel memory stack. This is not reclaimable", + "refId": "A", + "step": 4 + }, + { + "expr": "node_memory_Percpu_bytes{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "PerCPU - Per CPU memory allocated dynamically by loadable modules", + "refId": "B", + "step": 4 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Memory Kernel / CPU", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "bytes", + "label": "bytes", + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { + "Active": "#99440A", + "Buffers": "#58140C", + "Cache": "#6D1F62", + "Cached": "#511749", + "Committed": "#508642", + "Dirty": "#6ED0E0", + "Free": "#B7DBAB", + "Inactive": "#EA6460", + "Mapped": "#052B51", + "PageTables": "#0A50A1", + "Page_Tables": "#0A50A1", + "Slab_Cache": "#EAB839", + "Swap": "#BF1B00", + "Swap_Cache": "#C15C17", + "Total": "#511749", + "Total RAM": "#806EB7", + "Total RAM + Swap": "#806EB7", + "VmallocUsed": "#EA6460" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "decimals": 2, + "fieldConfig": { + "defaults": { + "custom": {}, + "links": [] + }, + "overrides": [] + }, + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 0, + "y": 58 + }, + "hiddenSeries": false, + "id": 140, + "legend": { + "alignAsTable": true, + "avg": false, + "current": true, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "sideWidth": null, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "maxPerRow": 6, + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.3.6", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "node_memory_HugePages_Free{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "HugePages_Free - Huge pages in the pool that are not yet allocated", + "refId": "A", + "step": 4 + }, + { + "expr": "node_memory_HugePages_Rsvd{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "HugePages_Rsvd - Huge pages for which a commitment to allocate from the pool has been made, but no allocation has yet been made", + "refId": "B", + "step": 4 + }, + { + "expr": "node_memory_HugePages_Surp{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "HugePages_Surp - Huge pages in the pool above the value in /proc/sys/vm/nr_hugepages", + "refId": "C", + "step": 4 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Memory HugePages Counter", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": "pages", + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": "", + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { + "Active": "#99440A", + "Buffers": "#58140C", + "Cache": "#6D1F62", + "Cached": "#511749", + "Committed": "#508642", + "Dirty": "#6ED0E0", + "Free": "#B7DBAB", + "Inactive": "#EA6460", + "Mapped": "#052B51", + "PageTables": "#0A50A1", + "Page_Tables": "#0A50A1", + "Slab_Cache": "#EAB839", + "Swap": "#BF1B00", + "Swap_Cache": "#C15C17", + "Total": "#511749", + "Total RAM": "#806EB7", + "Total RAM + Swap": "#806EB7", + "VmallocUsed": "#EA6460" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "decimals": 2, + "fieldConfig": { + "defaults": { + "custom": {}, + "links": [] + }, + "overrides": [] + }, + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 12, + "y": 58 + }, + "hiddenSeries": false, + "id": 71, + "legend": { + "alignAsTable": true, + "avg": false, + "current": true, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "sideWidth": null, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "maxPerRow": 2, + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.3.6", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "node_memory_HugePages_Total{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "HugePages - Total size of the pool of huge pages", + "refId": "A", + "step": 4 + }, + { + "expr": "node_memory_Hugepagesize_bytes{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Hugepagesize - Huge Page size", + "refId": "B", + "step": 4 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Memory HugePages Size", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "bytes", + "label": "bytes", + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": "", + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { + "Active": "#99440A", + "Buffers": "#58140C", + "Cache": "#6D1F62", + "Cached": "#511749", + "Committed": "#508642", + "Dirty": "#6ED0E0", + "Free": "#B7DBAB", + "Inactive": "#EA6460", + "Mapped": "#052B51", + "PageTables": "#0A50A1", + "Page_Tables": "#0A50A1", + "Slab_Cache": "#EAB839", + "Swap": "#BF1B00", + "Swap_Cache": "#C15C17", + "Total": "#511749", + "Total RAM": "#052B51", + "Total RAM + Swap": "#052B51", + "VmallocUsed": "#EA6460" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "decimals": 2, + "fieldConfig": { + "defaults": { + "custom": {}, + "links": [] + }, + "overrides": [] + }, + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 0, + "y": 68 + }, + "hiddenSeries": false, + "id": 128, + "legend": { + "alignAsTable": true, + "avg": true, + "current": false, + "hideEmpty": false, + "hideZero": false, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "sideWidth": null, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "maxPerRow": 6, + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.3.6", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "node_memory_DirectMap1G_bytes{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "DirectMap1G - Amount of pages mapped as this size", + "refId": "A", + "step": 4 + }, + { + "expr": "node_memory_DirectMap2M_bytes{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "DirectMap2M - Amount of pages mapped as this size", + "refId": "B", + "step": 4 + }, + { + "expr": "node_memory_DirectMap4k_bytes{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "DirectMap4K - Amount of pages mapped as this size", + "refId": "C", + "step": 4 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Memory DirectMap", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "bytes", + "label": "bytes", + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { + "Apps": "#629E51", + "Buffers": "#614D93", + "Cache": "#6D1F62", + "Cached": "#511749", + "Committed": "#508642", + "Free": "#0A437C", + "Hardware Corrupted - Amount of RAM that the kernel identified as corrupted / not working": "#CFFAFF", + "Inactive": "#584477", + "PageTables": "#0A50A1", + "Page_Tables": "#0A50A1", + "RAM_Free": "#E0F9D7", + "Slab": "#806EB7", + "Slab_Cache": "#E0752D", + "Swap": "#BF1B00", + "Swap_Cache": "#C15C17", + "Swap_Free": "#2F575E", + "Unused": "#EAB839" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "decimals": 2, + "fieldConfig": { + "defaults": { + "custom": {}, + "links": [] + }, + "overrides": [] + }, + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 12, + "y": 68 + }, + "hiddenSeries": false, + "id": 137, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "sideWidth": 350, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "maxPerRow": 6, + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.3.6", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "node_memory_Unevictable_bytes{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Unevictable - Amount of unevictable memory that can't be swapped out for a variety of reasons", + "refId": "A", + "step": 4 + }, + { + "expr": "node_memory_Mlocked_bytes{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "MLocked - Size of pages locked to memory using the mlock() system call", + "refId": "B", + "step": 4 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Memory Unevictable and MLocked", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "bytes", + "label": "bytes", + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { + "Active": "#99440A", + "Buffers": "#58140C", + "Cache": "#6D1F62", + "Cached": "#511749", + "Committed": "#508642", + "Dirty": "#6ED0E0", + "Free": "#B7DBAB", + "Inactive": "#EA6460", + "Mapped": "#052B51", + "PageTables": "#0A50A1", + "Page_Tables": "#0A50A1", + "Slab_Cache": "#EAB839", + "Swap": "#BF1B00", + "Swap_Cache": "#C15C17", + "Total": "#511749", + "Total RAM": "#052B51", + "Total RAM + Swap": "#052B51", + "Total Swap": "#614D93", + "VmallocUsed": "#EA6460" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "decimals": 2, + "fieldConfig": { + "defaults": { + "custom": {}, + "links": [] + }, + "overrides": [] + }, + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 0, + "y": 78 + }, + "hiddenSeries": false, + "id": 132, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "sideWidth": null, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "maxPerRow": 6, + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.3.6", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "node_memory_NFS_Unstable_bytes{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "NFS Unstable - Memory in NFS pages sent to the server, but not yet commited to the storage", + "refId": "A", + "step": 4 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Memory NFS", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "bytes", + "label": "bytes", + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + } + ], + "repeat": null, + "title": "Memory Meminfo", + "type": "row" + }, + { + "collapsed": true, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": {}, + "overrides": [] + }, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 70 + }, + "id": 267, + "panels": [ + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "custom": {}, + "links": [] + }, + "overrides": [] + }, + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 0, + "y": 9 + }, + "hiddenSeries": false, + "id": 176, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "maxPerRow": 6, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.3.6", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "/.*out/", + "transform": "negative-Y" + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "irate(node_vmstat_pgpgin{instance=\"$node\",job=\"$job\"}[5m])", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Pagesin - Page in operations", + "refId": "A", + "step": 4 + }, + { + "expr": "irate(node_vmstat_pgpgout{instance=\"$node\",job=\"$job\"}[5m])", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Pagesout - Page out operations", + "refId": "B", + "step": 4 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Memory Pages In / Out", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": "pages out (-) / in (+)", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "custom": {}, + "links": [] + }, + "overrides": [] + }, + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 12, + "y": 9 + }, + "hiddenSeries": false, + "id": 22, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "maxPerRow": 6, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.3.6", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "/.*out/", + "transform": "negative-Y" + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "irate(node_vmstat_pswpin{instance=\"$node\",job=\"$job\"}[5m])", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Pswpin - Pages swapped in", + "refId": "A", + "step": 4 + }, + { + "expr": "irate(node_vmstat_pswpout{instance=\"$node\",job=\"$job\"}[5m])", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Pswpout - Pages swapped out", + "refId": "B", + "step": 4 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Memory Pages Swap In / Out", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": "pages out (-) / in (+)", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { + "Apps": "#629E51", + "Buffers": "#614D93", + "Cache": "#6D1F62", + "Cached": "#511749", + "Committed": "#508642", + "Free": "#0A437C", + "Hardware Corrupted - Amount of RAM that the kernel identified as corrupted / not working": "#CFFAFF", + "Inactive": "#584477", + "PageTables": "#0A50A1", + "Page_Tables": "#0A50A1", + "RAM_Free": "#E0F9D7", + "Slab": "#806EB7", + "Slab_Cache": "#E0752D", + "Swap": "#BF1B00", + "Swap_Cache": "#C15C17", + "Swap_Free": "#2F575E", + "Unused": "#EAB839" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "decimals": 2, + "fieldConfig": { + "defaults": { + "custom": {}, + "links": [] + }, + "overrides": [] + }, + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 0, + "y": 19 + }, + "hiddenSeries": false, + "id": 175, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "sideWidth": 350, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "maxPerRow": 6, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.3.6", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "$$hashKey": "object:6118", + "alias": "Pgfault - Page major and minor fault operations", + "fill": 0, + "stack": false + } + ], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "irate(node_vmstat_pgfault{instance=\"$node\",job=\"$job\"}[5m])", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Pgfault - Page major and minor fault operations", + "refId": "A", + "step": 4 + }, + { + "expr": "irate(node_vmstat_pgmajfault{instance=\"$node\",job=\"$job\"}[5m])", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Pgmajfault - Major page fault operations", + "refId": "B", + "step": 4 + }, + { + "expr": "irate(node_vmstat_pgfault{instance=\"$node\",job=\"$job\"}[5m]) - irate(node_vmstat_pgmajfault{instance=\"$node\",job=\"$job\"}[5m])", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Pgminfault - Minor page fault operations", + "refId": "C", + "step": 4 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Memory Page Faults", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:6133", + "format": "short", + "label": "faults", + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "$$hashKey": "object:6134", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { + "Active": "#99440A", + "Buffers": "#58140C", + "Cache": "#6D1F62", + "Cached": "#511749", + "Committed": "#508642", + "Dirty": "#6ED0E0", + "Free": "#B7DBAB", + "Inactive": "#EA6460", + "Mapped": "#052B51", + "PageTables": "#0A50A1", + "Page_Tables": "#0A50A1", + "Slab_Cache": "#EAB839", + "Swap": "#BF1B00", + "Swap_Cache": "#C15C17", + "Total": "#511749", + "Total RAM": "#052B51", + "Total RAM + Swap": "#052B51", + "Total Swap": "#614D93", + "VmallocUsed": "#EA6460" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "decimals": 2, + "fieldConfig": { + "defaults": { + "custom": {}, + "links": [] + }, + "overrides": [] + }, + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 12, + "y": 19 + }, + "hiddenSeries": false, + "id": 307, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "sideWidth": null, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "maxPerRow": 6, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.3.6", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "irate(node_vmstat_oom_kill{instance=\"$node\",job=\"$job\"}[5m])", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "oom killer invocations ", + "refId": "A", + "step": 4 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "OOM Killer", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:5373", + "format": "short", + "label": "counter", + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "$$hashKey": "object:5374", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + } + ], + "repeat": null, + "title": "Memory Vmstat", + "type": "row" + }, + { + "collapsed": true, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": {}, + "overrides": [] + }, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 71 + }, + "id": 293, + "panels": [ + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "description": "", + "fieldConfig": { + "defaults": { + "custom": {}, + "links": [] + }, + "overrides": [] + }, + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 0, + "y": 44 + }, + "hiddenSeries": false, + "id": 260, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.3.6", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "/.*Variation*./", + "color": "#890F02" + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "node_timex_estimated_error_seconds{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "hide": false, + "interval": "", + "intervalFactor": 2, + "legendFormat": "Estimated error in seconds", + "refId": "A", + "step": 240 + }, + { + "expr": "node_timex_offset_seconds{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "hide": false, + "interval": "", + "intervalFactor": 2, + "legendFormat": "Time offset in between local system and reference clock", + "refId": "B", + "step": 240 + }, + { + "expr": "node_timex_maxerror_seconds{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "hide": false, + "interval": "", + "intervalFactor": 2, + "legendFormat": "Maximum error in seconds", + "refId": "C", + "step": 240 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Time Syncronized Drift", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "s", + "label": "seconds", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": "counter", + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "description": "", + "fieldConfig": { + "defaults": { + "custom": {}, + "links": [] + }, + "overrides": [] + }, + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 12, + "y": 44 + }, + "hiddenSeries": false, + "id": 291, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.3.6", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "node_timex_loop_time_constant{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "Phase-locked loop time adjust", + "refId": "A", + "step": 240 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Time PLL Adjust", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": "counter", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "description": "", + "fieldConfig": { + "defaults": { + "custom": {}, + "links": [] + }, + "overrides": [] + }, + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 0, + "y": 54 + }, + "hiddenSeries": false, + "id": 168, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.3.6", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "/.*Variation*./", + "color": "#890F02" + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "node_timex_sync_status{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "Is clock synchronized to a reliable server (1 = yes, 0 = no)", + "refId": "A", + "step": 240 + }, + { + "expr": "node_timex_frequency_adjustment_ratio{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "Local clock frequency adjustment", + "refId": "B", + "step": 240 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Time Syncronized Status", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": "counter", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "description": "", + "fieldConfig": { + "defaults": { + "custom": {}, + "links": [] + }, + "overrides": [] + }, + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 12, + "y": 54 + }, + "hiddenSeries": false, + "id": 294, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.3.6", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "node_timex_tick_seconds{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "Seconds between clock ticks", + "refId": "A", + "step": 240 + }, + { + "expr": "node_timex_tai_offset_seconds{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "International Atomic Time (TAI) offset", + "refId": "B", + "step": 240 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Time Misc", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "s", + "label": "seconds", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + } + ], + "title": "System Timesync", + "type": "row" + }, + { + "collapsed": true, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": {}, + "overrides": [] + }, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 72 + }, + "id": 312, + "panels": [ + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "custom": {}, + "links": [] + }, + "overrides": [] + }, + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 0, + "y": 11 + }, + "hiddenSeries": false, + "id": 62, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "maxPerRow": 6, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.3.6", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "node_procs_blocked{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Processes blocked waiting for I/O to complete", + "refId": "A", + "step": 240 + }, + { + "expr": "node_procs_running{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Processes in runnable state", + "refId": "B", + "step": 240 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Processes Status", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:6500", + "format": "short", + "label": "counter", + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "$$hashKey": "object:6501", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "custom": {}, + "links": [] + }, + "overrides": [] + }, + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 12, + "y": 11 + }, + "hiddenSeries": false, + "id": 315, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "maxPerRow": 6, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.3.6", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "node_processes_state{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "{{ state }}", + "refId": "A", + "step": 240 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Processes State", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:6500", + "format": "short", + "label": "counter", + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "$$hashKey": "object:6501", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "custom": {}, + "links": [] + }, + "overrides": [] + }, + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 0, + "y": 21 + }, + "hiddenSeries": false, + "id": 148, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "maxPerRow": 6, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.3.6", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "irate(node_forks_total{instance=\"$node\",job=\"$job\"}[5m])", + "format": "time_series", + "hide": false, + "intervalFactor": 2, + "legendFormat": "Processes forks second", + "refId": "A", + "step": 240 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Processes Forks", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:6640", + "format": "short", + "label": "forks / sec", + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "$$hashKey": "object:6641", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "custom": {}, + "links": [] + }, + "overrides": [] + }, + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 12, + "y": 21 + }, + "hiddenSeries": false, + "id": 149, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.3.6", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "/.*Max.*/", + "fill": 0 + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "irate(process_virtual_memory_bytes{instance=\"$node\",job=\"$job\"}[5m])", + "hide": false, + "interval": "", + "intervalFactor": 2, + "legendFormat": "Processes virtual memory size in bytes", + "refId": "A", + "step": 240 + }, + { + "expr": "process_resident_memory_max_bytes{instance=\"$node\",job=\"$job\"}", + "hide": false, + "interval": "", + "intervalFactor": 2, + "legendFormat": "Maximum amount of virtual memory available in bytes", + "refId": "B", + "step": 240 + }, + { + "expr": "irate(process_virtual_memory_bytes{instance=\"$node\",job=\"$job\"}[5m])", + "hide": false, + "interval": "", + "intervalFactor": 2, + "legendFormat": "Processes virtual memory size in bytes", + "refId": "C", + "step": 240 + }, + { + "expr": "irate(process_virtual_memory_max_bytes{instance=\"$node\",job=\"$job\"}[5m])", + "hide": false, + "interval": "", + "intervalFactor": 2, + "legendFormat": "Maximum amount of virtual memory available in bytes", + "refId": "D", + "step": 240 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Processes Memory", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "decbytes", + "label": "bytes", + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "custom": {}, + "links": [] + }, + "overrides": [] + }, + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 0, + "y": 31 + }, + "hiddenSeries": false, + "id": 313, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "maxPerRow": 6, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.3.6", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "$$hashKey": "object:709", + "alias": "PIDs limit", + "color": "#F2495C", + "fill": 0 + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "node_processes_pids{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "Number of PIDs", + "refId": "A", + "step": 240 + }, + { + "expr": "node_processes_max_processes{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "PIDs limit", + "refId": "B", + "step": 240 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "PIDs Number and Limit", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:6500", + "format": "short", + "label": "counter", + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "$$hashKey": "object:6501", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "custom": {}, + "links": [] + }, + "overrides": [] + }, + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 12, + "y": 31 + }, + "hiddenSeries": false, + "id": 305, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "maxPerRow": 6, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.3.6", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "$$hashKey": "object:4963", + "alias": "/.*waiting.*/", + "transform": "negative-Y" + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "irate(node_schedstat_running_seconds_total{instance=\"$node\",job=\"$job\"}[5m])", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "CPU {{ cpu }} - seconds spent running a process", + "refId": "A", + "step": 240 + }, + { + "expr": "irate(node_schedstat_waiting_seconds_total{instance=\"$node\",job=\"$job\"}[5m])", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "CPU {{ cpu }} - seconds spent by processing waiting for this CPU", + "refId": "B", + "step": 240 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Process schdeule stats Running / Waiting", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:4860", + "format": "s", + "label": "seconds", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "$$hashKey": "object:4861", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "custom": {}, + "links": [] + }, + "overrides": [] + }, + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 12, + "y": 41 + }, + "hiddenSeries": false, + "id": 314, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "maxPerRow": 6, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.3.6", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "$$hashKey": "object:709", + "alias": "Threads limit", + "color": "#F2495C", + "fill": 0 + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "node_processes_threads{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "Allocated threads", + "refId": "A", + "step": 240 + }, + { + "expr": "node_processes_max_threads{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "Threads limit", + "refId": "B", + "step": 240 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Threads Number and Limit", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:6500", + "format": "short", + "label": "counter", + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "$$hashKey": "object:6501", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + } + ], + "title": "System Processes", + "type": "row" + }, + { + "collapsed": true, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": {}, + "overrides": [] + }, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 73 + }, + "id": 269, + "panels": [ + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 0, + "y": 8 + }, + "hiddenSeries": false, + "id": 8, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "maxPerRow": 6, + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "irate(node_context_switches_total{instance=\"$node\",job=\"$job\"}[5m])", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Context switches", + "refId": "A", + "step": 240 + }, + { + "expr": "irate(node_intr_total{instance=\"$node\",job=\"$job\"}[5m])", + "format": "time_series", + "hide": false, + "intervalFactor": 2, + "legendFormat": "Interrupts", + "refId": "B", + "step": 240 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Context Switches / Interrupts", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": "counter", + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 12, + "y": 8 + }, + "hiddenSeries": false, + "id": 7, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "maxPerRow": 6, + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "node_load1{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "intervalFactor": 4, + "legendFormat": "Load 1m", + "refId": "A", + "step": 480 + }, + { + "expr": "node_load5{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "intervalFactor": 4, + "legendFormat": "Load 5m", + "refId": "B", + "step": 480 + }, + { + "expr": "node_load15{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "intervalFactor": 4, + "legendFormat": "Load 15m", + "refId": "C", + "step": 480 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "System Load", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:6261", + "format": "short", + "label": "counter", + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "$$hashKey": "object:6262", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 0, + "y": 18 + }, + "hiddenSeries": false, + "id": 259, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "/.*Critical*./", + "color": "#E24D42", + "fill": 0 + }, + { + "alias": "/.*Max*./", + "color": "#EF843C", + "fill": 0 + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "irate(node_interrupts_total{instance=\"$node\",job=\"$job\"}[5m])", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "{{ type }} - {{ info }}", + "refId": "A", + "step": 240 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Interrupts Detail", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": "counter", + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 12, + "y": 18 + }, + "hiddenSeries": false, + "id": 306, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "maxPerRow": 6, + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "irate(node_schedstat_timeslices_total{instance=\"$node\",job=\"$job\"}[5m])", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "CPU {{ cpu }}", + "refId": "A", + "step": 240 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Schedule timeslices executed by each cpu", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:4860", + "format": "short", + "label": "counter", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "$$hashKey": "object:4861", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 0, + "y": 28 + }, + "hiddenSeries": false, + "id": 151, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "maxPerRow": 6, + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "node_entropy_available_bits{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Entropy available to random number generators", + "refId": "A", + "step": 240 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Entropy", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:6568", + "format": "short", + "label": "counter", + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "$$hashKey": "object:6569", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 12, + "y": 28 + }, + "hiddenSeries": false, + "id": 308, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "maxPerRow": 6, + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "irate(process_cpu_seconds_total{instance=\"$node\",job=\"$job\"}[5m])", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "Time spent", + "refId": "A", + "step": 240 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "CPU time spent in user and system contexts", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:4860", + "format": "s", + "label": "seconds", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "$$hashKey": "object:4861", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 0, + "y": 38 + }, + "hiddenSeries": false, + "id": 64, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "$$hashKey": "object:6323", + "alias": "/.*Max*./", + "color": "#890F02", + "fill": 0 + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "process_max_fds{instance=\"$node\",job=\"$job\"}", + "interval": "", + "intervalFactor": 2, + "legendFormat": "Maximum open file descriptors", + "refId": "A", + "step": 240 + }, + { + "expr": "process_open_fds{instance=\"$node\",job=\"$job\"}", + "interval": "", + "intervalFactor": 2, + "legendFormat": "Open file descriptors", + "refId": "B", + "step": 240 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "File Descriptors", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:6338", + "format": "short", + "label": "counter", + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "$$hashKey": "object:6339", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + } + ], + "repeat": null, + "title": "System Misc", + "type": "row" + }, + { + "collapsed": true, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": {}, + "overrides": [] + }, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 74 + }, + "id": 304, + "panels": [ + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "custom": {}, + "links": [] + }, + "overrides": [] + }, + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 0, + "y": 67 + }, + "hiddenSeries": false, + "id": 158, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.3.6", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "$$hashKey": "object:6726", + "alias": "/.*Critical*./", + "color": "#E24D42", + "fill": 0 + }, + { + "$$hashKey": "object:6727", + "alias": "/.*Max*./", + "color": "#EF843C", + "fill": 0 + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "node_hwmon_temp_celsius{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "{{ chip }} {{ sensor }} temp", + "refId": "A", + "step": 240 + }, + { + "expr": "node_hwmon_temp_crit_alarm_celsius{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "hide": true, + "interval": "", + "intervalFactor": 2, + "legendFormat": "{{ chip }} {{ sensor }} Critical Alarm", + "refId": "B", + "step": 240 + }, + { + "expr": "node_hwmon_temp_crit_celsius{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "{{ chip }} {{ sensor }} Critical", + "refId": "C", + "step": 240 + }, + { + "expr": "node_hwmon_temp_crit_hyst_celsius{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "hide": true, + "interval": "", + "intervalFactor": 2, + "legendFormat": "{{ chip }} {{ sensor }} Critical Historical", + "refId": "D", + "step": 240 + }, + { + "expr": "node_hwmon_temp_max_celsius{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "hide": true, + "interval": "", + "intervalFactor": 2, + "legendFormat": "{{ chip }} {{ sensor }} Max", + "refId": "E", + "step": 240 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Hardware temperature monitor", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:6750", + "format": "celsius", + "label": "temperature", + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "$$hashKey": "object:6751", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "custom": {}, + "links": [] + }, + "overrides": [] + }, + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 12, + "y": 67 + }, + "hiddenSeries": false, + "id": 300, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.3.6", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "$$hashKey": "object:1655", + "alias": "/.*Max*./", + "color": "#EF843C", + "fill": 0 + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "node_cooling_device_cur_state{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "hide": false, + "interval": "", + "intervalFactor": 2, + "legendFormat": "Current {{ name }} in {{ type }}", + "refId": "A", + "step": 240 + }, + { + "expr": "node_cooling_device_max_state{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "Max {{ name }} in {{ type }}", + "refId": "B", + "step": 240 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Throttle cooling device", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:1678", + "format": "short", + "label": "counter", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "$$hashKey": "object:1679", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "custom": {}, + "links": [] + }, + "overrides": [] + }, + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 0, + "y": 77 + }, + "hiddenSeries": false, + "id": 302, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.3.6", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "node_power_supply_online{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "hide": false, + "interval": "", + "intervalFactor": 2, + "legendFormat": "{{ power_supply }} online", + "refId": "A", + "step": 240 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Power supply", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:1678", + "format": "short", + "label": "counter", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "$$hashKey": "object:1679", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + } + ], + "title": "Hardware Misc", + "type": "row" + }, + { + "collapsed": true, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": {}, + "overrides": [] + }, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 75 + }, + "id": 296, + "panels": [ + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "custom": {}, + "links": [] + }, + "overrides": [] + }, + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 0, + "y": 14 + }, + "hiddenSeries": false, + "id": 297, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.3.6", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "irate(node_systemd_socket_accepted_connections_total{instance=\"$node\",job=\"$job\"}[5m])", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "{{ name }} Connections", + "refId": "A", + "step": 240 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Systemd Sockets", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": "counter", + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "custom": {}, + "links": [] + }, + "overrides": [] + }, + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 12, + "y": 14 + }, + "hiddenSeries": false, + "id": 298, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.3.6", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "Failed", + "color": "#F2495C" + }, + { + "alias": "Inactive", + "color": "#FF9830" + }, + { + "alias": "Active", + "color": "#73BF69" + }, + { + "alias": "Deactivating", + "color": "#FFCB7D" + }, + { + "alias": "Activating", + "color": "#C8F2C2" + } + ], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "node_systemd_units{instance=\"$node\",job=\"$job\",state=\"activating\"}", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "Activating", + "refId": "A", + "step": 240 + }, + { + "expr": "node_systemd_units{instance=\"$node\",job=\"$job\",state=\"active\"}", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "Active", + "refId": "B", + "step": 240 + }, + { + "expr": "node_systemd_units{instance=\"$node\",job=\"$job\",state=\"deactivating\"}", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "Deactivating", + "refId": "C", + "step": 240 + }, + { + "expr": "node_systemd_units{instance=\"$node\",job=\"$job\",state=\"failed\"}", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "Failed", + "refId": "D", + "step": 240 + }, + { + "expr": "node_systemd_units{instance=\"$node\",job=\"$job\",state=\"inactive\"}", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "Inactive", + "refId": "E", + "step": 240 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Systemd Units State", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": "counter", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + } + ], + "title": "Systemd", + "type": "row" + }, + { + "collapsed": true, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": {}, + "overrides": [] + }, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 76 + }, + "id": 270, + "panels": [ + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "description": "", + "fieldConfig": { + "defaults": { + "custom": {}, + "links": [] + }, + "overrides": [] + }, + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 0, + "y": 15 + }, + "hiddenSeries": false, + "id": 9, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "hideZero": true, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "maxPerRow": 6, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.3.6", + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": null, + "seriesOverrides": [ + { + "$$hashKey": "object:2033", + "alias": "/.*Read.*/", + "transform": "negative-Y" + }, + { + "$$hashKey": "object:2034", + "alias": "/.*sda_.*/", + "color": "#7EB26D" + }, + { + "$$hashKey": "object:2035", + "alias": "/.*sdb_.*/", + "color": "#EAB839" + }, + { + "$$hashKey": "object:2036", + "alias": "/.*sdc_.*/", + "color": "#6ED0E0" + }, + { + "$$hashKey": "object:2037", + "alias": "/.*sdd_.*/", + "color": "#EF843C" + }, + { + "$$hashKey": "object:2038", + "alias": "/.*sde_.*/", + "color": "#E24D42" + }, + { + "$$hashKey": "object:2039", + "alias": "/.*sda1.*/", + "color": "#584477" + }, + { + "$$hashKey": "object:2040", + "alias": "/.*sda2_.*/", + "color": "#BA43A9" + }, + { + "$$hashKey": "object:2041", + "alias": "/.*sda3_.*/", + "color": "#F4D598" + }, + { + "$$hashKey": "object:2042", + "alias": "/.*sdb1.*/", + "color": "#0A50A1" + }, + { + "$$hashKey": "object:2043", + "alias": "/.*sdb2.*/", + "color": "#BF1B00" + }, + { + "$$hashKey": "object:2044", + "alias": "/.*sdb3.*/", + "color": "#E0752D" + }, + { + "$$hashKey": "object:2045", + "alias": "/.*sdc1.*/", + "color": "#962D82" + }, + { + "$$hashKey": "object:2046", + "alias": "/.*sdc2.*/", + "color": "#614D93" + }, + { + "$$hashKey": "object:2047", + "alias": "/.*sdc3.*/", + "color": "#9AC48A" + }, + { + "$$hashKey": "object:2048", + "alias": "/.*sdd1.*/", + "color": "#65C5DB" + }, + { + "$$hashKey": "object:2049", + "alias": "/.*sdd2.*/", + "color": "#F9934E" + }, + { + "$$hashKey": "object:2050", + "alias": "/.*sdd3.*/", + "color": "#EA6460" + }, + { + "$$hashKey": "object:2051", + "alias": "/.*sde1.*/", + "color": "#E0F9D7" + }, + { + "$$hashKey": "object:2052", + "alias": "/.*sdd2.*/", + "color": "#FCEACA" + }, + { + "$$hashKey": "object:2053", + "alias": "/.*sde3.*/", + "color": "#F9E2D2" + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "irate(node_disk_reads_completed_total{instance=\"$node\",job=\"$job\"}[5m])", + "intervalFactor": 4, + "legendFormat": "{{device}} - Reads completed", + "refId": "A", + "step": 8 + }, + { + "expr": "irate(node_disk_writes_completed_total{instance=\"$node\",job=\"$job\"}[5m])", + "intervalFactor": 2, + "legendFormat": "{{device}} - Writes completed", + "refId": "B", + "step": 4 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Disk IOps Completed", + "tooltip": { + "shared": false, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:2186", + "format": "iops", + "label": "IO read (-) / write (+)", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "$$hashKey": "object:2187", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "description": "", + "fieldConfig": { + "defaults": { + "custom": {}, + "links": [] + }, + "overrides": [] + }, + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 12, + "y": 15 + }, + "hiddenSeries": false, + "id": 33, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "hideZero": true, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "maxPerRow": 6, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.3.6", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "/.*Read.*/", + "transform": "negative-Y" + }, + { + "alias": "/.*sda_.*/", + "color": "#7EB26D" + }, + { + "alias": "/.*sdb_.*/", + "color": "#EAB839" + }, + { + "alias": "/.*sdc_.*/", + "color": "#6ED0E0" + }, + { + "alias": "/.*sdd_.*/", + "color": "#EF843C" + }, + { + "alias": "/.*sde_.*/", + "color": "#E24D42" + }, + { + "alias": "/.*sda1.*/", + "color": "#584477" + }, + { + "alias": "/.*sda2_.*/", + "color": "#BA43A9" + }, + { + "alias": "/.*sda3_.*/", + "color": "#F4D598" + }, + { + "alias": "/.*sdb1.*/", + "color": "#0A50A1" + }, + { + "alias": "/.*sdb2.*/", + "color": "#BF1B00" + }, + { + "alias": "/.*sdb3.*/", + "color": "#E0752D" + }, + { + "alias": "/.*sdc1.*/", + "color": "#962D82" + }, + { + "alias": "/.*sdc2.*/", + "color": "#614D93" + }, + { + "alias": "/.*sdc3.*/", + "color": "#9AC48A" + }, + { + "alias": "/.*sdd1.*/", + "color": "#65C5DB" + }, + { + "alias": "/.*sdd2.*/", + "color": "#F9934E" + }, + { + "alias": "/.*sdd3.*/", + "color": "#EA6460" + }, + { + "alias": "/.*sde1.*/", + "color": "#E0F9D7" + }, + { + "alias": "/.*sdd2.*/", + "color": "#FCEACA" + }, + { + "alias": "/.*sde3.*/", + "color": "#F9E2D2" + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "irate(node_disk_read_bytes_total{instance=\"$node\",job=\"$job\"}[5m])", + "format": "time_series", + "intervalFactor": 4, + "legendFormat": "{{device}} - Read bytes", + "refId": "A", + "step": 8 + }, + { + "expr": "irate(node_disk_written_bytes_total{instance=\"$node\",job=\"$job\"}[5m])", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{device}} - Written bytes", + "refId": "B", + "step": 4 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Disk R/W Data", + "tooltip": { + "shared": false, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "Bps", + "label": "bytes read (-) / write (+)", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "description": "", + "fieldConfig": { + "defaults": { + "custom": {}, + "links": [] + }, + "overrides": [] + }, + "fill": 3, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 0, + "y": 25 + }, + "hiddenSeries": false, + "id": 37, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "hideZero": true, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "sort": "current", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "maxPerRow": 6, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.3.6", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "/.*Read.*/", + "transform": "negative-Y" + }, + { + "alias": "/.*sda_.*/", + "color": "#7EB26D" + }, + { + "alias": "/.*sdb_.*/", + "color": "#EAB839" + }, + { + "alias": "/.*sdc_.*/", + "color": "#6ED0E0" + }, + { + "alias": "/.*sdd_.*/", + "color": "#EF843C" + }, + { + "alias": "/.*sde_.*/", + "color": "#E24D42" + }, + { + "alias": "/.*sda1.*/", + "color": "#584477" + }, + { + "alias": "/.*sda2_.*/", + "color": "#BA43A9" + }, + { + "alias": "/.*sda3_.*/", + "color": "#F4D598" + }, + { + "alias": "/.*sdb1.*/", + "color": "#0A50A1" + }, + { + "alias": "/.*sdb2.*/", + "color": "#BF1B00" + }, + { + "alias": "/.*sdb3.*/", + "color": "#E0752D" + }, + { + "alias": "/.*sdc1.*/", + "color": "#962D82" + }, + { + "alias": "/.*sdc2.*/", + "color": "#614D93" + }, + { + "alias": "/.*sdc3.*/", + "color": "#9AC48A" + }, + { + "alias": "/.*sdd1.*/", + "color": "#65C5DB" + }, + { + "alias": "/.*sdd2.*/", + "color": "#F9934E" + }, + { + "alias": "/.*sdd3.*/", + "color": "#EA6460" + }, + { + "alias": "/.*sde1.*/", + "color": "#E0F9D7" + }, + { + "alias": "/.*sdd2.*/", + "color": "#FCEACA" + }, + { + "alias": "/.*sde3.*/", + "color": "#F9E2D2" + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "irate(node_disk_read_time_seconds_total{instance=\"$node\",job=\"$job\"}[5m])", + "hide": false, + "intervalFactor": 4, + "legendFormat": "{{device}} - Read time", + "refId": "A", + "step": 8 + }, + { + "expr": "irate(node_disk_write_time_seconds_total{instance=\"$node\",job=\"$job\"}[5m])", + "hide": false, + "intervalFactor": 2, + "legendFormat": "{{device}} - Write time", + "refId": "B", + "step": 4 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Disk R/W Time", + "tooltip": { + "shared": false, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "s", + "label": "time. read (-) / write (+)", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "description": "", + "fieldConfig": { + "defaults": { + "custom": {}, + "links": [] + }, + "overrides": [] + }, + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 12, + "y": 25 + }, + "hiddenSeries": false, + "id": 35, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "hideZero": true, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "sort": "current", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "maxPerRow": 6, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.3.6", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "/.*sda_.*/", + "color": "#7EB26D" + }, + { + "alias": "/.*sdb_.*/", + "color": "#EAB839" + }, + { + "alias": "/.*sdc_.*/", + "color": "#6ED0E0" + }, + { + "alias": "/.*sdd_.*/", + "color": "#EF843C" + }, + { + "alias": "/.*sde_.*/", + "color": "#E24D42" + }, + { + "alias": "/.*sda1.*/", + "color": "#584477" + }, + { + "alias": "/.*sda2_.*/", + "color": "#BA43A9" + }, + { + "alias": "/.*sda3_.*/", + "color": "#F4D598" + }, + { + "alias": "/.*sdb1.*/", + "color": "#0A50A1" + }, + { + "alias": "/.*sdb2.*/", + "color": "#BF1B00" + }, + { + "alias": "/.*sdb3.*/", + "color": "#E0752D" + }, + { + "alias": "/.*sdc1.*/", + "color": "#962D82" + }, + { + "alias": "/.*sdc2.*/", + "color": "#614D93" + }, + { + "alias": "/.*sdc3.*/", + "color": "#9AC48A" + }, + { + "alias": "/.*sdd1.*/", + "color": "#65C5DB" + }, + { + "alias": "/.*sdd2.*/", + "color": "#F9934E" + }, + { + "alias": "/.*sdd3.*/", + "color": "#EA6460" + }, + { + "alias": "/.*sde1.*/", + "color": "#E0F9D7" + }, + { + "alias": "/.*sdd2.*/", + "color": "#FCEACA" + }, + { + "alias": "/.*sde3.*/", + "color": "#F9E2D2" + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "irate(node_disk_io_time_weighted_seconds_total{instance=\"$node\",job=\"$job\"}[5m])", + "intervalFactor": 4, + "legendFormat": "{{device}} - IO time weighted", + "refId": "A", + "step": 8 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Disk IOs Weighted", + "tooltip": { + "shared": false, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "s", + "label": "time", + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "description": "", + "fieldConfig": { + "defaults": { + "custom": {}, + "links": [] + }, + "overrides": [] + }, + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 0, + "y": 35 + }, + "hiddenSeries": false, + "id": 133, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "hideZero": true, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "sort": "current", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "maxPerRow": 6, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.3.6", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "/.*Read.*/", + "transform": "negative-Y" + }, + { + "alias": "/.*sda_.*/", + "color": "#7EB26D" + }, + { + "alias": "/.*sdb_.*/", + "color": "#EAB839" + }, + { + "alias": "/.*sdc_.*/", + "color": "#6ED0E0" + }, + { + "alias": "/.*sdd_.*/", + "color": "#EF843C" + }, + { + "alias": "/.*sde_.*/", + "color": "#E24D42" + }, + { + "alias": "/.*sda1.*/", + "color": "#584477" + }, + { + "alias": "/.*sda2_.*/", + "color": "#BA43A9" + }, + { + "alias": "/.*sda3_.*/", + "color": "#F4D598" + }, + { + "alias": "/.*sdb1.*/", + "color": "#0A50A1" + }, + { + "alias": "/.*sdb2.*/", + "color": "#BF1B00" + }, + { + "alias": "/.*sdb3.*/", + "color": "#E0752D" + }, + { + "alias": "/.*sdc1.*/", + "color": "#962D82" + }, + { + "alias": "/.*sdc2.*/", + "color": "#614D93" + }, + { + "alias": "/.*sdc3.*/", + "color": "#9AC48A" + }, + { + "alias": "/.*sdd1.*/", + "color": "#65C5DB" + }, + { + "alias": "/.*sdd2.*/", + "color": "#F9934E" + }, + { + "alias": "/.*sdd3.*/", + "color": "#EA6460" + }, + { + "alias": "/.*sde1.*/", + "color": "#E0F9D7" + }, + { + "alias": "/.*sdd2.*/", + "color": "#FCEACA" + }, + { + "alias": "/.*sde3.*/", + "color": "#F9E2D2" + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "irate(node_disk_reads_merged_total{instance=\"$node\",job=\"$job\"}[5m])", + "intervalFactor": 2, + "legendFormat": "{{device}} - Read merged", + "refId": "A", + "step": 4 + }, + { + "expr": "irate(node_disk_writes_merged_total{instance=\"$node\",job=\"$job\"}[5m])", + "intervalFactor": 2, + "legendFormat": "{{device}} - Write merged", + "refId": "B", + "step": 4 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Disk R/W Merged", + "tooltip": { + "shared": false, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "iops", + "label": "I/Os", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "description": "", + "fieldConfig": { + "defaults": { + "custom": {}, + "links": [] + }, + "overrides": [] + }, + "fill": 3, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 12, + "y": 35 + }, + "hiddenSeries": false, + "id": 36, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "hideZero": true, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "sort": "current", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "maxPerRow": 6, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.3.6", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "/.*sda_.*/", + "color": "#7EB26D" + }, + { + "alias": "/.*sdb_.*/", + "color": "#EAB839" + }, + { + "alias": "/.*sdc_.*/", + "color": "#6ED0E0" + }, + { + "alias": "/.*sdd_.*/", + "color": "#EF843C" + }, + { + "alias": "/.*sde_.*/", + "color": "#E24D42" + }, + { + "alias": "/.*sda1.*/", + "color": "#584477" + }, + { + "alias": "/.*sda2_.*/", + "color": "#BA43A9" + }, + { + "alias": "/.*sda3_.*/", + "color": "#F4D598" + }, + { + "alias": "/.*sdb1.*/", + "color": "#0A50A1" + }, + { + "alias": "/.*sdb2.*/", + "color": "#BF1B00" + }, + { + "alias": "/.*sdb3.*/", + "color": "#E0752D" + }, + { + "alias": "/.*sdc1.*/", + "color": "#962D82" + }, + { + "alias": "/.*sdc2.*/", + "color": "#614D93" + }, + { + "alias": "/.*sdc3.*/", + "color": "#9AC48A" + }, + { + "alias": "/.*sdd1.*/", + "color": "#65C5DB" + }, + { + "alias": "/.*sdd2.*/", + "color": "#F9934E" + }, + { + "alias": "/.*sdd3.*/", + "color": "#EA6460" + }, + { + "alias": "/.*sde1.*/", + "color": "#E0F9D7" + }, + { + "alias": "/.*sdd2.*/", + "color": "#FCEACA" + }, + { + "alias": "/.*sde3.*/", + "color": "#F9E2D2" + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "irate(node_disk_io_time_seconds_total{instance=\"$node\",job=\"$job\"}[5m])", + "intervalFactor": 4, + "legendFormat": "{{device}} - IO time", + "refId": "A", + "step": 8 + }, + { + "expr": "irate(node_disk_discard_time_seconds_total{instance=\"$node\",job=\"$job\"}[5m])", + "interval": "", + "intervalFactor": 4, + "legendFormat": "{{device}} - discard time", + "refId": "B", + "step": 8 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Time Spent Doing I/Os", + "tooltip": { + "shared": false, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "s", + "label": "time", + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "description": "", + "fieldConfig": { + "defaults": { + "custom": {}, + "links": [] + }, + "overrides": [] + }, + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 0, + "y": 45 + }, + "hiddenSeries": false, + "id": 34, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "hideZero": true, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "sort": "current", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "maxPerRow": 6, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.3.6", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "/.*sda_.*/", + "color": "#7EB26D" + }, + { + "alias": "/.*sdb_.*/", + "color": "#EAB839" + }, + { + "alias": "/.*sdc_.*/", + "color": "#6ED0E0" + }, + { + "alias": "/.*sdd_.*/", + "color": "#EF843C" + }, + { + "alias": "/.*sde_.*/", + "color": "#E24D42" + }, + { + "alias": "/.*sda1.*/", + "color": "#584477" + }, + { + "alias": "/.*sda2_.*/", + "color": "#BA43A9" + }, + { + "alias": "/.*sda3_.*/", + "color": "#F4D598" + }, + { + "alias": "/.*sdb1.*/", + "color": "#0A50A1" + }, + { + "alias": "/.*sdb2.*/", + "color": "#BF1B00" + }, + { + "alias": "/.*sdb3.*/", + "color": "#E0752D" + }, + { + "alias": "/.*sdc1.*/", + "color": "#962D82" + }, + { + "alias": "/.*sdc2.*/", + "color": "#614D93" + }, + { + "alias": "/.*sdc3.*/", + "color": "#9AC48A" + }, + { + "alias": "/.*sdd1.*/", + "color": "#65C5DB" + }, + { + "alias": "/.*sdd2.*/", + "color": "#F9934E" + }, + { + "alias": "/.*sdd3.*/", + "color": "#EA6460" + }, + { + "alias": "/.*sde1.*/", + "color": "#E0F9D7" + }, + { + "alias": "/.*sdd2.*/", + "color": "#FCEACA" + }, + { + "alias": "/.*sde3.*/", + "color": "#F9E2D2" + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "irate(node_disk_io_now{instance=\"$node\",job=\"$job\"}[5m])", + "intervalFactor": 4, + "legendFormat": "{{device}} - IO now", + "refId": "A", + "step": 8 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Disk IOs Current in Progress", + "tooltip": { + "shared": false, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "iops", + "label": "I/Os", + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "description": "", + "fieldConfig": { + "defaults": { + "custom": {}, + "links": [] + }, + "overrides": [] + }, + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 12, + "y": 45 + }, + "hiddenSeries": false, + "id": 301, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "hideZero": true, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "maxPerRow": 6, + "nullPointMode": "null as zero", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.3.6", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "$$hashKey": "object:2034", + "alias": "/.*sda_.*/", + "color": "#7EB26D" + }, + { + "$$hashKey": "object:2035", + "alias": "/.*sdb_.*/", + "color": "#EAB839" + }, + { + "$$hashKey": "object:2036", + "alias": "/.*sdc_.*/", + "color": "#6ED0E0" + }, + { + "$$hashKey": "object:2037", + "alias": "/.*sdd_.*/", + "color": "#EF843C" + }, + { + "$$hashKey": "object:2038", + "alias": "/.*sde_.*/", + "color": "#E24D42" + }, + { + "$$hashKey": "object:2039", + "alias": "/.*sda1.*/", + "color": "#584477" + }, + { + "$$hashKey": "object:2040", + "alias": "/.*sda2_.*/", + "color": "#BA43A9" + }, + { + "$$hashKey": "object:2041", + "alias": "/.*sda3_.*/", + "color": "#F4D598" + }, + { + "$$hashKey": "object:2042", + "alias": "/.*sdb1.*/", + "color": "#0A50A1" + }, + { + "$$hashKey": "object:2043", + "alias": "/.*sdb2.*/", + "color": "#BF1B00" + }, + { + "$$hashKey": "object:2044", + "alias": "/.*sdb3.*/", + "color": "#E0752D" + }, + { + "$$hashKey": "object:2045", + "alias": "/.*sdc1.*/", + "color": "#962D82" + }, + { + "$$hashKey": "object:2046", + "alias": "/.*sdc2.*/", + "color": "#614D93" + }, + { + "$$hashKey": "object:2047", + "alias": "/.*sdc3.*/", + "color": "#9AC48A" + }, + { + "$$hashKey": "object:2048", + "alias": "/.*sdd1.*/", + "color": "#65C5DB" + }, + { + "$$hashKey": "object:2049", + "alias": "/.*sdd2.*/", + "color": "#F9934E" + }, + { + "$$hashKey": "object:2050", + "alias": "/.*sdd3.*/", + "color": "#EA6460" + }, + { + "$$hashKey": "object:2051", + "alias": "/.*sde1.*/", + "color": "#E0F9D7" + }, + { + "$$hashKey": "object:2052", + "alias": "/.*sdd2.*/", + "color": "#FCEACA" + }, + { + "$$hashKey": "object:2053", + "alias": "/.*sde3.*/", + "color": "#F9E2D2" + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "irate(node_disk_discards_completed_total{instance=\"$node\",job=\"$job\"}[5m])", + "interval": "", + "intervalFactor": 4, + "legendFormat": "{{device}} - Discards completed", + "refId": "A", + "step": 8 + }, + { + "expr": "irate(node_disk_discards_merged_total{instance=\"$node\",job=\"$job\"}[5m])", + "interval": "", + "intervalFactor": 2, + "legendFormat": "{{device}} - Discards merged", + "refId": "B", + "step": 4 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Disk IOps Discards completed / merged", + "tooltip": { + "shared": false, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:2186", + "format": "iops", + "label": "IOs", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "$$hashKey": "object:2187", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + } + ], + "repeat": null, + "title": "Storage Disk", + "type": "row" + }, + { + "collapsed": true, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": {}, + "overrides": [] + }, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 77 + }, + "id": 271, + "panels": [ + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "decimals": 3, + "description": "", + "fieldConfig": { + "defaults": { + "custom": {}, + "links": [] + }, + "overrides": [] + }, + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 0, + "y": 16 + }, + "hiddenSeries": false, + "id": 43, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "maxPerRow": 6, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.3.6", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "node_filesystem_avail_bytes{instance=\"$node\",job=\"$job\",device!~'rootfs'}", + "format": "time_series", + "hide": false, + "intervalFactor": 2, + "legendFormat": "{{mountpoint}} - Available", + "metric": "", + "refId": "A", + "step": 4 + }, + { + "expr": "node_filesystem_free_bytes{instance=\"$node\",job=\"$job\",device!~'rootfs'}", + "format": "time_series", + "hide": true, + "intervalFactor": 2, + "legendFormat": "{{mountpoint}} - Free", + "refId": "B", + "step": 2 + }, + { + "expr": "node_filesystem_size_bytes{instance=\"$node\",job=\"$job\",device!~'rootfs'}", + "format": "time_series", + "hide": true, + "intervalFactor": 2, + "legendFormat": "{{mountpoint}} - Size", + "refId": "C", + "step": 2 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Filesystem space available", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:3826", + "format": "bytes", + "label": "bytes", + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "$$hashKey": "object:3827", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "description": "", + "fieldConfig": { + "defaults": { + "custom": {}, + "links": [] + }, + "overrides": [] + }, + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 12, + "y": 16 + }, + "hiddenSeries": false, + "id": 41, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "hideZero": true, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.3.6", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "node_filesystem_files_free{instance=\"$node\",job=\"$job\",device!~'rootfs'}", + "format": "time_series", + "hide": false, + "intervalFactor": 2, + "legendFormat": "{{mountpoint}} - Free file nodes", + "refId": "A", + "step": 4 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "File Nodes Free", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:3894", + "format": "short", + "label": "file nodes", + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "$$hashKey": "object:3895", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "description": "", + "fieldConfig": { + "defaults": { + "custom": {}, + "links": [] + }, + "overrides": [] + }, + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 0, + "y": 26 + }, + "hiddenSeries": false, + "id": 28, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "maxPerRow": 6, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.3.6", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "node_filefd_maximum{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "intervalFactor": 4, + "legendFormat": "Max open files", + "refId": "A", + "step": 8 + }, + { + "expr": "node_filefd_allocated{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Open files", + "refId": "B", + "step": 4 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "File Descriptor", + "tooltip": { + "shared": false, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": "files", + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "description": "", + "fieldConfig": { + "defaults": { + "custom": {}, + "links": [] + }, + "overrides": [] + }, + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 12, + "y": 26 + }, + "hiddenSeries": false, + "id": 219, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "hideZero": true, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.3.6", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "node_filesystem_files{instance=\"$node\",job=\"$job\",device!~'rootfs'}", + "format": "time_series", + "hide": false, + "intervalFactor": 2, + "legendFormat": "{{mountpoint}} - File nodes total", + "refId": "A", + "step": 4 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "File Nodes Size", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": "file Nodes", + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { + "/ ReadOnly": "#890F02" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "decimals": null, + "description": "", + "fieldConfig": { + "defaults": { + "custom": {}, + "links": [] + }, + "overrides": [] + }, + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 0, + "y": 36 + }, + "hiddenSeries": false, + "id": 44, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "hideEmpty": true, + "hideZero": true, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "maxPerRow": 6, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.3.6", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "node_filesystem_readonly{instance=\"$node\",job=\"$job\",device!~'rootfs'}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{mountpoint}} - ReadOnly", + "refId": "A", + "step": 4 + }, + { + "expr": "node_filesystem_device_error{instance=\"$node\",job=\"$job\",device!~'rootfs'}", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "{{mountpoint}} - Device error", + "refId": "B", + "step": 4 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Filesystem in ReadOnly / Error", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:3670", + "format": "short", + "label": "counter", + "logBase": 1, + "max": "1", + "min": "0", + "show": true + }, + { + "$$hashKey": "object:3671", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + } + ], + "repeat": null, + "title": "Storage Filesystem", + "type": "row" + }, + { + "collapsed": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": {}, + "overrides": [] + }, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 78 + }, + "id": 272, + "panels": [], + "repeat": null, + "title": "Network Traffic", + "type": "row" + }, + { + "aliasColors": { + "receive_packets_eth0": "#7EB26D", + "receive_packets_lo": "#E24D42", + "transmit_packets_eth0": "#7EB26D", + "transmit_packets_lo": "#E24D42" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 0, + "y": 79 + }, + "hiddenSeries": false, + "id": 60, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "sideWidth": 300, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.1", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "/.*Trans.*/", + "transform": "negative-Y" + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "irate(node_network_receive_packets_total{instance=\"$node\",job=\"$job\"}[5m])", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "{{device}} - Receive", + "refId": "A", + "step": 4 + }, + { + "expr": "irate(node_network_transmit_packets_total{instance=\"$node\",job=\"$job\"}[5m])", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "{{device}} - Transmit", + "refId": "B", + "step": 4 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Network Traffic by Packets", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "pps", + "label": "packets out (-) / in (+)", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 12, + "y": 79 + }, + "hiddenSeries": false, + "id": 142, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "hideEmpty": false, + "hideZero": false, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "sideWidth": 300, + "sort": "current", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.1", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "/.*Trans.*/", + "transform": "negative-Y" + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "irate(node_network_receive_errs_total{instance=\"$node\",job=\"$job\"}[5m])", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{device}} - Receive errors", + "refId": "A", + "step": 4 + }, + { + "expr": "irate(node_network_transmit_errs_total{instance=\"$node\",job=\"$job\"}[5m])", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{device}} - Rransmit errors", + "refId": "B", + "step": 4 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Network Traffic Errors", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "pps", + "label": "packets out (-) / in (+)", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 0, + "y": 89 + }, + "hiddenSeries": false, + "id": 143, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "hideEmpty": false, + "hideZero": false, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "sideWidth": 300, + "sort": "current", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.1", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "/.*Trans.*/", + "transform": "negative-Y" + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "irate(node_network_receive_drop_total{instance=\"$node\",job=\"$job\"}[5m])", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{device}} - Receive drop", + "refId": "A", + "step": 4 + }, + { + "expr": "irate(node_network_transmit_drop_total{instance=\"$node\",job=\"$job\"}[5m])", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{device}} - Transmit drop", + "refId": "B", + "step": 4 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Network Traffic Drop", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "pps", + "label": "packets out (-) / in (+)", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 12, + "y": 89 + }, + "hiddenSeries": false, + "id": 141, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "hideEmpty": false, + "hideZero": false, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "sideWidth": 300, + "sort": "current", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.1", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "/.*Trans.*/", + "transform": "negative-Y" + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "irate(node_network_receive_compressed_total{instance=\"$node\",job=\"$job\"}[5m])", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{device}} - Receive compressed", + "refId": "A", + "step": 4 + }, + { + "expr": "irate(node_network_transmit_compressed_total{instance=\"$node\",job=\"$job\"}[5m])", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{device}} - Transmit compressed", + "refId": "B", + "step": 4 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Network Traffic Compressed", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "pps", + "label": "packets out (-) / in (+)", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 0, + "y": 99 + }, + "hiddenSeries": false, + "id": 146, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "hideEmpty": false, + "hideZero": false, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "sideWidth": 300, + "sort": "current", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.1", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "/.*Trans.*/", + "transform": "negative-Y" + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "irate(node_network_receive_multicast_total{instance=\"$node\",job=\"$job\"}[5m])", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{device}} - Receive multicast", + "refId": "A", + "step": 4 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Network Traffic Multicast", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "pps", + "label": "packets out (-) / in (+)", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 12, + "y": 99 + }, + "hiddenSeries": false, + "id": 144, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "hideEmpty": false, + "hideZero": false, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "sideWidth": 300, + "sort": "current", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.1", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "/.*Trans.*/", + "transform": "negative-Y" + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "irate(node_network_receive_fifo_total{instance=\"$node\",job=\"$job\"}[5m])", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{device}} - Receive fifo", + "refId": "A", + "step": 4 + }, + { + "expr": "irate(node_network_transmit_fifo_total{instance=\"$node\",job=\"$job\"}[5m])", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{device}} - Transmit fifo", + "refId": "B", + "step": 4 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Network Traffic Fifo", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "pps", + "label": "packets out (-) / in (+)", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 0, + "y": 109 + }, + "hiddenSeries": false, + "id": 145, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "hideEmpty": false, + "hideZero": false, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "sideWidth": 300, + "sort": "current", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.1", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "$$hashKey": "object:576", + "alias": "/.*Trans.*/", + "transform": "negative-Y" + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "irate(node_network_receive_frame_total{instance=\"$node\",job=\"$job\"}[5m])", + "format": "time_series", + "hide": false, + "intervalFactor": 2, + "legendFormat": "{{device}} - Receive frame", + "refId": "A", + "step": 4 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Network Traffic Frame", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:589", + "format": "pps", + "label": "packets out (-) / in (+)", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "$$hashKey": "object:590", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 12, + "y": 109 + }, + "hiddenSeries": false, + "id": 231, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "hideEmpty": false, + "hideZero": false, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "sideWidth": 300, + "sort": "current", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.1", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "irate(node_network_transmit_carrier_total{instance=\"$node\",job=\"$job\"}[5m])", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{device}} - Statistic transmit_carrier", + "refId": "A", + "step": 4 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Network Traffic Carrier", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": "counter", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 0, + "y": 119 + }, + "hiddenSeries": false, + "id": 232, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "hideEmpty": false, + "hideZero": false, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "sideWidth": 300, + "sort": "current", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.1", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "/.*Trans.*/", + "transform": "negative-Y" + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "irate(node_network_transmit_colls_total{instance=\"$node\",job=\"$job\"}[5m])", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{device}} - Transmit colls", + "refId": "A", + "step": 4 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Network Traffic Colls", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": "counter", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 12, + "y": 119 + }, + "hiddenSeries": false, + "id": 61, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.1", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "$$hashKey": "object:663", + "alias": "NF conntrack limit", + "color": "#890F02", + "fill": 0 + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "node_nf_conntrack_entries{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "NF conntrack entries", + "refId": "A", + "step": 4 + }, + { + "expr": "node_nf_conntrack_entries_limit{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "NF conntrack limit", + "refId": "B", + "step": 4 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "NF Contrack", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:678", + "format": "short", + "label": "entries", + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "$$hashKey": "object:679", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 0, + "y": 129 + }, + "hiddenSeries": false, + "id": 230, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.1", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "node_arp_entries{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{ device }} - ARP entries", + "refId": "A", + "step": 4 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "ARP Entries", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": "Entries", + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 12, + "y": 129 + }, + "hiddenSeries": false, + "id": 288, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.1", + "pointradius": 1, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "node_network_mtu_bytes{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{ device }} - Bytes", + "refId": "A", + "step": 4 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "MTU", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": 0, + "format": "bytes", + "label": "bytes", + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 0, + "y": 139 + }, + "hiddenSeries": false, + "id": 280, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.1", + "pointradius": 1, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "node_network_speed_bytes{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{ device }} - Speed", + "refId": "A", + "step": 4 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Speed", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": 0, + "format": "bytes", + "label": "bytes", + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 12, + "y": 139 + }, + "hiddenSeries": false, + "id": 289, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.1", + "pointradius": 1, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "node_network_transmit_queue_length{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{ device }} - Interface transmit queue length", + "refId": "A", + "step": 4 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Queue Length", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": 0, + "format": "none", + "label": "packets", + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 0, + "y": 149 + }, + "hiddenSeries": false, + "id": 290, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "hideEmpty": false, + "hideZero": false, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "sideWidth": 300, + "sort": "current", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.1", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "$$hashKey": "object:232", + "alias": "/.*Dropped.*/", + "transform": "negative-Y" + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "irate(node_softnet_processed_total{instance=\"$node\",job=\"$job\"}[5m])", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "CPU {{cpu}} - Processed", + "refId": "A", + "step": 4 + }, + { + "expr": "irate(node_softnet_dropped_total{instance=\"$node\",job=\"$job\"}[5m])", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "CPU {{cpu}} - Dropped", + "refId": "B", + "step": 4 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Softnet Packets", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:207", + "format": "short", + "label": "packetes drop (-) / process (+)", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "$$hashKey": "object:208", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 12, + "y": 149 + }, + "hiddenSeries": false, + "id": 310, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "hideEmpty": false, + "hideZero": false, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "sideWidth": 300, + "sort": "current", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.1", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "irate(node_softnet_times_squeezed_total{instance=\"$node\",job=\"$job\"}[5m])", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "CPU {{cpu}} - Squeezed", + "refId": "A", + "step": 4 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Softnet Out of Quota", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:207", + "format": "short", + "label": "counter", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "$$hashKey": "object:208", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 0, + "y": 159 + }, + "hiddenSeries": false, + "id": 309, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "hideEmpty": false, + "hideZero": false, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "sideWidth": 300, + "sort": "current", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.1", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "node_network_up{operstate=\"up\",instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{interface}} - Operational state UP", + "refId": "A", + "step": 4 + }, + { + "expr": "node_network_carrier{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "instant": false, + "legendFormat": "{{device}} - Physical link state", + "refId": "B" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Network Operational Status", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": "counter", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "collapsed": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": {}, + "overrides": [] + }, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 169 + }, + "id": 273, + "panels": [], + "repeat": null, + "title": "Network Sockstat", + "type": "row" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 0, + "y": 170 + }, + "hiddenSeries": false, + "id": 63, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "hideEmpty": false, + "hideZero": false, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "sideWidth": 300, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.1", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "node_sockstat_TCP_alloc{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "TCP_alloc - Allocated sockets", + "refId": "A", + "step": 240 + }, + { + "expr": "node_sockstat_TCP_inuse{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "TCP_inuse - Tcp sockets currently in use", + "refId": "B", + "step": 240 + }, + { + "expr": "node_sockstat_TCP_mem{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "hide": true, + "interval": "", + "intervalFactor": 2, + "legendFormat": "TCP_mem - Used memory for tcp", + "refId": "C", + "step": 240 + }, + { + "expr": "node_sockstat_TCP_orphan{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "TCP_orphan - Orphan sockets", + "refId": "D", + "step": 240 + }, + { + "expr": "node_sockstat_TCP_tw{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "TCP_tw - Sockets wating close", + "refId": "E", + "step": 240 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Sockstat TCP", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": "counter", + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 12, + "y": 170 + }, + "hiddenSeries": false, + "id": 124, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "hideEmpty": false, + "hideZero": false, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "sideWidth": 300, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.1", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "node_sockstat_UDPLITE_inuse{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "UDPLITE_inuse - Udplite sockets currently in use", + "refId": "A", + "step": 240 + }, + { + "expr": "node_sockstat_UDP_inuse{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "UDP_inuse - Udp sockets currently in use", + "refId": "B", + "step": 240 + }, + { + "expr": "node_sockstat_UDP_mem{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "UDP_mem - Used memory for udp", + "refId": "C", + "step": 240 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Sockstat UDP", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": "counter", + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 0, + "y": 180 + }, + "hiddenSeries": false, + "id": 126, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "hideEmpty": false, + "hideZero": false, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "sideWidth": 300, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.1", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "node_sockstat_sockets_used{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "Sockets_used - Sockets currently in use", + "refId": "A", + "step": 240 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Sockstat Used", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": "sockets", + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 12, + "y": 180 + }, + "hiddenSeries": false, + "id": 220, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "hideEmpty": false, + "hideZero": false, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "sideWidth": 300, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.1", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "node_sockstat_TCP_mem_bytes{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "mem_bytes - TCP sockets in that state", + "refId": "A", + "step": 240 + }, + { + "expr": "node_sockstat_UDP_mem_bytes{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "mem_bytes - UDP sockets in that state", + "refId": "B", + "step": 240 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Sockstat Memory Size", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "bytes", + "label": "bytes", + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 0, + "y": 190 + }, + "hiddenSeries": false, + "id": 125, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "hideEmpty": false, + "hideZero": false, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "sideWidth": 300, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.1", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "node_sockstat_FRAG_inuse{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "FRAG_inuse - Frag sockets currently in use", + "refId": "A", + "step": 240 + }, + { + "expr": "node_sockstat_FRAG_memory{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "FRAG_memory - Used memory for frag", + "refId": "B", + "step": 240 + }, + { + "expr": "node_sockstat_RAW_inuse{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "RAW_inuse - Raw sockets currently in use", + "refId": "C", + "step": 240 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Sockstat FRAG / RAW", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:1572", + "format": "short", + "label": "counter", + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "$$hashKey": "object:1573", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "collapsed": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": {}, + "overrides": [] + }, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 200 + }, + "id": 274, + "panels": [], + "repeat": null, + "title": "Network Netstat", + "type": "row" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 0, + "y": 201 + }, + "height": "", + "hiddenSeries": false, + "id": 221, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "hideEmpty": false, + "hideZero": false, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "sideWidth": 300, + "sort": "current", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "maxPerRow": 12, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.1", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "$$hashKey": "object:1876", + "alias": "/.*Out.*/", + "transform": "negative-Y" + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "irate(node_netstat_IpExt_InOctets{instance=\"$node\",job=\"$job\"}[5m])", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "InOctets - Received octets", + "refId": "A", + "step": 4 + }, + { + "expr": "irate(node_netstat_IpExt_OutOctets{instance=\"$node\",job=\"$job\"}[5m])", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "OutOctets - Sent octets", + "refId": "B", + "step": 4 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Netstat IP In / Out Octets", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:1889", + "format": "short", + "label": "octects out (-) / in (+)", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "$$hashKey": "object:1890", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 12, + "y": 201 + }, + "height": "", + "hiddenSeries": false, + "id": 81, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "hideEmpty": false, + "hideZero": false, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "sideWidth": 300, + "sort": "current", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.1", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "irate(node_netstat_Ip_Forwarding{instance=\"$node\",job=\"$job\"}[5m])", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "Forwarding - IP forwarding", + "refId": "A", + "step": 4 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Netstat IP Forwarding", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:1957", + "format": "short", + "label": "datagrams", + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "$$hashKey": "object:1958", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "decimals": null, + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 0, + "y": 211 + }, + "height": "", + "hiddenSeries": false, + "id": 115, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "hideZero": false, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "sort": "current", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "maxPerRow": 12, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.1", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "/.*Out.*/", + "transform": "negative-Y" + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "irate(node_netstat_Icmp_InMsgs{instance=\"$node\",job=\"$job\"}[5m])", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "InMsgs - Messages which the entity received. Note that this counter includes all those counted by icmpInErrors", + "refId": "A", + "step": 4 + }, + { + "expr": "irate(node_netstat_Icmp_OutMsgs{instance=\"$node\",job=\"$job\"}[5m])", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "OutMsgs - Messages which this entity attempted to send. Note that this counter includes all those counted by icmpOutErrors", + "refId": "B", + "step": 4 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "ICMP In / Out", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": "messages out (-) / in (+)", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "decimals": null, + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 12, + "y": 211 + }, + "height": "", + "hiddenSeries": false, + "id": 50, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "hideZero": false, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "sort": "current", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "maxPerRow": 12, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.1", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "/.*Out.*/", + "transform": "negative-Y" + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "irate(node_netstat_Icmp_InErrors{instance=\"$node\",job=\"$job\"}[5m])", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "InErrors - Messages which the entity received but determined as having ICMP-specific errors (bad ICMP checksums, bad length, etc.)", + "refId": "A", + "step": 4 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "ICMP Errors", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": "messages out (-) / in (+)", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "decimals": null, + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 0, + "y": 221 + }, + "height": "", + "hiddenSeries": false, + "id": 55, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "hideZero": false, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "sort": "current", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "maxPerRow": 12, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.1", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "/.*Out.*/", + "transform": "negative-Y" + }, + { + "alias": "/.*Snd.*/", + "transform": "negative-Y" + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "irate(node_netstat_Udp_InDatagrams{instance=\"$node\",job=\"$job\"}[5m])", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "InDatagrams - Datagrams received", + "refId": "A", + "step": 4 + }, + { + "expr": "irate(node_netstat_Udp_OutDatagrams{instance=\"$node\",job=\"$job\"}[5m])", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "OutDatagrams - Datagrams sent", + "refId": "B", + "step": 4 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "UDP In / Out", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": "datagrams out (-) / in (+)", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 12, + "y": 221 + }, + "height": "", + "hiddenSeries": false, + "id": 109, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "hideZero": false, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "sort": "current", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "maxPerRow": 12, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.1", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "irate(node_netstat_Udp_InErrors{instance=\"$node\",job=\"$job\"}[5m])", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "InErrors - UDP Datagrams that could not be delivered to an application", + "refId": "A", + "step": 4 + }, + { + "expr": "irate(node_netstat_Udp_NoPorts{instance=\"$node\",job=\"$job\"}[5m])", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "NoPorts - UDP Datagrams received on a port with no listener", + "refId": "B", + "step": 4 + }, + { + "expr": "irate(node_netstat_UdpLite_InErrors{instance=\"$node\",job=\"$job\"}[5m])", + "interval": "", + "legendFormat": "InErrors Lite - UDPLite Datagrams that could not be delivered to an application", + "refId": "C" + }, + { + "expr": "irate(node_netstat_Udp_RcvbufErrors{instance=\"$node\",job=\"$job\"}[5m])", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "RcvbufErrors - UDP buffer errors received", + "refId": "D", + "step": 4 + }, + { + "expr": "irate(node_netstat_Udp_SndbufErrors{instance=\"$node\",job=\"$job\"}[5m])", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "SndbufErrors - UDP buffer errors send", + "refId": "E", + "step": 4 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "UDP Errors", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:4232", + "format": "short", + "label": "datagrams", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "$$hashKey": "object:4233", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "decimals": null, + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 0, + "y": 231 + }, + "height": "", + "hiddenSeries": false, + "id": 299, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "hideZero": false, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "sort": "current", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "maxPerRow": 12, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.1", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "/.*Out.*/", + "transform": "negative-Y" + }, + { + "alias": "/.*Snd.*/", + "transform": "negative-Y" + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "irate(node_netstat_Tcp_InSegs{instance=\"$node\",job=\"$job\"}[5m])", + "format": "time_series", + "instant": false, + "interval": "", + "intervalFactor": 2, + "legendFormat": "InSegs - Segments received, including those received in error. This count includes segments received on currently established connections", + "refId": "A", + "step": 4 + }, + { + "expr": "irate(node_netstat_Tcp_OutSegs{instance=\"$node\",job=\"$job\"}[5m])", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "OutSegs - Segments sent, including those on current connections but excluding those containing only retransmitted octets", + "refId": "B", + "step": 4 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "TCP In / Out", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": "datagrams out (-) / in (+)", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "description": "", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 12, + "y": 231 + }, + "height": "", + "hiddenSeries": false, + "id": 104, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "hideEmpty": false, + "hideZero": false, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "sort": "current", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "maxPerRow": 12, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.1", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "irate(node_netstat_TcpExt_ListenOverflows{instance=\"$node\",job=\"$job\"}[5m])", + "format": "time_series", + "hide": false, + "interval": "", + "intervalFactor": 2, + "legendFormat": "ListenOverflows - Times the listen queue of a socket overflowed", + "refId": "A", + "step": 4 + }, + { + "expr": "irate(node_netstat_TcpExt_ListenDrops{instance=\"$node\",job=\"$job\"}[5m])", + "format": "time_series", + "hide": false, + "interval": "", + "intervalFactor": 2, + "legendFormat": "ListenDrops - SYNs to LISTEN sockets ignored", + "refId": "B", + "step": 4 + }, + { + "expr": "irate(node_netstat_TcpExt_TCPSynRetrans{instance=\"$node\",job=\"$job\"}[5m])", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "TCPSynRetrans - SYN-SYN/ACK retransmits to break down retransmissions in SYN, fast/timeout retransmits", + "refId": "C", + "step": 4 + }, + { + "expr": "irate(node_netstat_Tcp_RetransSegs{instance=\"$node\",job=\"$job\"}[5m])", + "interval": "", + "legendFormat": "RetransSegs - Segments retransmitted - that is, the number of TCP segments transmitted containing one or more previously transmitted octets", + "refId": "D" + }, + { + "expr": "irate(node_netstat_Tcp_InErrs{instance=\"$node\",job=\"$job\"}[5m])", + "interval": "", + "legendFormat": "InErrs - Segments received in error (e.g., bad TCP checksums)", + "refId": "E" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "TCP Errors", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": "counter", + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 0, + "y": 241 + }, + "height": "", + "hiddenSeries": false, + "id": 85, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "hideZero": false, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "maxPerRow": 12, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.1", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "$$hashKey": "object:454", + "alias": "/.*MaxConn *./", + "color": "#890F02", + "fill": 0 + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "node_netstat_Tcp_CurrEstab{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "hide": false, + "interval": "", + "intervalFactor": 2, + "legendFormat": "CurrEstab - TCP connections for which the current state is either ESTABLISHED or CLOSE- WAIT", + "refId": "A", + "step": 4 + }, + { + "expr": "node_netstat_Tcp_MaxConn{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "hide": false, + "interval": "", + "intervalFactor": 2, + "legendFormat": "MaxConn - Limit on the total number of TCP connections the entity can support (Dinamic is \"-1\")", + "refId": "B", + "step": 4 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "TCP Connections", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:469", + "format": "short", + "label": "connections", + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "$$hashKey": "object:470", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "description": "", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 12, + "y": 241 + }, + "height": "", + "hiddenSeries": false, + "id": 91, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "hideEmpty": false, + "hideZero": false, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "sort": "current", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "maxPerRow": 12, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.1", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "/.*Sent.*/", + "transform": "negative-Y" + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "irate(node_netstat_TcpExt_SyncookiesFailed{instance=\"$node\",job=\"$job\"}[5m])", + "format": "time_series", + "hide": false, + "interval": "", + "intervalFactor": 2, + "legendFormat": "SyncookiesFailed - Invalid SYN cookies received", + "refId": "A", + "step": 4 + }, + { + "expr": "irate(node_netstat_TcpExt_SyncookiesRecv{instance=\"$node\",job=\"$job\"}[5m])", + "format": "time_series", + "hide": false, + "interval": "", + "intervalFactor": 2, + "legendFormat": "SyncookiesRecv - SYN cookies received", + "refId": "B", + "step": 4 + }, + { + "expr": "irate(node_netstat_TcpExt_SyncookiesSent{instance=\"$node\",job=\"$job\"}[5m])", + "format": "time_series", + "hide": false, + "interval": "", + "intervalFactor": 2, + "legendFormat": "SyncookiesSent - SYN cookies sent", + "refId": "C", + "step": 4 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "TCP SynCookie", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": "counter out (-) / in (+)", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 0, + "y": 251 + }, + "height": "", + "hiddenSeries": false, + "id": 82, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "hideZero": false, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "maxPerRow": 12, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.1", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "irate(node_netstat_Tcp_ActiveOpens{instance=\"$node\",job=\"$job\"}[5m])", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "ActiveOpens - TCP connections that have made a direct transition to the SYN-SENT state from the CLOSED state", + "refId": "A", + "step": 4 + }, + { + "expr": "irate(node_netstat_Tcp_PassiveOpens{instance=\"$node\",job=\"$job\"}[5m])", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "PassiveOpens - TCP connections that have made a direct transition to the SYN-RCVD state from the LISTEN state", + "refId": "B", + "step": 4 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "TCP Direct Transition", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": "connections", + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "collapsed": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": {}, + "overrides": [] + }, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 261 + }, + "id": 279, + "panels": [], + "repeat": null, + "title": "Node Exporter", + "type": "row" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "description": "", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 0, + "y": 262 + }, + "hiddenSeries": false, + "id": 40, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "show": true, + "sort": "current", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.1", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "node_scrape_collector_duration_seconds{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "hide": false, + "interval": "", + "intervalFactor": 2, + "legendFormat": "{{collector}} - Scrape duration", + "refId": "A", + "step": 4 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Node Exporter Scrape Time", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "s", + "label": "seconds", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "description": "", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 2, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 12, + "x": 12, + "y": 262 + }, + "hiddenSeries": false, + "id": 157, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.1", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "$$hashKey": "object:1969", + "alias": "/.*error.*/", + "color": "#F2495C", + "transform": "negative-Y" + } + ], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "node_scrape_collector_success{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "hide": false, + "interval": "", + "intervalFactor": 2, + "legendFormat": "{{collector}} - Scrape success", + "refId": "A", + "step": 4 + }, + { + "expr": "node_textfile_scrape_error{instance=\"$node\",job=\"$job\"}", + "format": "time_series", + "hide": false, + "interval": "", + "intervalFactor": 2, + "legendFormat": "{{collector}} - Scrape textfile error (1 = true)", + "refId": "B", + "step": 4 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Node Exporter Scrape", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:1484", + "format": "short", + "label": "counter", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "$$hashKey": "object:1485", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + } + ], + "refresh": "1m", + "schemaVersion": 30, + "style": "dark", + "tags": [ + "linux" + ], + "templating": { + "list": [ + { + "current": { + "selected": false, + "text": "default", + "value": "default" + }, + "description": null, + "error": null, + "hide": 0, + "includeAll": false, + "label": "datasource", + "multi": false, + "name": "DS_PROMETHEUS", + "options": [], + "query": "prometheus", + "queryValue": "", + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "type": "datasource" + }, + { + "allValue": null, + "current": {}, + "datasource": "Prometheus", + "definition": "", + "description": null, + "error": null, + "hide": 0, + "includeAll": false, + "label": "Job", + "multi": false, + "name": "job", + "options": [], + "query": { + "query": "label_values(node_uname_info, job)", + "refId": "Prometheus-job-Variable-Query" + }, + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "sort": 1, + "tagValuesQuery": "", + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": null, + "current": {}, + "datasource": "Prometheus", + "definition": "label_values(node_uname_info{job=\"$job\"}, instance)", + "description": null, + "error": null, + "hide": 0, + "includeAll": false, + "label": "Host:", + "multi": false, + "name": "node", + "options": [], + "query": { + "query": "label_values(node_uname_info{job=\"$job\"}, instance)", + "refId": "Prometheus-node-Variable-Query" + }, + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "sort": 1, + "tagValuesQuery": "", + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": null, + "current": { + "selected": false, + "text": "[a-z]+|nvme[0-9]+n[0-9]+", + "value": "[a-z]+|nvme[0-9]+n[0-9]+" + }, + "description": null, + "error": null, + "hide": 2, + "includeAll": false, + "label": null, + "multi": false, + "name": "diskdevices", + "options": [ + { + "selected": true, + "text": "[a-z]+|nvme[0-9]+n[0-9]+", + "value": "[a-z]+|nvme[0-9]+n[0-9]+" + } + ], + "query": "[a-z]+|nvme[0-9]+n[0-9]+", + "skipUrlSync": false, + "type": "custom" + } + ] + }, + "time": { + "from": "now-24h", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ], + "time_options": [ + "5m", + "15m", + "1h", + "6h", + "12h", + "24h", + "2d", + "7d", + "30d" + ] + }, + "timezone": "browser", + "title": "Node Exporter", + "uid": "rYdddlPWk", + "version": 2 +} diff --git a/roles/grafana/files/data/dashboards/proxmox-cluster.json b/roles/grafana/files/data/dashboards/proxmox-cluster.json new file mode 100644 index 00000000..9a7b9037 --- /dev/null +++ b/roles/grafana/files/data/dashboards/proxmox-cluster.json @@ -0,0 +1,1673 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": "-- Grafana --", + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "limit": 100, + "name": "Annotations & Alerts", + "showIn": 0, + "type": "dashboard" + } + ] + }, + "description": "Proxmox Virtual Environment Dashboard", + "editable": true, + "gnetId": 10347, + "graphTooltip": 0, + "id": null, + "iteration": 1633807397925, + "links": [], + "panels": [ + { + "aliasColors": {}, + "bars": false, + "cacheTimeout": null, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "unit": "percentunit" + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 6, + "x": 0, + "y": 0 + }, + "hiddenSeries": false, + "id": 7, + "interval": "", + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "maxDataPoints": 100, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.1", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "pve_cpu_usage_ratio{instance=\"$instance\"} / pve_cpu_usage_limit and on(id) pve_node_info", + "format": "time_series", + "interval": "", + "intervalFactor": 1, + "legendFormat": "{{id}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Host CPU", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "percentunit", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "decimals": 0, + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 18, + "x": 6, + "y": 0 + }, + "hiddenSeries": false, + "id": 2, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": false, + "rightSide": true, + "show": true, + "sideWidth": null, + "sort": "max", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": true, + "pluginVersion": "8.0.1", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "((pve_cpu_usage_ratio{instance=\"$instance\"} / pve_cpu_usage_limit) * on(id, instance) group_left(name, type) pve_guest_info) and on(id, instance) pve_up == 1", + "format": "time_series", + "interval": "", + "intervalFactor": 4, + "legendFormat": "{{name}} ({{type}})", + "refId": "A" + } + ], + "thresholds": [ + { + "colorMode": "critical", + "fill": true, + "line": false, + "op": "gt", + "value": 1, + "yaxis": "left" + } + ], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Guests CPU usage", + "tooltip": { + "shared": true, + "sort": 1, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": 2, + "format": "percentunit", + "label": "", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "percentunit", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "alert": { + "alertRuleTags": {}, + "conditions": [ + { + "evaluator": { + "params": [ + 0.85 + ], + "type": "gt" + }, + "operator": { + "type": "and" + }, + "query": { + "params": [ + "A", + "1m", + "now" + ] + }, + "reducer": { + "params": [], + "type": "avg" + }, + "type": "query" + } + ], + "executionErrorState": "alerting", + "for": "5m", + "frequency": "1m", + "handler": 1, + "name": "Host Memory alert", + "noDataState": "no_data", + "notifications": [] + }, + "aliasColors": {}, + "bars": false, + "cacheTimeout": null, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": {}, + "overrides": [ + { + "matcher": { + "id": "byType", + "options": "number" + }, + "properties": [ + { + "id": "unit", + "value": "percentunit" + } + ] + } + ] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 6, + "x": 0, + "y": 7 + }, + "hiddenSeries": false, + "id": 8, + "interval": null, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "maxDataPoints": 100, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.1", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "pve_memory_usage_bytes / pve_memory_size_bytes and on(id) pve_node_info", + "format": "time_series", + "interval": "", + "intervalFactor": 1, + "legendFormat": "{{ id }}", + "refId": "A" + } + ], + "thresholds": [ + { + "colorMode": "critical", + "fill": true, + "line": true, + "op": "gt", + "value": 0.85, + "visible": true + } + ], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Host Memory", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "percentunit", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "decimals": 0, + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 18, + "x": 6, + "y": 7 + }, + "hiddenSeries": false, + "id": 5, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": false, + "rightSide": true, + "show": true, + "sideWidth": null, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": true, + "pluginVersion": "8.0.1", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "(pve_memory_usage_bytes{instance=\"$instance\"} / pve_memory_size_bytes * on(id, instance) group_left(name, type) pve_guest_info) and on(id, instance) pve_up == 1", + "format": "time_series", + "interval": "", + "intervalFactor": 4, + "legendFormat": "{{name}} ({{type}})", + "refId": "A" + } + ], + "thresholds": [ + { + "colorMode": "critical", + "fill": true, + "line": false, + "op": "gt", + "value": 0.9, + "yaxis": "left" + } + ], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Guests Memory Usage", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": 1, + "format": "percentunit", + "label": "", + "logBase": 1, + "max": "1.2", + "min": null, + "show": true + }, + { + "format": "percentunit", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "cacheTimeout": null, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": {}, + "overrides": [ + { + "matcher": { + "id": "byType", + "options": "number" + }, + "properties": [ + { + "id": "unit", + "value": "percentunit" + } + ] + } + ] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 6, + "x": 0, + "y": 14 + }, + "hiddenSeries": false, + "id": 19, + "interval": null, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "maxDataPoints": 100, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.1", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "pve_memory_usage_bytes{instance=\"$instance\"} / pve_memory_size_bytes and on(id) pve_node_info", + "format": "time_series", + "interval": "", + "intervalFactor": 1, + "legendFormat": "{{ id }}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Host Memory", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "percentunit", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "decimals": 0, + "description": "", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 18, + "x": 6, + "y": 14 + }, + "hiddenSeries": false, + "id": 13, + "interval": "", + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "hideZero": true, + "max": true, + "min": false, + "rightSide": true, + "show": true, + "sideWidth": null, + "sort": "current", + "sortDesc": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": true, + "pluginVersion": "8.0.1", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "/RECV/", + "transform": "negative-Y" + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "(rate(pve_network_receive_bytes{instance=\"$instance\"}[5m]) * on(id, instance) group_left(name, type) pve_guest_info) and on(id, instance) pve_up == 1", + "format": "time_series", + "interval": "", + "intervalFactor": 3, + "legendFormat": "{{name}} RECV ({{type}})", + "refId": "A" + }, + { + "expr": "(rate(pve_network_transmit_bytes{instance=\"$instance\"}[5m])* on(id, instance) group_left(name, type) pve_guest_info) and on(id, instance) pve_up == 1", + "format": "time_series", + "interval": "", + "intervalFactor": 3, + "legendFormat": "{{name}} SEND ({{type}})", + "refId": "B" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Network IO/s", + "tooltip": { + "shared": false, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": 0, + "format": "Bps", + "label": "", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "percentunit", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": 10 + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "unit": "percentunit" + }, + "overrides": [ + { + "matcher": { + "id": "byType", + "options": "number" + }, + "properties": [ + { + "id": "unit", + "value": "percentunit" + } + ] + } + ] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 6, + "x": 0, + "y": 21 + }, + "hiddenSeries": false, + "id": 18, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.1", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "(rate(pve_disk_write_bytes[5m]) + rate(pve_disk_read_bytes[5m])) * on(id) pve_cluster_info", + "format": "time_series", + "instant": false, + "interval": "", + "intervalFactor": 1, + "legendFormat": "{{ id }} ", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Host Disk I/Os", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "percentunit", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "decimals": 0, + "description": "", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 18, + "x": 6, + "y": 21 + }, + "hiddenSeries": false, + "id": 12, + "interval": "", + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "hideZero": true, + "max": true, + "min": false, + "rightSide": true, + "show": true, + "sideWidth": null, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": true, + "pluginVersion": "8.0.1", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "((rate(pve_disk_write_bytes{instance=\"$instance\"}[5m]) + rate(pve_disk_read_bytes[5m])) * on(id, instance) group_left(name, type) pve_guest_info) and on(id, instance) pve_up == 1", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "{{name}} ({{type}})", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Guest Disk IO/s", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": 0, + "format": "Bps", + "label": "", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "percentunit", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": 10 + } + }, + { + "columns": [], + "datasource": "Prometheus", + "fontSize": "100%", + "gridPos": { + "h": 9, + "w": 24, + "x": 0, + "y": 28 + }, + "id": 17, + "links": [], + "pageSize": null, + "scroll": true, + "showHeader": true, + "sort": { + "col": 8, + "desc": true + }, + "styles": [ + { + "alias": "", + "align": "auto", + "colorMode": null, + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "mappingType": 1, + "pattern": "Time", + "thresholds": [], + "type": "hidden", + "unit": "short" + }, + { + "alias": "ID", + "align": "auto", + "colorMode": null, + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "mappingType": 1, + "pattern": "id", + "thresholds": [], + "type": "string", + "unit": "short" + }, + { + "alias": "Name", + "align": "auto", + "colorMode": null, + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "mappingType": 1, + "pattern": "name", + "thresholds": [], + "type": "string", + "unit": "short" + }, + { + "alias": "Type", + "align": "auto", + "colorMode": null, + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "mappingType": 1, + "pattern": "type", + "thresholds": [], + "type": "string", + "unit": "short" + }, + { + "alias": "", + "align": "auto", + "colorMode": null, + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "mappingType": 1, + "pattern": "Value #A", + "thresholds": [], + "type": "hidden", + "unit": "short" + }, + { + "alias": "Status", + "align": "auto", + "colorMode": "value", + "colors": [ + "rgba(245, 54, 54, 0.9)", + "#56A64B", + "rgba(50, 172, 45, 0.97)" + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 0, + "mappingType": 1, + "pattern": "Value #B", + "thresholds": [ + "0.5" + ], + "type": "string", + "unit": "short", + "valueMaps": [ + { + "text": "stopped", + "value": "0" + }, + { + "text": "running", + "value": "1" + } + ] + }, + { + "alias": "vCPUs", + "align": "auto", + "colorMode": null, + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 0, + "mappingType": 1, + "pattern": "Value #C", + "thresholds": [], + "type": "number", + "unit": "short" + }, + { + "alias": "Memory", + "align": "auto", + "colorMode": null, + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 1, + "mappingType": 1, + "pattern": "Value #D", + "thresholds": [], + "type": "number", + "unit": "bytes" + }, + { + "alias": "Mem usage (%)", + "align": "auto", + "colorMode": "value", + "colors": [ + "rgba(50, 172, 45, 0.97)", + "rgba(237, 129, 40, 0.89)", + "rgba(245, 54, 54, 0.9)" + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 0, + "mappingType": 1, + "pattern": "Value #E", + "thresholds": [ + "0.75", + " 0.9" + ], + "type": "number", + "unit": "percentunit" + }, + { + "alias": "Disk", + "align": "auto", + "colorMode": null, + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 1, + "mappingType": 1, + "pattern": "Value #F", + "thresholds": [], + "type": "number", + "unit": "bytes" + }, + { + "alias": "Disk usage (%)", + "align": "auto", + "colorMode": "value", + "colors": [ + "rgba(50, 172, 45, 0.97)", + "rgba(237, 129, 40, 0.89)", + "rgba(245, 54, 54, 0.9)" + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": null, + "mappingType": 1, + "pattern": "Value #G", + "thresholds": [ + "0.7", + " 0.9" + ], + "type": "number", + "unit": "percentunit" + } + ], + "targets": [ + { + "expr": "sum by (id, name, type) (pve_guest_info{instance=\"$instance\",template!=\"1\"})", + "format": "table", + "instant": true, + "intervalFactor": 1, + "legendFormat": "", + "refId": "A" + }, + { + "expr": "sum by (id) (pve_up{instance=\"$instance\",template!=\"1\"} and on (id, instance) pve_guest_info)", + "format": "table", + "instant": true, + "interval": "", + "intervalFactor": 1, + "legendFormat": "", + "refId": "B" + }, + { + "expr": "sum by (id) (pve_cpu_usage_limit{instance=\"$instance\",template!=\"1\"} and on (id, instance) pve_guest_info)", + "format": "table", + "instant": true, + "interval": "", + "intervalFactor": 1, + "legendFormat": "", + "refId": "C" + }, + { + "expr": "sum by (id) (pve_memory_size_bytes{instance=\"$instance\",template!=\"1\"} and on (id, instance) pve_guest_info)", + "format": "table", + "instant": true, + "interval": "", + "intervalFactor": 1, + "legendFormat": "", + "refId": "D" + }, + { + "expr": "sum by (id) (pve_memory_usage_bytes{instance=\"$instance\",template!=\"1\"} / pve_memory_size_bytes and on (id, instance) pve_guest_info)", + "format": "table", + "instant": true, + "interval": "", + "intervalFactor": 1, + "legendFormat": "", + "refId": "E" + }, + { + "expr": "sum by (id) (pve_disk_size_bytes{instance=\"$instance\",template!=\"1\"} and on (id, instance) pve_guest_info)", + "format": "table", + "instant": true, + "interval": "", + "intervalFactor": 1, + "legendFormat": "", + "refId": "F" + }, + { + "expr": "sum by (id) (pve_disk_usage_bytes{instance=\"$instance\",template!=\"1\"} / pve_disk_size_bytes and on (id, instance) pve_guest_info)", + "format": "table", + "instant": true, + "interval": "", + "intervalFactor": 1, + "legendFormat": "", + "refId": "G" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Resource allocation summary", + "transform": "table", + "type": "table-old" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "unit": "percentunit" + }, + "overrides": [ + { + "matcher": { + "id": "byType", + "options": "number" + }, + "properties": [ + { + "id": "unit", + "value": "percentunit" + } + ] + } + ] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 6, + "x": 0, + "y": 37 + }, + "hiddenSeries": false, + "id": 11, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.1", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "pve_disk_usage_bytes{instance=\"$instance\", id=~\"storage/.+\"} / pve_disk_size_bytes * on (id, instance) group_left(storage) pve_storage_info", + "format": "time_series", + "instant": false, + "interval": "", + "intervalFactor": 1, + "legendFormat": "{{ id }}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Host Storage usage", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "percentunit", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "decimals": 0, + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 18, + "x": 6, + "y": 37 + }, + "hiddenSeries": false, + "hideTimeOverride": false, + "id": 9, + "legend": { + "alignAsTable": true, + "avg": false, + "current": true, + "hideEmpty": false, + "hideZero": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sideWidth": null, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": true, + "pluginVersion": "8.0.1", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "/^pve_disk.+/", + "legend": false + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "pve_disk_usage_bytes{instance=\"$instance\"} / pve_disk_size_bytes{instance=\"$instance\"} * on (id, instance) group_left(name, type) pve_guest_info", + "format": "time_series", + "interval": "", + "intervalFactor": 1, + "legendFormat": "{{name}} ({{type}})", + "refId": "A" + } + ], + "thresholds": [ + { + "colorMode": "warning", + "fill": true, + "line": false, + "op": "gt", + "value": 0.75, + "yaxis": "left" + }, + { + "colorMode": "critical", + "fill": true, + "line": false, + "op": "gt", + "value": 0.9, + "yaxis": "left" + } + ], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Guests storage usage", + "tooltip": { + "shared": false, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": 1, + "format": "percentunit", + "label": null, + "logBase": 1, + "max": "1.2", + "min": null, + "show": true + }, + { + "format": "percentunit", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "description": "", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 9, + "w": 24, + "x": 0, + "y": 44 + }, + "hiddenSeries": false, + "id": 15, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": false, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.1", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "pve_disk_size_bytes{instance=\"$instance\", id=~\"storage/.+\"} * on (id, instance) group_left(storage) pve_storage_info", + "format": "time_series", + "instant": false, + "interval": "", + "intervalFactor": 1, + "legendFormat": "{{id}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Space allocation", + "tooltip": { + "shared": false, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "series", + "name": null, + "show": true, + "values": [ + "current" + ] + }, + "yaxes": [ + { + "decimals": 1, + "format": "bytes", + "label": "", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + } + ], + "refresh": false, + "schemaVersion": 30, + "style": "dark", + "tags": [ + "Proxmox", + "Prometheus" + ], + "templating": { + "list": [ + { + "allValue": null, + "current": { + "selected": false, + "text": "pve-exporter:9221", + "value": "pve-exporter:9221" + }, + "datasource": "Prometheus", + "definition": "label_values(pve_node_info, instance)", + "description": null, + "error": null, + "hide": 0, + "includeAll": false, + "label": null, + "multi": false, + "name": "instance", + "options": [], + "query": { + "query": "label_values(pve_node_info, instance)", + "refId": "Prometheus-instance-Variable-Query" + }, + "refresh": 2, + "regex": "", + "skipUrlSync": false, + "sort": 1, + "tagValuesQuery": "", + "tagsQuery": "", + "type": "query", + "useTags": false + } + ] + }, + "time": { + "from": "now-6h", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ], + "time_options": [ + "5m", + "15m", + "1h", + "6h", + "12h", + "24h", + "2d", + "7d", + "30d" + ] + }, + "timezone": "", + "title": "Proxmox Cluster", + "uid": "proxmox-cluster", + "version": 2 +} diff --git a/roles/grafana/files/data/dashboards/traefik-2-2.json b/roles/grafana/files/data/dashboards/traefik-2-2.json new file mode 100644 index 00000000..e9909223 --- /dev/null +++ b/roles/grafana/files/data/dashboards/traefik-2-2.json @@ -0,0 +1,756 @@ +{ + "annotations": { + "list": [ + { + "$$hashKey": "object:112", + "builtIn": 1, + "datasource": "-- Grafana --", + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "limit": 100, + "name": "Annotations & Alerts", + "showIn": 0, + "type": "dashboard" + } + ] + }, + "description": "Traefik dashboard (data from prometheus) (based on Traefik by Thomas Cheronneau https://grafana.com/grafana/dashboards/4475)", + "editable": true, + "gnetId": 12250, + "graphTooltip": 0, + "id": null, + "iteration": 1633807393879, + "links": [], + "panels": [ + { + "datasource": "Prometheus", + "fieldConfig": { + "defaults": {}, + "overrides": [] + }, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 16, + "title": "Global stats", + "type": "row" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 1 + }, + "hiddenSeries": false, + "id": 14, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.1", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(traefik_service_request_duration_seconds_sum{}) by (service) / sum(traefik_service_request_duration_seconds_count{}) by (service)", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": " {{service}}", + "refId": "A", + "step": 240 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Average response time by service", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:598", + "format": "s", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "$$hashKey": "object:599", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "breakPoint": "50%", + "cacheTimeout": null, + "combine": { + "label": "Others", + "threshold": 0 + }, + "datasource": "Prometheus", + "fontSize": "80%", + "format": "short", + "gridPos": { + "h": 7, + "w": 6, + "x": 12, + "y": 1 + }, + "id": 7, + "interval": null, + "legend": { + "show": true, + "values": true + }, + "legendType": "Right side", + "links": [], + "maxDataPoints": 3, + "nullPointMode": "connected", + "pieType": "pie", + "strokeWidth": 1, + "targets": [ + { + "expr": "sum(rate(traefik_service_requests_total[5m])) by (service) ", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "{{ service }}", + "refId": "A" + } + ], + "title": "Requests by service", + "type": "grafana-piechart-panel", + "valueName": "total" + }, + { + "aliasColors": {}, + "breakPoint": "50%", + "cacheTimeout": null, + "combine": { + "label": "Others", + "threshold": 0 + }, + "datasource": "Prometheus", + "fontSize": "80%", + "format": "short", + "gridPos": { + "h": 7, + "w": 6, + "x": 18, + "y": 1 + }, + "id": 8, + "interval": null, + "legend": { + "show": true, + "values": true + }, + "legendType": "Right side", + "links": [], + "maxDataPoints": 3, + "nullPointMode": "connected", + "pieType": "pie", + "strokeWidth": 1, + "targets": [ + { + "expr": "sum(rate(traefik_entrypoint_requests_total{entrypoint =~ \"$entrypoint\"}[5m])) by (entrypoint) ", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "{{ entrypoint }}", + "refId": "A" + } + ], + "title": "Requests by protocol", + "type": "grafana-piechart-panel", + "valueName": "total" + }, + { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 8 + }, + "hiddenSeries": false, + "id": 5, + "legend": { + "alignAsTable": true, + "avg": false, + "current": true, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "total": false, + "values": true + }, + "lines": false, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.1", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "rate(traefik_entrypoint_requests_total{entrypoint=~\"$entrypoint\",code=\"200\"}[5m])", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "{{method}} : {{code}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Status code 200 over 5min", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 8 + }, + "hiddenSeries": false, + "id": 6, + "legend": { + "alignAsTable": true, + "avg": false, + "current": true, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "total": false, + "values": true + }, + "lines": false, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.1", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "rate(traefik_entrypoint_requests_total{entrypoint=~\"$entrypoint\",code!=\"200\"}[5m])", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{ method }} : {{code}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Others status code over 5min", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "collapsed": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": {}, + "overrides": [] + }, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 15 + }, + "id": 10, + "panels": [], + "title": "$service stats", + "type": "row" + }, + { + "cacheTimeout": null, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "ms" + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 8, + "x": 0, + "y": 16 + }, + "id": 4, + "interval": null, + "links": [], + "maxDataPoints": 100, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "mean" + ], + "fields": "", + "values": false + }, + "text": {}, + "textMode": "auto" + }, + "pluginVersion": "8.0.1", + "targets": [ + { + "expr": "sum(traefik_service_request_duration_seconds_sum{service=\"$service\"}) / sum(traefik_service_requests_total{service=\"$service\"}) * 1000", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "", + "refId": "A" + } + ], + "title": "$service response time", + "type": "stat" + }, + { + "aliasColors": {}, + "breakPoint": "50%", + "cacheTimeout": null, + "combine": { + "label": "Others", + "threshold": 0 + }, + "datasource": "Prometheus", + "fontSize": "80%", + "format": "short", + "gridPos": { + "h": 7, + "w": 8, + "x": 8, + "y": 16 + }, + "id": 2, + "interval": null, + "legend": { + "percentage": true, + "show": true, + "values": true + }, + "legendType": "Right side", + "links": [], + "maxDataPoints": 3, + "nullPointMode": "connected", + "pieType": "pie", + "strokeWidth": 1, + "targets": [ + { + "expr": "traefik_service_requests_total{service=\"$service\"}", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "{{method}} : {{code}}", + "refId": "A" + } + ], + "title": "$service return code", + "type": "grafana-piechart-panel", + "valueName": "current" + }, + { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 8, + "x": 16, + "y": 16 + }, + "hiddenSeries": false, + "id": 3, + "legend": { + "alignAsTable": true, + "avg": true, + "current": false, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "total": false, + "values": true + }, + "lines": false, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.1", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(traefik_service_requests_total{service=\"$service\"}[5m]))", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "Total requests $service", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Total requests over 5min $service", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:509", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "$$hashKey": "object:510", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + } + ], + "refresh": "5m", + "schemaVersion": 30, + "style": "dark", + "tags": [ + "prometheus", + "traefik" + ], + "templating": { + "list": [ + { + "allValue": null, + "current": {}, + "datasource": "Prometheus", + "definition": "label_values(service)", + "description": null, + "error": null, + "hide": 0, + "includeAll": false, + "label": null, + "multi": false, + "name": "service", + "options": [], + "query": { + "query": "label_values(service)", + "refId": "Prometheus-service-Variable-Query" + }, + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "sort": 0, + "tagValuesQuery": "", + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": null, + "current": {}, + "datasource": "Prometheus", + "definition": "", + "description": null, + "error": null, + "hide": 0, + "includeAll": true, + "label": null, + "multi": true, + "name": "entrypoint", + "options": [], + "query": { + "query": "label_values(entrypoint)", + "refId": "Prometheus-entrypoint-Variable-Query" + }, + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "sort": 0, + "tagValuesQuery": "", + "tagsQuery": "", + "type": "query", + "useTags": false + } + ] + }, + "time": { + "from": "now-1h", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ], + "time_options": [ + "5m", + "15m", + "1h", + "6h", + "12h", + "24h", + "2d", + "7d", + "30d" + ] + }, + "timezone": "", + "title": "Traefik 2.2", + "uid": "O23g2BeWk", + "version": 2 +} diff --git a/roles/grafana/files/data/dashboards/traefik-2-by-service.json b/roles/grafana/files/data/dashboards/traefik-2-by-service.json new file mode 100644 index 00000000..237cbb7d --- /dev/null +++ b/roles/grafana/files/data/dashboards/traefik-2-by-service.json @@ -0,0 +1,1143 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": "-- Grafana --", + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "description": "", + "editable": true, + "gnetId": 11462, + "graphTooltip": 0, + "id": null, + "iteration": 1633807394234, + "links": [], + "panels": [ + { + "cacheTimeout": null, + "datasource": "Prometheus", + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "graph": false, + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": true, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "gridPos": { + "h": 18, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 33, + "interval": null, + "links": [], + "options": { + "graph": {}, + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "7.4.1", + "targets": [ + { + "expr": "sum(increase(traefik_service_requests_total{protocol=~\"$protocol\",service=~\"$service\"}[$interval])) by (service)", + "format": "time_series", + "instant": false, + "interval": "", + "intervalFactor": 1, + "legendFormat": "{{service}}", + "refId": "A", + "step": 120 + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Request per $interval", + "type": "timeseries" + }, + { + "cacheTimeout": null, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "decimals": 0, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "#37872D", + "value": null + }, + { + "color": "#37872D", + "value": 0 + }, + { + "color": "#C4162A", + "value": 1 + } + ] + }, + "unit": "none" + }, + "overrides": [] + }, + "gridPos": { + "h": 6, + "w": 3, + "x": 3, + "y": 18 + }, + "id": 26, + "interval": null, + "links": [], + "maxDataPoints": 100, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "max" + ], + "fields": "", + "values": false + }, + "text": {}, + "textMode": "auto" + }, + "pluginVersion": "8.0.1", + "targets": [ + { + "expr": "sum(increase(traefik_service_requests_total{code=\"404\",protocol=~\"$protocol\",service=~\"$service\"}[$interval]))", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "", + "metric": "traefik_requests_total", + "refId": "A", + "step": 60 + } + ], + "title": "404 Error Count", + "type": "stat" + }, + { + "cacheTimeout": null, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "decimals": 0, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "#37872D", + "value": null + }, + { + "color": "#C4162A", + "value": 0 + }, + { + "color": "#C4162A", + "value": 1 + } + ] + }, + "unit": "none" + }, + "overrides": [] + }, + "gridPos": { + "h": 6, + "w": 3, + "x": 6, + "y": 18 + }, + "id": 32, + "interval": null, + "links": [], + "maxDataPoints": 100, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "max" + ], + "fields": "", + "values": false + }, + "text": {}, + "textMode": "auto" + }, + "pluginVersion": "8.0.1", + "targets": [ + { + "expr": "sum(increase(traefik_service_requests_total{code=\"503\",protocol=~\"$protocol\",service=~\"$service\"}[$interval]))", + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "503 Error count", + "type": "stat" + }, + { + "aliasColors": {}, + "breakPoint": "50%", + "cacheTimeout": null, + "combine": { + "label": "Others", + "threshold": 0 + }, + "datasource": "Prometheus", + "fontSize": "80%", + "format": "short", + "gridPos": { + "h": 6, + "w": 4, + "x": 9, + "y": 18 + }, + "id": 18, + "interval": null, + "legend": { + "percentage": true, + "show": true, + "sort": null, + "sortDesc": null, + "values": true + }, + "legendType": "Right side", + "links": [], + "maxDataPoints": 3, + "nullPointMode": "connected", + "pieType": "pie", + "strokeWidth": 1, + "targets": [ + { + "expr": "topk(5, sum(traefik_service_requests_total{protocol=~\"$protocol\",service=~\"$service\"}) by (code))", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "{{code}}", + "refId": "A" + } + ], + "title": "Top 5 $protocol return code", + "type": "grafana-piechart-panel", + "valueName": "current" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 7, + "x": 13, + "y": 18 + }, + "hiddenSeries": false, + "id": 14, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.1", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(traefik_service_request_duration_seconds_sum{protocol=~\"$protocol\",service=~\"$service\"}) / sum(traefik_entrypoint_requests_total{protocol=~\"$protocol\"}) * 1000", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "Average response time (ms)", + "refId": "A", + "step": 240 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Average response time", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "ms", + "label": null, + "logBase": 10, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "decimals": 0, + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 12, + "x": 0, + "y": 24 + }, + "hiddenSeries": false, + "id": 10, + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.1", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(increase(traefik_service_requests_total{code=\"404\",method=\"GET\",protocol=~\"$protocol\",service=~\"$service\"}[$interval])) by (service)", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "{{service}} ", + "refId": "A", + "step": 240 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Bad Status Code Count", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": 0, + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 12, + "x": 12, + "y": 24 + }, + "hiddenSeries": false, + "hideTimeOverride": false, + "id": 4, + "legend": { + "alignAsTable": true, + "avg": true, + "current": false, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "total": false, + "values": true + }, + "lines": false, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.1", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(traefik_service_requests_total{service=~\"$service\"}[$interval]))", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "Total requests", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Total requests", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": 0, + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "decimals": 0, + "format": "short", + "label": "", + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "decimals": 0, + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 30 + }, + "hiddenSeries": false, + "id": 24, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.1", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(traefik_service_requests_total{protocol=~\"http|https\",service=~\"$service\"}[$interval])) by (service)", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "{{service}} ", + "refId": "A", + "step": 240 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Access to services", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": 0, + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 7, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 30 + }, + "hiddenSeries": false, + "id": 28, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": false, + "rightSide": true, + "show": true, + "sort": "avg", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.1", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sum(traefik_service_open_connections{service=~\"$service\"}) by (method)", + "format": "time_series", + "interval": "", + "intervalFactor": 1, + "legendFormat": "{{ method }}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "SERVICE - Open Connections", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": 0, + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "decimals": 0, + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 37 + }, + "hiddenSeries": false, + "id": 12, + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.1", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "/^[^234].*/", + "transform": "negative-Y" + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(increase(traefik_service_requests_total{protocol=~\"$protocol\",service=~\"$service\"}[$interval])) by (code)", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "{{code}}", + "refId": "A", + "step": 120 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Status Code Count ", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": 0, + "format": "short", + "label": "", + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + } + ], + "refresh": false, + "schemaVersion": 30, + "style": "dark", + "tags": [], + "templating": { + "list": [ + { + "allValue": null, + "current": { + "selected": true, + "text": "traefik", + "value": "traefik" + }, + "datasource": "Prometheus", + "definition": "", + "description": null, + "error": null, + "hide": 0, + "includeAll": false, + "label": "Job:", + "multi": false, + "name": "job", + "options": [], + "query": { + "query": "label_values(job)", + "refId": "Prometheus-job-Variable-Query" + }, + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "sort": 2, + "tagValuesQuery": "", + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": null, + "current": { + "selected": true, + "tags": [], + "text": [ + "All" + ], + "value": [ + "$__all" + ] + }, + "datasource": "Prometheus", + "definition": "label_values(traefik_service_requests_total, protocol)", + "description": null, + "error": null, + "hide": 0, + "includeAll": true, + "label": "Protocol:", + "multi": true, + "name": "protocol", + "options": [], + "query": { + "query": "label_values(traefik_service_requests_total, protocol)", + "refId": "Prometheus-protocol-Variable-Query" + }, + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "sort": 0, + "tagValuesQuery": "", + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "auto": true, + "auto_count": 30, + "auto_min": "10s", + "current": { + "selected": true, + "text": "auto", + "value": "$__auto_interval_interval" + }, + "description": null, + "error": null, + "hide": 0, + "label": "Interval", + "name": "interval", + "options": [ + { + "selected": true, + "text": "auto", + "value": "$__auto_interval_interval" + }, + { + "selected": false, + "text": "1m", + "value": "1m" + }, + { + "selected": false, + "text": "10m", + "value": "10m" + }, + { + "selected": false, + "text": "30m", + "value": "30m" + }, + { + "selected": false, + "text": "1h", + "value": "1h" + }, + { + "selected": false, + "text": "6h", + "value": "6h" + }, + { + "selected": false, + "text": "12h", + "value": "12h" + }, + { + "selected": false, + "text": "1d", + "value": "1d" + }, + { + "selected": false, + "text": "7d", + "value": "7d" + }, + { + "selected": false, + "text": "14d", + "value": "14d" + }, + { + "selected": false, + "text": "30d", + "value": "30d" + } + ], + "query": "1m,10m,30m,1h,6h,12h,1d,7d,14d,30d", + "queryValue": "", + "refresh": 2, + "skipUrlSync": false, + "type": "interval" + }, + { + "allValue": ".*", + "current": { + "selected": true, + "tags": [], + "text": [ + "All" + ], + "value": [ + "$__all" + ] + }, + "datasource": null, + "definition": "label_values(traefik_service_open_connections, service)", + "description": null, + "error": null, + "hide": 0, + "includeAll": true, + "label": "Service", + "multi": true, + "name": "service", + "options": [], + "query": { + "query": "label_values(traefik_service_open_connections, service)", + "refId": "StandardVariableQuery" + }, + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "sort": 0, + "tagValuesQuery": "", + "tagsQuery": "", + "type": "query", + "useTags": false + } + ] + }, + "time": { + "from": "now-3h", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ], + "time_options": [ + "5m", + "15m", + "1h", + "6h", + "12h", + "24h", + "2d", + "7d", + "30d" + ] + }, + "timezone": "", + "title": "Traefik 2 By Service", + "uid": "404sfKUMk", + "version": 2 +} diff --git a/roles/grafana/files/data/dashboards/traefik-2.json b/roles/grafana/files/data/dashboards/traefik-2.json new file mode 100644 index 00000000..b8e9c96e --- /dev/null +++ b/roles/grafana/files/data/dashboards/traefik-2.json @@ -0,0 +1,1678 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": "-- Grafana --", + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "description": "Simple dashboard for Traefik 2", + "editable": true, + "gnetId": 11462, + "graphTooltip": 0, + "id": null, + "iteration": 1633807394970, + "links": [], + "panels": [ + { + "datasource": "Loki", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "custom": { + "align": null, + "displayMode": "auto", + "filterable": false + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "ClientAddr" + }, + "properties": [ + { + "id": "custom.width", + "value": 181 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "RequestMethod" + }, + "properties": [ + { + "id": "custom.width", + "value": 113 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "RequestPath" + }, + "properties": [ + { + "id": "custom.width", + "value": 191 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Method" + }, + "properties": [ + { + "id": "custom.width", + "value": 73 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "OriginStatus" + }, + "properties": [ + { + "id": "custom.width", + "value": 101 + } + ] + } + ] + }, + "gridPos": { + "h": 13, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 35, + "options": { + "showHeader": true, + "sortBy": [ + { + "desc": true, + "displayName": "ts" + } + ] + }, + "pluginVersion": "8.0.1", + "targets": [ + { + "expr": "{container_name=\"traefik_server_1\"} |= \"$query\" | json", + "legendFormat": "", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Traefik Logs", + "transformations": [ + { + "id": "labelsToFields", + "options": {} + }, + { + "id": "organize", + "options": { + "excludeByName": { + "ClientHost": true, + "ClientPort": true, + "ClientUsername": true, + "DownstreamContentSize": true, + "DownstreamStatus": true, + "Duration": true, + "OriginContentSize": true, + "OriginDuration": true, + "Overhead": true, + "RequestContentSize": true, + "RequestCount": true, + "RequestPort": true, + "RequestProtocol": true, + "RequestScheme": true, + "RetryAttempts": true, + "ServiceAddr": true, + "ServiceURL_Fragment": true, + "ServiceURL_Opaque": true, + "ServiceURL_Path": true, + "ServiceURL_RawFragment": true, + "ServiceURL_RawPath": true, + "ServiceURL_RawQuery": true, + "ServiceURL_Scheme": true, + "StartLocal": true, + "StartUTC": true, + "container_id": true, + "container_name": true, + "entryPointName": true, + "filename": true, + "id": true, + "level": false, + "line": true, + "msg": true, + "providerName": true, + "stream": true, + "time": true, + "tsNs": true + }, + "indexByName": { + "ClientAddr": 7, + "ClientHost": 17, + "ClientPort": 1, + "ClientUsername": 38, + "DownstreamContentSize": 2, + "DownstreamStatus": 23, + "Duration": 3, + "OriginContentSize": 8, + "OriginDuration": 39, + "OriginStatus": 18, + "Overhead": 24, + "RequestAddr": 35, + "RequestContentSize": 25, + "RequestCount": 40, + "RequestHost": 10, + "RequestMethod": 9, + "RequestPath": 11, + "RequestPort": 29, + "RequestProtocol": 4, + "RequestScheme": 30, + "RetryAttempts": 26, + "RouterName": 41, + "ServiceAddr": 36, + "ServiceName": 31, + "ServiceURL_Fragment": 19, + "ServiceURL_Host": 27, + "ServiceURL_Opaque": 28, + "ServiceURL_Path": 32, + "ServiceURL_RawFragment": 21, + "ServiceURL_RawPath": 33, + "ServiceURL_RawQuery": 20, + "ServiceURL_Scheme": 14, + "StartLocal": 22, + "StartUTC": 12, + "container_id": 15, + "container_name": 5, + "entryPointName": 16, + "filename": 6, + "id": 44, + "level": 42, + "line": 43, + "msg": 34, + "stream": 37, + "time": 13, + "ts": 0, + "tsNs": 45 + }, + "renameByName": { + "ClientAddr": "Client Address", + "OriginContentSize": "", + "OriginStatus": "Status", + "RequestHost": "", + "RequestMethod": "Method", + "ServiceURL_Fragment": "" + } + } + } + ], + "type": "table" + }, + { + "cacheTimeout": null, + "datasource": "Prometheus", + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "graph": false, + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": true, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "gridPos": { + "h": 18, + "w": 24, + "x": 0, + "y": 13 + }, + "id": 33, + "interval": null, + "links": [], + "options": { + "graph": {}, + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "single" + } + }, + "pluginVersion": "7.4.1", + "targets": [ + { + "expr": "sum(increase(traefik_service_requests_total{protocol=~\"$protocol\"}[$interval])) by (service)", + "format": "time_series", + "instant": false, + "interval": "", + "intervalFactor": 1, + "legendFormat": "{{service}}", + "refId": "A", + "step": 120 + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Request per $interval", + "type": "timeseries" + }, + { + "cacheTimeout": null, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "s" + }, + "overrides": [] + }, + "gridPos": { + "h": 6, + "w": 3, + "x": 0, + "y": 31 + }, + "id": 22, + "interval": null, + "links": [], + "maxDataPoints": 100, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "text": {}, + "textMode": "auto" + }, + "pluginVersion": "8.0.1", + "targets": [ + { + "expr": "time() - process_start_time_seconds{job=\"$job\"}", + "format": "time_series", + "intervalFactor": 2, + "refId": "A" + } + ], + "title": "Uptime", + "type": "stat" + }, + { + "cacheTimeout": null, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "decimals": 0, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "#37872D", + "value": null + }, + { + "color": "#37872D", + "value": 0 + }, + { + "color": "#C4162A", + "value": 1 + } + ] + }, + "unit": "none" + }, + "overrides": [] + }, + "gridPos": { + "h": 6, + "w": 3, + "x": 3, + "y": 31 + }, + "id": 26, + "interval": null, + "links": [], + "maxDataPoints": 100, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "max" + ], + "fields": "", + "values": false + }, + "text": {}, + "textMode": "auto" + }, + "pluginVersion": "8.0.1", + "targets": [ + { + "expr": "sum(increase(traefik_service_requests_total{code=\"404\",protocol=~\"$protocol\"}[$interval]))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "", + "metric": "traefik_requests_total", + "refId": "A", + "step": 60 + } + ], + "title": "404 Error Count", + "type": "stat" + }, + { + "cacheTimeout": null, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "decimals": 0, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "#37872D", + "value": null + }, + { + "color": "#C4162A", + "value": 0 + }, + { + "color": "#C4162A", + "value": 1 + } + ] + }, + "unit": "none" + }, + "overrides": [] + }, + "gridPos": { + "h": 6, + "w": 3, + "x": 6, + "y": 31 + }, + "id": 32, + "interval": null, + "links": [], + "maxDataPoints": 100, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "max" + ], + "fields": "", + "values": false + }, + "text": {}, + "textMode": "auto" + }, + "pluginVersion": "8.0.1", + "targets": [ + { + "expr": "sum(increase(traefik_service_requests_total{code=\"503\",protocol=~\"$protocol\"}[$interval]))", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "503 Error count", + "type": "stat" + }, + { + "aliasColors": {}, + "breakPoint": "50%", + "cacheTimeout": null, + "combine": { + "label": "Others", + "threshold": 0 + }, + "datasource": "Prometheus", + "fontSize": "80%", + "format": "short", + "gridPos": { + "h": 6, + "w": 4, + "x": 9, + "y": 31 + }, + "id": 18, + "interval": null, + "legend": { + "percentage": true, + "show": true, + "sort": null, + "sortDesc": null, + "values": true + }, + "legendType": "Right side", + "links": [], + "maxDataPoints": 3, + "nullPointMode": "connected", + "pieType": "pie", + "strokeWidth": 1, + "targets": [ + { + "expr": "topk(5, sum(traefik_service_requests_total{protocol=~\"$protocol\"}) by (code))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{code}}", + "refId": "A" + } + ], + "title": "Top 5 $protocol return code", + "type": "grafana-piechart-panel", + "valueName": "current" + }, + { + "cacheTimeout": null, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "ms" + }, + "overrides": [] + }, + "gridPos": { + "h": 6, + "w": 4, + "x": 13, + "y": 31 + }, + "id": 20, + "interval": null, + "links": [], + "maxDataPoints": 100, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "mean" + ], + "fields": "", + "values": false + }, + "text": {}, + "textMode": "auto" + }, + "pluginVersion": "8.0.1", + "targets": [ + { + "expr": "sum(traefik_entrypoint_request_duration_seconds_sum) / sum(traefik_entrypoint_requests_total) * 1000", + "format": "time_series", + "intervalFactor": 2, + "refId": "A" + } + ], + "title": "Average response time", + "type": "stat" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 7, + "x": 17, + "y": 31 + }, + "hiddenSeries": false, + "id": 14, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.1", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(traefik_service_request_duration_seconds_sum{protocol=~\"$protocol\"}) / sum(traefik_entrypoint_requests_total{protocol=~\"$protocol\"}) * 1000", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Average response time (ms)", + "refId": "A", + "step": 240 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Average response time", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "ms", + "label": null, + "logBase": 10, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "decimals": 0, + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 12, + "x": 0, + "y": 37 + }, + "hiddenSeries": false, + "id": 10, + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.1", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(increase(traefik_service_requests_total{code=\"404\",method=\"GET\",protocol=~\"$protocol\"}[$interval])) by (service)", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "{{service}} ", + "refId": "A", + "step": 240 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Bad Status Code Count", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": 0, + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 12, + "x": 12, + "y": 37 + }, + "hiddenSeries": false, + "hideTimeOverride": false, + "id": 4, + "legend": { + "alignAsTable": true, + "avg": true, + "current": false, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "total": false, + "values": true + }, + "lines": false, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.1", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(traefik_service_requests_total[$interval]))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Total requests", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Total requests", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": 0, + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "decimals": 0, + "format": "short", + "label": "", + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 10, + "x": 0, + "y": 43 + }, + "hiddenSeries": false, + "id": 8, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null as zero", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.1", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "process_open_fds{job=~\"$job\"}", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "{{ instance }}", + "refId": "A", + "step": 240 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Used sockets", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "decimals": 0, + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 14, + "x": 10, + "y": 43 + }, + "hiddenSeries": false, + "id": 24, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.1", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(traefik_service_requests_total{protocol=~\"http|https\"}[$interval])) by (service)", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "{{service}} ", + "refId": "A", + "step": 240 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Access to services", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": 0, + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 7, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 49 + }, + "hiddenSeries": false, + "id": 30, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": false, + "rightSide": true, + "show": true, + "sort": "avg", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.1", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sum(traefik_entrypoint_open_connections) by (method)", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{ method }}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "ENTRYPOINT - Open Connections", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": 0, + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 7, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 49 + }, + "hiddenSeries": false, + "id": 28, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": false, + "rightSide": true, + "show": true, + "sort": "avg", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.1", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sum(traefik_service_open_connections) by (method)", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{ method }}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "SERVICE - Open Connections", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": 0, + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "decimals": 0, + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 56 + }, + "hiddenSeries": false, + "id": 12, + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.1", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "/^[^234].*/", + "transform": "negative-Y" + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(increase(traefik_service_requests_total{protocol=~\"$protocol\"}[$interval])) by (code)", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{code}}", + "refId": "A", + "step": 120 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Status Code Count ", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": 0, + "format": "short", + "label": "", + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + } + ], + "refresh": "", + "schemaVersion": 30, + "style": "dark", + "tags": [ + "traefik", + "load-balancer", + "docker", + "prometheus" + ], + "templating": { + "list": [ + { + "allValue": null, + "current": { + "selected": false, + "text": "traefik", + "value": "traefik" + }, + "datasource": "Prometheus", + "definition": "", + "description": null, + "error": null, + "hide": 0, + "includeAll": false, + "label": "Job:", + "multi": false, + "name": "job", + "options": [], + "query": { + "query": "label_values(job)", + "refId": "Prometheus-job-Variable-Query" + }, + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "sort": 2, + "tagValuesQuery": "", + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": null, + "current": { + "selected": true, + "text": [ + "All" + ], + "value": [ + "$__all" + ] + }, + "datasource": "Prometheus", + "definition": "label_values(traefik_service_requests_total, protocol)", + "description": null, + "error": null, + "hide": 0, + "includeAll": true, + "label": "Service:", + "multi": true, + "name": "protocol", + "options": [], + "query": { + "query": "label_values(traefik_service_requests_total, protocol)", + "refId": "Prometheus-protocol-Variable-Query" + }, + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "sort": 0, + "tagValuesQuery": "", + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "auto": true, + "auto_count": 30, + "auto_min": "10s", + "current": { + "selected": false, + "text": "auto", + "value": "$__auto_interval_interval" + }, + "description": null, + "error": null, + "hide": 0, + "label": "Interval", + "name": "interval", + "options": [ + { + "selected": true, + "text": "auto", + "value": "$__auto_interval_interval" + }, + { + "selected": false, + "text": "1m", + "value": "1m" + }, + { + "selected": false, + "text": "10m", + "value": "10m" + }, + { + "selected": false, + "text": "30m", + "value": "30m" + }, + { + "selected": false, + "text": "1h", + "value": "1h" + }, + { + "selected": false, + "text": "6h", + "value": "6h" + }, + { + "selected": false, + "text": "12h", + "value": "12h" + }, + { + "selected": false, + "text": "1d", + "value": "1d" + }, + { + "selected": false, + "text": "7d", + "value": "7d" + }, + { + "selected": false, + "text": "14d", + "value": "14d" + }, + { + "selected": false, + "text": "30d", + "value": "30d" + } + ], + "query": "1m,10m,30m,1h,6h,12h,1d,7d,14d,30d", + "queryValue": "", + "refresh": 2, + "skipUrlSync": false, + "type": "interval" + }, + { + "current": { + "selected": false, + "text": "", + "value": "" + }, + "description": null, + "error": null, + "hide": 0, + "label": "Query Logs", + "name": "query", + "options": [ + { + "selected": true, + "text": "", + "value": "" + } + ], + "query": "", + "skipUrlSync": false, + "type": "textbox" + } + ] + }, + "time": { + "from": "now-12h", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ], + "time_options": [ + "5m", + "15m", + "1h", + "6h", + "12h", + "24h", + "2d", + "7d", + "30d" + ] + }, + "timezone": "", + "title": "Traefik 2", + "uid": "3ipsWfViz", + "version": 2 +} diff --git a/roles/grafana/files/data/dashboards/traefik.json b/roles/grafana/files/data/dashboards/traefik.json new file mode 100644 index 00000000..e38c239c --- /dev/null +++ b/roles/grafana/files/data/dashboards/traefik.json @@ -0,0 +1,258 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": "-- Grafana --", + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": true, + "gnetId": null, + "graphTooltip": 0, + "id": null, + "links": [], + "panels": [ + { + "datasource": "Loki", + "fieldConfig": { + "defaults": { + "custom": { + "align": null, + "displayMode": "auto", + "filterable": false + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "ClientAddr" + }, + "properties": [ + { + "id": "custom.width", + "value": 181 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "RequestMethod" + }, + "properties": [ + { + "id": "custom.width", + "value": 113 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "RequestPath" + }, + "properties": [ + { + "id": "custom.width", + "value": 191 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Method" + }, + "properties": [ + { + "id": "custom.width", + "value": 73 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "OriginStatus" + }, + "properties": [ + { + "id": "custom.width", + "value": 101 + } + ] + } + ] + }, + "gridPos": { + "h": 18, + "w": 17, + "x": 0, + "y": 0 + }, + "id": 2, + "options": { + "showHeader": true, + "sortBy": [ + { + "desc": true, + "displayName": "ts" + } + ] + }, + "pluginVersion": "8.0.1", + "targets": [ + { + "expr": "{container_name=\"traefik_server_1\"} | json", + "legendFormat": "", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Traefik Logs", + "transformations": [ + { + "id": "labelsToFields", + "options": {} + }, + { + "id": "organize", + "options": { + "excludeByName": { + "ClientHost": true, + "ClientPort": true, + "ClientUsername": true, + "DownstreamContentSize": true, + "DownstreamStatus": true, + "Duration": true, + "OriginContentSize": true, + "OriginDuration": true, + "Overhead": true, + "RequestContentSize": true, + "RequestCount": true, + "RequestPort": true, + "RequestProtocol": true, + "RequestScheme": true, + "RetryAttempts": true, + "ServiceAddr": true, + "ServiceURL_Fragment": true, + "ServiceURL_Opaque": true, + "ServiceURL_Path": true, + "ServiceURL_RawFragment": true, + "ServiceURL_RawPath": true, + "ServiceURL_RawQuery": true, + "ServiceURL_Scheme": true, + "StartLocal": true, + "StartUTC": true, + "container_id": true, + "container_name": true, + "entryPointName": true, + "filename": true, + "id": true, + "level": false, + "line": true, + "msg": true, + "stream": true, + "time": true, + "tsNs": true + }, + "indexByName": { + "ClientAddr": 7, + "ClientHost": 17, + "ClientPort": 1, + "ClientUsername": 38, + "DownstreamContentSize": 2, + "DownstreamStatus": 23, + "Duration": 3, + "OriginContentSize": 8, + "OriginDuration": 39, + "OriginStatus": 18, + "Overhead": 24, + "RequestAddr": 35, + "RequestContentSize": 25, + "RequestCount": 40, + "RequestHost": 10, + "RequestMethod": 9, + "RequestPath": 11, + "RequestPort": 29, + "RequestProtocol": 4, + "RequestScheme": 30, + "RetryAttempts": 26, + "RouterName": 41, + "ServiceAddr": 36, + "ServiceName": 31, + "ServiceURL_Fragment": 19, + "ServiceURL_Host": 27, + "ServiceURL_Opaque": 28, + "ServiceURL_Path": 32, + "ServiceURL_RawFragment": 21, + "ServiceURL_RawPath": 33, + "ServiceURL_RawQuery": 20, + "ServiceURL_Scheme": 14, + "StartLocal": 22, + "StartUTC": 12, + "container_id": 15, + "container_name": 5, + "entryPointName": 16, + "filename": 6, + "id": 44, + "level": 42, + "line": 43, + "msg": 34, + "stream": 37, + "time": 13, + "ts": 0, + "tsNs": 45 + }, + "renameByName": { + "ClientAddr": "Client Address", + "OriginContentSize": "", + "OriginStatus": "Status", + "RequestHost": "", + "RequestMethod": "Method", + "ServiceURL_Fragment": "" + } + } + } + ], + "type": "table" + } + ], + "schemaVersion": 30, + "style": "dark", + "tags": [], + "templating": { + "list": [] + }, + "time": { + "from": "now-6h", + "to": "now" + }, + "timepicker": {}, + "timezone": "", + "title": "Traefik", + "uid": "traefik", + "version": 2 +} diff --git a/roles/grafana/files/provisioning/dashboards/json.yaml b/roles/grafana/files/provisioning/dashboards/json.yaml new file mode 100644 index 00000000..090b7254 --- /dev/null +++ b/roles/grafana/files/provisioning/dashboards/json.yaml @@ -0,0 +1,26 @@ +apiVersion: 1 + +providers: + # an unique provider name. Required + - name: json + # Org id. Default to 1 + orgId: 1 + # name of the dashboard folder. + folder: '' + # folder UID. will be automatically generated if not specified + folderUid: '' + # provider type. Default to 'file' + type: file + # disable dashboard deletion + disableDeletion: false + # enable dashboard editing + editable: true + # how often Grafana will scan for changed dashboards + updateIntervalSeconds: 30 + # allow updating provisioned dashboards from the UI + allowUiUpdates: true + options: + # path to dashboard files on disk. Required when using the 'file' type + path: /var/lib/grafana/dashboards + # use folder names from filesystem to create folders in Grafana + foldersFromFilesStructure: true \ No newline at end of file diff --git a/roles/grafana/tasks/main.yml b/roles/grafana/tasks/main.yml new file mode 100644 index 00000000..a21fe021 --- /dev/null +++ b/roles/grafana/tasks/main.yml @@ -0,0 +1,106 @@ +--- +- name: Create Directories + file: + path: /netsoc/{{ item }} + mode: 0770 + state: directory + loop: + - /grafana + - /grafana/exports + - /grafana/exports/db + - /grafana/data + - /grafana/data/dashboards + - /grafana/provisioning + - /grafana/provisioning/notifiers + - /grafana/provisioning/plugins + - /grafana/provisioning/datasources + +- name: "Copy config provisioning" + become: yes + copy: + mode: 0770 + src: files/provisioning/ # without / copies provisioning itself not just contents + dest: /netsoc/grafana/provisioning + +- name: "Template Prometheus Datasource" + become: yes + template: + mode: 0770 + src: templates/provisioning/datasources/prometheus.yaml + dest: /netsoc/grafana/provisioning/datasources/prometheus.yaml + +- name: "Template Discord Webhook" + become: yes + template: + mode: 0770 + src: templates/provisioning/notifiers/discord.yaml + dest: /netsoc/grafana/provisioning/notifiers/discord.yaml + +- name: "Template Loki Config" + become: yes + template: + mode: 0770 + src: templates/provisioning/datasources/loki.yml + dest: /netsoc/grafana/provisioning/datasources/loki.yml + +- name: Ensure Grafana Docker Container + become: yes + docker_compose: + project_name: grafana + recreate: always + restarted: yes + remove_orphans: yes + state: present + definition: + version: "3.8" + networks: + rendering: + traefik: + name: traefik + external: true + services: + grafana: + image: "grafana/grafana:8.0.1" + user: root + restart: always + networks: + traefik: + rendering: + labels: + - "traefik.enable=true" + - "traefik.http.routers.grafana.rule=Host(`{{ host }}`)" + - "traefik.http.routers.grafana.entrypoints=web-secure" + - "traefik.http.routers.grafana.tls.certResolver=letsencrypt" + - "traefik.http.services.grafana-service.loadbalancer.server.port=3000" + - "traefik.http.routers.grafana.service=grafana-service" + - "traefik.docker.network=traefik" + volumes: + - "/netsoc/grafana/provisioning/:/etc/grafana/provisioning/" + - "/netsoc/grafana/data/:/var/lib/grafana/" + ports: + - 3000 + environment: + GF_SECURITY_ADMIN_PASSWORD: "{{ grafana.password }}" + GF_SERVER_ROOT_URL: "https://{{ host }}" + GF_SERVER_DOMAIN: "{{ host }}" + GF_RENDERING_SERVER_URL: "http://renderer:8081/render" + GF_RENDERING_CALLBACK_URL: "http://grafana:3000/" + GF_INSTALL_PLUGINS: "grafana-piechart-panel" + # Keycloak setup: + GF_AUTH_GENERIC_OAUTH_ENABLED: "true" + GF_AUTH_GENERIC_OAUTH_NAME: "Netsoc" + GF_AUTH_GENERIC_OAUTH_ALLOW_SIGN_UP: "true" + GF_AUTH_GENERIC_OAUTH_EMAIL_ATTRIBUTE_NAME: email + GF_AUTH_GENERIC_OAUTH_CLIENT_ID: "grafana" + GF_AUTH_GENERIC_OAUTH_SCOPES: email microprofile-jwt profile roles web-origins + GF_AUTH_GENERIC_OAUTH_AUTH_URL: "https://{{ keycloak_host }}/auth/realms/freeipa/protocol/openid-connect/auth" + GF_AUTH_GENERIC_OAUTH_TOKEN_URL: "https://{{ keycloak_host }}/auth/realms/freeipa/protocol/openid-connect/token" + GF_AUTH_GENERIC_OAUTH_API_URL: "https://{{ keycloak_host }}/auth/realms/freeipa/protocol/openid-connect/userinfo" + GF_AUTH_GENERIC_OAUTH_ROLE_ATTRIBUTE_PATH: "contains(groups[*], 'netsoc_sysadmin') && 'Admin'" + renderer: + image: "grafana/grafana-image-renderer:3.0.1" + restart: on-failure + networks: + rendering: + ports: + - 8081 diff --git a/roles/grafana/templates/provisioning/datasources/loki.yml b/roles/grafana/templates/provisioning/datasources/loki.yml new file mode 100644 index 00000000..3b05f35e --- /dev/null +++ b/roles/grafana/templates/provisioning/datasources/loki.yml @@ -0,0 +1,24 @@ +# config file version +apiVersion: 1 + +# list of datasources to insert/update depending +# what's available in the database +datasources: + # name of the datasource. Required + - name: Loki + # datasource type. Required + type: loki + # access mode. proxy or direct (Server or Browser in the UI). Required + access: proxy + # url + url: https://loki.netsoc.co/ + # enable/disable basic auth + basicAuth: true + # basic auth username, if used + basicAuthUser: "{{ loki.username }}" + isDefault: false + # allow users to edit datasources from the UI. + editable: false + secureJsonData: + # basic auth password, if used + basicAuthPassword: "{{ loki.password }}" \ No newline at end of file diff --git a/roles/grafana/templates/provisioning/datasources/prometheus.yaml b/roles/grafana/templates/provisioning/datasources/prometheus.yaml new file mode 100644 index 00000000..dd45945a --- /dev/null +++ b/roles/grafana/templates/provisioning/datasources/prometheus.yaml @@ -0,0 +1,18 @@ +# config file version +apiVersion: 1 + +# list of datasources to insert/update depending +# what's available in the database +datasources: + # name of the datasource. Required + - name: Prometheus + # datasource type. Required + type: prometheus + # access mode. proxy or direct (Server or Browser in the UI). Required + access: proxy + # url + url: "http://{{databases.infra.prometheus}}:9090" + isDefault: true + version: 1 + # allow users to edit datasources from the UI. + editable: false \ No newline at end of file diff --git a/roles/grafana/templates/provisioning/notifiers/discord.yaml b/roles/grafana/templates/provisioning/notifiers/discord.yaml new file mode 100644 index 00000000..da275415 --- /dev/null +++ b/roles/grafana/templates/provisioning/notifiers/discord.yaml @@ -0,0 +1,13 @@ +notifiers: + - name: Discord + type: discord + uid: discord + org_id: 1 + is_default: true + send_reminder: true + frequency: 24h + disable_resolve_message: false + settings: + uploadImage: true + content: "" + url: "{{ grafana.discord_webhook }}" \ No newline at end of file diff --git a/roles/hlm.netsoc.co/tasks/main.yml b/roles/hlm.netsoc.co/tasks/main.yml new file mode 100644 index 00000000..6e88c813 --- /dev/null +++ b/roles/hlm.netsoc.co/tasks/main.yml @@ -0,0 +1,46 @@ +--- +- name: Ensure config.py in Docker Swarm Secrets + become: yes + docker_secret: + name: hlm_config.py + data: "{{ lookup('template', 'config.py') }}" + #register: result + ignore_errors: true + +- name: Ensure HLM Container running + become: yes + docker_stack: + state: present + name: hlm_netsoc_co + compose: + - version: '3.7' + services: + server: + image: uccnetsoc/hlm + networks: + traefik: + secrets: + - source: hlm_config.py + target: config.py + deploy: + mode: replicated + replicas: 1 + restart_policy: + condition: any + delay: 5s + max_attempts: 5 + labels: + - "traefik.enable=true" + - "traefik.http.routers.hlm_netsoc_co.rule=Host(`hlm.{{ co_site }}`)" + - "traefik.http.routers.hlm_netsoc_co.entrypoints=web-secure" + - "traefik.http.routers.hlm_netsoc_co.tls.certResolver=letsencrypt" + - "traefik.http.services.hlm_netsoc_co-service.loadbalancer.server.port=5000" + - "traefik.http.routers.hlm_netsoc_co.service=hlm_netsoc_co-service" + - "traefik.docker.network=traefik" + networks: + traefik: + external: true + name: traefik + secrets: + hlm_config.py: + external: true diff --git a/roles/hlm.netsoc.co/templates/config.py b/roles/hlm.netsoc.co/templates/config.py new file mode 100644 index 00000000..59062139 --- /dev/null +++ b/roles/hlm.netsoc.co/templates/config.py @@ -0,0 +1,7 @@ +email_config = { + "api_key": "{{ sendgrid_apikey }}", + "to_address": "netsoc@uccsocieties.ie", + "from_address": "nominations@netsoc.co" +} + +secret_key = "{{ 9999999999999999999999 | random | to_uuid }}" diff --git a/roles/impressive/tasks/main.yml b/roles/impressive/tasks/main.yml new file mode 100644 index 00000000..4fb7c0cd --- /dev/null +++ b/roles/impressive/tasks/main.yml @@ -0,0 +1,39 @@ +--- +- name: Ensure Impressive + become: yes + docker_stack: + state: present + name: impressive + compose: + - version: '3.7' + networks: + traefik: + external: true + services: + server: + image: strum355/impressive + container_name: impressive_server + networks: + - traefik + deploy: + mode: replicated + replicas: 1 + restart_policy: + condition: any + delay: 5s + max_attempts: 5 + labels: + - "traefik.enable=true" + - "traefik.http.routers.impressive.entrypoints=web-secure" + - "traefik.http.routers.impressive.rule=Host(`impressive.{{ co_site }}`) && Method(`POST`)" + - "traefik.http.routers.impressive.tls.certResolver=letsencrypt" + - "traefik.http.routers.impressive.service=impressive-service" + - "traefik.http.services.impressive-service.loadbalancer.server.port=3000" + - "traefik.docker.network=traefik" + - "traefik.http.routers.impressive-readme.entrypoints=web-secure" + - "traefik.http.routers.impressive-readme.rule=Host(`impressive.{{ co_site }}`) && Method(`GET`)" + - "traefik.http.routers.impressive-readme.service=unused-service@file" + - "traefik.http.routers.impressive-readme.middlewares=impressive-redirect@docker" + - "traefik.http.middlewares.impressive-redirect.redirectregex.regex=^(.*)" + - "traefik.http.middlewares.impressive-redirect.redirectregex.replacement=https://github.com/cahalane/impressive" + - "traefik.http.routers.impressive-readme.tls.certResolver=letsencrypt" \ No newline at end of file diff --git a/roles/freeipa-client/tasks/main.yml b/roles/ipa-client-enroll/tasks/main.yml similarity index 65% rename from roles/freeipa-client/tasks/main.yml rename to roles/ipa-client-enroll/tasks/main.yml index 272db930..377334ec 100644 --- a/roles/freeipa-client/tasks/main.yml +++ b/roles/ipa-client-enroll/tasks/main.yml @@ -5,21 +5,12 @@ apt: name: - freeipa-client - - freeipa-admintools state: latest - update_cache: yes - -- name: "Check enrollment status" - become: yes - shell: | - cat /etc/ipa/default.conf | grep "^server = {{ freeipa.server }}$" && echo false - register: result - ignore_errors: true + - name: "Unenroll from enrolled server" become: yes - shell: ipa-client-install --uninstall - when: "'rc' in result and result.rc != 0" + shell: echo "no" | ipa-client-install --uninstall; rm -rf /var/lib/ipa-client/sysrestore.state ignore_errors: true - name: "Enroll server as a FreeIPA client" @@ -27,23 +18,23 @@ command: > ipa-client-install --unattended - --server {{ freeipa.server }} - --domain {{ freeipa.domain }} - --realm {{ freeipa.realm }} + --server {{ ipa.server }} + --domain {{ ipa.domain }} + --realm {{ ipa.realm }} --hostname {{ ansible_fqdn }} --principal admin - --password {{ freeipa.admin_password }} + --password {{ ipa.admin_password }} --ip-address {{ client.addresses | join('--ip-address ') }} --force-join --ssh-trust-dns register: result2 - when: "'rc' in result and result.rc != 0" + #when: "('rc' in result and result.rc != 0) or (force is defined and force is true) or true" - debug: msg="{{ result2.stdout }}" - when: "'rc' in result and result.rc != 0" + #when: "'rc' in result and result.rc != 0" - debug: msg="{{ result2.stderr }}" - when: "'rc' in result and result.rc != 0" + #when: "'rc' in result and result.rc != 0" - name: "Update nsswitch.conf to use Files, SSSD for auth" become: yes diff --git a/roles/keycloak-docker/tasks/main.yml b/roles/keycloak-docker/tasks/main.yml deleted file mode 100644 index 56f65f12..00000000 --- a/roles/keycloak-docker/tasks/main.yml +++ /dev/null @@ -1,35 +0,0 @@ ---- - -- name: Ensure keycloak dir - become: yes - file: - path: "{{ mount }}" - owner: root - group: root - mode: 0777 - state: directory - -- become: yes - copy: - content: "{{ realm }}" - dest: "{{ mount }}/realm.json" - mode: 0777 - -- docker_container: - name: keycloak - image: jboss/keycloak:9.0.3 - recreate: yes - env: - DB_VENDOR: h2 - KEYCLOAK_USER: "{{ keycloak.username }}" - KEYCLOAK_PASSWORD: "{{ keycloak.password }}" - KEYCLOAK_IMPORT: "/tmp/keycloak/realm.json" - KEYCLOAK_FRONTEND_URL: "{{ keycloak.hostname }}" - hostname: "{{ keycloak.hostname }}" - ports: - - "8080:8080" - volumes: - - "{{ mount }}/:/tmp/keycloak/" - - "/etc/localtime:/etc/localtime:ro" - # - "./backing-services/keycloak/krb5.keytab:/krb5.keytab" - # - "./backing-services/keycloak/themes/admin:/opt/jboss/keycloak/themes/admin" diff --git a/roles/minecraft/files/manifest.json b/roles/minecraft/files/manifest.json new file mode 100644 index 00000000..9fee105d --- /dev/null +++ b/roles/minecraft/files/manifest.json @@ -0,0 +1,488 @@ +{ + "minecraft": { + "version": "1.18.1", + "modLoaders": [ + { + "id": "forge-39.1.2", + "primary": true + } + ] + }, + "manifestType": "minecraftModpack", + "manifestVersion": 1, + "name": "Netsoc 2.0", + "author": "", + "files": [ + { + "projectID": 251767, + "fileID": 3547986, + "required": true + }, + { + "projectID": 291874, + "fileID": 3599020, + "required": true + }, + { + "projectID": 328085, + "fileID": 3706700, + "required": true + }, + { + "projectID": 388800, + "fileID": 3735785, + "required": true + }, + { + "projectID": 59613, + "fileID": 3681617, + "required": true + }, + { + "projectID": 352039, + "fileID": 3683190, + "required": true + }, + { + "projectID": 225643, + "fileID": 3664223, + "required": true + }, + { + "projectID": 461822, + "fileID": 3614629, + "required": true + }, + { + "projectID": 289712, + "fileID": 3711077, + "required": true + }, + { + "projectID": 404465, + "fileID": 3598890, + "required": true + }, + { + "projectID": 404468, + "fileID": 3657259, + "required": true + }, + { + "projectID": 422301, + "fileID": 3693291, + "required": true + }, + { + "projectID": 368293, + "fileID": 3649485, + "required": true + }, + { + "projectID": 392805, + "fileID": 3542929, + "required": true + }, + { + "projectID": 421770, + "fileID": 3629298, + "required": true + }, + { + "projectID": 567709, + "fileID": 3667659, + "required": true + }, + { + "projectID": 283644, + "fileID": 3647860, + "required": true + }, + { + "projectID": 486392, + "fileID": 3687357, + "required": true + }, + { + "projectID": 261924, + "fileID": 3606204, + "required": true + }, + { + "projectID": 513688, + "fileID": 3606078, + "required": true + }, + { + "projectID": 494206, + "fileID": 3662020, + "required": true + }, + { + "projectID": 225738, + "fileID": 3641681, + "required": true + }, + { + "projectID": 241895, + "fileID": 3666478, + "required": true + }, + { + "projectID": 282001, + "fileID": 3606346, + "required": true + }, + { + "projectID": 509285, + "fileID": 3634963, + "required": true + }, + { + "projectID": 399558, + "fileID": 3712395, + "required": true + }, + { + "projectID": 552176, + "fileID": 3550750, + "required": true + }, + { + "projectID": 411816, + "fileID": 3654853, + "required": true + }, + { + "projectID": 233019, + "fileID": 3543562, + "required": true + }, + { + "projectID": 577805, + "fileID": 3735766, + "required": true + }, + { + "projectID": 577252, + "fileID": 3651718, + "required": true + }, + { + "projectID": 314906, + "fileID": 3627154, + "required": true + }, + { + "projectID": 416294, + "fileID": 3647781, + "required": true + }, + { + "projectID": 274259, + "fileID": 3601938, + "required": true + }, + { + "projectID": 309927, + "fileID": 3661868, + "required": true + }, + { + "projectID": 231951, + "fileID": 3587149, + "required": true + }, + { + "projectID": 324973, + "fileID": 3648146, + "required": true + }, + { + "projectID": 563928, + "fileID": 3651452, + "required": true + }, + { + "projectID": 238086, + "fileID": 3670982, + "required": true + }, + { + "projectID": 351725, + "fileID": 3683687, + "required": true + }, + { + "projectID": 398521, + "fileID": 3739915, + "required": true + }, + { + "projectID": 359540, + "fileID": 3724479, + "required": true + }, + { + "projectID": 313866, + "fileID": 3712871, + "required": true + }, + { + "projectID": 254268, + "fileID": 3722113, + "required": true + }, + { + "projectID": 419699, + "fileID": 3728613, + "required": true + }, + { + "projectID": 74924, + "fileID": 3693897, + "required": true + }, + { + "projectID": 416935, + "fileID": 3613566, + "required": true + }, + { + "projectID": 220318, + "fileID": 3616582, + "required": true + }, + { + "projectID": 250398, + "fileID": 3648602, + "required": true + }, + { + "projectID": 438116, + "fileID": 3696703, + "required": true + }, + { + "projectID": 231484, + "fileID": 3606191, + "required": true + }, + { + "projectID": 429235, + "fileID": 3652644, + "required": true + }, + { + "projectID": 389697, + "fileID": 3620249, + "required": true + }, + { + "projectID": 404183, + "fileID": 3600701, + "required": true + }, + { + "projectID": 401955, + "fileID": 3704010, + "required": true + }, + { + "projectID": 288885, + "fileID": 3639779, + "required": true + }, + { + "projectID": 248787, + "fileID": 3686482, + "required": true + }, + { + "projectID": 363535, + "fileID": 3681610, + "required": true + }, + { + "projectID": 230976, + "fileID": 3590415, + "required": true + }, + { + "projectID": 531761, + "fileID": 3658029, + "required": true + }, + { + "projectID": 238222, + "fileID": 3723162, + "required": true + }, + { + "projectID": 348521, + "fileID": 3641133, + "required": true + }, + { + "projectID": 363569, + "fileID": 3712017, + "required": true + }, + { + "projectID": 439890, + "fileID": 3725854, + "required": true + }, + { + "projectID": 306770, + "fileID": 3630725, + "required": true + }, + { + "projectID": 546841, + "fileID": 3570790, + "required": true + }, + { + "projectID": 299540, + "fileID": 3639777, + "required": true + }, + { + "projectID": 312353, + "fileID": 3665638, + "required": true + }, + { + "projectID": 71738, + "fileID": 3681606, + "required": true + }, + { + "projectID": 378646, + "fileID": 3683707, + "required": true + }, + { + "projectID": 351914, + "fileID": 3640643, + "required": true + }, + { + "projectID": 534610, + "fileID": 3717756, + "required": true + }, + { + "projectID": 400933, + "fileID": 3682900, + "required": true + }, + { + "projectID": 426558, + "fileID": 3709855, + "required": true + }, + { + "projectID": 351938, + "fileID": 3680290, + "required": true + }, + { + "projectID": 347488, + "fileID": 3625421, + "required": true + }, + { + "projectID": 368098, + "fileID": 3642415, + "required": true + }, + { + "projectID": 362528, + "fileID": 3613621, + "required": true + }, + { + "projectID": 429371, + "fileID": 3584653, + "required": true + }, + { + "projectID": 60089, + "fileID": 3578801, + "required": true + }, + { + "projectID": 223852, + "fileID": 3611505, + "required": true + }, + { + "projectID": 256717, + "fileID": 3616324, + "required": true + }, + { + "projectID": 231095, + "fileID": 3673005, + "required": true + }, + { + "projectID": 388172, + "fileID": 3629661, + "required": true + }, + { + "projectID": 502372, + "fileID": 3683039, + "required": true + }, + { + "projectID": 263420, + "fileID": 3663017, + "required": true + }, + { + "projectID": 331936, + "fileID": 3642713, + "required": true + }, + { + "projectID": 453925, + "fileID": 3682819, + "required": true + }, + { + "projectID": 555300, + "fileID": 3646956, + "required": true + }, + { + "projectID": 465066, + "fileID": 3580591, + "required": true + }, + { + "projectID": 485681, + "fileID": 3579662, + "required": true + }, + { + "projectID": 560323, + "fileID": 3580119, + "required": true + }, + { + "projectID": 363703, + "fileID": 3559400, + "required": true + }, + { + "projectID": 570354, + "fileID": 3614046, + "required": true + } + ], + "overrides": "overrides" +} \ No newline at end of file diff --git a/roles/minecraft/files/server-icon.png b/roles/minecraft/files/server-icon.png new file mode 100644 index 00000000..3b546488 Binary files /dev/null and b/roles/minecraft/files/server-icon.png differ diff --git a/roles/minecraft/files/server.properties b/roles/minecraft/files/server.properties new file mode 100644 index 00000000..30ef6757 --- /dev/null +++ b/roles/minecraft/files/server.properties @@ -0,0 +1,51 @@ +allow-flight=true +allow-nether=true +broadcast-console-to-ops=true +broadcast-rcon-to-ops=true +difficulty=hard +enable-command-block=true +enable-jmx-monitoring=false +enable-query=false +enable-rcon=true +enable-status=true +enforce-whitelist=false +entity-broadcast-range-percentage=100 +force-gamemode=false +function-permission-level=2 +gamemode=survival +generate-structures=true +generator-settings= +hardcore=false +level-name=world +level-seed= +level-type=minecraft\:normal +max-players=20 +max-tick-time=-1 +max-world-size=10000 +motd=UCC Netsoc's Minecraft Server - Download modpack at http://minecraft.netsoc.co +network-compression-threshold=256 +online-mode=true +op-permission-level=4 +player-idle-timeout=0 +prevent-proxy-connections=false +pvp=true +query.port=25565 +rate-limit=0 +rcon.password=minecraft +rcon.port=25575 +resource-pack= +resource-pack-sha1= +server-ip= +server-name=Netcraft +server-port=25565 +snooper-enabled=true +spawn-animals=true +spawn-monsters=true +spawn-npcs=true +spawn-protection=16 +sync-chunk-writes=true +text-filtering-config= +texture-pack= +use-native-transport=true +view-distance=10 +white-list=false \ No newline at end of file diff --git a/roles/mysql-server-docker/tasks/main.yml b/roles/mysql-server-docker/tasks/main.yml deleted file mode 100644 index 0a1b1a2d..00000000 --- a/roles/mysql-server-docker/tasks/main.yml +++ /dev/null @@ -1,26 +0,0 @@ ---- - -- name: Ensure mysql dir - become: yes - file: - path: "{{ mount }}/" - owner: root - group: root - # needs to 775 as this folder is accessed internally by a dirsrv user - # https://github.com/freeipa/freeipa-container/issues/281 - mode: 0777 - state: directory - -- name: Ensure MySQL server container - become: yes - docker_container: - name: "{{ container_name }}" - state: started - recreate: yes - image: mysql:8.0.20 - env: - MYSQL_ROOT_PASSWORD: "{{ root_password }}" - volumes: - - "{{ mount }}/:/var/lib/mysql" - ports: - - "{{ ip }}:{{ port | default(3306) }}:3306" \ No newline at end of file diff --git a/roles/netsoc.co/tasks/main.yml b/roles/netsoc.co/tasks/main.yml new file mode 100644 index 00000000..6816a526 --- /dev/null +++ b/roles/netsoc.co/tasks/main.yml @@ -0,0 +1,40 @@ +--- +- name: Ensure netsoc.co Docker Container + become: yes + docker_stack: + state: present + name: netsoc_co + compose: + - version: "3.7" + services: + live: + image: uccnetsoc/netsoc.co:latest + networks: + traefik: + deploy: + mode: replicated + replicas: 1 + labels: + - "traefik.enable=true" + - "traefik.http.routers.netsoc_co.rule=Host(`{{ co_site }}`) || Host(`www.{{ co_site }}`)" + - "traefik.http.routers.netsoc_co.entrypoints=web-secure" + - "traefik.http.routers.netsoc_co.tls.certResolver=letsencrypt" + - "traefik.http.services.netsoc_co-service.loadbalancer.server.port=80" + - "traefik.http.routers.netsoc_co.service=netsoc_co-service" + - "traefik.http.middlewares.rk-redirect.redirectregex.regex=^https://{{ co_site }}/(r(?:[^k].*)|[^r].*)?$$" + - "traefik.http.middlewares.rk-redirect.redirectregex.replacement=https://{{ co_site }}/rk/$${1}" + - "traefik.http.middlewares.rk-redirect.redirectregex.permanent=true" + - "traefik.http.middlewares.rk-strip.stripprefix.prefixes=/rk" + - "traefik.http.middlewares.www-redirect.redirectregex.regex=^https://www.{{ co_site }}/(.*)" + - "traefik.http.middlewares.www-redirect.redirectregex.replacement=https://{{ co_site }}/$${1}" + - "traefik.http.middlewares.www-redirect.redirectregex.permanent=true" + - "traefik.http.routers.netsoc_co.middlewares=rk-redirect@docker,rk-strip@docker,www-redirect@docker" + - "traefik.docker.network=traefik" + restart_policy: + condition: any + delay: 5s + max_attempts: 5 + networks: + traefik: + external: true + diff --git a/roles/netsocadmin2/tasks/main.yml b/roles/netsocadmin2/tasks/main.yml new file mode 100644 index 00000000..62c38dfa --- /dev/null +++ b/roles/netsocadmin2/tasks/main.yml @@ -0,0 +1,51 @@ +--- +- name: Login to registry + become: true + docker_login: + registry: "{{ docker_registry }}" + username: "{{ docker_registry_username }}" + password: "{{ docker_registry_password }}" + +- name: Install NetsocAdmin2 + become: yes + docker_stack: + name: netsocadmin2 + with_registry_auth: true + state: present + compose: + - version: "3.7" + services: + server: + image: uccnetsoc/netsocadmin + hostname: admin.netsoc.co + volumes: + - "/media/odin/admin.netsoc.co/storage/backups:/backups" + - "/home/users:/home/users" + # - "/netsoc/netsocadmin2/wordpress_installer_config.py:/netsocadmin/wordpress_installer/wordpress_installer/config.py" + # - "/netsoc/netsocadmin2/admin_passwords.py:/netsocadmin/webapp/passwords.py" + - "/netsoc/netsocadmin2/config.py:/netsocadmin/netsocadmin/config.py" + - "/netsoc/netsocadmin2/.uri.db:/netsocadmin/netsocadmin/.uri.db" + networks: + traefik: + deploy: + mode: global + placement: + constraints: + - node.hostname == leela + preferences: + - spread: node.id + labels: + - "traefik.enable=true" + - "traefik.http.routers.netsocadmin2.rule=Host(`admin.{{ co_site }}`)" + - "traefik.http.routers.netsocadmin2.entrypoints=web-secure" + - "traefik.http.routers.netsocadmin2.tls.certResolver=letsencrypt" + - "traefik.http.services.netsocadmin2-service.loadbalancer.server.port=5050" + - "traefik.http.routers.netsocadmin2.service=netsocadmin2-service" + - "traefik.docker.network=traefik" + restart_policy: + condition: any + delay: 5s + max_attempts: 5 + networks: + traefik: + external: true \ No newline at end of file diff --git a/roles/nfs-client-requirements/tasks/main.yml b/roles/nfs-client-requirements/tasks/main.yml deleted file mode 100644 index 1e970a38..00000000 --- a/roles/nfs-client-requirements/tasks/main.yml +++ /dev/null @@ -1,78 +0,0 @@ ---- - -- name: Ensure nfs-common - apt: - name: nfs-common - state: latest - -- name: Ensure autofs - apt: - name: autofs - state: latest - -- name: "Setup client as using NFS service and keytab" - become: yes - shell: | - #!/bin/bash - echo '{{ freeipa.admin_password }}' | kinit admin -l 0h1m - - if [ $? -eq 1 ]; then - echo "Invalid IPA password" - exit 1; - fi - - (echo 'nfs/{{ ansible_fqdn }}' | ipa service-show) - - if [ $? -ne 0 ]; then - echo "Could not find service nfs/{{ ansible_fqdn }}, adding as a service" - ipa service-add 'nfs/{{ ansible_fqdn }}' - fi - - ipa-getkeytab -s {{ freeipa.server }} -p nfs/{{ ansible_fqdn }} -k /etc/krb5.keytab - args: - executable: /bin/bash - register: result - -- debug: - msg: "{{result.stdout}}" -- debug: - msg: "{{result.stderr}}" - -- name: "Setup IPA automount config" - become: yes - shell: echo 'yes' | ipa-client-automount - ignore_errors: yes - register: result - -- name: "Setup idmapd.conf" - become: yes - copy: - content: "{{ idmap }}" - dest: /etc/idmapd.conf - -- debug: - msg: "{{result.stdout}}" -- debug: - msg: "{{result.stderr}}" - -- name: Enable service rpcbind - become: yes - service: - name: rpcbind - enabled: yes - state: restarted - -- name: Enable service rpc-gssd - become: yes - service: - name: rpc-gssd - enabled: yes - state: restarted - ignore_errors: yes - -- name: Enable service rpc-gssd - become: yes - service: - name: nfs-client.target - enabled: yes - state: restarted \ No newline at end of file diff --git a/roles/nfs4-server-krb5/tasks/main.yml b/roles/nfs4-server-krb5/tasks/main.yml deleted file mode 100644 index 011d26c5..00000000 --- a/roles/nfs4-server-krb5/tasks/main.yml +++ /dev/null @@ -1,75 +0,0 @@ -- name: "Install packages" - become: yes - apt: - name: - - nfs-kernel-server - - nfs-common - state: latest - -- name: "Create exports file" - become: yes - copy: - content: | - {{ exports }} - dest: "/etc/exports" - -- become: yes - name: "Create idmap.conf file" - copy: - content: | - {{ idmap }} - dest: "/etc/idmap.conf" - -- become: yes - lineinfile: - path: /etc/default/nfs-kernel-server - state: present - regexp: "^{{ item }}" - line: "{{ item }}=yes" - with_items: - - NEED_IDMAPD - - NEED_GSSD - - NEED_SVCGSSD - -- become: yes - lineinfile: - path: /etc/default/nfs-common - state: present - regexp: "^{{ item }}" - line: "{{ item }}=yes" - with_items: - - NEED_IDMAPD - - NEED_GSSD - - NEED_SVCGSSD - -- become: yes - modprobe: - name: "{{ item }}" - state: present - with_items: - - rpcsec_gss_krb5 - - nfs - - nfsd - -- become: yes - lineinfile: - path: /etc/modules - state: present - regexp: "^{{ item }}" - line: "{{ item }}" - with_items: - - rpcsec_gss_krb5 - - nfs - - nfsd - -- become: yes - shell: exportfs -va - -- name: Enable service - service: - name: "{{ item }}" - enabled: yes - state: restarted - with_items: - - nfs-kernel-server - - rpc-gssd \ No newline at end of file diff --git a/roles/packer-provisioning-dhcp-bridge/defaults/main.yml b/roles/packer-provisioning-dhcp-bridge/defaults/main.yml deleted file mode 100644 index bf6ab898..00000000 --- a/roles/packer-provisioning-dhcp-bridge/defaults/main.yml +++ /dev/null @@ -1,12 +0,0 @@ -bridge_interface: "vmbr1" -bridge_address: "10.0.100.1" -bridge_netmask: "24" -nat_interface: "vmbr0.20" -dhcp_range_begin: "10.0.100.3" -dhcp_range_end: "10.0.100.255" -dhcp_netmask: "255.255.255.0" -dhcp_lease_length: "24h" -dhcp_dns_servers: "8.8.8.8,8.8.4.4" - -# time.nist.gov -dhcp_ntp_servers: "129.6.15.28,129.6.15.29,129.6.15.30" \ No newline at end of file diff --git a/roles/packer-provisioning-dhcp-bridge/files/proxmox.conf.j2 b/roles/packer-provisioning-dhcp-bridge/files/proxmox.conf.j2 deleted file mode 100644 index 01192e8f..00000000 --- a/roles/packer-provisioning-dhcp-bridge/files/proxmox.conf.j2 +++ /dev/null @@ -1,14 +0,0 @@ -# Disable DNS -port=0 - -interface={{ bridge_interface }} -dhcp-authoritative - -bind-interfaces -domain=netsoc.co -# start, end, netmask -dhcp-range={{ dhcp_range_begin }},{{ dhcp_range_end }},{{ dhcp_netmask }},{{ dhcp_lease_length }} - -dhcp-option=option:router,{{ bridge_address }} -dhcp-option=option:ntp-server,{{ dhcp_ntp_servers }} -dhcp-option=option:dns-server,{{ dhcp_dns_servers }} \ No newline at end of file diff --git a/roles/packer-provisioning-dhcp-bridge/tasks/main.yml b/roles/packer-provisioning-dhcp-bridge/tasks/main.yml deleted file mode 100644 index efc68ce7..00000000 --- a/roles/packer-provisioning-dhcp-bridge/tasks/main.yml +++ /dev/null @@ -1,38 +0,0 @@ -- name: Add dnsmasq - apt: - name: dnsmasq - state: latest - -- name: Enable dnsmasq conf dir - shell: echo 'conf-dir=/etc/dnsmasq.d/,*.conf' >> /etc/dnsmasq.conf - -- name: Template proxmox.conf (dnsmasq entries) - template: - src: "files/proxmox.conf.j2" - dest: "/etc/dnsmasq.d/proxmox.conf" - -- name: Insert bridge into /etc/network/interfaces.d - copy: - path: /etc/network/interfaces.d/01-packer-provisioning-dhcp-bridge - content: | - # Packer provisioning subnetwork - auto {{ bridge_interface }} - iface {{ bridge_interface }} inet static - - address {{ bridge_address }} - netmask {{ bridge_netmask }} - bridge_ports none - bridge_stp off - bridge_fd 0 - post-up echo 1 > /proc/sys/net/ipv4/ip_forward - post-up iptables -t nat -A POSTROUTING -s '{{ bridge_address }}/{{ bridge_netmask }}' -o {{ nat_interface }} -j MASQUERADE - post-up iptables -t raw -I PREROUTING -i fwbr+ -j CT --zone 1 - post-down iptables -t nat -D POSTROUTING -s '{{ bridge_address }}/{{ bridge_netmask }}' -o {{ nat_interface }} -j MASQUERADE && iptables -t raw -D PREROUTING -i fwbr+ -j CT --zone 1 - -- name: Reload networking - command: ifreload -a - -- name: Start dnsmasq - systemd: - name: dnsmasq - state: restarted diff --git a/roles/packer-proxmox-template/defaults/main.yml b/roles/packer-proxmox-template/defaults/main.yml deleted file mode 100644 index 5a99a92e..00000000 --- a/roles/packer-proxmox-template/defaults/main.yml +++ /dev/null @@ -1,4 +0,0 @@ -proxmox_api_url: "https://{{ build_host }}:8006/api2/json" -proxmox_node: "{{ build_host }}" -http_bind_address: "10.0.100.1" -cloudinit: yes \ No newline at end of file diff --git a/roles/packer-proxmox-template/tasks/main.yml b/roles/packer-proxmox-template/tasks/main.yml deleted file mode 100644 index 498fe35d..00000000 --- a/roles/packer-proxmox-template/tasks/main.yml +++ /dev/null @@ -1,264 +0,0 @@ - -- name: Build Host - Ensure dnsmasq/dhcp running - become: yes - service: - name: dnsmasq - state: started - when: "inventory_hostname == build_host" - -- name: Build Host - Ensure pacer directory on server - become: yes - file: - path: /tmp/NaC/packer - state: directory - mode: '0700' - when: "inventory_hostname == build_host" - -- name: Build Host - Ensure packer directory files copied to server - become: yes - synchronize: - src: "./{{ build_directory }}" - dest: "/tmp/NaC/packer/." - when: "inventory_hostname == build_host" - -- name: Build Host - Ensure any templates in the root of the packer directory are templated - become: yes - template: - src: "{{ item }}" - dest: "/tmp/NaC/{{ build_directory }}/{{ item | basename | regex_replace('\\.j2', '') }}" - with_fileglob: - - "./{{ build_directory }}/*.j2" - when: "inventory_hostname == build_host" - -# We need to start a HTTP server that serves any provisoning files -# The reason we do this rather than rely on Packer's HTTP server -# is because it does not bind to the ip on the vmbr1 interface -# Packer's HTTP server picks the first IP to bind from and this would typically be on -# the main network. We want to use an internal network isntead -# Generate port -- name: Build Host - Generate HTTP server port - set_fact: - http_port: "{{ range(35000, 65355) | random }}" - when: "inventory_hostname == build_host" - -- name: Build Host - Fork Python HTTP server in local directory" - become: yes - raw: nohup bash -c 'python3 -m http.server {{ http_port }} --bind {{ http_bind_address }} -d /tmp/NaC/{{ build_directory }} >/dev/null 2>&1 &' - register: http_pid_result - when: "inventory_hostname == build_host" - -# Because packer doesn't yet support ceph/rbd we need to generate a template on every Proxmox host -# If two packers execute at the exact same time, they will both retrieve the same id to create the disk -# for their VM and conflict -# Therefore we hash the template_name + the proxmox hostname and get a predictable vm id -- name: All Hosts - Generate VM ID for each template - set_fact: - vm_id_generated: "{{ range(1000, 5000000) | random(seed=template_name+'-'+inventory_hostname) }}" - -- debug: - msg: "{{ vm_id_generated }}" - -# We need to build up the command line args we pass to packer -# We pass in template name (for the respective proxmox host), -# HTTP server and port -# Proxmox creds -- name: Build Host - Build Packer arguments - set_fact: - packer_arguments: " " - when: "inventory_hostname == build_host" - -- name: Build Host - Build Packer arguments - set_fact: - packer_arguments: "{{ packer_arguments }} -var 'vm_id={{ vm_id_generated }}' " - when: "inventory_hostname == build_host" - -- name: Build Host - Build Packer arguments - set_fact: - packer_arguments: "{{ packer_arguments }} -var 'vm_name=packer-{{ template_name }}-{{ inventory_hostname }}' " - when: "inventory_hostname == build_host" - -- name: Build Host - Build Packer arguments - set_fact: - packer_arguments: "{{ packer_arguments }} -var 'template_name={{ template_name }}-{{ inventory_hostname }}' " - when: "inventory_hostname == build_host" - -- name: Build Host - Build Packer arguments - set_fact: - packer_arguments: "{{ packer_arguments }} -var 'http_base_url=http://{{ http_bind_address }}:{{ http_port }}' " - when: "inventory_hostname == build_host" - -- name: Build Host - Build Packer arguments - set_fact: - packer_arguments: "{{ packer_arguments }} -var 'proxmox_api_url={{ proxmox_api_url }}' " - when: "inventory_hostname == build_host" - -- name: Build Host - Build Packer arguments - set_fact: - packer_arguments: "{{ packer_arguments }} -var 'proxmox_username={{ proxmox.username }}' " - when: "inventory_hostname == build_host" - -- name: Build Host - Build Packer arguments - set_fact: - packer_arguments: "{{ packer_arguments }} -var 'proxmox_password={{ proxmox.password }}' " - when: "inventory_hostname == build_host" - -- name: Build Host - Build Packer arguments - set_fact: - packer_arguments: "{{ packer_arguments }} -var 'proxmox_node={{ proxmox_node }}' " - when: "inventory_hostname == build_host" - -# Then add any vars they passed in packer -- name: Build Host - Build Packer arguments - set_fact: - packer_arguments: "{{ packer_arguments }} -var '{{ item.key }}={{ item.value }}' " - loop: "{{ packer | dict2items }}" - when: "packer is defined and inventory_hostname == build_host" - -- name: Provisioning & Cluster Hosts - Remove a previous template if it exists - proxmox_kvm: - api_user: "{{ proxmox.username }}" - api_password: "{{ proxmox.password }}" - api_host: "{{ proxmox_node }}" - name: "{{ template_name }}-{{ inventory_hostname }}" - state: absent - ignore_errors: true - -- name: Provisioning & Cluster Hosts - Stop a previous building template if it exists - proxmox_kvm: - api_user: "{{ proxmox.username }}" - api_password: "{{ proxmox.password }}" - api_host: "{{ proxmox_node }}" - name: "packer-{{ template_name }}-{{ inventory_hostname }}" - state: stopped - force: yes - ignore_errors: true - -- name: Provisioning & Cluster Hosts - Remove a previous building template if it exists - proxmox_kvm: - api_user: "{{ proxmox.username }}" - api_password: "{{ proxmox.password }}" - api_host: "{{ proxmox_node }}" - name: "packer-{{ template_name }}-{{ inventory_hostname }}" - state: absent - ignore_errors: true - - -- name: Build Host - Call packer - become: yes - command: - chdir: "/tmp/NaC/{{ build_directory }}" - cmd: "packer build {{ packer_arguments }} packer.json" - register: io - when: "inventory_hostname == build_host" - -- name: Build Host - Kill HTTP server - shell: kill -9 `lsof -wni tcp:{{ http_port }} | tail -n +2 | cut -d' ' -f 2` - when: "inventory_hostname == build_host" - -- debug: - msg: "{{ io.stdout.split('\n') }}" - when: "inventory_hostname == build_host" - -- debug: - msg: "{{ io.stderr.split('\n') }}" - when: "inventory_hostname == build_host" - -# We need to get the VM id from the list, if there was a collision with the ID we generated it uses the next free one -- name: Build Host - Get created Packer VM ID - raw: qm list | tail -n +2 | awk '{ if($2=="{{ template_name }}-{{ inventory_hostname }}") print $1 }' - register: vm_id_result - when: "inventory_hostname == build_host" - -- set_fact: - vm_id: "{{ vm_id_result.stdout | trim }}" - when: "inventory_hostname == build_host" - -- name: Build Host - Add serial console to created VM (not handled by packer yet) - become: yes - command: - cmd: qm set {{ vm_id }} -serial0 socket - when: "inventory_hostname == build_host" - -- name: All Hosts - Make template vzdump location - become: yes - file: - path: "/tmp/packer-proxmox-template-{{ vm_id }}" - state: absent - when: "inventory_hostname == build_host" - -- name: All Hosts - Make template vzdump location - become: yes - file: - path: "/tmp/packer-proxmox-template-{{ vm_id }}" - state: directory - owner: root - group: root - mode: '0755' - when: "inventory_hostname == build_host" - -- name: Build Host - VZDump the created template - shell: "vzdump {{ vm_id }} --dumpdir /tmp/packer-proxmox-template-{{ vm_id }}" - when: "inventory_hostname == build_host" - -- name: Build Host - Rename dump file from timestamp generated to known file - shell: "mv /tmp/packer-proxmox-template-{{ vm_id }}/*.vma /tmp/packer-proxmox-template-{{ vm_id }}/vm.vma" - when: "inventory_hostname == build_host" - -- name: Cluster Hosts - Pull the VZDump from the Build Host - Create Dir - file: - path: "/tmp/packer-proxmox-template-{{ hostvars[item]['vm_id_generated'] }}/" - state: directory - delegate_to: "{{ item }}" - with_items: "{{ ansible_play_hosts | select('ne', inventory_hostname) | list }}" - when: "inventory_hostname == build_host" - -# Copy the VZDump from the provisioning host into a directory on each of the cluster hosts with the id changed to it's generated one -- name: Cluster Hosts - Pull the VZDump from the Build Host - synchronize: - src: "/tmp/packer-proxmox-template-{{ hostvars[build_host]['vm_id'] }}/vm.vma" - dest: "/tmp/packer-proxmox-template-{{ hostvars[item]['vm_id_generated'] }}/vm.vma" - mode: pull - delegate_to: "{{ item }}" - with_items: "{{ ansible_play_hosts | select('ne', inventory_hostname) | list }}" - when: "inventory_hostname == build_host" - -- name: Cluster Hosts - Restore VZDump on the server, creating the template - shell: > - qmrestore - /tmp/packer-proxmox-template-{{ vm_id_generated }}/vm.vma - {{ vm_id_generated }} - when: "inventory_hostname != build_host" - -# The VM we restore will have the template name + the hostname of the provisioning host -# We need to rename this to the template name + the hostname of the cluster host or conflicts will occur - -# Get ID of VM we stored -- name: Cluster Hosts - Get restored VZDump VM ID - raw: qm list | tail -n +2 | awk '{ if($2=="{{ template_name }}-{{ build_host }}") print $1 }' - register: restored_vm_id_result - when: "inventory_hostname != build_host" - -- set_fact: - restored_vm_id: "{{ restored_vm_id_result.stdout | trim }}" - when: "inventory_hostname != build_host" - -# Rename VM - -- name: Cluster Hosts - Renamed restored VM to match the hostname of the machine it was restored onto - shell: > - qm set {{ restored_vm_id }} - --name "{{ template_name }}-{{ inventory_hostname }}" - when: "inventory_hostname != build_host" - -- name: Build Hosts - Delete template vzdump location - become: yes - file: - path: "/tmp/packer-proxmox-template-{{ hostvars[build_host]['vm_id'] }}" - state: absent - -- name: Cluster Hosts - Delete template vzdump location - become: yes - file: - path: "/tmp/packer-proxmox-template-{{ hostvars[build_host]['vm_id_generated'] }}" - state: absent - when: "inventory_hostname != build_host" \ No newline at end of file diff --git a/roles/packer/tasks/main.yml b/roles/packer/tasks/main.yml index 9d8304d6..5eeb190c 100644 --- a/roles/packer/tasks/main.yml +++ b/roles/packer/tasks/main.yml @@ -4,9 +4,9 @@ name: unzip state: present -- name: Ensure Packer 1.5.5 +- name: Ensure Packer 1.6.5 unarchive: - src: https://releases.hashicorp.com/packer/1.5.6/packer_1.5.6_linux_amd64.zip + src: https://releases.hashicorp.com/packer/1.6.5/packer_1.6.5_linux_amd64.zip dest: /usr/local/bin mode: +x remote_src: yes \ No newline at end of file diff --git a/roles/portainer/README.md b/roles/portainer/README.md new file mode 100644 index 00000000..66817830 --- /dev/null +++ b/roles/portainer/README.md @@ -0,0 +1,5 @@ +Portainer +========= + +Swarm support coming soon + diff --git a/roles/portainer/tasks/main.yml b/roles/portainer/tasks/main.yml new file mode 100644 index 00000000..29605b25 --- /dev/null +++ b/roles/portainer/tasks/main.yml @@ -0,0 +1,81 @@ +--- + + +- set_fact: + unique_name: "{{ portainer.hostname | regex_replace('\\.','_') }}" + +- name: Ensure mount exists with 0755 + become: yes + file: + path: "{{ mount }}/" + owner: root + group: root + mode: 0755 + state: directory + +- name: Ensure Portainer Docker network + become: yes + docker_network: + name: portainer + driver: overlay + attachable: yes + + +- name: Ensure Portainer Web UI + Agents + become: yes + docker_stack: + name: "{{ unique_name }}" + state: present + compose: + - version: "3.5" + services: + webui: + image: portainer/portainer + volumes: + - "{{mount}}/:/data" + - /var/run/docker.sock:/var/run/docker.sock + command: -H tcp://tasks.agent:9001 --tlsskipverify + ports: + - target: 8000 + published: 8001 + protocol: tcp + mode: host + - target: 9000 + published: 9000 + protocol: tcp + mode: host + networks: + portainer: + traefik: + deploy: + mode: global + labels: + - "traefik.enable=true" + - "traefik.http.routers.{{ unique_name }}.rule=Host(`{{ portainer.hostname }}`)" + - "traefik.http.routers.{{ unique_name }}.entrypoints=web-secure" + - "traefik.http.routers.{{ unique_name }}.tls.certResolver=letsencrypt" + - "traefik.http.routers.{{ unique_name }}.service={{ unique_name }}" + - "traefik.http.services.{{ unique_name }}.loadbalancer.server.port=9000" + - "traefik.docker.network=traefik" + agent: + restart: always + image: portainer/agent + environment: + AGENT_CLUSTER_ADDR: tasks.agent + volumes: + - /var/run/docker.sock:/var/run/docker.sock + - /var/lib/docker/volumes:/var/lib/docker/volumes + ports: + - target: 9001 + published: 9001 + protocol: tcp + mode: host + networks: + portainer: + deploy: + mode: global + networks: + traefik: + external: true + portainer: + external: true diff --git a/roles/prometheus-exporter/files/prometheus_exporter_exporter.service b/roles/prometheus-exporter/files/prometheus_exporter_exporter.service new file mode 100644 index 00000000..44a82f9a --- /dev/null +++ b/roles/prometheus-exporter/files/prometheus_exporter_exporter.service @@ -0,0 +1,14 @@ +[Unit] +Description=Prometheus Node Exporter +After=network.target + +[Service] +Type=simple +User=exp-exp +Group=exp-exp +ExecStart=/usr/local/bin/exporter_exporter -config.file /etc/exporter_exporter.yaml +SyslogIdentifier=prometheus_exporter_exporter +Restart=always + +[Install] +WantedBy=multi-user.target \ No newline at end of file diff --git a/roles/prometheus-exporter/tasks/exporter_exporter.yml b/roles/prometheus-exporter/tasks/exporter_exporter.yml new file mode 100644 index 00000000..1c215cbe --- /dev/null +++ b/roles/prometheus-exporter/tasks/exporter_exporter.yml @@ -0,0 +1,50 @@ +- name: "Create exp-exp user" + become: yes + user: + name: exp-exp + shell: /usr/sbin/nologin + system: true + create_home: false + home: / + +- name: "Download Exporter Exporter" + get_url: + url: https://github.com/QubitProducts/exporter_exporter/releases/download/v0.4.0/exporter_exporter-0.4.0.linux-amd64.tar.gz + checksum: sha1:10cc48ea8baeeab63d830fe15071105636ee7468 + dest: /tmp/exp_exp.tar.gz + +- name: "Unarchive Exporter Exporter" + unarchive: + src: /tmp/exp_exp.tar.gz + dest: /tmp/ + remote_src: yes + +- name: "Copy Exporter Exporter to /usr/local/bin" + become: yes + copy: + src: /tmp/exporter_exporter-0.4.0.linux-amd64/exporter_exporter + dest: /usr/local/bin/exporter_exporter + remote_src: yes + mode: 0770 + owner: exp-exp + group: exp-exp + +- name: "Copy systemd unit file" + become: yes + copy: + src: "files/prometheus_exporter_exporter.service" + dest: "/etc/systemd/system/prometheus_exporter_exporter.service" + +- name: "Generate config" + become: yes + template: + src: "templates/exporter_exporter.yaml.j2" + dest: "/etc/exporter_exporter.yaml" + +- name: "Enable systemd service" + become: yes + systemd: + name: "prometheus_exporter_exporter" + daemon_reload: yes + enabled: yes + state: restarted \ No newline at end of file diff --git a/roles/prometheus-exporter/tasks/main.yml b/roles/prometheus-exporter/tasks/main.yml new file mode 100644 index 00000000..a39810b2 --- /dev/null +++ b/roles/prometheus-exporter/tasks/main.yml @@ -0,0 +1,59 @@ +--- + +- name: Node Exporter + include_role: + name: cloudalchemy.node-exporter + vars: + node_exporter_enabled_collectors: # enabled in addition to default collectors + - ntp + - systemd + +- name: Cadvisor + when: "'prometheus_docker' in group_names" + become: yes + docker_container: + name: cadvisor + image: "google/cadvisor:v0.33.0" + command: + - "--docker_only" + - "--housekeeping_interval=15s" + - "--disable_metrics disk,tcp,udp" + state: started + restart_policy: always + ports: + - "9338:8080" + volumes: + - "/:/rootfs:ro" + - "/var/run:/var/run:rw" + - "/sys:/sys:ro" + - "/var/lib/docker/:/var/lib/docker:ro" + - "/dev/disk/:/dev/disk:ro" + +- name: IPMI Exporter + when: "'prometheus_ipmi' in group_names" + become: yes + docker_container: + name: ipmi_exporter + image: "uccnetsoc/ipmi_exporter" + pull: true + state: started + restart_policy: on-failure + ports: + - "9289:9289" + devices: + - "/dev/ipmi0" + +- name: Apache Prometheus Exporter + when: "'prometheus_apache' in group_names" + become: yes + docker_container: + name: prometheus_apache + image: "lusotycoon/apache-exporter:v0.8.0" + command: ["-scrape_uri", "http://{{ ansible_host }}/server-status/?auto"] + state: started + restart_policy: on-failure + ports: + - "9117:9117" + +- name: Exporter Exporter + include_tasks: "exporter_exporter.yml" diff --git a/roles/prometheus-exporter/templates/exporter_exporter.yaml.j2 b/roles/prometheus-exporter/templates/exporter_exporter.yaml.j2 new file mode 100644 index 00000000..64ec7873 --- /dev/null +++ b/roles/prometheus-exporter/templates/exporter_exporter.yaml.j2 @@ -0,0 +1,40 @@ +modules: + node: + method: http + http: + port: 9100 + +{% if 'prometheus_docker' in group_names %} + cadvisor: + method: http + http: + port: 9338 +{% endif %} + +{% if 'prometheus_ipmi' in group_names %} + ipmi: + method: http + http: + port: 9289 +{% endif %} + +{% if 'prometheus_apache' in group_names %} + apache: + method: http + http: + port: 9117 +{% endif %} + +{% if inventory_hostname == 'minecraft.infra.netsoc.co' %} + minecraft: + method: http + http: + port: 19565 +{% endif %} + +{% if 'prometheus_traefik' in group_names %} + traefik: + method: http + http: + port: 8082 +{% endif %} \ No newline at end of file diff --git a/roles/prometheus-server/defaults/main.yml b/roles/prometheus-server/defaults/main.yml new file mode 100644 index 00000000..96870e82 --- /dev/null +++ b/roles/prometheus-server/defaults/main.yml @@ -0,0 +1,3 @@ +prometheus_dir: "/mnt/data-disk/prometheus" +blackbox_exporter_dir: "/mnt/data-disk/blackbox_exporter" +pve_dir: "/mnt/data-disk/pve" \ No newline at end of file diff --git a/roles/prometheus-server/files/blackbox_exporter.yaml b/roles/prometheus-server/files/blackbox_exporter.yaml new file mode 100644 index 00000000..68a32607 --- /dev/null +++ b/roles/prometheus-server/files/blackbox_exporter.yaml @@ -0,0 +1,9 @@ +modules: + http_2xx: + prober: http + http_2xx_traefik_auth: + prober: http + http: + basic_auth: + username: "{{ traefik.username }}" + password: "{{ traefik.password }}" \ No newline at end of file diff --git a/roles/prometheus-server/handlers/main.yml b/roles/prometheus-server/handlers/main.yml new file mode 100644 index 00000000..640585d6 --- /dev/null +++ b/roles/prometheus-server/handlers/main.yml @@ -0,0 +1,20 @@ +- name: restart prometheus + become: yes + docker_container: + name: prometheus + state: started + restart: true + +- name: restart blackbox exporter + become: yes + docker_container: + name: blackbox_exporter + state: started + restart: true + +- name: restart pve exporter + become: yes + docker_container: + name: pve-exporter + state: started + restart: true \ No newline at end of file diff --git a/roles/prometheus-server/tasks/main.yml b/roles/prometheus-server/tasks/main.yml new file mode 100644 index 00000000..274d7418 --- /dev/null +++ b/roles/prometheus-server/tasks/main.yml @@ -0,0 +1,134 @@ +--- +- name: "Create prometheus directory" + become: yes + file: + path: "{{ prometheus_dir }}" + mode: 0770 + owner: nobody # Prometheus runs as nobody + group: nogroup + state: directory + +- name: "Create prometheus/config directory" + become: yes + file: + path: "{{ prometheus_dir }}/config" + mode: 0770 + owner: nobody + group: nogroup + state: directory + +- name: "Create prometheus/data directory" + become: yes + file: + path: "{{ prometheus_dir }}/data" + mode: 0770 + owner: nobody + group: nogroup + state: directory + +- name: "Create blackbox_exporter directory" + become: yes + file: + path: "{{ blackbox_exporter_dir }}" + mode: 0770 + owner: root + group: root + state: directory + +- name: "Create proxmox exporter directory" + become: yes + file: + path: "{{ pve_dir }}" + mode: 0770 + owner: nobody # pve exporter runs as nobody + group: nogroup + state: directory + +- name: "Generate Prometheus config" + become: yes + template: + mode: 0770 + owner: nobody + group: nogroup + src: "templates/prometheus.yml.j2" + dest: "{{ prometheus_dir }}/config/prometheus.yml" + notify: + - restart prometheus + +- name: "Generate Blackbox Exporter Config" + become: yes + template: + mode: 0440 + src: "files/blackbox_exporter.yaml" + dest: "{{ blackbox_exporter_dir }}/blackbox_exporter.yaml" + notify: + - restart blackbox exporter + +- name: "Generate Proxmox Exporter Config" + become: yes + template: + mode: 0440 + owner: nobody + group: nogroup + src: templates/pve.yml.j2 + dest: "{{ pve_dir }}/pve.yml" + notify: + - restart pve exporter + +- name: "Ensure Docker monitoring network" + become: yes + docker_network: + name: monitoring + appends: yes + +- name: "Prometheus Server" + become: yes + docker_container: + name: prometheus + networks: + - name: monitoring + network_mode: bridge + purge_networks: true + image: "prom/prometheus:v2.30.0" + command: + - "--config.file=/etc/prometheus/prometheus.yml" + - "--storage.tsdb.path=/prometheus" + - "--storage.tsdb.retention.time=60d" + - "--web.console.libraries=/usr/share/prometheus/console_libraries" + - "--web.console.templates=/usr/share/prometheus/consoles" + ports: + - "9090:9090" + restart_policy: always + volumes: + - "{{ prometheus_dir }}/config:/etc/prometheus" + - "{{ prometheus_dir }}/data:/prometheus" + +- name: "Blackbox Exporter" + become: yes + docker_container: + name: blackbox_exporter + networks: + - name: monitoring + network_mode: bridge + purge_networks: true + image: "prom/blackbox-exporter:v0.17.0" + command: "--config.file=/config/blackbox_exporter.yaml" + restart_policy: always + volumes: + - "{{ blackbox_exporter_dir }}/blackbox_exporter.yaml:/config/blackbox_exporter.yaml" + +- name: "Proxmox Exporter Container" + become: yes + docker_container: + image: prompve/prometheus-pve-exporter:1.3 + networks: + - name: monitoring + name: pve-exporter + network_mode: bridge + purge_networks: true + state: started + restart_policy: always + ports: + - "9221:9221" + volumes: + - "{{ pve_dir }}/pve.yml:/etc/pve.yml" \ No newline at end of file diff --git a/roles/prometheus-server/templates/prometheus.yml.j2 b/roles/prometheus-server/templates/prometheus.yml.j2 new file mode 100644 index 00000000..7f2b8953 --- /dev/null +++ b/roles/prometheus-server/templates/prometheus.yml.j2 @@ -0,0 +1,191 @@ +global: + scrape_interval: 30s # Set the scrape interval to every 30 seconds. Default is every 1 minute. + evaluation_interval: 30s # Evaluate rules every 30 seconds. The default is every 1 minute. + +rule_files: + - "/etc/prometheus/rules/*" + +scrape_configs: + - job_name: 'prometheus' + static_configs: + - targets: ['localhost:9090'] + labels: + instance: "{{inventory_hostname}}" + +# todo(jac) Update when grafana has been moved to the new setup +# - job_name: 'grafana' +# static_configs: +# - targets: ['grafana:3000'] +# labels: +# instance: "{{inventory_hostname}}" + + - job_name: 'expexp_metrics' + static_configs: + {% for host in groups['prometheus_base'] -%} + - + targets: +{%+ if "10.0.20.0/24" | network_in_usable(hostvars[host].ansible_host) %} + - {{hostvars[host].ansible_host | ipmath(2560) }}:9999 +{% else %} + - {{hostvars[host].ansible_host}}:9999 +{% endif %} + labels: + instance: "{{host}}" + {% endfor %} + + - job_name: 'node' + metrics_path: /proxy + params: + module: + - node + static_configs: + {% for host in groups['prometheus_base'] -%} + - + targets: +{%+ if "10.0.20.0/24" | network_in_usable(hostvars[host].ansible_host) %} + - {{hostvars[host].ansible_host | ipmath(2560) }}:9999 +{% else %} + - {{hostvars[host].ansible_host}}:9999 +{% endif %} + labels: + instance: "{{host}}" + {% endfor %} + +{% if 'prometheus_docker' in groups %} + - job_name: 'cadvisor' + metrics_path: /proxy + params: + module: + - cadvisor + static_configs: + {% for host in groups['prometheus_docker'] -%} + - + targets: + - {{hostvars[host].ansible_host}}:9999 + labels: + instance: "{{host}}" + {% endfor %} +{% endif %} + +{% if 'prometheus_apache' in groups %} + - job_name: 'apache' + metrics_path: /proxy + params: + module: + - apache + static_configs: + {% for host in groups['prometheus_apache'] -%} + - + targets: + - {{hostvars[host].ansible_host}}:9999 + labels: + instance: "{{host}}" + {% endfor %} +{% endif %} + +{% if 'prometheus_ipmi' in groups %} + - job_name: 'ipmi' + metrics_path: /proxy + params: + module: + - ipmi + static_configs: + {% for host in groups['prometheus_ipmi'] -%} + - + targets: + - {{hostvars[host].ansible_host}}:9999 + labels: + instance: "{{host}}" + {% endfor %} +{% endif %} + +{% if 'prometheus_traefik' in groups %} + - job_name: 'traefik' + metrics_path: /metrics + params: + module: + - traefik + static_configs: + {% for host in groups['prometheus_traefik'] -%} + - + targets: + - {{hostvars[host].ansible_host}}:8082 + labels: + instance: "{{host}}" + {% endfor %} +{% endif %} + +# ansible_host is on vlan 20 i.e. 10.0.20.XX +# databases cannot access vlan 20 +# proxmox hosts have presence on every vlan +# adding 2560 to 10.0.20.XX = 10.0.30.XX +# 2560 = (256 * 10) + - job_name: 'pve' + metrics_path: /pve + params: + module: [default] + static_configs: + - targets: + - "{{hostvars[groups['proxmox_hosts'][0]].ansible_host | ipmath(2560)}}" + relabel_configs: + - source_labels: [__address__] + target_label: __param_target + - target_label: __address__ + replacement: pve-exporter:9221 + + - job_name: 'site-up' + metrics_path: /probe + static_configs: + - targets: + - 'https://netsoc.co/' + - 'https://wiki.netsoc.co/' + - 'https://netsoc.dev/' + - 'https://keycloak.netsoc.dev/' + - 'https://portainer.netsoc.dev/' + - 'https://ipa.netsoc.dev/ipa/ui/' + - 'https://uccexpress.ie/' + - 'https://motley.ie/' + labels: + module: http_2xx + - targets: + - 'https://traefik.netsoc.dev/' + labels: + module: http_2xx_traefik_auth + relabel_configs: + - source_labels: [__address__] + target_label: __param_target + - source_labels: [module] + target_label: __param_module + - source_labels: [__param_target] + target_label: instance + regex: '^https?:\/\/(.*)\/' + - target_label: __address__ + replacement: blackbox_exporter:9115 + + - job_name: 'discord-bot' + metrics_path: /metrics + static_configs: + - targets: + - 'bot.netsoc.co' + labels: + module: discord_bot + + - job_name: 'minecraft' + metrics_path: / + static_configs: + - targets: + - '10.0.30.65:19565' + labels: + module: minecraft + +# TODO: Investigate why this won't work but ^ directly does +# - job_name: 'minecraft' +# metrics_path: /proxy +# params: +# module: +# - minecraft +# static_configs: +# - targets: +# - 10.0.30.65:9999 +# labels: +# instance: "minecraft.infra.netsoc.co" \ No newline at end of file diff --git a/roles/prometheus-server/templates/pve.yml.j2 b/roles/prometheus-server/templates/pve.yml.j2 new file mode 100644 index 00000000..7024c0b6 --- /dev/null +++ b/roles/prometheus-server/templates/pve.yml.j2 @@ -0,0 +1,4 @@ +default: + user: "{{ auditor.username }}@pve" + password: "{{ auditor.password }}" + verify_ssl: false \ No newline at end of file diff --git a/roles/proxmox-cloudinit-vm/tasks/main.yml b/roles/proxmox-cloudinit-vm/tasks/main.yml new file mode 100644 index 00000000..82886d80 --- /dev/null +++ b/roles/proxmox-cloudinit-vm/tasks/main.yml @@ -0,0 +1,318 @@ +--- + +- name: Check if VM with this name already exists (also gets id) + shell: pvesh get /nodes/{{ inventory_hostname }}/qemu/ --output-format=json | jq '.[] | select(.name=="{{ vm.name }}").vmid' -r --exit-status + register: vm_exists_result + ignore_errors: true + +- debug: + msg: "{{ vm_exists_result }}" + +- set_fact: + vm_already_exists: false + +- set_fact: + vm_already_exists: true + vm_existing_id: "{{ vm_exists_result.stdout | trim }}" + when: "('rc' in vm_exists_result and vm_exists_result.rc == 0)" + +- name: Stop already existing VM + shell: pvesh create /nodes/{{ inventory_hostname }}/qemu/{{ vm_existing_id }}/status/stop + when: "vm_already_exists is true" + +- set_fact: + vm_needs_creation: false + +- name: Destroy already existing VM if we're recreating it + shell: pvesh delete /nodes/{{ inventory_hostname }}/qemu/{{ vm_existing_id }} + when: "vm_already_exists is true and (recreate is defined and recreate is true)" + +- set_fact: + vm_needs_creation: true + when: "vm_already_exists is false or (recreate is defined and recreate is true)" + + +# Proxmox goes ape if 2 VMs get cloned simulateneously and both choose the same ID (due to the sequential numbering system) +# Use a hash of the name and add the hostname to make it unique instead +- set_fact: + vm_hash_id: "{{ range(1000, 5000000) | random(seed=vm.name+'-'+inventory_hostname) }}" + +- name: Get clone storage path + shell: pvesh get storage/{{ vm.template.storage }} --output-format=json | jq .path -r --exit-status + register: clone_storage_path_result +- set_fact: + clone_storage_path: "{{ clone_storage_path_result.stdout | trim }}" + +- file: + path: "{{ clone_storage_path }}/template/qemu" + state: directory + +- name: Get qcow image + get_url: + url: "{{ vm.template.image_url }}" + dest: "{{ clone_storage_path }}/template/qemu/{{ vm.template.image_url.split('/')[-1] }}.qcow2" + checksum: "{{ vm.template.image_hash }}" + when: "vm_needs_creation is true" + +- name: Ensure Proxmox VM created + proxmox_kvm: + api_host: "localhost" + api_user: "{{ proxmox.username }}" + api_password: "{{ proxmox.password }}" + vmid: "{{ vm_hash_id }}" + timeout: "{{ vm.timeout | default(300) }}" + node: "{{ ansible_hostname }}" + name: "{{ vm.name }}" + storage: "{{ vm.template.storage }}" + state: present + when: "vm_needs_creation" + +# Fixes: fatal: [lovelace]: FAILED! => {"changed": false, "msg": "VM worker1.docker does not exist in cluster."} +- name: Wait to prevent a race condition where Proxmox doesn't think the VM exists yet + wait_for: + timeout: 6 + delegate_to: localhost + +# proxmox_kvm has a load of issues so here are a bunch of workarounds below + +# It does not provide a register to output the vm_id of the new vm +# We can't assume the vm hash id we chose was the next free one +# we need to use shell commands to figure out the vm_id by name +# in: https://github.com/ansible/ansible/pull/42313 you can see he forced pushed +# and overrode a load of previous commits ._. +# you can use register: output & output.vm_id instead +- name: Get created/existing VM ID + shell: pvesh get /nodes/{{ inventory_hostname }}/qemu/ --output-format=json | jq '.[] | select(.name=="{{ vm.name }}").vmid' -r --exit-status + register: vm_id_result +- set_fact: + vm_id: "{{ vm_id_result.stdout | trim }}" +- debug: + msg: "{{ vm_id }}" + + +- name: Temporarily disable protection + shell: pvesh set /nodes/{{ inventory_hostname }}/qemu/{{ vm_id }}/config -protection 0 + +# Set some vm stats +- name: Ensure specs set + proxmox_kvm: + api_host: "localhost" + api_user: "{{ proxmox.username }}" + api_password: "{{ proxmox.password }}" + name: "{{ vm.name }}" + node: "{{ inventory_hostname }}" + description: "{{ vm.description | from_yaml | to_nice_yaml }}" + cores: "{{ vm.cores | default(1) }}" + memory: "{{ vm.memory | default(1024) }}" + protection: "no" + update: yes + state: present + + +# proxmox_kvm doesn't give you a way of setting net, virtio, ide, sata, scsi with the update: yes flag +# and maybe description +# workaround below +- name: Set net + shell: qm set {{ vm_id }} --{{ item.key }} {{ item.value }} + with_dict: "{{ vm.net }}" + +- name: Set UEFI + shell: qm set {{ vm_id }} --bios ovmf --machine q35 + +- name: Enable guest agent + shell: qm set {{ vm_id }} --agent 1 + +- name: Enable serial port + shell: qm set {{ vm_id }} -serial3 socket + +- name: Set VirtIO SCSI + shell: qm set {{ vm_id }} --scsihw virtio-scsi-pci + +- name: Set VirtIO RNG + shell: qm set {{ vm_id }} --rng0 source=/dev/urandom + +- name: Set balloon + shell: qm set {{ vm_id }} --balloon 256 + +- name: Delete old images directory if (re)creating VM + shell: | + rm -rf {{ clone_storage_path }}/images/{{ vm_id }}/ + when: "vm_needs_creation is true" + +- name: Ensure images directory + shell: | + mkdir -p {{ clone_storage_path }}/images/{{ vm_id }} + +- name: Add boot disk if it does not exist + shell: | + pvesh get /nodes/{{ inventory_hostname }}/qemu/{{ vm_id }}/config --output-format=json | jq 'select(.virtio0)' -r --exit-status + + if [ $? -eq 4 ]; then + cp {{ clone_storage_path }}/template/qemu/{{ vm.template.image_url.split('/')[-1] }}.qcow2 {{ clone_storage_path }}/images/{{ vm_id }}/vm-{{ vm_id }}-disk-0.qcow2 && + pvesh create /nodes/{{ inventory_hostname }}/qemu/{{ vm_id }}/config -virtio0 {{ vm.template.storage }}:{{ vm_id }}/vm-{{ vm_id }}-disk-0.qcow2 + fi + +- name: Add EFI disk if it does not exist + shell: | + pvesh get /nodes/{{ inventory_hostname }}/qemu/{{ vm_id }}/config --output-format=json | jq 'select(.efidisk0)' -r --exit-status + if [ $? -eq 4 ]; then + pvesh create /nodes/{{ inventory_hostname }}/qemu/{{ vm_id }}/config -efidisk0 {{ vm.storage }}:1,format=qcow2 + fi + +- name: Set boot disk order + shell: qm set {{ vm_id }} --bootdisk virtio0 + +- name: Get storage of boot disk + shell: | + pvesh get /nodes/{{ inventory_hostname }}/qemu/{{ vm_id }}/config --output-format=json | jq .virtio0 -r --exit-status + register: "boot_disk_storage_result" + +- set_fact: + boot_disk_storage: "{{ boot_disk_storage_result.stdout.split(':')[0] | trim }}" + +- name: Move boot disk to target storage if target storage is different than current/clone storage + shell: + pvesh create /nodes/{{ inventory_hostname }}/qemu/{{ vm_id }}/move_disk -storage {{ vm.storage }} -disk virtio0 -delete 1 + when: "vm.storage != boot_disk_storage" + +- name: Get storage of efi disk + shell: | + pvesh get /nodes/{{ inventory_hostname }}/qemu/{{ vm_id }}/config --output-format=json | jq .efidisk0 -r --exit-status + register: "efi_disk_storage_result" + +- set_fact: + efi_disk_storage: "{{ efi_disk_storage_result.stdout.split(':')[0] | trim }}" + +- name: Move efi disk to target storage if target storage is different than current/clone storage + shell: + pvesh create /nodes/{{ inventory_hostname }}/qemu/{{ vm_id }}/move_disk -storage {{ vm.storage }} -disk efidisk0 -delete 1 + when: "vm.storage != efi_disk_storage" + +- name: Resize boot disk + shell: + pvesh set /nodes/{{ inventory_hostname }}/qemu/{{ vm_id }}/resize -disk virtio0 -size {{ vm.disks.boot.size }}G + +- name: Add the extra disks if they don't exist already and resize + shell: | + pvesh get /nodes/{{ inventory_hostname }}/qemu/{{ vm_id }}/config --output-format=json | jq 'select(.virtio{{ index+1 }})' -r --exit-status + if [ $? -eq 4 {{ '|| true' if item.override is defined and item.override is true else '' }} ]; then + pvesh create /nodes/{{ inventory_hostname }}/qemu/{{ vm_id }}/config -virtio{{ index+1 }} '{{ vm.storage }}:{{ item.size | regex_replace ('[^0-9]','') }},format={{ item.format | default("raw") }}' + fi + pvesh set /nodes/{{ inventory_hostname }}/qemu/{{ vm_id }}/resize -disk virtio{{ index+1 }} -size {{ item.size }}G + args: + executable: /bin/bash + loop: "{{ vm.disks.extra | default('[]') }}" + loop_control: + index_var: index + when: "vm.disks.extra is defined" + +# TODO, storage moving for extra discs + +- name: Get Cloud-Init storage path + shell: pvesh get storage/{{ vm.cloudinit.storage }} --output-format=json | jq .path -r --exit-status + register: cloudinit_storage_path_result + when: "vm.cloudinit is defined" + +- set_fact: + cloudinit_storage_path: "{{ cloudinit_storage_path_result.stdout | trim }}" + when: "vm.cloudinit is defined" + +# We force re run cloudinit by booting the machine with a bootcmd that removes any previous cloudinit state +- name: Ensure stopped VM + proxmox_kvm: + api_host: "localhost" + api_user: "{{ proxmox.username }}" + api_password: "{{ proxmox.password }}" + name: "{{ vm.name }}" + node: "{{ inventory_hostname }}" + state: stopped + +- name: FORCE RERUN CLOUDINIT - Clear Cloud-Init metadata file + copy: + content: "" + dest: "{{ cloudinit_storage_path }}/snippets/{{ vm.name }}.metadata.yml" + when: "vm_needs_creation is false and vm.cloudinit is defined and vm.cloudinit.force is true" + +- name: FORCE RERUN CLOUDINIT - Ensure Cloud-Init userdata file that clears previous Cloud-Init run and shuts down machine + copy: + content: | + #cloud-config + bootcmd: + - rm -f /etc/netplan/50-cloud-init.yaml + - rm -rf /var/lib/cloud + - shutdown now + dest: "{{ cloudinit_storage_path }}/snippets/{{ vm.name }}.userdata.yml" + when: "vm_needs_creation is false and vm.cloudinit is defined and vm.cloudinit.force is true" + +- name: FORCE RERUN CLOUDINIT - Clear Cloud-Init networking + copy: + content: | + version: 2 + ethernets: [] + dest: "{{ cloudinit_storage_path }}/snippets/{{ vm.name }}.networkconfig.yml" + when: "vm_needs_creation is false and vm.cloudinit is defined and vm.cloudinit.force is true" + +- name: FORCE RERUN CLOUDINIT - Regenerate Cloud-Init drive + shell: | + pvesh set /nodes/{{ inventory_hostname }}/qemu/{{ vm_id }}/config -delete ide2 + pvesh set /nodes/{{ inventory_hostname }}/qemu/{{ vm_id }}/config --cicustom "user={{ vm.cloudinit.storage }}:snippets/{{ vm.name }}.userdata.yml,network={{ vm.cloudinit.storage }}:snippets/{{ vm.name }}.networkconfig.yml,meta={{ vm.cloudinit.storage }}:snippets/{{ vm.name }}.metadata.yml" + pvesh set /nodes/{{ inventory_hostname }}/qemu/{{ vm_id }}/config -ide2 {{ vm.cloudinit.storage }}:cloudinit,format=qcow2 + when: "vm_needs_creation is false and vm.cloudinit is defined and vm.cloudinit.force is true" + +- name: FORCE RERUN CLOUDINIT - Start VM + proxmox_kvm: + api_host: "localhost" + api_user: "{{ proxmox.username }}" + api_password: "{{ proxmox.password }}" + name: "{{ vm.name }}" + node: "{{ inventory_hostname }}" + state: started + when: "vm_needs_creation is false and vm.cloudinit is defined and vm.cloudinit.force is true" + +- name: FORCE RERUN CLOUDINIT - Wait for VM to shutdown after clearing Cloud-Init + shell: | + while pvesh get nodes/{{ inventory_hostname }}/qemu/{{ vm_id }}/status/current --output-format=json | jq 'select(.status=="running")' -r --exit-status; + do sleep 1; + done + when: "vm_needs_creation is false and vm.cloudinit is defined and vm.cloudinit.force is true" + +- name: FORCE RERUN CLOUDINIT - Stop VM + proxmox_kvm: + api_host: "localhost" + api_user: "{{ proxmox.username }}" + api_password: "{{ proxmox.password }}" + name: "{{ vm.name }}" + node: "{{ inventory_hostname }}" + state: stopped + when: "vm_needs_creation is false and vm.cloudinit is defined and vm.cloudinit.force is true" + +# Old cloud-init removed +# Now re-add it and set our fun stuff + +- name: Ensure Cloud-Init metadata file + copy: + content: | + {{ vm.cloudinit.metadata | default('') }} + dest: "{{ cloudinit_storage_path }}/snippets/{{ vm.name }}.metadata.yml" + when: "vm.cloudinit is defined" + +- name: Ensure Cloud-Init userdata file + copy: + content: | + {{ vm.cloudinit.userdata | default('#cloud-config\n') }} + dest: "{{ cloudinit_storage_path }}/snippets/{{ vm.name }}.userdata.yml" + when: "vm.cloudinit is defined" + +- name: Ensure Cloud-Init networking + copy: + content: | + {{ vm.cloudinit.networkconfig | default('---\n') | from_yaml }} + dest: "{{ cloudinit_storage_path }}/snippets/{{ vm.name }}.networkconfig.yml" + when: "vm.cloudinit is defined" + +- name: Regenerate Cloud-Init drive + shell: | + pvesh set /nodes/{{ inventory_hostname }}/qemu/{{ vm_id }}/config -delete ide2 + pvesh set /nodes/{{ inventory_hostname }}/qemu/{{ vm_id }}/config --cicustom "user={{ vm.cloudinit.storage }}:snippets/{{ vm.name }}.userdata.yml,network={{ vm.cloudinit.storage }}:snippets/{{ vm.name }}.networkconfig.yml,meta={{ vm.cloudinit.storage }}:snippets/{{ vm.name }}.metadata.yml" + pvesh set /nodes/{{ inventory_hostname }}/qemu/{{ vm_id }}/config -ide2 {{ vm.cloudinit.storage }}:cloudinit,format=qcow2 + when: "vm.cloudinit is defined" diff --git a/roles/proxmox-infra-cloudinit-vm/tasks/main.yml b/roles/proxmox-infra-cloudinit-vm/tasks/main.yml deleted file mode 100644 index 4e20df7d..00000000 --- a/roles/proxmox-infra-cloudinit-vm/tasks/main.yml +++ /dev/null @@ -1,171 +0,0 @@ ---- - -- name: Check if VM with this name already exists - shell: qm list | tail -n +2 | awk '{ if($2=="{{ vm.name }}") print $1 }' | grep "." - register: vm_exists_result - ignore_errors: true - -- set_fact: - vm_existing_id: "{{ vm_exists_result.stdout | trim }}" - -- name: Stop already existing VM - shell: qm stop {{ vm_existing_id }} - when: "'rc' in vm_exists_result and vm_exists_result.rc == 0" - -- name: Destroy already existing VM - shell: qm destroy {{ vm_existing_id }} - when: "'rc' in vm_exists_result and vm_exists_result.rc == 0 and (vm.recreate is defined and vm.recreate)" - -# Proxmox goes ape if 2 VMs get cloned simulateneously and both choose the same ID (due to the sequential numbering system) -# Use a hash of the name and add the hostname to make it unique instead -- set_fact: - vm_hash_id: "{{ range(1000, 5000000) | random(seed=vm.name+'-'+inventory_hostname) }}" - -- name: Ensure Proxmox VM cloned (if it does not exist) - proxmox_kvm: - api_host: "localhost" - api_user: "{{ proxmox.username }}" - api_password: "{{ proxmox.password }}" - clone: "{{ vm.clone }}" - target: "{{ inventory_hostname }}" - newid: "{{ vm_hash_id }}" - timeout: "{{ vm.timeout | default(300) }}" - node: "{{ inventory_hostname }}" - name: "{{ vm.name }}" - storage: "local-lvm" - full: yes - state: present - when: "(not vm_exists_result.rc == 0 and vm.clone is defined and vm.clone) or (vm.recreate is defined and vm.recreate)" - -- name: Ensure Proxmox VM exists - proxmox_kvm: - api_host: "localhost" - api_user: "{{ proxmox.username }}" - api_password: "{{ proxmox.password }}" - vmid: "{{ vm_hash_id }}" - timeout: "{{ vm.timeout | default(300) }}" - node: "{{ inventory_hostname }}" - name: "{{ vm.name }}" - storage: "local-lvm" - state: present - when: "vm.clone is not defined" - -# proxmox_kvm has a load of issues so here are a bunch of workarounds below - -# It does not provide a register to output the vmid of the new vm -# We can't assume the vm hash id we chose was the next free one -# we need to use shell commands to figure out the vmid by name -# in: https://github.com/ansible/ansible/pull/42313 you can see he forced pushed -# and overrode a load of previous commits ._. -# you can use register: output & output.vmid instead -- name: Get VMID - raw: qm list | tail -n +2 | awk '{ if($2=="{{ vm.name }}") print $1 }' - register: vmid_result - -- set_fact: - vmid: "{{ vmid_result.stdout | trim }}" - -# Fixes: fatal: [lovelace]: FAILED! => {"changed": false, "msg": "VM worker1.docker does not exist in cluster."} -- name: Wait to prevent a race condition where Proxmox doesn't think the VM exists yet - wait_for: - timeout: 5 - delegate_to: localhost - -# Set some vm stats -- name: Ensure specs set - proxmox_kvm: - api_host: "localhost" - api_user: "{{ proxmox.username }}" - api_password: "{{ proxmox.password }}" - name: "{{ vm.name }}" - node: "{{ inventory_hostname }}" - description: "{{ vm.description | from_yaml }}" - cores: "{{ vm.cores | default(1) }}" - memory: "{{ vm.memory | default(1024) }}" - protection: "{{ vm.protection | default('yes') }}" - update: yes - state: present - -# proxmox_kvm doesn't give you a way of setting net, virtio, ide, sata, scsi with the update: yes flag -# and maybe description -# workaround below -- name: Set net - shell: qm set {{ vmid }} --{{ item.key }} {{ item.value }} - with_dict: "{{ vm.net }}" - -- name: Add the new disks (if they don't exist already) - shell: | - # e.g. existing_disk=`qm config 1232366 | grep ^ide3 | cut -d' ' -f2 | cut -d',' -f1 | grep ^local-lvm` - existing_disk=`qm config {{ vmid }} | grep ^{{ item.key }} | cut -d' ' -f2 | cut -d',' -f1 | grep ^{{ item.value.pool }}` - - if [[ $existing_disk == '' || {{ 'true' if 'override' in item.value and item.value.override else 'false' }} ]]; then - # no disk, add one - qm set {{ vmid }} --{{ item.key }} {{ item.value.pool }}:{{ item.value.definition }} - fi - args: - executable: /bin/bash - register: result - with_dict: "{{ vm.disks | default('{}') }}" - when: "'definition' in item.value" - -- name: Resize disks - shell: qm resize {{ vmid }} {{ item.key }} {{ item.value.resize }} - with_dict: "{{ vm.disks | default('{}') }}" - when: "'resize' in item.value" - -- name: Set description - raw: qm set {{ vmid }} --description "{{ vm.description | from_yaml | to_nice_yaml }}" - -- name: Ensure cloud-init metadata file - copy: - content: | - {{ cloudinit.metadata | default('') }} - dest: "/var/lib/vz/snippets/{{ vm.name }}.metadata.yml" - -- name: Ensure cloud-init userdata file - copy: - content: | - {{ cloudinit.userdata | default('#cloud-config\n') }} - dest: "/var/lib/vz/snippets/{{ vm.name }}.userdata.yml" - -- name: Ensure cloud-init networking - copy: - content: | - {{ cloudinit.networkconfig | default('---\n') | from_yaml }} - dest: "/var/lib/vz/snippets/{{ vm.name }}.networkconfig.yml" - -- name: Ensure cloud-init file options set - command: - cmd: 'qm set {{ vmid }} --cicustom "user=local:snippets/{{ vm.name }}.userdata.yml,network=local:snippets/{{ vm.name }}.networkconfig.yml,meta=local:snippets/{{ vm.name }}.metadata.yml"' - -- name: Attach/regenerate cloud-init NoCloud drive (if it existed) - shell: | - cloudinit_drive=`qm config {{ vmid }} | grep "cloudinit,media=cdrom" | cut -d":" -f1` - protection=`qm config {{ vmid }} | grep ^protection | cut -d' ' -f2` - - if [[ $cloudinit_drive != '' ]]; then - qm set {{ vmid }} --protection 0 - #qm set {{ vmid }} --$cloudinit_drive none,media=cdrom - qm unlink {{ vmid }} --idlist $cloudinit_drive - qm set {{ vmid }} --protection $protection - fi - - qm set {{ vmid }} --{{ cloudinit.drive_device }} local-lvm:cloudinit - args: - executable: /bin/bash - -- name: Start VM if it was stopped - proxmox_kvm: - api_host: "localhost" - api_user: "{{ proxmox.username }}" - api_password: "{{ proxmox.password }}" - name: "{{ vm.name }}" - node: "{{ inventory_hostname }}" - state: started - -- name: Wait for SSH - wait_for: - port: 22 - search_regex: OpenSSH - host: "{{ wait_for_ssh_ip | ipmath(0) }}" # ipmath(0) will remove the subnet mask if they added it in - when: wait_for_ssh_ip is defined \ No newline at end of file diff --git a/roles/proxmox-lxc/tasks/main.yml b/roles/proxmox-lxc/tasks/main.yml new file mode 100644 index 00000000..b5ee66cb --- /dev/null +++ b/roles/proxmox-lxc/tasks/main.yml @@ -0,0 +1,123 @@ +--- + +- name: PROXMOX LXC - Check if LXC with this name already exists (also gets id) + shell: pvesh get /nodes/{{ ansible_hostname }}/lxc/ --output-format=json | jq '.[] | select(.name=="{{ lxc.name }}").vmid' -r --exit-status + register: lxc_exists_result + ignore_errors: true + +- debug: + msg: "{{ lxc_exists_result }}" + +- set_fact: + lxc_already_exists: false + +- set_fact: + lxc_already_exists: true + lxc_existing_id: "{{ lxc_exists_result.stdout | trim }}" + when: "('rc' in lxc_exists_result and lxc_exists_result.rc == 0)" + +- name: PROXMOX LXC - Shut down already existing LXC + shell: pvesh create /nodes/{{ ansible_hostname }}/lxc/{{ lxc_existing_id }}/status/shutdown + when: "lxc_already_exists is true" + ignore_errors: true + +- set_fact: + lxc_needs_creation: false + +- name: PROXMOX LXC - Destroy already existing VM if we're recreating it + shell: pvesh delete /nodes/{{ ansible_hostname }}/lxc/{{ lxc_existing_id }} + when: "lxc_already_exists is true and (recreate is defined and recreate is true)" + +- set_fact: + lxc_needs_creation: true + when: "lxc_already_exists is false or (recreate is defined and recreate is true)" + +# Proxmox goes ape if 2 VMs get cloned simulateneously and both choose the same ID (due to the sequential numbering system) +# Use a hash of the name and add the hostname to make it unique instead +- set_fact: + lxc_hash_id: "{{ range(1000, 5000000) | random(seed=lxc.name+'-'+ansible_hostname) }}" + +- name: PROXMOX LXC - Download tar.gz LXC image + shell: pveam download {{ lxc.template.storage }} {{ lxc.template.image }} + +- name: PROXMOX LXC - Ensure LXC created + proxmox: + proxmox_default_behavior: "compatibility" + api_host: "localhost" + api_user: "{{ proxmox.username }}" + api_password: "{{ proxmox.password }}" + node: "{{ ansible_hostname }}" + vmid: "{{ lxc_hash_id }}" + hostname: "{{ lxc.name }}" + ostemplate: "{{ lxc.template.storage }}:vztmpl/{{ lxc.template.image }}" + description: "{{ lxc.description | from_yaml | to_nice_yaml }}" + pubkey: "{{ lxc.authorized_keys | default(null) }}" + timeout: "{{ lxc.timeout | default('300') }}" + storage: "{{ lxc.storage }}" + disk: "{{ lxc.disks.rootfs.size }}" + nameserver: "1.1.1.1" + cores: "{{ lxc.cores | default(1) }}" + memory: "{{ lxc.memory | default(512) }}" + swap: "{{ lxc.swap | default(512) }}" + unprivileged: "{{ lxc.unprivileged | default(yes) }}" + when: "lxc_needs_creation" + +- name: PROXMOX LXC - Wait to prevent a race condition where Proxmox hasn't named the LXC yet + wait_for: + timeout: 6 + delegate_to: localhost + +- name: PROXMOX LXC - Get created/existing LXC ID + shell: pvesh get /nodes/{{ ansible_hostname }}/lxc/ --output-format=json | jq '.[] | select(.name=="{{ lxc.name }}").vmid' -r --exit-status + register: lxc_id_result +- set_fact: + lxc_id: "{{ lxc_id_result.stdout | trim }}" +- debug: + msg: "{{ lxc_id }}" + +- name: PROXMOX LXC - Disable protection + shell: pvesh set /nodes/{{ ansible_hostname }}/lxc/{{ lxc_id }}/config -protection 0 + + +# # Set stats +# - name: PROXMOX LXC - Ensure specs set +# proxmox: +# proxmox_default_behavior: "no_defaults" +# api_host: "localhost" +# api_user: "{{ proxmox.username }}" +# api_password: "{{ proxmox.password }}" +# vmid: "{{ lxc_id }}" +# hostname: "{{ lxc.name }}" +# node: "{{ ansible_hostname }}" +# description: "{{ lxc.description | from_yaml | to_nice_yaml }}" +# cores: "{{ lxc.cores | default(1) }}" +# memory: "{{ lxc.memory | default(1024) }}" +# cpus: "1" +# swap: "{{ lxc.swap | default(1024) }}" +# unprivileged: "{{ lxc.unprivileged | default(yes) }}" + +- name: PROXMOX LXC - Set net + shell: pvesh set /nodes/{{ ansible_hostname }}/lxc/{{ lxc_id }}/config -{{ item.key }} {{ item.value }} + with_dict: "{{ lxc.net | default({}) }}" + +- name: PROXMOX LXC - Set features + shell: pvesh set /nodes/{{ ansible_hostname }}/lxc/{{ lxc_id }}/config -features {{ lxc.features }} + when: "lxc.features is defined" + +- name: PROXMOX LXC - Get storage of rootfs + shell: | + pvesh get /nodes/{{ ansible_hostname }}/lxc/{{ lxc_id }}/config --output-format=json | jq .rootfs -r --exit-status + register: "rootfs_storage_result" + +- set_fact: + rootfs_storage: "{{ rootfs_storage_result.stdout.split(':')[0] | trim }}" + +- name: PROXMOX LXC - Move rootfs disk to target storage if target storage is different than current/clone storage + shell: + pvesh create /nodes/{{ ansible_hostname }}/lxc/{{ lxc_id }}/move_disk -storage {{ lxc.storage }} -disk rootfs -delete 1 + when: "lxc.storage != rootfs_storage" + +- name: PROXMOX LXC - Resize rootfs + shell: + pvesh set /nodes/{{ ansible_hostname }}/lxc/{{ lxc_id }}/resize -disk rootfs -size {{ lxc.disks.rootfs.size }} + when: lxc.rootfs is defined and lxc_needs_creation is false diff --git a/roles/proxmox-templates/tasks/build-lxc-template.yml b/roles/proxmox-templates/tasks/build-lxc-template.yml new file mode 100644 index 00000000..39d12a6e --- /dev/null +++ b/roles/proxmox-templates/tasks/build-lxc-template.yml @@ -0,0 +1,128 @@ +- name: PROXMOX TEMPLATES (LXC) - Gather facts + setup: + when: "inventory_hostname == proxmox_host" + +- name: PROXMOX TEMPLATES (LXC) - Generate SSH keypair + become: no + openssh_keypair: + path: /tmp/ansible_{{ template.lxc.name }}.id_ssh + force: True + delegate_to: localhost + +- name: PROXMOX TEMPLATES (LXC) - Create LXC + include_role: + name: proxmox-lxc + vars: + recreate: yes + lxc: "{{ template.lxc | combine({'authorized_keys': lookup('file', '/tmp/ansible_' + template.lxc.name + '.id_ssh.pub')}) }}" + when: "inventory_hostname == proxmox_host" + +- name: PROXMOX TEMPLATES (LXC) - Start container + proxmox: + proxmox_default_behavior: "no_defaults" + api_host: "localhost" + api_user: "{{ proxmox.username }}" + api_password: "{{ proxmox.password }}" + node: "{{ inventory_hostname }}" + hostname: "{{ template.lxc.name }}" + state: started + ignore_errors: yes + when: "inventory_hostname == proxmox_host" + +- name: PROXMOX TEMPLATES (LXC) - Wait for net + pause: + seconds: 5 + when: "inventory_hostname == proxmox_host" + + +- name: PROXMOX TEMPLATES (LXC) - Get IP + shell: | + id=`pvesh get /nodes/{{ ansible_hostname }}/lxc/ --output-format=json | jq '.[] | select(.name=="{{ template.lxc.name }}").vmid' -r --exit-status` + lxc-info -n $id -iH + args: + executable: /bin/sh + register: provisionee_ip_out + when: "inventory_hostname == proxmox_host" + +- name: PROXMOX TEMPLATES (LXC) - Remember IP + set_fact: + provisionee_ip: "{{ provisionee_ip_out.stdout | trim }}" + when: "inventory_hostname == proxmox_host" + +- name: PROXMOX TEMPLATES (LXC) - Wait for SSH + wait_for: + port: 22 + search_regex: OpenSSH + host: "{{ provisionee_ip }}" + when: "inventory_hostname == proxmox_host" + +- name: PROXMOX TEMPLATES (LXC) - Gather facts + setup: + when: "inventory_hostname == proxmox_host" + +- name: PROXMOX TEMPLATES (LXC) - Configure ansible_host, etc for LXC provisionee group + set_fact: + ansible_host: "{{ hostvars[proxmox_host]['provisionee_ip'] }}" + ansible_ssh_user: root + ansible_ssh_private_key_file: "/tmp/ansible_{{ template.lxc.name }}.id_ssh" + ansible_ssh_common_args: '-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null' + when: "inventory_hostname == provisionee_host" + +- name: PROXMOX TEMPLATES (LXC) - Gather facts on LXC + setup: + when: "inventory_hostname == provisionee_host" + +# The butt-pucker zone +- name: PROXMOX TEMPLATES (LXC) - Test provisionee_host to ensure user is not an idiot and provisioning the proxmox host instead of the container (1/2) + shell: "! which pvesh" # errors if the pvesh binary exists + when: "inventory_hostname == provisionee_host and inventory_hostname != proxmox_host" + +- name: PROXMOX TEMPLATES (LXC) - Test provisionee_host to ensure user is not an idiot and provisioning the proxmox host instead of the container (2/2) + shell: "! which pveam" # errors if the pveam binary exists + when: "inventory_hostname == provisionee_host and inventory_hostname != proxmox_host" + +- name: PROXMOX TEMPLATES (LXC) - Provision LXC + include_tasks: "{{ template.tasks }}" + when: "inventory_hostname == provisionee_host and inventory_hostname != proxmox_host" + # ^^^ !!! DO NOT REMOVE THIS LINE !!! ^^^ + # WILL CAUSE CATASTROPHIC DAMAGE TO THE PROXMOX HOST IF REMOVED + +- name: PROXMOX TEMPLATES (LXC) - Delete host keys + file: + path: /root/.ssh/id_rsa + state: absent + when: "inventory_hostname == provisionee_host" + +- name: PROXMOX TEMPLATES (LXC) - Delete SSH key on host + file: + path: /tmp/ansible_{{ template.lxc.name }}.id_ssh + state: absent + when: "inventory_hostname == proxmox_host" + +- name: PROXMOX TEMPLATES (LXC) - Stop LXC + proxmox: + proxmox_default_behavior: "no_defaults" + node: "{{ proxmox_host }}" + api_host: "localhost" + api_user: "{{ proxmox.username }}" + api_password: "{{ proxmox.password }}" + hostname: "{{ template.lxc.name }}" + state: stopped + force: yes + when: "inventory_hostname == proxmox_host" + +- name: PROXMOX TEMPLATES (LXC) - Convert LXC into template + shell: | + id=`pvesh get /nodes/{{ ansible_hostname }}/lxc/ --output-format=json | jq '.[] | select(.name=="{{ template.lxc.name }}").vmid' -r --exit-status` + pvesh create /nodes/{{ ansible_hostname }}/lxc/$id/template + when: "inventory_hostname == proxmox_host" + +- name: PROXMOX TEMPLATES (LXC) - Delete SSH keypair + become: no + file: + path: "{{ item }}" + state: absent + loop: + - "/tmp/ansible_{{ template.lxc.name }}.id_ssh" + - "/tmp/ansible_{{ template.lxc.name }}.id_ssh.pub" + delegate_to: localhost \ No newline at end of file diff --git a/roles/proxmox-templates/tasks/build-vm-template.yml b/roles/proxmox-templates/tasks/build-vm-template.yml new file mode 100644 index 00000000..cfac3470 --- /dev/null +++ b/roles/proxmox-templates/tasks/build-vm-template.yml @@ -0,0 +1,169 @@ + + + +- name: PROXMOX TEMPLATES (VM) - Gather facts + setup: + when: "inventory_hostname == proxmox_host" + +- name: PROXMOX TEMPLATES (VM) - Generate SSH keypair + become: no + openssh_keypair: + path: /tmp/ansible_{{ template.vm.name }}.id_ssh + force: True + delegate_to: localhost + +- set_fact: + vm_mixin: + recreate: yes + cloudinit: + storage: "{{ template.vm.cloudinit.storage }}" + userdata: | + #cloud-config + preserve_hostname: false + manage_etc_hosts: true + fqdn: "{{ template.vm.name }}" + packages: + - qemu-guest-agent + runcmd: + - [ systemctl, start, qemu-guest-agent, --no-block ] + - [ systemctl, enable, qemu-guest-agent ] + users: + - name: netsoc + gecos: Netsoc Management User + primary_group: netsoc + groups: netsoc + shell: /bin/bash + sudo: ALL=(ALL) NOPASSWD:ALL + ssh_authorized_keys: + - "{{ lookup('file', '/tmp/ansible_{{ template.vm.name }}.id_ssh.pub') }}" + networkconfig: + version: 2 + ethernets: + ens18: + dhcp4: yes + optional: true + link-local: [] + when: "inventory_hostname == proxmox_host and template.tasks is defined" + + +- set_fact: + vm_mixin: + recreate: yes + when: "inventory_hostname == proxmox_host and template.tasks is not defined" + +- name: PROXMOX TEMPLATES (VM) - Create VM + include_role: + name: proxmox-cloudinit-vm + vars: + recreate: yes + vm: "{{ template.vm | combine(vm_mixin, recursive=true) }}" + when: "inventory_hostname == proxmox_host" + +- name: PROXMOX TEMPLATES (VM) - Start VM + proxmox_kvm: + proxmox_default_behavior: no_defaults + node: "{{ proxmox_host }}" + api_host: "localhost" + api_user: "{{ proxmox.username }}" + api_password: "{{ proxmox.password }}" + name: "{{ template.vm.name }}" + state: started + when: "inventory_hostname == proxmox_host and template.tasks is defined" + ignore_errors: yes + +- name: PROXMOX TEMPLATES (VM) - Wait for guest agent ping + shell: | + id=`pvesh get /nodes/{{ proxmox_host }}/qemu/ --output-format=json | jq '.[] | select(.name=="{{ template.vm.name }}").vmid' -r --exit-status` + pvesh create /nodes/{{ proxmox_host }}/qemu/$id/agent/ping + retries: 30 + delay: 3 + register: result + until: result.rc == 0 + when: "inventory_hostname == proxmox_host and template.tasks is defined" + +- name: PROXMOX TEMPLATES (VM) - Wait for net + pause: + seconds: 2 + when: "inventory_hostname == proxmox_host and template.tasks is defined" + +- name: PROXMOX TEMPLATES (VM) - Get IP + shell: | + id=`pvesh get /nodes/{{ inventory_hostname }}/qemu/ --output-format=json | jq '.[] | select(.name=="{{ template.vm.name }}").vmid' -r --exit-status` + pvesh get /nodes/{{ inventory_hostname }}/qemu/$id/agent/network-get-interfaces --output-format=json | jq -r '.result[] | select(.name=="ens18") | ."ip-addresses" | .[] | select(."ip-address-type"=="ipv4") | ."ip-address"' + args: + executable: /bin/sh + register: provisionee_ip_out + when: "inventory_hostname == proxmox_host and template.tasks is defined" + +- name: PROXMOX TEMPLATES (VM) - Remember IP + set_fact: + provisionee_ip: "{{ provisionee_ip_out.stdout | trim }}" + when: "inventory_hostname == proxmox_host and template.tasks is defined" + +- name: PROXMOX TEMPLATES (VM) - Wait for SSH + wait_for: + port: 22 + search_regex: OpenSSH + host: "{{ provisionee_ip }}" + when: "inventory_hostname == proxmox_host and template.tasks is defined" + +- name: PROXMOX TEMPLATES (VM) - Gather facts + setup: + when: "inventory_hostname == proxmox_host and template.tasks is defined" + +- name: PROXMOX TEMPLATES (VM) - Configure ansible_host, etc for LXC + set_fact: + ansible_host: "{{ hostvars[proxmox_host]['provisionee_ip'] }}" + ansible_ssh_user: netsoc + ansible_ssh_private_key_file: "/tmp/ansible_{{ template.vm.name }}.id_ssh" + ansible_ssh_common_args: '-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null' + when: "inventory_hostname == provisionee_host and template.tasks is defined" + +- name: PROXMOX TEMPLATES (VM) - Gather facts on VM + setup: + when: "inventory_hostname == provisionee_host and template.tasks is defined" + +# The butt-pucker zone +- name: PROXMOX TEMPLATES (VM) - Test provisionee_host to ensure user is not an idiot and provisioning the proxmox host instead of the vm (1/2) + shell: "! which pvesh" # errors if the pvesh binary exists + when: "inventory_hostname == provisionee_host and inventory_hostname != proxmox_host and template.tasks is defined" + +- name: PROXMOX TEMPLATES (VM) - Test provisionee_host to ensure user is not an idiot and provisioning the proxmox host instead of the vm (2/2) + shell: "! which pveam" # errors if the pveam binary exists + when: "inventory_hostname == provisionee_host and inventory_hostname != proxmox_host and template.tasks is defined" + +- name: PROXMOX TEMPLATES (VM) - Provision VM + include_tasks: "{{ template.tasks }}" + args: + apply: + become: yes + when: "inventory_hostname == provisionee_host and inventory_hostname != proxmox_host and template.tasks is defined" + # ^^^ !!! DO NOT REMOVE THIS LINE !!! ^^^ + # WILL CAUSE CATASTROPHIC DAMAGE TO THE PROXMOX HOST IF REMOVED + +- name: PROXMOX TEMPLATES (VM) - Stop VM + proxmox_kvm: + node: "{{ proxmox_host }}" + api_host: "localhost" + api_user: "{{ proxmox.username }}" + api_password: "{{ proxmox.password }}" + name: "{{ template.vm.name }}" + state: stopped + force: yes + when: "inventory_hostname == proxmox_host" + +- name: PROXMOX TEMPLATES (VM) - Convert VM into template + shell: | + id=`pvesh get /nodes/{{ proxmox_host }}/qemu/ --output-format=json | jq '.[] | select(.name=="{{ template.vm.name }}").vmid' -r --exit-status` + pvesh create /nodes/{{ proxmox_host }}/qemu/$id/config -template 1 + when: "inventory_hostname == proxmox_host" + +- name: PROXMOX TEMPLATES (VM) - Delete SSH keypair + become: no + file: + path: "{{ item }}" + state: absent + loop: + - "/tmp/ansible_{{ template.vm.name }}.id_ssh" + - "/tmp/ansible_{{ template.vm.name }}.id_ssh.pub" + delegate_to: localhost \ No newline at end of file diff --git a/roles/proxmox-templates/tasks/main.yml b/roles/proxmox-templates/tasks/main.yml new file mode 100644 index 00000000..35573c06 --- /dev/null +++ b/roles/proxmox-templates/tasks/main.yml @@ -0,0 +1,15 @@ + +- setup: + when: "inventory_hostname != provisionee_host" + +- include_tasks: "build-lxc-template.yml" + loop: "{{ templates }}" + loop_control: + loop_var: "template" + when: "template.lxc is defined and ('all' in ansible_run_tags or template.lxc.name in ansible_run_tags)" + +- include_tasks: "build-vm-template.yml" + loop: "{{ templates }}" + loop_control: + loop_var: "template" + when: "template.vm is defined and ('all' in ansible_run_tags or template.vm.name in ansible_run_tags)" \ No newline at end of file diff --git a/packer/netsoc-ubuntu-server/roles/shells/tasks/main.yml b/roles/shells/tasks/main.yml similarity index 100% rename from packer/netsoc-ubuntu-server/roles/shells/tasks/main.yml rename to roles/shells/tasks/main.yml diff --git a/roles/simple-disk/tasks/main.yml b/roles/simple-disk/tasks/main.yml deleted file mode 100644 index 84c51b7f..00000000 --- a/roles/simple-disk/tasks/main.yml +++ /dev/null @@ -1,35 +0,0 @@ -- name: "Ensure data disk is partitioned" - become: yes - parted: - device: "{{ device }}" - number: 1 - state: present - part_end: "{{ partition_size }}" - -- name: "Ensure data disk is ext4" - become: yes - filesystem: - fstype: "{{ fstype }}" - dev: "{{ device }}1" # i.e /dev/sdb1 - # grow fs if it already exists - resizefs: yes - -- name: "Get data disk uuid" - become: yes - shell: "blkid -s UUID -o value {{ device }}1" - register: uuid_result - -- name: "Ensure path for data disk mount" - become: yes - file: - path: "{{ mount_path }}" - state: directory - -- name: "Ensure data disk mount" - become: yes - mount: - path: "{{ mount_path }}" - fstype: "{{ fstype }}" - src: "UUID={{ uuid_result.stdout | trim }}" - opts: "{{ mount_opts }}" - state: mounted \ No newline at end of file diff --git a/roles/simple-zfs/tasks/main.yml b/roles/simple-zfs/tasks/main.yml deleted file mode 100644 index 0ffd513d..00000000 --- a/roles/simple-zfs/tasks/main.yml +++ /dev/null @@ -1,35 +0,0 @@ -- name: "Check if zpool {{ pool }} exists / create it if it doesn't" - become: yes - block: - - zpool_facts: - pool: "{{ pool }}" - register: zpool_result - rescue: - - command: - cmd: "zpool create -o autoexpand=on {{ pool }} {{ device }} -m {{ mount }}" - -- name: "Create zfs {{ item }} in {{ pool }}" - become: yes - zfs: - name: "{{ pool }}/{{ item }}" - state: present - with_items: "{{ fs }}" - -- name: "755 {{ item }} in {{ pool }}" - become: yes - file: - name: "/{{ pool }}/{{ item }}" - mode: 0755 - with_items: "{{ fs }}" - -- name: "Configure intervals for zfs-auto-snapshot" - become: yes - shell: | - #!/bin/bash - zfs set com.sun:auto-snapshot=true {{ pool }}/{{ item }} - zfs set com.sun:auto-snapshot:monthly={{ snapshot.monthly | default('true') | bool | lower }} {{ pool }}/{{ item }} - zfs set com.sun:auto-snapshot:weekly={{ snapshot.weekly | default('true') | bool | lower }} {{ pool }}/{{ item }} - zfs set com.sun:auto-snapshot:daily={{ snapshot.daily | default('true') | bool | lower }} {{ pool }}/{{ item }} - zfs set com.sun:auto-snapshot:hourly={{ snapshot.hourly | default('false') | bool | lower }} {{ pool }}/{{ item }} - zfs set com.sun:auto-snapshot:frequent={{ snapshot.frequent | default('true') | bool | lower }} {{ pool }}/{{ item }} - with_items: "{{ fs }}" \ No newline at end of file diff --git a/roles/terraform/tasks/main.yml b/roles/terraform/tasks/main.yml deleted file mode 100644 index 760d41fd..00000000 --- a/roles/terraform/tasks/main.yml +++ /dev/null @@ -1,24 +0,0 @@ - -- name: Ensure unarchive requirements - apt: - name: unzip - state: present - -- name: Ensure Terraform 0.12.20 - unarchive: - src: https://releases.hashicorp.com/terraform/0.12.20/terraform_0.12.20_linux_amd64.zip - dest: /usr/local/bin - mode: +x - remote_src: yes - -- name: Ensure terraform.d dir - file: - path: /root/.terraform.d/ - state: directory - mode: '0755' - -- name: Ensure terraform plugins dir - file: - path: /root/.terraform.d/plugins - state: directory - mode: '0755' \ No newline at end of file diff --git a/roles/traefik/tasks/main.yml b/roles/traefik/tasks/main.yml deleted file mode 100644 index a6b8d337..00000000 --- a/roles/traefik/tasks/main.yml +++ /dev/null @@ -1,131 +0,0 @@ ---- - -- name: Ensure mount dir - become: yes - file: - path: "{{ mount }}/" - owner: root - group: root - # needs to 775 as this folder is accessed internally by a dirsrv user - # https://github.com/freeipa/freeipa-container/issues/281 - mode: 0777 - state: directory - -- name: Ensure Cloudflare DNS token in Docker Swarm Secrets - run_once: true - become: yes - docker_secret: - name: cloudflare_dns_api_token.txt - data: "{{ cloudflare.api.dns_api_token | default('') }}" - register: result - ignore_errors: true - -- name: Remove Docker Secret from Swarm Service to update the Secret - become: yes - docker_stack: - state: absent - absent_retries: 5 - name: cloudflare_dns_api_token.txt - when: result is failed - -- name: Retry setting Docker Secret in Docker Swarm Secrets if necessary - run_once: true - when: result is failed - become: yes - docker_secret: - name: cloudflare_dns_api_token.txt - data: "{{ cloudflare.api.dns_api_token | default('') }}" - -- name: Ensure Traefik Docker network - become: yes - docker_network: - name: traefik - driver: overlay - attachable: yes - -- become: yes - docker_stack: - name: traefik - state: absent - -- name: Ensure Traefik Docker Config - docker_config: - name: traefik_static_config.yml - data: "{{ config | from_yaml }}" - force: yes - state: present - -- name: Ensure Traefik Docker container - become: yes - docker_stack: - state: present - name: traefik - compose: - - version: "3.8" - services: - server: - image: traefik:2.2.0 - ports: - - target: 80 - published: 80 - protocol: tcp - mode: host - - target: 443 - published: 443 - protocol: tcp - mode: host - networks: - traefik: - deploy: - mode: global - placement: - constraints: - - node.role == manager - preferences: - - spread: node.id - restart_policy: - condition: any - delay: 2s - max_attempts: 5 - update_config: - order: stop-first - failure_action: rollback - labels: - # global redirect to https - - "traefik.enable=true" - - "traefik.docker.network=traefik" - - "traefik.http.routers.https-redirect.entrypoints=web" - - "traefik.http.routers.https-redirect.rule=HostRegexp(`{any:.*}`)" - - "traefik.http.routers.https-redirect.middlewares=https-redirect" - - "traefik.http.middlewares.https-redirect.redirectscheme.scheme=https" - - "traefik.http.middlewares.https-redirect.redirectscheme.port=443" - - "traefik.http.middlewares.https-redirect.redirectscheme.permanent=true" - - # passworded dashboard - - "traefik.http.routers.dashboard.entrypoints=web-secure" - - "traefik.http.routers.dashboard.rule=Host(`{{ dashboard_domain }}`)" - - "traefik.http.routers.dashboard.tls" - - "traefik.http.routers.dashboard.service=dashboard-service" - - "traefik.http.services.dashboard-service.loadbalancer.server.port=8080" - - "traefik.http.middlewares.dashboard-auth.basicauth.users={{ dashboard_basicauth }}" - - "traefik.http.routers.dashboard.middlewares=dashboard-auth@docker" - volumes: - - "/var/run/docker.sock:/var/run/docker.sock" - - "{{ mount }}:/traefik/:shared" - command: traefik --configFile=/static_config.yml - secrets: - - "cloudflare_dns_api_token.txt" - environment: - CLOUDFLARE_DNS_API_TOKEN_FILE: "/run/secrets/cloudflare_dns_api_token.txt" - configs: - - source: traefik_static_config.yml - target: /static_config.yml - secrets: - cloudflare_dns_api_token.txt: - external: true - configs: - traefik_static_config.yml: - external: true - networks: - traefik: - external: true \ No newline at end of file diff --git a/packer/netsoc-ubuntu-server/roles/utf8-locale/tasks/main.yml b/roles/utf8-locale/tasks/main.yml similarity index 100% rename from packer/netsoc-ubuntu-server/roles/utf8-locale/tasks/main.yml rename to roles/utf8-locale/tasks/main.yml diff --git a/roles/zfs-auto-snapshot/tasks/main.yml b/roles/zfs-auto-snapshot/tasks/main.yml deleted file mode 100644 index 79e7c74b..00000000 --- a/roles/zfs-auto-snapshot/tasks/main.yml +++ /dev/null @@ -1,31 +0,0 @@ - -- name: "Install auto-snapshot requirements" - become: yes - apt: - name: - - zfs-auto-snapshot - -- name: "Modify zfs-auto-snapshot script to set our options" - become: yes - blockinfile: - dest: /usr/sbin/zfs-auto-snapshot - content: | - opt_backup_full='' - opt_backup_incremental='' - opt_default_exclude='1' - opt_dry_run='' - opt_event='-' - opt_fast_zfs_list='1' - opt_keep='' - opt_label='' - opt_prefix='snapshot' - opt_recursive='' - opt_sep='-' - opt_setauto='' - opt_syslog='' - opt_skip_scrub='' - opt_verbose='' - opt_pre_snapshot='' - opt_post_snapshot='' - opt_do_snapshots='1' - insertafter: "^opt_do_snapshots" # insert after their list of defaults, so our list immediately overrides it diff --git a/run.sh b/run.sh new file mode 100755 index 00000000..28b9bdae --- /dev/null +++ b/run.sh @@ -0,0 +1,8 @@ +#!/bin/bash +if [[ ! -z "${VAULT_PASS}" ]]; then + echo "$VAULT_PASS" > ./_vault_pass + ansible-playbook -i proxmox_inventory.py -i hosts --vault-password-file ./_vault_pass ${@:1} || true + rm _vault_pass +else + ansible-playbook -i proxmox_inventory.py -i hosts --ask-vault-pass ${@:1} +fi \ No newline at end of file diff --git a/setup-backups.yml b/setup-backups.yml new file mode 100644 index 00000000..1fc93403 --- /dev/null +++ b/setup-backups.yml @@ -0,0 +1,104 @@ +--- +- name: "BACKUP JOBS" + hosts: localhost + tasks: + - name: BACKUP JOBS - Ensure duplicity config path + file: + path: '/root/.duplicity' + state: directory + + - name: BACKUP JOBS - Ensure duplicity config path; credentials + file: + path: '/root/.duplicity/credentials' + state: touch + + - name: BACKUP JOBS - Ensure duplicity config path; excludes + file: + path: '/root/.duplicity/excludes' + state: touch + + - name: BACKUP JOBS - Ensure duplicity config path; gdrive.cache + file: + path: '/root/.duplicity/gdrive.cache' + state: touch + + - name: BACKUP JOBS - Ensure duplicity OneDrive credentials + copy: + content: | + client_config_backend: settings + client_config: + client_id: "{{ gdrive.client_id }}" + client_secret: "{{ gdrive.client_secret }}" + save_credentials: True + save_credentials_backend: file + save_credentials_file: /root/.duplicity/gdrive.cache + get_refresh_token: True + dest: '/root/.duplicity/credentials' + + - name: 'BACKUP JOBS - Ensure duplicity config' + copy: + content: '{{ gdrive.cache }}' + dest: '/root/.duplicity/gdrive.cache' + + - name: BACKUP JOBS - Ensure backup script on host + copy: + content: | + #!/bin/bash + for VM in $(qm list --full | + awk '/netsoc.co/ { if ($2 !~ /"{{ blacklist | join('|') }}"/) { printf "%s\n\n", $1; } }') ; + do CONF=`pvesh get /nodes/$(hostname -s)/qemu/$VM/config --output-format=json` && + [[ `echo $CONF | jq .virtio0` != "null" ]] && [[ `echo $CONF | jq .virtio0` != *"backup=0"* ]] && pvesh set /nodes/$(hostname -s)/qemu/$VM/config -virtio0 `echo $CONF | jq -r .virtio0`,backup=0 && sleep 5; + [[ `echo $CONF | jq .virtio1` != "null" ]] && + echo "Backing up $VM" && MDIR="{{ backup.directory }}/$(echo $CONF | jq -r .name)" && + mkdir -p $MDIR && (vzdump --compress {{ compress }} $VM --mode {{ mode }} --dumpdir $MDIR --exclude-path /boot || + curl -H "Content-Type: application/json" -X POST -d "{\"username\": \"$(hostname -s)\", \"content\": \"Error backing up VM $VM\"}" {{ webhooks.discord }}); + done; + GOOGLE_DRIVE_SETTINGS=~/.duplicity/credentials duplicity --exclude-filelist ~/.duplicity/excludes {{ backup.directory }} gdocs://{{ gdrive.user_id }}/{{ gdrive.location }}/$(hostname -s) --no-encryption || + curl -H "Content-Type: application/json" -X POST -d "{\"username\": \"$(hostname -s)\", \"content\": \"Error syncing with Google Drive. You may need to update the refresh token in ansible vault :/\"}" {{ webhooks.discord }}; + curl -H "Content-Type: application/json" -X POST -d "{\"username\": \"$(hostname -s)\", \"content\": \"VM backups completed\"}" {{ webhooks.discord }} + rm -rf /root/.duplicity # remove after termination + dest: /root/backup.sh + mode: '0755' + + - name: BACKUP JOBS - Ensure backup cron job on control host + cron: + user: 'root' + name: 'Run VZdump and duplicity for control host' + weekday: '{{ backup.weekday }}' + hour: '{{ backup.hour }}' + minute: '{{ backup.minute }}' + job: > + bash -c " + scp -r -i {{ nac }}/keys/{{ control.name }}/id_rsa -P {{ control.port }} /root/.duplicity root@{{ control.host }}:/root/.duplicity && + scp -i {{ nac }}/keys/{{ control.name }}/id_rsa -P {{ control.port }} /root/backup.sh root@{{ control.host }}:/root/backup.sh && + ssh -i {{ nac }}/keys/{{ control.name }}/id_rsa root@{{ control.host }} -p {{ control.port }} /root/backup.sh + " >> /var/log/backup-{{ control.name }}.log + + - name: BACKUP JOBS - Ensure backup cron job on each host + cron: + user: 'root' + name: 'Run VZdump and duplicity for {{ item }}' + weekday: '{{ backup.weekday }}' + hour: '{{ backup.hour + index }}' + minute: '{{ backup.minute }}' + job: > + bash -c " + scp -r -i {{ nac }}/keys/{{ control.name }}/id_rsa -P {{ control.port }} /root/.duplicity root@{{ control.host }}:/root/.duplicity && + scp -i {{ nac }}/keys/{{ control.name }}/id_rsa -P {{ control.port }} /root/backup.sh root@{{ control.host }}:/root/backup.sh && + ssh -i {{ nac }}/keys/{{ control.name }}/id_rsa root@{{ control.host }} -p {{ control.port }} \" + scp -r /root/.duplicity root@{{ item }}:/root/.duplicity && + scp /root/backup.sh root@{{ item }}:/root/backup.sh && + ssh root@{{ item }} /root/backup.sh && + rm -rf /root/.duplicity + \" + " >> /var/log/backup-{{ item }}.log + + when: item != control.name + loop: "{{ groups['proxmox_hosts'] }}" + loop_control: + index_var: index + + vars_files: + - 'vars/secrets.yml' + - 'vars/secrets_mapping.yml' + - 'vars/backups.yml' diff --git a/setup-control-host.yml b/setup-control-host.yml index d025b131..ad7100b1 100644 --- a/setup-control-host.yml +++ b/setup-control-host.yml @@ -1,22 +1,29 @@ - hosts: control - gather_facts: no + become: yes roles: - - ansible - git - hosts: control - tasks: + tasks: - set_fact: sysadmins: - { name: eric, public_key: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDIH9yhmm/hMX3FHK5TAaSwYHGl94CrG56Sy7CQNTymlsq3XFMuP2cWuTUNwj3uN22Mj+id+6AhvcttE5o5h3ASuVWY51CKHsq1NliOAnPUlSN5X9EEWbeYzAN5aWaars4Kwvrhf22TrPqVI7kjiRIF2ikR3j4tSyrX7Bjtn9WIsYzFGTCrGTFCKa8ImjwxKSJkRmiuuVRKoofk4M+517G7vRl9Q/14fpp9SndmSIosQFXUyEVTX66h2Uu3feOKB3XUSps6I8UicVmnXO0ZNS/YpWKK2oiA6RVbVRzPBAZx/RoQYhJ2t8rlMTdadZvOL+8WUGKlKcSMQ6+rLV9Z6FhIiXdxHoQGLA1R2R83CGltN44DmT/G3pa0Jcl3k0YJ1Qyxnb5WOq/BoTscCSIdnfHN9K9pFgICjt4qa1s9sSxg0YgSZhVo2FUMBj7EJZVWmA5dda50hdnmAFPD6TLrcFwi6YHi1S2WYklXATkobUanbov70os87yT8i7xX48sah5rE9vzr7EiiFDuF+9QpH42Nog49JqOo4ypTYiBl7rL0RBpAekHTmUKM0MukPvdNNX8FBdkcDX0kSqlNlosysg/fJkGxsZWRRpfB4pl1Q23q+LDcjswyJOF0Nwta+ILtyQdanx1Zs0peqjiwZjOe1fM9k8hDtXcLIxvMI4qZCdM5cQ==" } - - { name: jac, public_key: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDwrBcldRunun/bN5EfBmUKGf2exQscaNaRv/6C97IOWpfmaTvu7VoObkJhxkvYjqs2ZEnpvVgegXN1yQ0Tq+hO2c3ZHbn6aOAlwcAC8ToYkjq/cpnAYpQr4PRiDennIeQzzbF5vZZXNA37rHToc0GAHvFWlwemDaWiCOXZzK6KLpTT4kiWcKI8FowcJ0z/UDCGAaA4rRuntcbfvvkoZjXxgbL0nW6LakZutAFO9SM8RGHiu9NYCw3aKV8ggAfwE09ojszcE/TgHkeGXnHalsqLLGmEgboaiGgozsO6J9/iMYEmNf9M4LPxuIVUYTbF4HduRDsIhzAcinUrda0tdli64gBcfObQgUFFho7RRezZk5Ofyq87oWz5rDZivxGx6BfdGx3u8WiGekIx7m9RV6irdpCMMcKmxRQ++9u9dPstrJQlkq0bkb+FNGPzfagCvbrIJx+2rjotAfD6DF18JrPIpzQdlXnPKmkb3+iCcpEXHiKNQiDf9SV1kxWkCby7LBYllfZhqhYuZnjMTMtLdc8D2UJXawVL7JYXBeD9e/9tyK2Bp1CFymftCL9wCLU8hlSbZ/sItcxD+4EoZpBs+UK+TyUpPTEAwCRtzECjXk8Ppba0EyTDXnvTtNRRElYJDBFq8ZVSrBKrfI4KNXa+vrhd0h7b0spAt39zAy4dZOpqKw==" } - - { name: arthan, public_key: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDTYW99tbx5gUgTqvbQVRj27Lhz6A3ugS70RsbLxKso5OxcrOJJ4RPwpyT0hYekUV/usigqshnirGUqnuA3wl3J4N2WI2gVbUaOKJmbrAlTRgQvEmAACztXSmlRgBQ7g04OKpC9f/Ira924JbYzgpiPmoJDJZ+QOKmAdJHHVlFI6EzGAk8GNLHF1FpTxWXtKMOTYlW0VURf1dy4yO/8d8+cw4wRd4Q39/6ESNjo9TrxSvPNO8yWw/XmL5YVCFZ1sV/q0f5TiBN9fuoTv0peKGbdLJGU8AzRfuJT4DJSs8AwAn8Ug09VuPrnjlDS9PmeQlxYD6PsmmmHu76I31gU1u2BP2h5AkdbIb//3AuvA4VUZzTePDeE4ozfHwWJY5JPlWpvTPJSOMAfY9ZP1EzZY+Mw3U2JyLwVtamlF6Qt4zPz+cPH0iRNr8GsfN+1YdaEQ1eP/X+PlvlbvEzDAvn51QTHW6dqrp1uRaK7glT17MgWb4bonDtt3A1j6pW9KizRomo58HxnFtElMLTBLcrdka1p8VzwIrhkMOFepoWUB7ozOqS6hyokb4yeQgkTOmTCU6sc5tRPjxNaA0S6NXi7nz30QQysLKGb4mda0DsFIqudad9sqIzGjyvvsFUCYBqGnTONsQHD1RQClvTa7UyzBWbcYftAzUIBOIakpwBofuZFnw==" } - - { name: thomas, public_key: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDELuxQz6pZKnoEz/8rpNNMKiBEqplDQ63oZiU11zqhUPhI9XzCdWTDUjiEjGzbiOjj9B+ls3HBCn0EEuXzfEohz5g2Vd8BNs85gP0j1xyQ3CtYybD3UhTLPVlmSezZxDwb1/tzgfh8asJh6eFOLH7Z7v6BNMYuFblCFIzN9COVCegxpnBBGszBBgfAGDyc8ayEZxIeTnckTsLqv+0nYb3ud2bF9HWToXRMljPbfwBLGezQRrr6S4SrTQzlQT86kGJjzYTT/UrQUOMTN4zDb205ZAtPqnlqNyr8146w/hXydzhF04eX94xZerazXZzgxez3GsWN/g9nzqwkLtTjoX83qAftTz8SPioRvuXUptYCma9DyNEm4VeCAVzbsH9geOgMbzBjYqGwuTPQiX6bD7ItgQzEs9uVRMMcIhBMFrE45ecLAA/o/0s9r+7jUDeG26e+EwtluRmVdnGm5KzIkg1zCWUn+Pxg3AslmUAssMuZJKGJV0FyBJsganSE7pQWQN0swdqN9AyZm5AMyiEpGddzZ90AEqDGm5iYJFrPnk3wv7uHqI8ChTd2NC4id6qrUhtr9kf5ebtvbItzIwpzKkZA5/7wOlrBsxlyeBKyyuAef4umduRC0/UCEPF74Lel545p5IgprNTx1UZSTcaMS9/2VMbyGRxvoDcRrsPkpkhZKw==" } - - { name: strum355, public_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIz3MrCIBKCBFzoE+jQkKcR3kzf5LHx2XAuFsHmVhsWs" } + - { name: jac, public_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIL/IHyI7Ohh01Y4lmaGifVcXLdzIHiT+GLzEpYrG7pca" } + - { name: thomas, public_key: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDmEeA6/INHf3eSyTjviBGSkgJwbDZR0ERBXtrOfM6D3dgUmwbu5zYpuAASmRUQIRnq7VKJrNyVZtxIighBD10DrJjyysYmeCEyKcYil6RrWsbMLsSMsYeda0YPdePAQlT+oYEE0j1QL7k2uBaHHMgEDaYpvogUJdXKZdnVdHCPz7fFFsop5b0GtkrlmU/a8WjJrmJw4Yl47woz2ipLGZiaOAuTpj2ZzpxQOVgIJt7Zu0vfcQV8Ivbhbg4epjIbm/eRi2odbw0oyUAwrqu9u23lwXPfzINl5BoO3gERwRYXx5K8R7nQK93rlwnWVYMx5ru7M4wRvDZL/ikOxZAsIZa1AFY0nLL2/AC23s6OYP0PkByn2s3gGi42AgzqvZdzlicHC1mpWSZUFFMq8QWMmkHujRegX9eL1YCJAvOfjdFl5zW7O+eUEsz68raAeWQVnw7Mkc4v7+kLSUx4RRqcUEqOiWG1lMCybbpDoRewvXvYYezFd1eysKVA2HngbAA4o8CLtM0fCdElns9ULYU0spnLHDi03/BO7NZKneyvput/AYtwxECnyx6xu7BHjbWBWqc+3/Uw0oTCJ8ZipCg0pqNPBdFx9SpMCRckoIhcd9ezItVzf+dnH21eML0opcAaM95R323abrSwHG8LRbCcP6cUBi/97hq2h8sVfe7CZVPD5Q==" } - { name: ocanty, public_key: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC6KgSclCW2dhdtPc7AfyvOjr9nL+0pQIMRWGtv2AjMNOXfrCf3aOWhiUug1FbEPC+vjYGPaDc4hplj3Kfb5AaVYsY9XF48v1x9hiBtxiyE/BdFNa7aMzXT4qx3GS/kuw/P9CJaYPTTPplase98hTljU13VQrlveh5t1xM1tLLR7y5/adbl3UyMyFY5V+HT1nWns01qsZMe2m0q4Uvz2UbvIlYD5cN3OjTCrMtfeLQGeBOm/ScpkNTbNxu9nomBa6NW3MOp3g3JjBfut4RRZPgWGXfFj0CKBVKTaXc/OFtf5JlcnWpSY6f8DZbW2V8Ymssasqq4HnT4fhA27iwvHoUF4exmgH5B4jtFRZccRyF1W+t9Rxb8EN/MfgMxh1mHCiSBSaNwGCxeNTMT1ZgkWmDcT2GoCJmkVUdF3JbKk26gjVDTI8gDM/Td8cLbgIwc+iLWNd6MXhOR5jt9OsvrT71RV9t0z0RyT/2KsaxJe8UVrI+48va+TpSRfyBcv+BelAE=" } - # - { name: mloc, key: } - # - { name: oisinaylward, key: } - # - { name: fordetek, key: } + - { name: oofsauce, public_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHW94S5zZ3xN2r3M7QL8svMgY1pKI+CKHz4FjIkEZtpH zwei-win@DESKTOP-86PGM04" } + - { name: ciaran, public_key: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDDpUsmZIo4cDkDDUe+hZLH0wBc5fnpmiQA9SQB/bomYGZ8GT4ECvGBRBeIHLARatXVnC39noGmZvpp0msmUaLXadYManQDeFXFiXrQJeM2BLkwyA9HUZfWs8XaN9YO278CwHJlY6gzaGSxhWriSsg5/JTWhACD6mtKVXk7LqD21XOC22HP8oN5uTmrQHb8hePeHK4w4z5iUqsRGANam1JDzv69EMf6zbaFq+8AxTFiQSFXSlm50VFAtk+e3HrZYYgyDrN+5ffYQxeiWP3E4tvgBtvp9XwtIUuS3L/B/WvM5e9ZAy3zML9VR5paRcHLTS1SVut2oSXvulrSf8hkQEhd rsa-key-20211224" } + - { name: reece, public_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIC6ifkMAy38PHhm2bN00lmtwOrYQqpclFIVis6J6V9sV" } + - { name: colm, public_key: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDOJk4xXXqU5CI6h7m/A1Afkk9AHRPITmpY3V/S4Fse5aqvKrARx8g3TQ/cpFZ24gp7IlGegVIaCmfOZOPuFlgySrIrFR7VhcP3I3GWeDgAS/QeInLJCC5tYiEWFhgJLYO6C6s6l1avUBPWttUzniA1lMj9FfHBgrRlhneEVbryvbnT4ldGiF7kQPDqtrjWOKaPyqekFakAuT+t73ohTJzeu7uxMS+K7/VfbEvAaTMNBTTqJkhFitgiydh4Chmqn67KoBVX6/s8gprkSc3W2ZfwNLfoFleptLpTj8+4OF+hg0uXau/EnIzBiFJ5D/R7smgS1IopFR+uGH6NS80Ap7txWMLe4YoglL85jLmZ5DQnjEjMcDIFFWhhoWCCvJT3s3OsMTM51lSAmfTlb1Bh2cqX8rM9Iu0Qhe9JdN7bez1KQGMWEfaT1igDjDwdTUBS6xP/s9PZ+VhNihJuvS/Es0KYnFoYNZG4WLbP6agbdfWZ8toq1vss6Mxbffi1WfxXGvs= colm@pop-os" } + - { name: max, public_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIM1IpwXwefHIZpFyXVTdvFUUuMAizWMBKN3rZRSvQrDP max"} + - { name: meabh, public_key: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCpaZI30OkhPqdzug8c4ejR3cZI0+nSkaofHxSfhB78qN6H+9AX7fa+7aEt/9VmSD+MfnVn+A6G9cRVEkYXZ+KVMD880ZGUkPdmDH/mZPhjfZIT8oEj4sm4aQu1skWkSXhSwEpZU2NG8A3tFDPvjXsCvbR9URFddKYEcJkez1bsd+LdOUOkLm/l0DtLJ3KNNe9lVXtSFyGEB2sKO5zvLKfeq6Q3065sLJS27kuR7IkhPJ14hH2YZo5ln0LmiriacDGr8+auWEIYCOX5TvD3W7MCGc5s4IXj5fx6JkFUMCEfVRm/kEu9Nv3Q9xk51TUjZAPZ4iRnOoZSChJlzS0nCCeWiMhPY8o/1wgfGFpK+ZtEarrTTEhoiQoNvHxKQzjgBFHeColJoiZn24Qp1X3cxziZVi/V5UIPFPi7uzv265+745gOorwfBJPDAf9sYAFUk0Z87rpr7w1pfRf2crIpHeRcM8CqH8yW3Rb8F3maIhA4tkVQjZK8V5rmZ+2Q3t1yzk0Y82CxU9zCjfLUz6aEH5yRbDII9Jn+moxuH7KXSui29sy/bP3e0arqd7XZToa7mM4ipoDgX81P6sLW80z8d9XEHyOpXPEXAI0+6bow5mE8cLN3PMyRMsgk/bALZp5vgr6HRR5k6P3UmACRHE5k7sDlcfbdZrlBPApB67h0WDDdAQ==" } + - { name: Dolan, public_key: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC2Zsh6oW47sGOq6xuIuPZ2vg24OtcwWapWzNXbfrFJ/ed7A1BGc3CU59C2bdU5mnJarUm/Dk78C7SaPMtmRCXKcFZ+bHqRz5x/a0aMKwc97rR2USF60EQyLwyBgHXdPr+KeIFRHKQPPkf2CHiZuQ7+9Yma5EyJD8u1tOmGsV6/U4kmK/op09OqZcQ5BU3bBxyUuz3hAlNbAtzLW+kLZRS93q9BDeaMJHXiDfhRTSV6rfbR3rcrmYlSr/0QpWAfmevjfjMsTkT0YDJZRLWkcMtgqPTZ3Qla0mg6xaZlECBUJHeqC29ODFcg6gotn6FPmR3I3TwDdC94yw5lgTjVTbZ7jHqPADuJkaFEgQsQrSeh5iA/SkbFs8MPq1CDmPmbGDGXC8DxMooDdXBcXz2WOjGwF8v7gB8whYpj4hbaGvyWvyXd0pB+/GVvVAjB8tkgqdzF+8WRpWUFqMRm+ZAXsLkoNPtXqiD6e/08L9fwTMP1XObKLXUvcBwAmvWzF9p54RCCu1Wp5By/+5ORiU56UIyAEeSZmSSSpKB+U5JODbYhDenBDMhfAEzOYng9890LsDx85tEdPs+nDQ1P5G/e9kOd8HyheWBNtIR94NUJ9vLNephwG1dadMC5PXtbC5u3+m8iJrOf4TkX4q9CcSql+aycOnVFlxYf1reo4KwR+slN5w=="} + - { name: shang, public_key: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCV1uY+Y6pzN8xp2Z8axn72zxW4DqjXUeiVyQoWkQk2OHRGJ6nipnEo2AVtWdz1WSoXw7QehNa41Tik078daxBUsgbU8F7+6eic16FGeYTRnFV67yPgq0mzSAxQ1K+wleRmNTC5UigDU9wkGh8q8QjGheMxuIAwhjiq2rE+EeO8HmVn4htNlGSEtyTNmx+DDLBGh4GH4evr7o0zUMmBmckO0c4mwv1uJCGovVLYq0W0o9AsKZj08J67+Src0y+zKkUxkO7Qk3BrLfWMx2vOBrs+6gasFvxMurCtV5Ym+mpguJJG7WG7v5WO7kU0MS3OpkDHiMWzhxuohKcTv9JEF4xJh3x91O+d4mcXt+pnj1OeTmil6bQTarlsnUIEWmVYo6pwxDZNRLBFmjBvDR73t+EUiFX92h9+7rSkqT9nhiHYQyC/cOdZD4/wZjR+WMD7XTMb5o0OQ+9tDCrj0RKAhAZ/+DMgMgrf0i4E5EkUyc27VG0S7EOfQ+pxSDveob0ayGiOrkFJLFDQwaHFWDQwg5YL6vaSFYWG7IqcWOFCjtcMEviKkoNSkm7DHoswdrbv7BH3xt0hWhvrUDhwZzhkmWtAWux7XpWfFYQSXHPjLbRWyJ/084TZlevDnKLGa8tADHoTSs2aTa92p92GHOIncRi6MNp6OJMPl1cc/4seOYulXQ=="} + - { name: victor, public_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOKNBark29wr9F9lR/PqwhnWzRFiE8HNx1f/0iazzogW"} + - { name: aleksy, public_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH+gipoXcQyEB8Vel+P7benQW1s/gH2KJ3jNk+a5P20H"} + + # User used by github action deployments: + - { name: github, public_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDSRDNj4SupDnA/1fjJ23GGVVpYF0rL8op/ExrQYQAtI" } - name: Setup SysAdmin accounts hosts: control @@ -25,8 +32,8 @@ group: name: netsoc_sysadmin state: present - - - name: Create SysAdmin Linux accounts + + - name: Create SysAdmin Linux accounts user: name: "{{ item.name }}" state: present @@ -41,7 +48,13 @@ state: present with_items: "{{ sysadmins }}" - - name: Create netsoc_sysadmin Proxmox group (if it doesn't exist) and give it admin role + - name: Add SysAdmins to sudo + lineinfile: + path: /etc/sudoers + regexp: "%admins ALL=(ALL) ALL" + line: "%netsoc_sysadmin ALL=(ALL) ALL" + + - name: Create netsoc_sysadmin Proxmox group (if it doesn't exist) and give it admin role shell: | pveum group list --output-format=json | jq .[].groupid | grep netsoc_sysadmin || pveum group add netsoc_sysadmin -comment 'Netsoc SysAdmins' pveum aclmod / -group netsoc_sysadmin -role Administrator @@ -49,4 +62,15 @@ - name: Create Proxmox-PAM users for Netsoc SysAdmin Linux accounts (if they don't exist) shell: | pveum user list --output-format=json | jq .[].userid | grep {{ item.name }}@pam || pveum user add {{ item.name }}@pam --groups netsoc_sysadmin - with_items: "{{ sysadmins }}" \ No newline at end of file + with_items: "{{ sysadmins }}" + + - name: Create `netsoc_cloud` Proxmox Resource Pool (id it doesn't exist) + shell: | + pvesh ls /pools --output-format=json | jq .[].name | grep "netsoc_cloud" || pvesh create /pools --poolid netsoc_cloud --comment "User Containers & VMs" + +- name: Clone NaC onto github account + hosts: control + tasks: + - git: + repo: 'https://github.com/UCCNetsoc/NaC.git' + dest: /home/github/NaC diff --git a/setup-external-dns.yml b/setup-external-dns.yml index 96198616..37ce6f3c 100644 --- a/setup-external-dns.yml +++ b/setup-external-dns.yml @@ -1,179 +1,195 @@ --- - - name: "Setup DNS" hosts: localhost connection: local tasks: - set_fact: + records: + "netsoc.co": + # A + - { type: A, name: "cix-0", value: "84.39.234.50" } + - { type: A, name: "cix-1", value: "84.39.234.51" } + - { type: A, name: "cix-2", value: "84.39.234.52" } + - { type: A, name: "cix-3", value: "84.39.234.53" } + - { type: A, name: "cix-4", value: "84.39.234.54" } + - { type: A, name: "ucc-0", value: "143.239.87.40" } + - { type: A, name: "ucc-1", value: "143.239.87.41" } + + # Historical hostnames + - { type: A, name: "bigbertha", value: "84.39.234.50" } + - { type: A, name: "boole", value: "84.39.234.54" } + - { type: A, name: "feynman", value: "84.39.234.53" } + - { type: A, name: "leela", value: "84.39.234.51" } + - { type: A, name: "lovelace", value: "84.39.234.52" } + + - { type: A, name: "elon", value: "143.239.87.40" } + - { type: A, name: "tesla", value: "143.239.87.41" } + + # handbook + - { type: CNAME, name: handbook, value: "uccnetsoc.github.io" } + + # status + - { type: CNAME, name: status, value: "uccnetsoc.github.io" } + + # For old ldap + - { type: CNAME, name: ldap, value: elon.netsoc.co } + + # To cix-3.netsoc.co + - { type: CNAME, name: control, value: "cix-3.netsoc.co" } + - { type: CNAME, name: minecraft, value: "cix-3.netsoc.co" } + + # To cix-1.netsoc.co + - { type: CNAME, name: leela-vm, value: "cix-1.netsoc.co" } + - { type: CNAME, name: admin, value: "leela-vm.netsoc.co" } + - { type: CNAME, name: mysql, value: "leela-vm.netsoc.co" } + - { type: CNAME, name: "*.evan", value: "leela-vm.netsoc.co" } + - { type: CNAME, name: www.*.evan, value: "leela-vm.netsoc.co" } + + # To cix-1.netsoc.co + - { type: CNAME, name: web, value: "cix-1.netsoc.co" } + + - { type: CNAME, name: netsoc.co, value: "web.netsoc.co" } + - { type: CNAME, name: ipa, value: "web.netsoc.co" } + - { type: CNAME, name: keycloak, value: "web.netsoc.co" } + - { type: CNAME, name: semaphore, value: "web.netsoc.co" } + - { type: CNAME, name: traefik, value: "web.netsoc.co" } + - { type: CNAME, name: prometheus, value: "web.netsoc.co" } + - { type: CNAME, name: ci, value: "web.netsoc.co" } + - { type: CNAME, name: grafana, value: "web.netsoc.co" } + - { type: CNAME, name: loki, value: "web.netsoc.co" } + - { type: CNAME, name: bot, value: "web.netsoc.co" } + + - { type: CNAME, name: wiki, value: "web.netsoc.co" } + - { type: CNAME, name: whodis, value: "web.netsoc.co" } + - { type: CNAME, name: links, value: "web.netsoc.co" } + - { type: CNAME, name: www, value: "web.netsoc.co" } + - { type: CNAME, name: mentorships, value: "web.netsoc.co" } + - { type: CNAME, name: tutorial, value: "web.netsoc.co" } + - { type: CNAME, name: constitution, value: "web.netsoc.co" } + - { type: CNAME, name: portal, value: "web.netsoc.co" } + - { type: CNAME, name: blog, value: "web.netsoc.co" } + - { type: CNAME, name: discord, value: "web.netsoc.co" } + - { type: CNAME, name: esports, value: "web.netsoc.co" } + - { type: CNAME, name: cloud, value: "web.netsoc.co" } + - { type: CNAME, name: "*", value: "web.netsoc.co" } + - { type: CNAME, name: www.*, value: "web.netsoc.co" } + + - { type: CNAME, name: build, value: "web.netsoc.co" } + + # MX + - { type: MX, name: "netsoc.co", value: "mx.zoho.com" } + - { type: MX, name: "netsoc.co", value: "mx2.zoho.com" } + + - { type: MX, name: "blog.netsoc.co", value: "mxa.eu.mailgun.org" } + - { type: MX, name: "blog.netsoc.co", value: "mxb.eu.mailgun.org" } + + # TXT + - { type: TXT, name: "_dmarc", value: "v=DMARC1; p=none"} + - { type: TXT, name: "_github-challenge-uccnetsoc", value: "58926b4c4e"} + - { type: TXT, name: "netsoc.co", value: "v=spf1 mx include:zoho.com include:u18778499.wl250.sendgrid.net -all"} + - { type: TXT, name: "zoho._domainkey", value: "k=rsa; t=y; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCB3sWPAMJHYvSCWEueINNaIsPy4OeAQgFsm3y+IcOSUcXJUhHr+LrYGuD9SZzIEh0ekm0Usm73gRz4LgGYfeZ9SXbR3H1LupOETGym0FRRQnAjnXI9L/wfaOzYwbpKm04lhpbobhAwrtsUcgMyo+wmEByM3AR25+YDmlUuijmNTwIDAQAB" } + + - { type: TXT, name: "blog.netsoc.co", value: "v=spf1 include:mailgun.org ~all"} + - { type: TXT, name: "email._domainkey.blog.netsoc.co", value: "k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDc8qQcyiS0SM47o6W3yzGAT9dT3f5uyEGnYvljOU05nq7tcpBcxatOrJS0ADhqCBr/o20K4s1BKYecR9ChXOWQkDSpw67piVWlg9ikoOMv9B3jtu1w/z5FrGYX1m5lVYPkY6p7M9FRYF+CM26oqjl0Al11nhfu/h9EWDQCGzXaQQIDAQAB" } + + # Email + - { type: CNAME, name: "em9504", value: "u18778499.wl250.sendgrid.net"} + - { type: CNAME, name: "s1._domainkey", value: "s1.domainkey.u18778499.wl250.sendgrid.net" } + - { type: CNAME, name: "s2._domainkey", value: "s2.domainkey.u18778499.wl250.sendgrid.net" } + + - { type: CNAME, name: "email.blog.netsoc.co", value: "eu.mailgun.org" } + + # SRV + - { type: SRV, name: "minecraft", proto: "tcp", service: "minecraft", port: "1194", priority: 0, weight: 5, value: "minecraft.netsoc.co"} + - { type: SRV, name: "build", proto: "tcp", service: "minecraft", port: "16938", priority: 0, weight: 5, value: "build.netsoc.co"} + "netsoc.cloud": + - { type: CNAME, name: "netsoc.cloud", value: "web.netsoc.co" } + - { type: CNAME, name: api, value: "web.netsoc.co" } + - { type: CNAME, name: proxy, value: "web.netsoc.co" } + - { type: CNAME, name: ssh, value: "web.netsoc.co" } + - { type: CNAME, name: sftp, value: "web.netsoc.co" } + - { type: CNAME, name: "*", value: "web.netsoc.co" } + "netsoc.dev": + # A + - { type: CNAME, name: "*", value: "web.netsoc.co" } cf_headers: X-Auth-Email: "{{ cloudflare.api.email }}" Authorization: "Bearer {{ cloudflare.api.dns_api_token }}" Content-Type: "application/json" - - # DNS for netsoc.dev - - name: "Get zone ID for netsoc.dev" + grafana_basic_auth: "{{ grafana.username }}:{{ grafana.password }}" + + # - name: "Set Grafana dashboard annotation" + # uri: + # url: https://grafana.netsoc.co/api/annotations + # method: POST + # headers: + # Content-Type: "application/json" + # Accept: "application/json" + # Authorization: "Basic {{ grafana_basic_auth | b64encode }}" + # body_format: json + # body: '{ + # "panelId": 10, + # "dashboardId": 25, + # "time": {{ ansible_date_time.epoch | int * 1000 }}, + # "tags": [ "ansible" ], + # "text": "Ansible setup-external-dns.yml playbook started", + # }' + + - name: Get zone details for all domains in `records` uri: - url: https://api.cloudflare.com/client/v4/zones?name=netsoc.dev + url: "https://api.cloudflare.com/client/v4/zones?name={{ records | join(',') }}" return_content: yes headers: "{{ cf_headers }}" - register: zone_id_result + register: zone_details - - name: "Get zone records for netsoc.dev" + - name: Get all dns records for domains in `records` using zone id uri: - url: "https://api.cloudflare.com/client/v4/zones/{{ zone_id_result.json.result[0].id }}/dns_records?per_page=100" + url: "https://api.cloudflare.com/client/v4/zones/{{ item }}/dns_records?per_page=100" return_content: yes headers: "{{ cf_headers }}" + loop: "{{ zone_details.json.result | map(attribute='id') | list }}" register: zone_records_result - - name: "Delete records for netsoc.dev" - cloudflare_dns: - zone: "netsoc.dev" - record: "{{ item.name }}" - state: absent - account_email: "{{ cloudflare.api.email }}" - account_api_token: "{{ cloudflare.api.key }}" - with_items: "{{ zone_records_result.json.result }}" - - - name: "Set records for netsoc.dev" - cloudflare_dns: - zone: "netsoc.dev" - type: "{{ item.type }}" - record: "{{ item.name }}" - value: "{{ item.value }}" - state: present - account_email: "{{ cloudflare.api.email }}" - account_api_token: "{{ cloudflare.api.key }}" - with_items: - # A Records - - { type: A, name: "bigbertha", value: "84.39.234.50" } - - { type: A, name: "boole", value: "84.39.234.54" } - - { type: A, name: "feynman", value: "84.39.234.53" } - - { type: A, name: "leela", value: "84.39.234.51" } - - { type: A, name: "lovelace", value: "84.39.234.52" } - # CNAMEs - - { type: CNAME, name: "*.netsoc.dev", value: "bigbertha.netsoc.dev" } - - { type: CNAME, name: "netsoc.dev", value: "bigbertha.netsoc.dev" } - - { type: CNAME, name: "www.*.netsoc.dev", value: "bigbertha.netsoc.dev" } - - # DNS for netsoc.co - - name: "Get zone ID for netsoc.co" + # Flatten records for all zones and for every record check if name,type,value match any record in playbook in that zone + - name: Delete records not in playbook uri: - url: https://api.cloudflare.com/client/v4/zones?name=netsoc.co - return_content: yes + url: "https://api.cloudflare.com/client/v4/zones/{{ item.zone_id }}/dns_records/{{ item.id }}" + method: "DELETE" headers: "{{ cf_headers }}" - register: zone_id_result + when: > + {'name': item.name | regex_replace('(.+?)\\.?' + item.zone_name + '$', '\\1'), 'type': item.type, 'value': item.content} not in records[item.zone_name] + with_items: "{{ zone_records_result.results | map(attribute='json.result') | flatten }}" + loop_control: + label: "{{ item.zone_name }} {{ item.type }} {{ item.name }} {{ item.content }}" - - name: "Get zone records for netsoc.co" + - name: Refresh dns records uri: - url: "https://api.cloudflare.com/client/v4/zones/{{ zone_id_result.json.result[0].id }}/dns_records?per_page=100" + url: "https://api.cloudflare.com/client/v4/zones/{{ item }}/dns_records?per_page=100" return_content: yes headers: "{{ cf_headers }}" + loop: "{{ zone_details.json.result | map(attribute='id') | list }}" register: zone_records_result - - name: "Delete records for netsoc.co" - cloudflare_dns: - zone: "netsoc.co" - record: "{{ item.name }}" - state: absent - account_email: "{{ cloudflare.api.email }}" - account_api_token: "{{ cloudflare.api.key }}" - with_items: "{{ zone_records_result.json.result }}" - - - name: "Set records for netsoc.co" - cloudflare_dns: - zone: "netsoc.co" - type: "{{ item.type }}" - record: "{{ item.name }}" - value: "{{ item.value }}" - state: present - account_email: "{{ cloudflare.api.email }}" - account_api_token: "{{ cloudflare.api.key }}" - with_items: - # A Records - - { type: A, name: "bigbertha", value: "84.39.234.50" } - - { type: A, name: "boole", value: "84.39.234.54" } - - { type: A, name: "feynman", value: "84.39.234.53" } - - { type: A, name: "leela", value: "84.39.234.51" } - - { type: A, name: "lovelace", value: "84.39.234.52" } - - { type: A, name: "elon", value: "143.239.87.40" } - - { type: A, name: "tesla", value: "143.239.87.41" } - - - { type: A, name: "ns1", value: "84.39.234.50" } # Legacy - - { type: A, name: "ns2", value: "84.39.234.52" } - - - { type: A, name: "ipa.vm", value: "10.0.{{ subnets.infra }}.10" } - - # New - post proxmoxification - - { type: A, name: 80-443-swarm-ingress, value: "84.39.234.53" } - - - { type: CNAME, name: traefik, value: 80-443-swarm-ingress.netsoc.co } - - - { type: CNAME, name: ipa, value: traefik.netsoc.co } - - # ;; CNAME Records - - { type: CNAME, name: admin, value: bigbertha.netsoc.co } - - { type: CNAME, name: alerts, value: bigbertha.netsoc.co } - - { type: CNAME, name: bert.ci, value: bigbertha.netsoc.co } - - { type: CNAME, name: blog, value: bigbertha.netsoc.co } - - { type: CNAME, name: ci, value: bigbertha.netsoc.co } - - { type: CNAME, name: constitution, value: uccnetworkingsociety.github.io } - - { type: CNAME, name: consul, value: bigbertha.netsoc.co } - - { type: CNAME, name: discord, value: bigbertha.netsoc.co } - - { type: CNAME, name: docker, value: boole.netsoc.co } - - { type: CNAME, name: es, value: bigbertha.netsoc.co } - - { type: CNAME, name: esports, value: bigbertha.netsoc.co } - - { type: CNAME, name: "*.evan", value: leela.netsoc.co } - - { type: CNAME, name: grafana, value: bigbertha.netsoc.co } - - { type: CNAME, name: hlm, value: bigbertha.netsoc.co } - - { type: CNAME, name: impressive, value: bigbertha.netsoc.co } - - { type: CNAME, name: irc, value: bigbertha.netsoc.co } - - { type: CNAME, name: ldap, value: elon.netsoc.co } - - { type: CNAME, name: logs, value: bigbertha.netsoc.co } - - { type: CNAME, name: lxd, value: bigbertha.netsoc.co } - - { type: CNAME, name: minecraft, value: feynman.netsoc.co } - - { type: CNAME, name: mysql, value: bigbertha.netsoc.co } - - { type: CNAME, name: "*", value: bigbertha.netsoc.co } - - { type: CNAME, name: netsoc.co, value: bigbertha.netsoc.co } - - { type: CNAME, name: portainer, value: boole.netsoc.co } - - { type: CNAME, name: prom, value: bigbertha.netsoc.co } - - { type: CNAME, name: pterodactyl-daemon, value: lovelace.netsoc.co } - - { type: CNAME, name: sentry, value: boole.netsoc.co } - - { type: CNAME, name: tutorials, value: blog.netsoc.co } - - { type: CNAME, name: unf2b, value: leela.netsoc.co } - - { type: CNAME, name: userdomains, value: leela.netsoc.co } - - { type: CNAME, name: vault, value: bigbertha.netsoc.co } - - { type: CNAME, name: warpcon.co, value: leela.netsoc.co } - - { type: CNAME, name: wiki, value: bigbertha.netsoc.co } - - { type: CNAME, name: www.*.evan, value: leela.netsoc.co } - - { type: CNAME, name: www.*, value: bigbertha.netsoc.co } - - { type: CNAME, name: www, value: bigbertha.netsoc.co } - - { type: CNAME, name: www.warpcon.co, value: leela.netsoc.co } - - # MX - - { type: MX, name: "netsoc.co", value: "mx.zoho.com" } - - { type: MX, name: "netsoc.co", value: "mx2.zoho.com" } - - # TXT - - { type: TXT, name: "_dmarc", value: "v=DMARC1; p=none"} - - { type: TXT, name: "_github-challenge-uccnetsoc", value: "58926b4c4e"} - - { type: TXT, name: "netsoc.co", value: "v=spf1 mx include:zoho.com include:u1980078.wl.sendgrid.net -all"} - - { type: TXT, name: "zoho._domainkey", value: "k=rsa; t=y; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCB3sWPAMJHYvSCWEueINNaIsPy4OeAQgFsm3y+IcOSUcXJUhHr+LrYGuD9SZzIEh0ekm0Usm73gRz4LgGYfeZ9SXbR3H1LupOETGym0FRRQnAjnXI9L/wfaOzYwbpKm04lhpbobhAwrtsUcgMyo+wmEByM3AR25+YDmlUuijmNTwIDAQAB" } - - - name: "Add Minecraft SRV record" - cloudflare_dns: - zone: "netsoc.co" - name: "minecraft" - type: "SRV" - proto: "tcp" - service: "minecraft" - port: 1194 - priority: 0 - weight: 5 - value: "minecraft.netsoc.co" - state: present - account_email: "{{ cloudflare.api.email }}" - account_api_token: "{{ cloudflare.api.key }}" + # For every record in playbook create it if cloudflare does not have it + # Use json_query to extract name,content,type,zone from CF API results + # - CF API uses `zone_name` and Ansible cloudflare_dns uses `zone` so change key to `zone` + # - CF API uses `content` but we use `value`. Ansible cf_dns module has content/value aliased + # For comparison append zone to record name (unless name == zone) as CF API uses full name e.g. sub.example.net + - name: Create missing records + cloudflare_dns: "{{ item | combine({'account_email': cloudflare.api.email, 'account_api_token': cloudflare.api.key}) }}" + loop: > + [ + {% set cf_records = zone_records_result.results | map(attribute='json.result') | flatten | json_query("[].{name: name, value: content, type: type, zone: zone_name}") %} + {% for zone in records %} + {% for record in records[zone] %} + {% set check = {'value': record.value, 'name': record.name | regex_replace('(?!'+zone+')^(.*)$', '\\1.' + zone), 'zone': zone, 'type': record.type} %} + {% if check not in cf_records %} + {{ record | combine({'zone': zone}) }}, + {% endif %} + {% endfor %} + {% endfor %} + ] vars_files: - vars/network.yml - - vars/cloudflare.yml - - vars/secrets.yml \ No newline at end of file + - vars/secrets_mapping.yml + - vars/secrets.yml diff --git a/setup-proxmox-host-initial-networking.yml b/setup-proxmox-host-initial-networking.yml deleted file mode 100644 index cb926eec..00000000 --- a/setup-proxmox-host-initial-networking.yml +++ /dev/null @@ -1,71 +0,0 @@ ---- - -# This playbook needs to be ran manually on the Proxmox host before it has any networking setup -# It sets up the bridges for VLANs - -- name: "Setup bridges & Packer DHCP bridge" - hosts: localhost - connection: local - roles: - - role: packer-provisioning-dhcp-bridge - vars: - bridge_inteface: "vmbr1" - bridge_address: "10.0.100.1" - bridge_netmask: "24" - nat_interface: "vmbr0.20" - dhcp_range_begin: "10.0.100.2" - dhcp_range_end: "10.0.100.254" - dhcp_netmask: "255.255.255.0" - dhcp_lease_length: "24h" - dhcp_dns_servers: "8.8.8.8,8.8.4.4" - - # TODO(ocanty) - automate me - # tasks: - # - name: Setup /etc/network/interfaces - # copy: - # content: | - # source /etc/network/interfaces.d/* - - # auto lo - # iface lo inet loopback - - # iface enp6s0 inet manual - - # iface enp4s0 inet manual - - # iface ens3f0 inet manual - - # iface ens3f1 inet manual - - # auto vmbr0 - # iface vmbr0 inet manual - # bridge-ports enp6s0 - # bridge-stp off - # bridge-fd 0 - # bridge-vlan-aware yes - # bridge-vids 2-4094 - - # auto vmbr0.10 - # iface vmbr0.10 inet static - # address 10.0.10.53/24 - - # auto vmbr0.20 - # iface vmbr0.20 inet static - # address 10.0.20.53/24 - # gateway 10.0.20.1 - - # auto vmbr0.30 - # iface vmbr0.30 inet static - # address 10.0.30.53/24 - - # auto vmbr0.80 - # iface vmbr0.80 inet static - # address 10.0.80.53/24 - - # auto vmbr0.90 - # iface vmbr0.90 inet static - # address 10.0.90.3/24 - - # auto vmbr0.40 - # iface vmbr0.40 inet static - # address 10.0.40.53/24 diff --git a/setup-proxmox-host-initial.yml b/setup-proxmox-host-initial.yml new file mode 100644 index 00000000..b435db5c --- /dev/null +++ b/setup-proxmox-host-initial.yml @@ -0,0 +1,108 @@ +- name: Ensure ansible and provisioning requirements on proxmox host + hosts: localhost + gather_facts: no + pre_tasks: + - name: 'Install Dependencies' + become: yes + apt: + name: + - python3-pip + - sudo + + # - name: 'Pin httplib2<0.16.0 to ensure duplicity works' + # pip: + # executable: /usr/bin/pip2 + # name: httplib2 + # version: '0.14.0' + + # - name: 'Ensure pydrive for duplicity' + # become: yes + # pip: + # executable: /usr/bin/pip2 + # name: pydrive + + # - name: 'Ensure backups directory' + # become: yes + # file: + # name: '{{ backup.directory }}' + # state: directory + + # - name: 'Ensure duplicity' + # become: yes + # apt: + # name: duplicity + # state: latest + # update_cache: yes + vars_files: + - 'vars/secrets.yml' + - 'vars/secrets_mapping.yml' + - 'vars/backups.yml' + roles: + - ansible + - ifupdown2 + - packer + - jq # for manipulating the proxmox api pvesh when it was --output-format=json + + + # TODO(ocanty) - automate me + # tasks: + # - name: Setup /etc/network/interfaces + # copy: + # content: | + # source /etc/network/interfaces.d/* + + # auto lo + # iface lo inet loopback + + # iface enp6s0 inet manual + + # iface enp4s0 inet manual + + # iface ens3f0 inet manual + + # iface ens3f1 inet manual + + # auto vmbr0 + # iface vmbr0 inet manual + # bridge-ports enp6s0 + # bridge-stp off + # bridge-fd 0 + # bridge-vlan-aware yes + # bridge-vids 2-4094 + + # auto vmbr0.10 + # iface vmbr0.10 inet static + # address 10.0.10.53/24 + + # auto vmbr0.20 + # iface vmbr0.20 inet static + # address 10.0.20.53/24 + # gateway 10.0.20.1 + + # auto vmbr0.30 + # iface vmbr0.30 inet static + # address 10.0.30.53/24 + + # auto vmbr0.80 + # iface vmbr0.80 inet static + # address 10.0.80.53/24 + + # auto vmbr0.90 + # iface vmbr0.90 inet static + # address 10.0.90.3/24 + + # auto vmbr0.40 + # iface vmbr0.40 inet static + # address 10.0.40.53/24 + + # - role: packer-provisioning-dhcp-bridge + # vars: + # bridge_inteface: "vmbr1" + # bridge_address: "10.0.100.1" + # bridge_netmask: "24" + # nat_interface: "vmbr0.20" + # dhcp_range_begin: "10.0.100.2" + # dhcp_range_end: "10.0.100.254" + # dhcp_netmask: "255.255.255.0" + # dhcp_lease_length: "24h" + # dhcp_dns_servers: "8.8.8.8,8.8.4.4" \ No newline at end of file diff --git a/setup-proxmox-hosts.yml b/setup-proxmox-hosts.yml deleted file mode 100644 index fc30ff17..00000000 --- a/setup-proxmox-hosts.yml +++ /dev/null @@ -1,8 +0,0 @@ -- name: Ensure ansible and provisioning requirements on every proxmox host - hosts: proxmox_hosts - gather_facts: no - roles: - - ansible - - ifupdown2 - - packer - - jq # for manipulating the proxmox api pvesh when it was --output-format=json \ No newline at end of file diff --git a/ssh.sh b/ssh.sh deleted file mode 100755 index f877cdc9..00000000 --- a/ssh.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/bash - -hostname="$1.vm.netsoc.co" -ip=`./proxmox_inventory.py --list | jq '._meta.hostvars["'$"$hostname"'"].ansible_host' | sed 's/"//g'` -key=`./proxmox_inventory.py --list | jq '._meta.hostvars["'$"$hostname"'"].ansible_ssh_private_key_file' | sed 's/"//g'` -echo $ip -shift -ssh netsoc@$ip -i $key -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o LogLevel=ERROR $@ diff --git a/start-dev.sh b/start-dev.sh index dbbaaeb9..ee45352b 100755 --- a/start-dev.sh +++ b/start-dev.sh @@ -1,9 +1,20 @@ #!/bin/bash if [ ! -d "./bin" ]; then - virtualenv -p /usr/bin/python2.7 . + virtualenv -p /usr/bin/python3 . source bin/activate - pip install requirements.txt + pip install -r ./requirements.txt + ansible-galaxy install -r requirements.yml fi -bash --init-file <(echo "source bin/activate; source proxmox_secrets.sh") +git config --local merge.ansible-vault.driver "./vault-merge.sh %O %A %B %L %P" +git config --local merge.ansible-vault.name "Ansible Vault merge driver" + +if [[ $# -eq 1 ]] ; then + if [[ $1 == 'fish' ]] ; then + fish -C "source bin/activate.fish; source bass.fish; bass source proxmox_secrets.sh" + fi + exit 0 +fi + +bash --init-file <(echo "source bin/activate; source proxmox_secrets.sh") \ No newline at end of file diff --git a/template-netsoc-ubuntu-server.yml b/template-netsoc-ubuntu-server.yml deleted file mode 100644 index 33a456d4..00000000 --- a/template-netsoc-ubuntu-server.yml +++ /dev/null @@ -1,12 +0,0 @@ -- name: "Ensure Ubuntu Template" - hosts: proxmox_hosts - roles: - - role: packer-proxmox-template - vars: - template_name: "netsoc-ubuntu-server" - build_host: lovelace - build_directory: ./packer/netsoc-ubuntu-server - vars_files: - - vars/packer.yml - - vars/proxmox.yml - - vars/secrets.yml \ No newline at end of file diff --git a/template-netsoc-vyos-router.yml b/template-netsoc-vyos-router.yml index 01f2de41..b725d89b 100644 --- a/template-netsoc-vyos-router.yml +++ b/template-netsoc-vyos-router.yml @@ -13,7 +13,7 @@ # chdir: /tmp/vyos-build # - name: Build ISO # shell: -# docker run --rm -t --privileged -v $(pwd):/vyos -w /vyos vyos-builder bash -c "./configure --custom-package python-pip --custom-package qemu-guest-agent --custom-package expect --custom-package python3-jsonschema --custom-package python3-oauthlib --custom-package python3-jsonpatch && sudo make iso" +# docker run --rm -t --privileged -v $(pwd):/vyos -w /vyos vyos-builder bash -c "./configure --custom-package python3-pip --custom-package python-pip --custom-package qemu-guest-agent --custom-package expect --custom-package python3-jsonschema --custom-package python3-oauthlib --custom-package python3-jsonpatch && sudo make iso" # args: # chdir: /tmp/vyos-build diff --git a/vars/backups.yml b/vars/backups.yml new file mode 100644 index 00000000..4fc692de --- /dev/null +++ b/vars/backups.yml @@ -0,0 +1,14 @@ +backup: + weekday: 4 # Day of the week that the job should run ( 0-6 for Sunday-Saturday, *, etc ). + hour: 3 + minute: 0 + directory: '/backups' +blacklist: + - 'router.vm.netsoc.co' +compress: 'lzo' +nac: '/root/NaC' +mode: snapshot +control: + host: 'feynman.netsoc.co' + name: 'feynman' + port: '2222' \ No newline at end of file diff --git a/vars/cloudflare.yml b/vars/cloudflare.yml deleted file mode 100644 index 26b39324..00000000 --- a/vars/cloudflare.yml +++ /dev/null @@ -1,2 +0,0 @@ - -cloudflare: "{{ vault_cloudflare }}" \ No newline at end of file diff --git a/vars/cloudflare_legacy.yml b/vars/cloudflare_legacy.yml new file mode 100644 index 00000000..941e2506 --- /dev/null +++ b/vars/cloudflare_legacy.yml @@ -0,0 +1,3 @@ +cloudflare_api_email: "{{ vault_cloudflare_api_email }}" +cloudflare_api_key: "{{ vault_cloudflare_api_key }}" +cloudflare_dns_api_token: "{{ vault_cloudflare_dns_api_token }}" \ No newline at end of file diff --git a/vars/freeipa.yml b/vars/freeipa.yml deleted file mode 100644 index 2dfb78a4..00000000 --- a/vars/freeipa.yml +++ /dev/null @@ -1,6 +0,0 @@ -freeipa: - ds_password: "{{ vault_freeipa.ds_password }}" - admin_password: "{{ vault_freeipa.admin_password }}" - domain: "vm.netsoc.co" - server: "ipa.vm.netsoc.co" - realm: "VM.NETSOC.CO" diff --git a/vars/idmap.yml b/vars/idmap.yml deleted file mode 100644 index e5c9807e..00000000 --- a/vars/idmap.yml +++ /dev/null @@ -1,27 +0,0 @@ -idmap: | - [General] - - Verbosity = 0 - Pipefs-Directory = /run/rpc_pipefs - # set your own domain here, if it differs from FQDN minus hostname - # Domain = localdomain - - Domain = vm.netsoc.co - - [Mapping] - Nobody-User = nobody - Nobody-Group = nogroup - - [Translation] - GSS-Methods = static,nsswitch - - [Static] - nfs/manager0.vm.netsoc.co@VM.NETSOC.CO = root - nfs/manager1.vm.netsoc.co@VM.NETSOC.CO = root - nfs/manager2.vm.netsoc.co@VM.NETSOC.CO = root - nfs/manager3.vm.netsoc.co@VM.NETSOC.CO = root - nfs/manager4.vm.netsoc.co@VM.NETSOC.CO = root - nfs/worker0.vm.netsoc.co@VM.NETSOC.CO = root - nfs/worker1.vm.netsoc.co@VM.NETSOC.CO = root - nfs/worker2.vm.netsoc.co@VM.NETSOC.CO = root - nfs/worker3.vm.netsoc.co@VM.NETSOC.CO = root \ No newline at end of file diff --git a/vars/keycloak-realm-exported.json b/vars/keycloak-realm-exported.json new file mode 100644 index 00000000..93fa6055 --- /dev/null +++ b/vars/keycloak-realm-exported.json @@ -0,0 +1,7118 @@ +$ANSIBLE_VAULT;1.1;AES256 +31323937363039623666323033316465323063613836666433623030643633316164393636613538 +6333663131363366373061366134623866396531356361660a353861613539306239633237646234 +62623539646230346336363263323961383337346562303832306531636261313937653034643133 +6163663434376165650a653330613964636431353930303561323531386533303338383034316638 +32323064633839346632643934336539303065353833333733346166376236356564343835376661 +34653032646432396365653833373461393536356366633261653530323335643231363062613132 +66386234326364616331373963656439316433383437656536666130623265393764386634333461 +30386633633433663639333133646239663139393933616461653363386663353163646262343166 +62333362303133386635663365303938373039633636396336343261333261633230383266326330 +36633863663734633031396530333130383965643662383939613035663239323764376235663064 +62353364643765303331356665343331663134663630613163626233656631383966316362663964 +32373434643634393262373337333461623664636265346434333065306561393761383133366532 +61656363643739313539313738303863363464363361366631363966356337666234356333396565 +36623964313833653865633535653565306333613065396364396330373464633136616632396634 +32336230643165326537623036356632333034313431646166316330636137636535376537653362 +62373166303034396332333539623262616631656633393733313565353461393965666338616264 +37663736383136333439363134653731353937643334653932363862393166653437373762363365 +65383761336264626163393432656239613363386366623466613761373437663436336566326432 +62653362393134623838313263633533643633373334666631613035353837323936623463363739 +36373663626465396565326630306335646437653532343261336363356637636364373134336232 +33623539343031653134393138306235386430303062316531303035666235323733393765663932 +38383037376563346133653664323839386531323332623762306335643236663132636236656433 +39386631663834353034306538326538393065383031383432313831326439363734656639356232 +35323364663134363463376635336564373331303532623461353961656364643165656633643834 +61616231373135616363613461643864383932323663616666326437326264303831656239626232 +37343631343136656464636561343061333038623663656230633762653331663762356538336563 +63316439306637653235653965383965313962386137636630333234356430383438373430346437 +63616532653765316532313164316231363231383765393235333333643761346637653337316639 +32333538346538633339633231613638323437393534326430386238383338613264363831366262 +32623132346261396535373334376566643935373562396538666435636638663536343963306633 +66386564386266316637306361363436303461636664643263613930636361373336666364303430 +62616435643432633830666166616538316233373430626337633435613364333562333237386439 +66613661373163653464636532316633653162663263326136336134393437343861373737346436 +35306537356136643631663164653465633233326264313034376562376537376264303333376137 +35343561373938623432623661313664303030356130623830346536333364333430613366663863 +36613831636563356164343236393365346138393832373163356130623066363239306162613331 +62663938643736663839643237663031303838363262393263333461623761333839356365636463 +34333162633262346266373361356336363137333335666530646538613733633134636339623832 +64616466373130663730376263653938313465646165383136363832353965613933646131333635 +39336239396336383335653933303965626563383264323763363439303939313266383336396638 +63383933663563393939393830623664396234316435356433323664666237623132373931333261 +61656131653331663862626338333462306638383939383865363665396661396336316338653434 +31396433656461666436343434386333343537353563353938316461383131303466633631303932 +36626532633865623631363662383164366361653662656265346536616431343365373132396266 +32643039313437663534613965343935323333383533666239636430643435343930386134633363 +33363134636539656639376631326338313936376664366232653339336536353732636661643461 +65393532663236333838373761393139383138343561396239343363386561323632363736386534 +36643930363334313530333430383930663661353363393330383764343530396238326639363538 +34653839346339316563336132366262353139303532666231636236326433666133646366623532 +63653137383838663137393762303235333662343231346165616138643863313963653238343663 +37313231643934323433343230373833626335643230363839386630373836626330343530373664 +32306130653837363637376234633033633364373333633162326161396535643137666462613138 +66353862393736633030353338643635353165633236666537383664303164613936396631366435 +66643066336439623564356335363031376561323537323437363339353533396435633737616636 +36393733313130653837373632396532366465623964616437636637663038643962303766373433 +64346234393638336265393538393034363366366262646165346331396430643830346539373865 +62383636666563316534313664376661316461393937616665653564636365663432373064306461 +33323130643739663931393134663332653630343566303335663932303563323061353036666339 +66306535336431353566306433386338356161326535343162323431383937333163383463643931 +39613033383336633566373535313361303331396361373731653834336435626630313432643732 +63633230653935353766383038356266343661373863643964303735663639373566343532353839 +32353636386139653137643664653035333136343366323062303064353165653863613732393966 +32383531616263353866306433373761623762363065316237393137656131653263663035663163 +33656565653731336638303963663166393433393737666436336366613636383836623061613337 +30323230303566346530653665323036376661366239386362326639653738383765623630303830 +39333334633763663630323261383066636230376438313962616136653864333762313830643737 +39333430663163643835633631356137376638643635653462343563376265333932383162313239 +33343735633532653434383233643265316133356531393537383631306230323430323762616161 +38663139386231343532323835386363396137643065306133643039613738366630656537306363 +64333031636664313139306539636133663265666330643137363766663730336130376630616162 +33613437316230343631626430326466346638383661326531383435376334636437643463313066 +35636335656362623330353431373762353039316235353865316339303133346437343536326661 +66343464313232336466623537376537373938333262663535366265666136363262386234326239 +64373035366233396361306262333566383833653139336264613331613364393334326466623064 +37646339393238653463373633336639353432653037333861333662633535653435333137373032 +31623064616432623461653331333435356133326461653636366137616436663039333633666332 +36303337333565343364316565326637333531313634393533383538363135393833343262633566 +63326130393462623030616435626265376366383434363263663365316339643461623030333063 +62666130636633656336396161386466663666373134613738356232313734656362323630393232 +61373038323938666362363133303362646137666263353938666236646238623862306236626430 +36646533326364643861353266663238356562623863353766323264343237336463323665626634 +61616464303466633436376434623537643463303436616131373332313531346666663734646465 +39393563306331326562643033313065386461393634623838373263643039326138333130346132 +65396166316232303839306637613934666532303031663639333130306430363839396230343234 +66393961363436363632626230636161306661316231366261353866666463353266636463303064 +30643464623461343730393831396661323462396532623964303039653238386130373965626265 +35303866393138363062313265333062623334336634376435346439333465326433363634363031 +61333766373766323737653334626230383039383963613035656365303064316161653031643232 +62623165386136353134636364666334396163653963363033623366393461376230666431636361 +34626364633933363536653139333035663633626338396564303034373463376461333438376364 +32306661316434656361616462386664356135616536313835373263663631643061646139356636 +35386664643132623932623935356230313461383337656462316331336463636464356262666435 +64346465376234633830666333666232373335333239353337343737326565653432306232313461 +30616634336339343435393038346366393766626434643630313562613461363732626534326438 +62626162396231386166333235663637336463346236363666356462333233656565313164646163 +39346636396332653964343434356639383638356331386336303865663330366239333061396665 +61303939616532643034623963356534626132313566376232643865643333643039366139643766 +30616433613966656334663131636266373663666138336565326461336136353632376665346632 +33313835623333383337616561386335323335363430366232373437623730626466366561626636 +65636135386230653131326335393861333735623131363361333732336261333432393633313130 +30636136633965363532343235663262613065643637613736393734656661353535656361626466 +65396161326163323932376662393539386136333735656530636237633163633263376130643639 +62666662666334366366346466346663326235356434643238396666623961393637343936393061 +36326138336239366236643239656337303232303835626639383831393061653363373936313938 +35343330636231373138373637366438356630616631653764343533393730303635613133303238 +64396165303438646566366134346337333239633161376434626231383164393235386634313730 +38653430633237316134363162396137623264346231616430373566336536656462323733656434 +35613661643531626263323165393264623335303637313261343563616431623637346565633565 +39623666343730633930306239336363366137613936326464316237303561363966653733323135 +34653132303163386231323133366234623634656633666638633532343639616531653138653338 +39333562663839316436396562316361633131613432633062313038613230333139383537316136 +39643734366666656362616165663134626561663033666365366263396633386637616236626365 +61373236323232313466396263323061393038633462643735383265303636383331643062376139 +61346134363363623064623530643034626332353431313237313762383333343564326163393964 +37323933383132643537366461313230343962376335366663376661626166663862623362373638 +66396663646635393562383737636532633365393138666464633231623361363232373533303837 +36346533333434626366316638386336343831353465363961633030346162343130313133656532 +35653864613662323364633233376166323734646530393964363165333339626666633032613930 +32303266353561663930656231363631353533363764663565336638663766613966613934613935 +34336261383264653233656536383234646333613735323132396632623931373061303032333639 +65666264313762396663343036316230313638636132353864663662343938373964313764663362 +30633031326661663533613833303064343335343137386336346633623734316433613662313364 +62376165653630336233393435333961383433373131396464333533666136383534376261666430 +32653963633332646237613137643366633939363766366133303865653637386137376566323437 +66666164653530313165666230626337666663353334333038643163333832613531643864333835 +32306533333830343366623463323764356131376262376532363464646434363838383631373637 +64303066613063383534313365333464393565616637623964316461656439376162366234383062 +34383062613231313238643635316330653539646565626135613336303633633337643334666133 +38363031383162353832623434613463373031633936383961336239666634613365646664313630 +65366436633465666431643063616161303133623833633635356233323362636335663838366664 +33306166373437326130323561316533376364383539633834353738383664383662666335633830 +39643030333365303235616563383465333731643963353636383136643430333636363665343362 +61336232333063356331383061663563643730336666333636353163393863626264396533623362 +35323466356233623232303434363766323663333934333336373038383561643933303537623937 +39323734663366333031336135333961613936313836373964303036316332333966326364386537 +34333565333662663266663432363431613761343964333536643865616262333431623239363836 +66623832643837653537343465636535356231626132396532623938653136303836343232373536 +65363334373536353932663664373235373433353838646132643363323530613538366330323165 +30323365613139366531653962373033636264346662326633626335363830323031316462313637 +35633935616234343166303735356530333136303239353062343836306563653132393230323838 +65303031326161626261353064656561663838353163653661303032643965326535313135366264 +37343830626263626361346639373265396632333236316537623133626230356131316338613963 +32326634333930313437633238356135353863323666613663626631393038303334326562393830 +39343535643333303835343935613535346537396539393162316632366637653165373063316135 +33346165306663656535633766656439373961643733346230373935363034303962393661326133 +66636332656462623764666362653030343864663030396233343361343063666164636363653733 +63316438343265323934616231663664633332643038376136633133623764643139666439383465 +64653937336531663534323231613639616364323431643963323132313066356234393831643739 +31343838353639343637353136646265353563393865316263396138383038653533623635343136 +38623431653939363961333033386130316562303162376661623433613564633461386235376239 +31663236363639313538623430343934623361303332666161303331396134643739333261643339 +65396436343334326165313064613135306565326664343235386338613061653936646537386533 +33656166373738386663303365623865336631643161363033336530336332303466393965663162 +34363630333663323032336435393038643933323234343038323261313962313635303635393339 +62653232346232313064666638663763366433653564386631633135323138316431613139366133 +64363033383131643739343535623662383463333931333031376336333132303036396637306237 +66633733373136646131396136323662616562366239633934353833646239383761323439326535 +33643035343363326334313963346465663831393633646336376336646337303931663334623662 +65333332333966396565613864626634366166326335303937333133303164646137646239356636 +32616666343031353063323636343639663734636632343838646639646237646661633034623332 +35353461323066613132633930363566646630386231643461353134333238623365396334613962 +32333030616263353139353132383837313439343265393139346634396163393865363731653536 +63666338393864393630303838613166613639386137653866383161613835653566373562626437 +66343962633932623165646466373230666565623464633765346361346335643530333131356262 +35343961373864303263336461646663326235666266333063323566373138383132323238656166 +66616337346166636463316166643338633339363137346334363861363764303134656365363461 +34626165366166396365663564633437663465663437336337363836616333383737666664636238 +35323362376632653234663935616437363438396262336338393563613839353366643539626463 +34343130663137393733356165633765316233643131313232643165613635663835396262626164 +34323934323635376166393164393335336131323662336562366533336162363132396165666134 +32633137626431653636636633303237373735623464383764383865366233323966363339343061 +61396136333732363162636632386237353637656164306561326633376539666537613163356665 +32643431666232633035663639363765393438333631366532393366303839363932343565393366 +62393531363133616461633736633063326239333437643238303633376433303461366635643738 +31616434633565376561333235303362666232306135343730313536333035643630376532393436 +31663166303431376431313238613235393538636630643761643337633730373032643330353137 +62356131303764363438333833306139303931653434366430653534623034303836613431396362 +38393265633037373763306365656132376335323363386237323130653533633032646666616264 +62303537653765346235393138313939366465326162613133303339343239653436646266656264 +30643634643666316665663562386363396338333361363033343338623031646464353362346538 +30343662316139646533313961656561333331626334333335663336336336653332366131343132 +34303238356536356238306464323737373130323965376635656639613637373637386331383431 +36363038616261363264623130663033613365323437653731663464633433663138666435333635 +31306438313732346539623866353664646261373461333664393761636337623764346161613432 +31376464656231363464643433633536613535653938616539396432306162663562313636393534 +32396565363466346636623033633966343234343636666565666238336230356437306230393064 +65383739616139313438373238396338356662303863666132373833653239626465613764333333 +62396337323466666463313066336161653638666363313936343036646538383965626635346465 +61306531343963646331333231303032396136383631646330623730393562333932653062643333 +61623939346630383635633961623332323830303063343438363830363730636563653734653239 +33663439383433623663323961363931363932313965343266396330393235656336373434613035 +34303766333564303361653066363662306535363662666238393566326331356464333062663234 +31393266663039306434363738656263383831616262613933366131363030366366346639623931 +61653337363231376530656463353532333835366463616461366638336263313634323637376663 +39313232366265663330653262323230613366306364356164663837646333396437326431316231 +30323561383838326266646236313766633430383466626233316538366239336435316261303034 +66323461626264303532356631303134376164636133323731616136643736373364396661353731 +63386161393434666663306530336537623635623764633732383538626364623336646131383032 +35313038643635663761643334623335613236306262633464653534363332653763616234343164 +64333832366234343231363037616166626432633634653638396434343362373563363863396362 +38376565663962346339333465666433386432336536333938613161643634313232376232306233 +36653030346537623339313834636265376361373663373238653630353033656462653432343532 +39643135663735306330626436636133306164613234326637376431316365316261353061303133 +35333563393834333961323263343137363434613431616235323462363338383234303636323462 +39316631636163656564316432653531316130616132303930633964613034653462323661356630 +63646533306263323164303366656563353732303134396465613266663633376636646465313261 +37376164623235333733316162663938323031356236376534373931303134633433326332623432 +65623964363937653464383866663365663131653532646537336332616361373935353238336534 +30373734306665343735326432326465346461316135336563613231386633333437313230303038 +37653431393735626430306262656332326365643230356131306164636261376531383861646564 +32386538366161366439343561373031386438343162613865363633666665316537666332653266 +63373738663534643462306237316164323162343037613735386532623333303133623663303364 +38623036383837633333373931383264333931303331313262643965636334613436343163303965 +34373666363930393136326161343838626365366364653361333039396663353233326330336331 +34383634363332383361306134326362323365613266663266613634366137356664306633353964 +66396432663539343264353638303537383234633636373965636365663965316436336265636136 +66633066333162343732346163393535663366646566613835303439626139326361376537643766 +34396565613064613330373661393264366136393837656566306335643934636336313339323265 +37616666343834333530613334333438653537393335306363316139663364643363643937663235 +64393239613233336463653433356133626234363361376137376439333766343634663930316636 +61373564633531353530313433633461383363646562323762636338353637623039646631303864 +36376262383537633962666231623435666135326334343833346665363731393035313830666566 +30653230386664353339636266613961663464346261316562306632356165333665636266383637 +66623561623065363137326466396538336161636238363932623439356234663438333535626636 +62356239636566383935373935613531383064636363643666346230356564653034316562353135 +32623462366632623035343432656330316639393138376666633232623332663163613236396364 +34383463363130323834373963633033353666356235373630323230646337343432356535653139 +34663738633835306430303766656437663162653938366663613266306133623834663737333439 +62396432623165313630613039303438343730633730643532346130383538626462396531663462 +62316333333963623664646365366338303730383932663532653738393630633633653432313033 +63316138613537356161313939333638386631373533613137626334303533356563343435326631 +30303939306339343630356666383832643264316536376561313235646531386333383733306337 +31356265666435666535626362313735326532626635396232646133626135313731626534306663 +35343530383663633439333137656436666431386537633730366238313665366238353366646563 +61643336333533646163373165346537616133663065636132313531343938643232316634306233 +63383266623533643761663866356631373832613862633635653333623436396530353633613430 +38333130386633616532313565383539316435656139346636336530613138633862653330386637 +35613934376561646165646531623937333530386131356431393465373038623865396665623034 +39326633396330323536316135613639613236343736323562633438633339383061393434613566 +64363461383164613237663937366361313362313161336330363732383438356161633139613865 +65336137323031653266653134636261663434626264356137643033646136383766326336656262 +30343861646563376638636135626438373766666531323364356336646535386262363938356331 +39316237666637633435373037353131366231353939326162353639633931653466343132643139 +64656633323063363237613131653532656637306466633838376336396466396138653837373730 +34303935303833623335623964313931356132613365656463313939366637396434363663396662 +63373736636665323836363136636639343463653863336332633234333534353664393863323861 +32623463316334316636313461393834633462373263666131616563363837396437636433383562 +38343235396634336237636630373663386263323432316430663238633531613765363131356539 +35383030383933653365303765396136633761316537623933663361663065623736376663656630 +64636430643935613733346632393766383763613737333163656261303136656339613234396563 +38353030633761363763623363343862626438663365613236306234623863623336373430353034 +66306335323836316336366536333564613266633361616331353463643036613264373837646362 +63373830323335333230303939356564636262383563363364356131646562336431306538663362 +62613832333231356138373731656132666432633735636333653465303236393065393864623836 +39373031353634353639383065343066323234653938323265313836353335376364643937326664 +36376164666662613962306266373434326138356339353564666537653661316538666332656565 +36316538653339373363323234386534346663613661303866633830656133386565623930613735 +36663538653761313837326464373362336431326633313932356264656232663334366336386234 +33623032356634353433623439636564643465373161626530346463373366343637343232626331 +37326537653635373130663233643431663837636566316362323133373430653665653039663433 +66663731666135373664343761303736323837393539336536356338343333393434326163323266 +38643739383566666166303863393739653734356364633561646238386163353166613064373031 +63316163313365663530323063373866663236373365313064393136646435663835323931633364 +63613732383036343638326530353838613263613062323432356163663330356431396662356339 +66646239623963393139636637376536356531356630343239636236346230353637653631363265 +31323831393335393066383235366433356130666662633339666363646362326239303934306436 +61306231343361616337303938623233336561626331663633326439363831336163393732393730 +31393836643666616664613835376334306263333861663930353734613433336637353162373635 +32386437666361316433623063366438663235383033313930383634386235373731633931396539 +38646438316663306363303330316162393262636663616563363062623832343835336565353361 +37356233316462386135613932653163653132613561656331396465353838376436363830636661 +35336362343565343638666466363933333232633163343532396432343336663635383266623438 +61656163343635646262363061333734393465333463333238356639666262306134666561653962 +34633931336364333832363034313737616366383232363638343638386161393563373463363065 +32643638653063636337386133666438623330633235313732663466303966313533343765646665 +30653664643566396134636136326336643263623533663138386235643332353364653532343262 +30396337643061353837383962613031333437333030373064393163393163303261396266313331 +63346266306361376334323136346462633664306338643333306336393033333032663766313933 +65636162356536353837653930376563613338373039326336643532323561386566633832353735 +66313261326138646633393336663939396333613332663964633962646236336134393364626431 +63313538366238623963396536326664386165383637303234613032366239336332663761636162 +30376165346332666536303835333530366532333936343464333533626235316561663566646563 +31613637333535363332623032343865353835356365393833313532336633636533326233366535 +35616631636334363834323561353539636339646337666264303034396365643163663966666139 +66356134363434316262336166346634343363653866316563373731636435336562316437393033 +61626232323539343863306262376534366232656563333263613062363536643338343939333630 +63306265326635386664323737643139326366626238613061313732346232666561333831646363 +39303061353561383031333434333034396339303033623735653836636239313661323437633334 +62356366383836663262303262373232343934653630663934343436663336376636313137336566 +34363539333837313730623264653636643033323633353033376261386364346136336339303364 +30356332326135313539633463363436666364323639383664356536653864653636363835366132 +63653934346433643137383263316230333661646632373535343839346464343864393334326466 +65343733393935346561646131336532613965643735666538333130303566613038396338346633 +35353164313637316663373063623366623432306565326332326339336337356630323235393862 +37663630356461656565313763636239336235353861356237623563653064613137626132386631 +39393535636432326231306562306465326262656535656261613164646535313639313561393566 +36393466373137656333313564396230303935623238323330333132383538356538373431623464 +64383831303161303034663963363134636332626665346233316337373038636364303661373937 +36653461346139373839366232373763643335636234396334326262646565343132376636303833 +63313737333835383638326166326662333630646237386163393063656364333562316131333966 +65353534353964343633333366303965643231653966313839326237646364633464653463316266 +63616535393232633735323133363838326137346139663634326564313161663932623837393332 +37633762303233366438373535383830346465623933303733383664326438666535373731623732 +37353037633036616361353061373533346539376363366232393930626531386133653036373466 +39356562393163336463653661613330633534366633356230393638623730313635396234656361 +37613436623663343664366638653965356138623264353739393336306639316461626438666135 +32616131333962373963373730626563303230623166653837666133663134373936306562613837 +37393634383362613662626231376233663366303563373339336230616132636664643164613836 +31346531626665633531613333356366323763303437386164313262313665646236303362663166 +32306434383432303431626266363934373362306165323034376433373466663531313363323230 +33626363393434386330366536336262636263346430336238346231396266306164393735363061 +39383263393630353839373139373233316265616339666130373931383863616638643736306436 +61333332396664373131303563303237663435666266376664656236383064383361643565313832 +38303564383933323831666133366137386264656138636637393163633961616666336339663265 +32336630333062333632363864613166653466303533323835663732323135643266663864323931 +65663862333136353230646634326263393135373330633733373136343734333732363664363532 +30333639353966623937343432666430383830326366363265653463643435643463303437656633 +39353264363465383737356533643530303264313139376435613338336565393136373536306637 +33653636353033653165366530376561323664333733633235613337303765646436323866376163 +63613433303236326632353537623363333364643562343835336666306638393861346537633062 +32626334326338353237333335323637636666393365633762333736373365646130363935356338 +64323831366664616138336235613131653964616239333239333066393837663835353330663961 +31363766633162376264343164636632353066353731653663633632353964636435326330366335 +36313731656235353235333238666663346239326265613836646338336465353865383636363135 +38326139313434636339623334346331316337353262376563396436616464636439313533613331 +39653139313431363234313433346134663431313039306263663563616136333730303333333232 +61666662326134353137313133313231373164666535643537316631376534353234396138313432 +33396363383633613431333230373039643637633239306637653764356565333664373665386434 +36626335373761326334363034383039353134666366303733626363666638343432383039346531 +36303332643065626531303262666463383265376632396461316232653635356161303336336361 +32363039653534303265383231383338643162343665656166363333653334663033636161656661 +62316164663531363564653163656663336332656238646464336233623866333231323836343862 +65646466663133303661633533326436633065663362356161636235343364656238356637396430 +30363363623136323765636164326366313039326533383135313561663364643735666630393366 +37336238343937643533303838336562343664323730353933613030363764643333353533666661 +32623565373239386665363039376237366365303464613065386334373634646638623235643964 +61623132316332303662393638393866633736373332623139656331376432376534316530636432 +62323531363935303932366637303137396666653063363432623763646536613431643166653033 +65636435383635643233366432613961666363626666656163656363633139646466633531393133 +30336539353237356562383363316333666132613263323332333231643531653835323031643831 +37303862393730373631323135656262643032663235336564386536303231373635663433613739 +62623130353362313830346432663933333838663939366364313161363231323537353135353737 +64383136393764616233636264386632623537646437396231393364383837353931376430356466 +35623633333235656236333338363936373837613035356466316263353434303438393732393730 +65666132356337376461373739316264306166626138373437363966336437316464613264643437 +35333031626333306664633162353637303864303362323739633665636131376466313337323565 +32323634313431623165663062613039336135326532666566336630303032396336386664626231 +64323433653061643531646538346232663066663865636430373831353463303938313539643634 +34356533373239383231376437623734373762303035303064633735353033643832633930623336 +62373239663431623764303561383238383134376163336239343030313430313836383666303930 +61646535656135616635653930643964643061386265633530376239373436636262386431633636 +62373734623864303835626262393538656131306536346135373235613564376562653931353733 +66383031356165636332373662336639326364636661353664633132623838643538653739343833 +36343433363134613436633339383265393135346261633166643231386238303362343666373434 +61323566613862353163643830353731363763636234343532333733616635393630616466303365 +64663537666266363339653833333430383538333966313137396639356337303361393238333435 +31643161366631386339303439336262393266393533343965303065666630383563306232343536 +37333434633139353337383462346130356561613764633261643962303739316261613066353665 +34346437386266373235313665343062383562623433633437656636353930663238643338393563 +32616461663263333264656530343239353336616330646436373436623866643961653535323863 +33393636386562646533393335346538633963316437313738613332623238366263613466313238 +66333232633331653264663864666530376231386366383133306336363530366465313431663631 +31373563313838633639326233613836326438336265363835323663653566613739306361613933 +33306164323063626439336439633863346134346137666436636362333038316564373766666339 +64616366326335303862313937363965623830663434616466323262326130303365303465383038 +34313361336262663732373361346637653439656331663065323464653233333333353736643338 +65343162633865393437383537363539316663333366643566316162366162376633353334613633 +36316332626136626533396231353664626535323731613835623936636233623938323938643766 +34356462383231356563373030376437356236313666316634396237323339363737623636303462 +37633539303838326262633633303965626230353565333463336361643932393232323036363537 +61333766613665393230303161333730643330353739326565313866376132336464316231373438 +62626234376439613830313164336537663831666430353139363238316130363737316538343537 +35363934396335613966636662376336326438626135643937393839333232666231386130343261 +38303661323765623865663562356530616432313335656337336463633963623261353235323330 +32613739373733306164323636363034363061343235313366653863386137396236326463333337 +65326365323936336663613930663737383835323038663263663162303639613363333463313331 +39636138643633383165316238363635623037333364363832333533653731663634623837333634 +35356466636637313866313836313635343035346533663962333864346633343939646163626565 +64326666386264613664356533306231316465353062626336613161376432623962356236623165 +62353062326439373936393531353331633732646362613163643433346636633134336136363130 +36306632376363383465393065353039333634663734383664346233373566306261613632613766 +33613834343934656532373065343762306264646336386432333131323337346532636235623238 +35353462663135326336323161663432303162306663616536663536363035353963373161386335 +39643461323266616534633362393638326261303436376438313731643135333832356562346464 +33316331396233373761623535646639393133623334663331333934663032363666343036636661 +64326166663831613165636566363134303231376562343665653131313231356262613435636337 +37363936353561363639643365316531643130386634333733653066343465666662636662623133 +37343835643531663138323335383930366334623364373331383835333163316530336330383236 +66633532336563613034353831613130633361393839323930313933343339323562346564333237 +36316433653963376638333030303537366137646238316337336330383765333062323561633536 +34323238623163666637313866336666333338613235303534646332333134306465326337616166 +35643364376436333739343461353137313263336663373062663237383234323634336362386436 +65663963623564346231643364306162616532356436303139613431646234313566643636396264 +30343739303233373535393432376337346162333133363165346265333434643437663638653464 +61383030313931656531393865646334343834653261373261613738343734393932666266326539 +30633761363361386431383137376135643062643930633731626438646434346139356530616431 +38343036316533383265343863656134646162393237666464383238393835323864633132306331 +39643635653138313062656363643834333335393832376638613663373839353565313031323638 +65366336623430666534343834373236663665643232636238633965626133643435643162633064 +37333937393035323465323735646638303836633037643136376537343535646164316437316431 +38343536326133343039643232636630373330353839313038363531623664363430313861373330 +38363035303364313861373763353931393733393339326161383333333139356565373665616664 +64633337613663636130373834613736313233653661646534343365613833356562343132363137 +65613832386333633132386337383162623164633731343964633434623933323439613264383265 +61646165656338663662663838326664333865356566646337623632646163376336343132643330 +36653363633035373163383866663761313364363435356338346639306138326637303164376433 +30393437613263343466613862666439353262353366323562383638356163663532656532633334 +34326561373663656466333564646665623263363633636266366137643539366466306665643737 +64343233353562386533383430313433336463306461383538653538396365383262353130623039 +61643664343835636165653239373733363462396234373432323636653835326332303866316433 +30663634316534313530623038643034326637623633653966626666303562643962356631353034 +35656530356564313235346133616131666163336437386637366434333730333631383462313664 +30616334396232386161336139396336326661633135613963633737633037353263383237303533 +39646165353032336361393361626164393835326539623963303664623463636366316338356437 +37363030316237323038373935323365623137353566323938323164393564633961393131353336 +32616330326536353939363032363166373765626632396262643561646430663738653532326136 +66383737383530633735323134633731303662663935353231356566336335346536323061383065 +63316661393965663636333235356662363738653236363633383630346636303764313836643166 +65333531386533303338386265363562353038376161366564373066366334363563663534366539 +39316666313966303638356562613239333831663839663737306363376634653932383832393863 +35376564346234366664623039383339656539356132303434633532396434306337303432633035 +39373237326566353432383936646639313732343331356133623839353433323037383061633739 +37656236653236616166306262646137306431393366633837346639653863393734313330616564 +34613538636362656166303934613139396434643039653530356565383531633935303164393661 +64396538373438343732306533303363313538313262383032666134373537656362646131393131 +63373633376333353439336632386231356534666666393737646466323065616264363037336463 +32623935333462353034653132323563333230633537336135623661386465666230376134643339 +36313730353439376237396163383633663638333738353664343038656539343139346464636532 +63326538613539623462306231393235303732356236306337396263353166653337373339363465 +34646133653031663862623035653732313366383833323961313863303762313065393839326331 +64363137626135653166383566613132323261643463633763313962666562653531356261633064 +32393063336665376563326664326534363739376337616637383237356132653830313261336165 +63343964353235343933666331333330356530373037623132363331326563656538646565633035 +35313239633638636534373065633266393163313462626339366433323838633364623136633833 +38343239613531646231323934326639356562643936313864376534366662393063316638363732 +65616261616165373931333164303131393437363936626334663337356335616265303236663363 +36303364653333383030313631323261303761396535383066353761663034623161653366353132 +66373837663234333633373731613135336666363332383136353233303961353862336331636638 +31353065623035613066333561663932343765343737333337323534613966303633316565393964 +63353863373031373565643938363433316365356330653665313132393031616364313162353338 +61363437396331346162353366616464643736313734393566336664373963373761616539336562 +35633435643038396365353136363665303465643465346432613766373230383136353733636436 +31343766376139353639636435613631393838373663316534306537366465303537343431376335 +63346131346133333737643438663334313163336266316165336539323839623661373531633835 +36633538323563396638393033343731343765663831386530373736623537373762303635376334 +33326134653562313966383664303337323264656637333865343761383739393935656563333733 +34613639363438636566356236303233346538383662653237393136323836306536353133626161 +35326165396237376165363466613130316361353939346331386539326164663335623635386538 +64363738643936616261303234393262663032366464333931626265646365613131326231666561 +33303737313261386566313232336164653462636533313439666261626363356463366562366266 +63353165313036653337653962303037636534656163353664343533356235653430346639323431 +33333634663264616332663662626363393831623931663564616139343766396532633862303962 +65383537303530353363636639323863323032663763613438313931353830616537623266646138 +34643433346433363537633865623662613730366430363731366436613133383737616563393662 +30313461313864636264383266613233633833316338353236313665366534343130386166313637 +61363633643037376235363539343833343931346335386461363830393237333236653538336239 +66633334353235313861383934636136303635343862343537313664373138333562363735316339 +35613930373162646438346339333731303863613363333739313339373165353461343364626137 +65616439363065303734386435643534373036626637633038306232313462303764333061333730 +34393031646135666337623962313835633864353035333264363337646563353232643039643437 +61613139376334643563663539393834646562616531653333656232366633636136346363333637 +30303565386235333639323566633633356464653333366134326162653665333963353232633165 +35363132633439643133323464623633363536303061363930336138666662613761323165636566 +38663563663537373863366638646564623863333432386635363738393033333139643733623431 +61656631396565303831366338646630383734376332316539356336303839366337313862393862 +66653739663832373533646131633634313438623064373330393265656562643337363865343230 +61616635616632313963376265353735613133323932653764613461373661643663323862396439 +66343237656132333233323030373736656330663566396432666231383934396263353961303231 +30323130363862646465363437383561396361383261366433363839346563303634356636616531 +65353631653739373463653937353864333363643239623932343131613933316537633666643233 +33376362346366383161643038613232333638373465666663353665646366353963323538623132 +33666331343337336533336230393034396261326535363762366462346535333664623336346562 +66623161343637623832363937306532303537633164303762313166626463333665373465646661 +36373031663434373730383539363236366563366663633732633834396233346436636630326334 +64343463323462323133623166653839353862313362623061356635303963663832653064663764 +37613466626363626233623961373161316137613435663164333832623563336330656566613861 +39623264306233623863613366353564383736326564393763383965393231383633373661366161 +30663261323262323333373037653337303737376338653262303636336431353538313234373837 +65636163343538316161353633656636613439363038333662303762343333653664393435316337 +30343065333736383736663735626466343562613831313731313132623465383363383332643464 +30333537356630346130626634313938343362353638383231383765366632346666636433386635 +33613861373834343234316331666130656130313837333263303932633766613764663363366338 +32373434376639646564666564396337376639303365303334313661613163363236383063313231 +33633838663266303063666565383432353534623836356663323138613733323431353232373431 +63306337353136373465633765326132333464326230373131346432373335326237353139656439 +63353462333865613537333335326637353931663932386638613164306539663031373637383162 +30666663343338626366326165663166353434353236323463613435303832656465363164643461 +65323230336532363564323135313866613933343831396135656131383732386435393330613137 +62666366323234633331303664363539336266303961313738666438393166613634383731303734 +65656432383535373637663538383233356536623139393134663462303930356365313466333165 +62383163386665636538663638363130373763323338323461383132663930353338393762316431 +34326234396638626630366466626535386632396266643535623362383032306533646333383837 +33343464356538363263616465373734316332366464653638636563616161343633323362343235 +39336661646138303764646439303432656163343038353539306661326364376532306335383336 +66376662383538653330326230636134613538666130363233626564626366316133383833663735 +61326235373264343930663832663433303234363765643136363537363662633264643461643333 +39353863656236373065666633366631346564363532363162663064623239333933656336663566 +30373330346562323163633035346263653939313937613031326565393762643366313535633339 +65383731323333323439323035333335393863626666343963353963616538653366316632376361 +38653362326266336364363239353764333361663062646631353130356135333139353838303435 +34383134356631376236356564326235336630663431633235333134306662333830393666316439 +30383739383630656432633739646636376461646231373334363939393465643036633465333032 +62346230666232373936346639646165306362613331343366386563653763663235323838376537 +36396137393766393934363135643538353036633431643464333432613534336364323639303663 +34353334356361356635306436326265653932326239333730343139313565323339643830623931 +65323164626237323431336164613262613132393662386465643466386139616539383632626630 +39663363396539653639663735366331346431393562333836393630356335656230613266663332 +36366665336562346432303261656438383633336366643335633630616337623663346637313832 +36646135613161626166356234626266396665386539363938363639306261646334643762646531 +39396664643234356262316162326535323437666265393935616135653761626538656434353235 +32323838616566323365333466333062663236346664333131623530666234393832356131373762 +36633563393236653063623533383432666131366633333934626434353535626266353061623535 +39386537396434616362646430353032376334393637646566316137643936633766323235303936 +62356633623834663939653136653134356263336432356166616235323130656631383932353761 +33663761633432393331373430386366626563653830303663313933386435363039333733653666 +35323231663033333461643762396637376462363237306339366138356434656632653431353530 +36653931383361376233343034303239363733386565633939653062353531663930363635613737 +66346637633038666630646435646432333730356631353935346234313135636435613733616665 +37366466663966373338656231323837336138343035653631646165313131313537656532303066 +33366637323766313232666166373037636630376663653033613466323038643966386464356564 +65333561323333643764626664343563663665613561353865363536353031333464656234353232 +61616335626232383366653636386466666636376166663163313235306665366136613861343663 +63366466653436363532623030626661373733643762636233633636343766613830323834663566 +32386363376563356235636361383266626364346465366232666463393639303236306364636165 +61393434373130656239333437356239313532623366333261613766346435623838366631633864 +66646664316162626464363633326466663465363636663065396266336666666636663365666266 +36666131313165623230613262653863643238373137326634316164666239386434623936666461 +38313839626537396436373436383230626364646138363233616336323235326633326537646330 +65326437356564613539653138326335376334383361376437656363323563336565383435666365 +37623265393162336632363032373136383766393630356432626666346264363531626463656131 +63313330303066333933343632663265366337376231373562343532336163396462343837343736 +35646337636632386336663063653831383637333835383233613334333631333633663235653032 +61323136613666613166373730363762366462613163306632666162383232326336623233316136 +63396164393736663466666331306135383337303131336663623739613933373536333036356136 +63313866316236616461313565336633383931373861616163666465383463376364613434323438 +63373762363563326564373431376663386363343062333933346334616661653438616231303634 +36303461653263663561383963333139353030626163393832313665316232613635373236376134 +35353134353362343061643635346232666236353534353333326237383134623763653062313237 +38643039346535613930636236393038666438636330383836343962613263363464333435663838 +31663039303535656563666461313136616635663031653435396263393538326436383536303862 +39626533396134306238653536383336656434623430616439623663303865323061383730356437 +38646632633765623666653431383264343664643064623637333135386233323333666466616163 +35306565336431643237623365383963633139353039343066616335396630373535353332346363 +65633930633731666438643965636238306437346562656634663866313135393033333134383361 +65313334333333326637656564333462383731323036373031383634656363363031333064623062 +65346639633638623066343334356638356438643062663965663534333231613464393932343733 +33653737623263666333613430323832326237306461353063313731323633623864646663363063 +66333934323831623064616531323166356133376332316634363132396362616131303962373938 +63393239323331316262346538636662666165333737396364386161656631376266386164343335 +39663638646162306461323636333037323138376332396461383365663963626338363130653838 +37636536643436313362383731656438313231633137343038616133636132626631626638303332 +37373463326666356537373161393134343639666239653339386633376335373136663338636235 +34343764303039616137626438326465323630396631656438393036353232343264393539666263 +36363635343538656134653434393733643139626231303861356162663333613763666162306334 +38343664643330653039393930376231313333336230353261353837663139353061646232303437 +33626335386436623438386431376564323033623564656538316433303166346265626561386565 +31316232636330666335333037656539613965393266643566366365623263313832613333343838 +61396437323236643066633537373634343635313538306631656631386366626530333161363061 +37643132303333366338336362646532653961653363653762656663333030363035326238386230 +39313931336462313533393965343262626130386238376461373731306438303662323935393562 +37656264383434626161316432303333356165633937326534386331363563336139333664333131 +32346562343930343064653432643862633738303037396561356534663764376338323038363631 +39623765636436313665326236613036373932613934316662383631346666643832363562376464 +65363662333666333166333366663164653239366133656637323234343735383065373062363030 +63323163343734373130646562623964393436636566383933363565376232613162306364643966 +63663238363363343039383034656238653061643835363536303336323235303935366631343130 +35656630363730353164343830333332343332616639366263393966373465366431616639663330 +32626634383262633338393432363236623062353263653631356431616362323137623264613432 +36653432333463656636663738346134383139326666323465663537643962336534663334396536 +30666337656463643437656131613162346333373338353162323833393038333464326336636266 +62653132383934326266306365393064326633656631303064613236363138346334316262313365 +62353261333862643165313034613336373735346535653763643732656164323939376435393234 +66623039363137336366643337366235346335303934636562373932653039613433623535633762 +36363366313061303632636463343063393939613765633235303465393735333937653731323030 +31613231343832373534386336623637623866323665623639353264373135396339633435613062 +66336432326435326632636132633537393234623261383734333631393832633663393132393334 +36326433316636323735656439643137366661396261323739656362646463306231343162383935 +33393964613534616134323836336664616162383237313038323833343939656134643566626136 +39366331313265306433343564373662386363623766323365666338633862336663623566653238 +37636365616365303064393630303764643635373431623365336534336330663038353735326437 +31643633373764633164653935646362623265626565383330313436633263313263343333306639 +36363934376132326463313764376432346562633766643234323233333933393062303761323863 +64323732343762393133373931333933303135373334396436323937663061633562396433306231 +39396465343631613362633536306138306564633336363335343665323462376165326563643562 +65633836373834363032393961323938626232653761616335613034393639373462613631663938 +65656535313138366166323838303535613231313233646130366665616238323630613431663530 +66396432303466383035343865646430346165663033336465626531653165313564316132363564 +31656531626461353331663563303433336632303730383861393862396365316138376161643866 +34386339386535626362366437666665303936666563323637336230636537316562653639353838 +61306631613263613339383130613039396666336637663930376262346239303332333239313137 +65343233393936636666366637613063636636636632646364623166653031353936656564366435 +62626139306664363261303435383265353338613437616137646435663437663538353832396263 +30303739626536643533623336633035666335363534626530376565306264666633626135306336 +37393935633936303435666661346462643564373365356463323432633133616136373663643035 +34643963653232633136306235343066353938646163333939303963396239303761366365393931 +33323238383639633033613137393732633536326336386430326665333832656235333539393438 +36393035353666323166336634346633666632393265313638323632613831626431636338613362 +61353238343466373138663164613034353864393235633363613637666164626435306638393934 +39636261346266343930663630656135356635326535386262373931306431343165303835363663 +31626636353263636561366138346133373861653132323438663130633637356232376637613837 +62393461616433326533326265623333646439613331653732373165356362656131663335303234 +31616233303139323133653130306564643233323663613032643766626535343633386233383264 +63386261306165333537343830663763303135316464383933333434313961633633333835653365 +64663637643130336566616234623465353935623664363864373536356361643033363830613439 +37363637346437346536356662343864323236346238643561303335353134666463326363633563 +38393134323436626134363039346133636637643666303039633664363966363431623262343331 +39633931313765343737653237636131616537353235633066656230323964633264356634633133 +63346238393833663839626136333833363236323035656165313032366135313765303139663764 +34666133646431376463353263396334393131623837626566383839346364313336646238326264 +62306366336234636564306533323163643236353862646565373938343036326165663865376261 +30643437353130646537633565663130633337353363393134663835346363303935376162313839 +38373430363832323332333430353136376563393361386536393038633965376337616161613437 +61303861363137623339306134623466306333383837393561396663356265653339323037633639 +37613061633134396439336666373865363464356265623635653633343663346638616633373562 +39313733306165616236653663353933386361353163663332396165666162366362343861633338 +61613564373464306463326434626666613930656464633662616264376539353062646563636336 +62633630646437353966653534366339366236343033316465326166356233333761623733383061 +66656339343961376431363338343534656133666533353534343563393636383663313231393538 +62366366336138353763316131623437633732353362633462663165666466663863663866343937 +30363736323864666462356463363939386434346230386437323436383030666562643738663034 +64646665656531303064376432356533316639666664366462353463323062343430393237356230 +61373234623462653931656161313436653433646236313339363230346663383338333334663032 +37666166626238303431323835343634643131396130653466306432356239393033313034336565 +39376463666165373134393331633930656335393565666232306366626235626638393863363432 +64333335396335326165323937333130373930356238616465636462373866633132386433323335 +64313061633234353439653532343165323233393230336431623362343235636134333062313631 +65343062333039373432373761326466633133633562623938393862326337353361343032353662 +66333337366532336231376336663532666435383533396136646237666466366630356535663738 +64343932386139626134366133306531376531636637343830626638313337383731333432323832 +31653832386235636162626466313735383135343964396563616235633935346339373062653237 +65346639366366383633343135666239643935636434363038313931363735323735343532626131 +34626465633138643932373462313034653861633162396139316166383837373432373263336634 +35316366306362396338643337326463656461323966333239653333343138373731373739646266 +30613935623839363361336366313561333564613032633638663836326465373766313439353262 +38373733323633346463323037396364313862653463303430373032626264363731623035393930 +63393664636631356364666533303931343631663766306233306564623539323737623764613762 +63303461396663653332313762373837663461316636313163316239336162393237333262333837 +64343934343431303766373536666466626235643365636332313833356161386134326566376662 +36386335623639313339666534623530643535656231306663356533326136396530616230306137 +36326263373362333236653835333361643633383765643165366339306538353634626366626132 +36363433653862326464633266383136643436313037343430623031643036333937336233386361 +38303434383431333736396138313638323631346262323835656133353635393832323866366233 +36326435373137316232333432663830616136633430633865633631643264363536613137653061 +61666535626565363739323863366634616131616336666231383265663733643364626362386439 +36383339376633343134616337313065666363383433373239343239343665653636656264346165 +36353131373162396466343037336462306337323265396230346632646566646362373733336664 +33363662313637653533336337626366336337646264356137626133366364393234326261353362 +37343633646535373938383138643436633031353430626439636562353664373965313137306662 +36323739343562346336326237663362313135336136393834623763363433663061353863653633 +34373035643535393966323966623231313037373761366231323866366134333839353633386134 +31326566333939376639396531613935336230633137626539376162313963626166623364396433 +61356630323232356263623333393862383365333732376264373631633231313163383961343962 +65316661383638363831366262643333313233376361346631633265616465333966306663313861 +62376463656536613734653834336235353436323661343531373565343461326239343763356264 +61616330616662346336623662363339373862323530323864666561383833653264393039656664 +61663164373236336337333837616364303065333835633166386535343232376230613063383839 +30383437393031633862363534323134323366326561643936653966383463346337303966356332 +39643761376364316130313864646663653238323436316634616630303563646435633665633763 +37363735306464376364333932346134333963633862613236383934353962366265363431656561 +64373232313265613361666637363765373831376434663961373565346661373632303261613361 +32636135326135303036633665666462623066396632623566396237333430313535383231306538 +66623762633739366137643232393338326663663364376439626262643263373866373963336437 +62376635303765363637656431663263626331616465333137663038383465396162643034653139 +61343031646462396362313731383863643639633762303330366335333835666536653335616535 +63353136323361323338383165613735653566646438636432326638306433313462383139626166 +63303432663962356232393832623138623863303764616634366239613961366661303436373031 +64653261303635613136323362653239333465623635333639336236613030663334346238313439 +31383331643632343131376435393465316339363763313735353839653232646565653439356332 +37333034633034346531373164663038316536656531626265333366616134366666613261393031 +38383238636334333164336566356165366630653964333162376430633665313036306632353237 +34643436386565323930333537663739643063316663656538326330383133373838303434643565 +63663133303531353035363963656638373965383339656337373838653533303632626331326231 +33623463303162353831346533313763366238386539613639313462356566646535376564616663 +64386439333132333566343835623062616461383962633131386562393033366263356531616234 +31666630393565623034356339333563353862363037363539333830363331306232386131623962 +34326432633564393237353835656463626136323634356633393130303832666361373533366538 +30376561333566336337356135333933366661336239343232363764616637393632393631383665 +36356431633630336235656636363837363566643039313131643030613637323033323162653662 +30656235666139656439366466646461303530306136383530366533613030326433363965323633 +31323665373836316139333263306435653937383761653563636235373861363461383530616639 +32613539636337643131353736623238363330313465633537616439356664316665633035643433 +65373966363966383834653666623733666131373137636331336337396439666238646537323165 +62343763613835326532653064306166663232303233393465333161383564366233343962393166 +66316636663432306565653531346166623633396661323762326137613339613034326562326534 +62376436633065373732303463383265613737633864353237333834333736626566363030336664 +65656633343865626264653234333231336466316339656539313833356430373333363734346431 +65386538363662323536306131383066646562663939313736353036316463613063623239633364 +32343937373265346166396266393961663034383437383430323031373734316462313537663838 +32623032363430613432373663656164313130373462323537363838633863373536613463666532 +30653631396230333164323364303630633837653539633138306566633263663330343432366633 +62313332656432323961333533306631383037313138653334633331653734656362636532643638 +62656239323964323839373338633465623561336134323934356162353637623030383636356134 +64396463623630633431356662633633396334303463623963666631613739393038386632353332 +62306434343637343066633561613837376331313136303939343965643734353530333166623862 +37386161346539663032336334643035666666386261303362326161636330306632363663333032 +33663766633239306437653232353137643331303566366530326637333665353736626166363365 +38633238336636313739666463653530663265616666306235306239373163346530323038626632 +39653533633363366132366361646234343031366266663733373264646461393438643566663664 +32633532303030623231356532616662353861326261393638666663323734353865323531623466 +65373838346438396238613835373565343561656639373831346566646339663162353336313738 +61383738303337376536386363326430313961666338653766663535306138613336383265366538 +62613130333065396633643039633431663565303532323266613165623666306564323039306662 +36306332373030333766323637303365623438346338643431663365353232666536343537663335 +36373431303736616464353861613531636165636265316130653334653632303262633837396334 +62643738636534666636323965313932643564343530306435363766363965363738376536336237 +38646432313965336534303635373762313038306638376437633533653362643262633135386164 +31393133656633616366333864323630363063343537326466373266336139323437343164343038 +30376230336237643936346635663838303134363735333931376137643733653533323764613466 +30343261393761346130646636623132623561376632646530626332653061666663353436623261 +36623334313434393637643036333437616238393461613635623932376262383534616636346465 +31353034346564336262396161633466343862363863376439373035613065326531306338353563 +30636361346439353664646630333730633032326338393030386362623632346536393039636463 +36323930396536616564653261666265316237306332363634656361353430653338663238353737 +64643064633964363266313335663762636331383761316237363130643837393130333030393936 +39393539396464616364343963323734366132373734393337623333396538363962353330313066 +31373965393435366534393934393663323034636330356430313638616362653836383261336639 +64393234386233376536363933343866316231393966313631303464653365363832616133666462 +32303630666637616662343161636164643833373334633962313364363731643265353239363639 +39353231653139666366633165313331626562643563663734316538393339386235343835653339 +39363464383737396134373438323839376432323736396130396664353139303266313434666263 +32333463653863356332633734316664393433326336613763653630623863333065646331643338 +61396136343638366436313236663837386562326537623066363030656635663132343939616530 +64376663386131373933336566316263626430656339386662343665633764373262613661373537 +62623164616430366531373831343861333763346436653937383363336130356439373839663433 +62663137666664366566643631393938656135356464643338313063623663323432623163386264 +35383631393662653661333537313033336665323535613563363732356361653231383061343562 +37653864643965646236316166613034303438303039636130383332623933653635343434386539 +63303738623635373965393863393234313735353637613830303736346634373362613935666432 +38343837336435323834333661393337643162666338623764646330393436363861666635363031 +34363938626636626338326464613036333831626131303236663534393734613764613730353539 +35363164643536353333656430323432613462656663373161363466333031623730316336353361 +35616563616632373732363432323036306564336263353363333939623135303631316239386136 +32636661643032633066326333346366633265396661313833373033643265663965306136656261 +34343631333037663366626634363965353162326139613432646435346532383262333862623232 +64656235646362306334633664363265386336383062356265353836333164663665343663663830 +37386664666635306131616533666166646231343231663964393561373461346166356232336232 +61613734626164666365643439303834643261333131663031336634303238633261663631626561 +34336238373636386333383932363237616332613634653565373632616566376461323765326564 +30653765663639383735396134636230393132303461393234323364633262333238373430393065 +64616361623466633664373535656339646434366365336133323262303266623937383038626166 +64363061363937316332313063633865333935646333313831313437363036646639356637656166 +35616663346465303065323565616637386362313365373734643332643638636436633961623938 +38373031623337383463366131383532386638646262653835383931363837323664663165346166 +63306239366564636564346136373039316362653130653863616234383938336563363431383934 +62376165353230333333323263303734393739643334306462336530613965343465636165373363 +31306634313636363633656439383232643439396630643337336138656466656430373166306337 +62376266336162383565383432613635383237323538626633383935356634383532306138393538 +61386539303430303834313332616331333132346634623561613535633862633436346534393831 +33323130623037303331333835643862316162336561323236363130636637393636663834633039 +35613766343062613534666334666235663334383935636238393637363230643566333235626661 +30623564393466353164616463353537656163313538363839363435383261666538393633643763 +34643164663932663961376662323362326338386632346531643630303966613764626635623964 +65643437613935633761633234343364626531306638366637343230316261626530346433303730 +64326433393036356561393666656139303432393336303165653439666433386532356436613065 +64343335313630666661376163623362383831613164616366303966646365366439666266363934 +35626336323331646136336238623065313434366666383665323464663064316534353433623439 +39373233613435656664363062383135356662663039303839353633646566356166336664393038 +35363233353931313834663162613530303133376264636161333732376234323331303865323434 +39326331646334353830613939626536306537343266343033346539633464346561613632666165 +38373937366530613831613634653964633939613330393933623365653066643032646335613831 +33353933653634316539303137366338356530326634626334656666353538633466313634626364 +32666361653461646237386631626138643036323036646635616263326436313534343537643533 +31656232653334346262613038376338353134313435613935373539336334613338303262323930 +36393866373135383334373937613862393836303162346563393831346437373032376664346363 +34643235326331336164323535383866623032353062303431356437323464663462646239353638 +31303065336332383661613564316637393963356539646435643663383834383036383665343436 +64633936666662353936383162626137326665303863353232366563376336303032663566656162 +36666565623238373838386435356331666633373938303536383830633031626338346239346163 +34663533313939383561313435613763393734633130626130653136663838376638316237303561 +30343165366562663263303932326663363461396533366662393165363035653262383139313564 +62666434333333666539316163666532323839303732393463316330396135623764633639323535 +34396635663031633134643439333831313561363032346538393763343637313030376431366235 +36353562333664626232653035316364336333373133383538396538346533313561623964363265 +61663864343433356332633937626439393837363734366666666635353533343263343835646263 +65366635316435373761386534613632333731336365636333373931626436666633343236353638 +66313832373366313238623565333032643233313163393037613637356165613834656235636165 +39633339326431303930626535666338363036353636316338613166623631636364646230383464 +65653833356133643030323161356463636664356638343136363831623034623965623263373465 +33613335363537643435396233316235346533633863613238653437346162653135616334363031 +30663831633032346433393536613062363264326439386565633733306139363733633864643034 +34646533646262326432313232346633653931353562633530333532313235376435373865343065 +66626463383934373966613133646564366164613238383261373662313131666265643764326465 +63366565343032613262333130386432316234333231323636393833366132613533373562323034 +30303336313662306665633332653939336536336634366236303239613264373835666230656163 +66353262663235383164323663623230306537326135313565396534346237646132383236636535 +32313034643534623930626161643936333936656233376235626435326261653863396364663865 +64343236343630316632643139663135343831396464346363393832363231626533626333643139 +35393866353662373034626264316635313663383038356430613438393333383835353063363233 +66366431626361613961633935346665313561336431373036393762386466353132646230356435 +38383065393163333530333134653330396531623835323533303536346335323835316131373663 +32666464376230333861613637393639306635383736363361383336663239363739306133313063 +66313834343965353338336465623534366538376661336566333331393532326434323434346665 +32653365653065386161353066633139303863303066323663353261663063356362383765316530 +30333262393665383533343961636138313062633239383638343439356630303539643462623636 +36383132626334316237666638373165383163326463336136633431623833366666653139653863 +38353335353232643462646262336365653733356237323464636365393230613539663339623638 +39373662666364346537666234333732343239613265626333333637373262306565306137343166 +38396361303235386638333539656334656264623766393938303365626439643333646637663438 +66636134383138343965323138353036663832666531613034373462333564303036313634613562 +33356437613739643332313966333834656232633432646564396334626332613834313138376538 +37613831373866336338663666616535393766626437613166386539643738316163626132383263 +36633666623966373935326661366163653939336262363534666361363338306161306134323665 +31353464633163306135323830326232626164313035643935633263306539396431636263633134 +63363038373534356662643465373632353839376364346663363737373566626565386566353633 +30386131313431393564396662653563386234343764323431643064363466356162383739663735 +32303562326533636161353537386532303938666434343635303536393061623762396661313761 +32666664663336613236313234623733313735323236663963393233623234343932613661346538 +37666339343033656666303561623264363130613864646533383331666131336636626337653338 +62336361346530623261336163626463653738636363633039333663366438393939666639363736 +37366263633861383133373962323133353562646638346534636164336462313064643935656639 +64363730386532616530366130623936663862653465613932336362323736326335343630356139 +61663530313666373465663765633833363136653434373935633262333461336466626537623531 +61383663353264353064343531613533623364313661313461383066663036353234393966386162 +38336362313531303934326636323265366239663239646133303863626135656162373033393031 +34666564646633363831343734613765353733636262336662383236313065323932396166303966 +37613865373532613466393166366665653130303065613662353834643239373638356661386262 +37343166383762626637386163373135363166646432396232616337336436383934373636323665 +39376532623738646531313331623964303363386633633237373564383666376661646630323061 +36373632653938626632346435323730383765666230316265633334613761343861393634643766 +38346662336337336264656636663862336134666366326335323263633132346164323761353866 +30643562303231643532643266653335663330626163326536356434653062343165333763376130 +32346434383131333037326139333562313666303630383766633935356532626634313434313437 +31316436373237393931623565666264363539666138653631613439336436356263363339623964 +32376238303830633635613466333163323666643362373133346339316533333739346132323637 +32373936663364386665353233633961376163396162363461616338373833616333393063623037 +65346435373831336531363333656639663362613130383334356661386262616665316435346162 +64643039346631366663366432356533613937343334306265396231366565343433643137353263 +38316662643630646462386531353835623539386433393065646131393837663731363664653132 +66613739623237353437356339333265343364653861383261333062336438656135376331663662 +62643461346566626633653763666630323237343739636531396330393965666438643365356134 +30303936626565643165363739663733366134333135353532306133613361663336356338396136 +64303866396135376434323862303933356662646536333663373236333136396361373935356165 +61646632306339616632343861653734616366373162323333613661636432633139316638626639 +31393531616363343632343633303432376434333739383038646235666635663130383866393364 +61333264396664376565643263376232613863343932343362623535386139376438323962353330 +64633036643735633334613536313638346531653235313831666661646439316138653532663063 +37353435306336366131643533393131303630376466643666333238313336373163376431393730 +38343038656630373934653938343137376133666134626234313466383734383961316135396634 +64653564306434363762386163633332613335656662306330633264393633613233636437373962 +30633162393561323032646535383262333162336633326438303333363132373138303836336465 +33323066386332363831623363313532653164656435343939633436326262386634653732656435 +37646637623065663334643838653765336137646433636263613735623764636266343230313435 +39623264613765383966336563646636646338353366333164346562303732653437323036353438 +61323539326464656161616535623435346533393031323535363638623864313262373932336331 +39306539633335326364616161643235623339373630386130623435333935393932393639333132 +39303235313066333634313730303736633365393139353937303462626539333862373630363137 +39316362323731656161353662373637383264396131626264356339306665653132343437333039 +38393532623030623934663063663338616434613665353236653831323236626234346566656263 +64383663316262303231333034326264383766303736633166343236386362306637333664353739 +39373162343433363033616432643164326236386566343133366634306135396463336339666330 +65303163343434643933333166643234396366643764393836353634343037626438343837353839 +62356363653762613732396361306461343335353465323562306261343063303739613665386564 +30623530373065656663323838653037333937306363396336616266376364346436333932383365 +34626431306333633633373338363637656161383037343966373533666232626466323038663061 +36626361306236626432633733323331306364393162626239343065623234363031333665633765 +63363339616437326432663966363435323037643363313231396534346434323865306239643933 +38636563393331323337343336623034623030363066386530386337383834623637666561336566 +37346661653761386331336232653765383231373331633931383737653563366365633637633032 +33663430366361636666373431646163306131633762353566323630396466343636633262653931 +38326633303333656464376166616261376332393263316365663463613735376530343137316661 +31303239643762626531386566613863393762333266336134316537343137636131376465643332 +32643639356365313966393334643066653138383264383663616432303831616664643865353038 +34653232643033643034333665643234316130346461633730353339633438333362306536393533 +38313939363935653639396361306237393466376535326139323563633063313737353139616230 +38313136616564663432633463386234333738386664643630343561663766313339656236643535 +32616664316639363739616534373037633337373631343866306464383031386564656436306535 +30336533646630643333393635373466383839363837313230333765346433313662373632653131 +64626131653637326632353339396266376161303966626538356339623038653634376266623535 +30313433336339356230356633646237313231656232346233663433666133663638626137363766 +31653334363762356138346439383964353062616562656362333732653738336536396364333062 +33346566323939623465663230646131653838653938343239353165303338613132646131663033 +62633930303432376534323563313666633839393530643233313163623763666531653634383635 +32383331343933303932316564646430323638363534363963663637343137643331373433306134 +61343361326661333761616362303738373233383030323135363733383835303864363362303163 +34316336626238326464343465303130633330386566366537303231356363363037376430613563 +34336231656565326165653034666332336535353032623964323138323339343064323266313466 +38613263346635643363643162656662396663613766353639666137316234623439643732303832 +36633061386439613264613131663566343565646531323134306334396362353232643035613865 +30383330303139616238616139363264643365623938333939636365613036326334333136363538 +32383038393761623934353138333034343963323033656138376165633764633033393363666531 +66313238666661343838316232373638393433653931363765303137373364663333643234663263 +35313733393066313463316434343739303137303531623334613137363537643064303133616163 +32646665313664396231333334383335323061646632316430323836633033643139626632393962 +61646233363936636565643436653231303165326165623432613639646638313265303066323262 +39336466383766633466643537363536613239386136393962613432306335343138613335663839 +35333064613730663038313537343538376538343635333363623164666238393833306563363030 +64303732643635323664623163666137653464303632303831303164613034383663653932336238 +64653230383936666565613435393437366666353063323366353865373631323730386336663861 +62613363346239393931666637383866393838643662303933616366323564386461393266343331 +62356235666136656162666238373837666562396635613762333462653130306233353664343531 +64323961313134306365396165386563633930333032366139333131613930353466343438383139 +63656162613936646639366565323338326566323531323131653261303464306339613566626364 +66386262633739333131373561616534613163663335313537313863613666316531663734633931 +30633063303635663234326263373865376561363464623832623166653738633265363338623135 +32373565633836393534383265613564643737323330656166656235666361666663323238396233 +63396462616139323733663632363237633933396537326235396231323635643734363136373766 +35643464363738383037646235336231366630656231343161333763643261363963303564666430 +65336435633131316464643166363538653131366465623337373833643036616633336434383162 +62303664613337653661643861623631633634373335303933323132366163386465626434616135 +61653063303231666533383762663032303666396362326235366164303435323535343033356133 +39646165303361373266303539353963316433383930653466333138376438646330633165303532 +66363961633863613033323131653463656331663930333162613235656463323565663830363662 +37646639663937613664303466323137363433626262643038383436336436613132623433336238 +66623161353937336365336663366237373365306430666163396462613834336466653331303761 +31396238623266653236663162326538333733646537396164316336643131643437303439626164 +35393630343664343866313463363330633333336534613235316334356464373266373832346534 +33313730623832356231393530316662386331323239666637393836396431316164303932346632 +65323735363566303635353130623532346264386630343966363732313735393261353138616131 +32653561636331663439636131326563346666643866383861363238306266613430386436353164 +65376232333835613633396537613063623432383435366635333565346261356137613361303131 +37363133396435616564393966393431386566366239363263666336353466393866336564366633 +36393762666336626362663737343436326530656138663164373734333761653139386335626332 +65336638653339316136356366346466363438633039623831323434376436663633613735373336 +35386634353265323336323130626430353336366261386537346136343633653230656565393934 +32376530346461333833616366646630333134343030376339313663373533653837323034646363 +66623263346136323539343039313632306237613664356138613939333661656330666633353636 +64363964656339303131633636633462313130663636316432386533323839373134646130663136 +34363764343366356234623764313364346534313261306561343237383263336265303535653937 +64653131363861633466356563333961623735633464613139323365636131636138303764663032 +30666339656537613230313062336361313935663139643766383239383537303938656637373030 +39653863653435396439333936326361313966363837326336396330353262623966366333366261 +37343133623639633033376265303966323433366662383464633764626632316634616264633232 +30316539393630316333343564356461376331343939646530396366303261393139373030653164 +34323532343766643765363961316133643261653931626434346330616161303631333032366136 +61336439326239613731393734653637656166303833643034643938393738646165646130653866 +63303231616232623066373166346561363939643530666236343535633135656532393564346337 +39623463373533653034323938313961333037343838643136386433636235646264363765643538 +66306335336630356565623231626562643334386464343732393061656465393863373536396561 +64363638653863346661636332373364616331303538636339363866363436383632653066346364 +33326239313534653066326166616364396230666564306233326662343666313033333934346365 +38636338636164623563373336626433393535646531643839653831376165333530393934326566 +38353335383639626431303236326363366133306664366233353436313865616665376332663762 +36623833303233393335303330373461633637353138326338383136653031356163643638326363 +30636339376631356431363430306234633465393838656237393836363633393664663031623665 +63343761646534323233333734613163353363383530663239373436616330343134633037646236 +35663965633965653431343138616532636334666132353335353364646235346334393961646238 +63666632313764663038633136316562616534323034616630376439393461313165313864396435 +30323531346466333530623163636439323830616563326637663234313039356535313565323434 +63616362336364346165336133396138643465623334613733356538623736323165376161373964 +38346430663836613638633463383233303832333439376661643865363132353834343436393236 +36383062613239666231303532636362396130643634353239643234623433343862656265623538 +32316164663339363939363034343635333231333466363361343465646461653438313931323531 +33353130356665373962343262326631353361373432353965663334626464376466626566363566 +39323061343364353833393433333736643236386562656264613134306264646635306631323966 +31396537616537336263623233613337383666633431353664343664643238633065636163636138 +62613639363162633163306337613237623336346135653439386133323034343736616466623331 +38353264616161353335323862386330373338396233326562386433643032353139316530353332 +63333762363339626432343664386336376537623365623633316430613930383137343831643966 +65626366376535366539343864316465346662636535313761356330336639623164663831373863 +34666634623838643236643239636230353761373532363865336464636334633735386466373538 +66613335613862346166363462663432366665363130326336633230653262393236323961343862 +61353363343135383235333166376566306333666261623464623934663766386534636462356561 +36383831336132343231663830346664366137613364623737653732653638313639396135323434 +30353135346236386233336361313963336136666464363639306137633733336461353930323232 +34643036333839656437383961626164313031366434323930633839333066313533636136623837 +65316233326661613966323332336566636536353534396432636666363738623063643032366561 +64346463336232303230313637376161396533616362383835313962336332306532666333663365 +35663038313666343862333566393831356639396561383133636539393834396135376232336430 +35353761336338323135383739383232663961323964313464326231666235393737353237663231 +63653831336536376364373163323465366136383430393130363937373836623330616261633338 +62323433383334356439643135383761326163653834643034343265333330383930656535363439 +64626364323838623632303663376361376636616430643835303738386336346565353136613034 +30336539373461396238383466663438353832393936346134323533623530383264306362316663 +66306332393765386161343833333865316165323731323932356230393963616165663263646532 +30613862373337383861623137326139323864356562346261363839623364333535623732616235 +66316436326632376538356133663431653264383063363836376233333162353737353263303930 +66396461306431333364393034656231373763323165373362366262633738336132633835666663 +36383536386362346431316237653634323461323865626131633132333832363061663838666331 +38636262633165633465633536623634616434386263323631316234633463376433633061626665 +38363734653264383335636265626239373563663630666435383032383062343633333431313036 +32663565626138653131636230623134306565316330373931303738663562353465316164306234 +35653536333336663530633938383131323833333036363834343766643235373865623664393866 +33633237353962393537353562303966376632336662643764643132633039316434636263656532 +38316434663562343234396661373039613231313331366636643961636530646461613033653661 +66313139313935353635636561343962386237323961306532326438323063633832626266353061 +62313639383036666639333063303832343730633566656363613739343739373565633762626663 +32356430346338396234336335333962323632373664316634363235356362303662366166643363 +39306238616237303565346634653030346562323762346533303530633763633866383164316461 +31343231333332623031636439383138626535356639353962623335343261336662656166393231 +36313665636363373163643065346263666633343565653230316538303136333031383262316230 +64313764636538376330666365313939366235616632333862643162626338363564353036363264 +62373833656631303931343166353662343839383731613365636266633030376164353934636436 +32646635633264343934333531396133343465373836326164616434336431376333653162616639 +38346231666630323738623835613136656131303262396565396332633332346231323333666164 +66366636373833393038313364353833336134346262313537306364386532373066636133336630 +30633433626563326166313433653066633237383635323038613066646364666137343238366235 +66303138383965393261656535323464613966643563393062336165363031646234353330313361 +37633436636636623366636131316266316636303838353930623730636233643737303365313866 +33646564333162326231306165623836623631303638326436633934643739663431316564646430 +35663762303936333830396432656163396431663439383330626330356534316639343236623530 +34363263663231336530363935313265666234656537373965386535383338343566613562386563 +33346637326465643434663333366639613664356235373635346439633835653163626665393636 +37306262373262636534376230616537383831646534623861326466646637363338373930643738 +34303833633864323038646363633761343234623839353838636439633762356634313237633063 +32656630363561636636356236653431313834366235383565646565363336386638303366623235 +61653064623631306462353739383466303535656461363136626565646266383132393634663331 +33356166643638303065346239333631333261646266396566353837663461373061383836633261 +64633431313535666535373232313632323461343139313536653434393634626339666235393034 +36623930663035663265333932336561393064333834383236353965333562633732396565303336 +35383530326634333661303834376262643237313034656465383664343332353931343635623863 +66313233316136393366663866383363633433316538353032623730303335343033313839643239 +35366635336162336663343638303139663731393135623165363738353566333837313435373234 +31636430363033343833333336316139636662666330333565643336653438366234343063633636 +36306666396266653065623762383463353732663663313335346163633738363532656365633663 +64353732623430646363323465653639346561373164393862343933333133666237373030313435 +62333932396230666334383237663432393430363961336133303737373633336166643564623532 +33626634623461663664366366386539333831396464396564363630383662633963666432363835 +36323530633362316561363331336430353635373866613565613733616430643933336631393036 +37356662363931663464376561616361383536303433353838656434353733363763653035353736 +35373963623239646631376136623038323730363563303038313464303763343839653462346664 +35393362343134333831383165326638633833316335353734356536343966323666313932643733 +38363533363730646333376237613330316230623933623735626463663039383334646563343132 +62633163613134346232343534666338613439353362366534356433373135323634623631313964 +63656639346534333633623631663537636466363765643338353661633239386638623630386662 +61663134373263373361613465336664656236343031636239313463633136663065333564643766 +37346466643664333538663966356539366331306463643962656234346432613465383062643439 +36323538393535336137636164313462303036396235663765646364333164313834616239656363 +38306534383733313638356661303532373839376237393536646635373535623538663039613666 +63323666646534613835306632346637346165306561633366643734353033313931616532393832 +39653937633532363430336165356437623432326139313266636634366463633137323665626132 +35393965613765653831333565306364386336393430333836353536303338633165313063396337 +38383739623331396464636238636366623030336335366330326336633937376664373966313238 +36633930373339623132353761303434363637303335316366616632646137653661333461356462 +63313437363166396165623531653439313862616263613132373537356335646637666635356133 +34333733383864656539363436656564666130663761613130613833643031323664306131663861 +62636333343665646265663062373863323363653239326162303361363234643438383037316438 +33363332333431303132323235326263663130333838346130363633656165313563616637313061 +30383737356234333866636665666335363930323039326634376463363236396661343436383332 +37313762316465626365383432623961383733626665613136653366643731616134323937363239 +34643836316234313034633163633435373635343930343164636633343537383236396438383439 +63643335636466646339653235633330313338373565653139333562373738656233303234376331 +65666536656463356462353032643637353366306639326531613533623964303234376636343337 +64396130313262643862356162383235633565306262653537316539386237336534666663643337 +38366339386334653939373963383439386561326464393765363439663031666661306665653864 +65333435303364653632316435386365313833623635366161633138346161303765636562623739 +36303535336562313863643365383563633865383139363338616132613461623034393032373135 +62643938666564646233623234373862376362343939666638353238313734303335333864376632 +62396561353333323036333436303734303864623566333438323739336165313730656536323762 +32653732313135666435373465643362636361393065626237323631376161323164313632363235 +32366366313766383561393737396333353131396562303561373631393761343133643666313435 +35363437626535363964313765396634643338643762356664366538613435363134336364336530 +36646161393037343030383063643866336337633631303536396633626433666430353065353635 +63653435363366323035646565373163316662646565303535313539396439353964353866643435 +34613762663366396636306634646665363664376263613936336562646566646635663161343765 +37396239643436313234363864363437363365646437336361346538626431386136643561373630 +31653134656632363661646166396235353264373239306238626636393862346662663636393763 +63316138623236333963343762323230383238636631623164343462613237616364343235316533 +32663665316334623533323038313562613663353239353837653737363633363031393232313732 +36343834623063373662366638643836366338623864363038346535363634363035643536306262 +62633165356366613136376230643638383236303564653138623535333439633265383636346631 +61343631656134303864343961616333623966343734623733353537613261346636336431313135 +34373738306164613133346236366130623938306432396234643261303730333439383766396565 +30353231333663643766623130383438343935303462396264353933323536663232323135336635 +39333438363163323735333735343766316265316633353165353634326230646330303830346161 +64623361386439633037353539373262636336666138653833373234633036306166663436643430 +31356362316333313630393361653939363366643333633030626163643136633236386637393062 +62386230356363346165643765326264663734616630393638353330386232303062376231656437 +39643330343865613239663830636136393765643138393836346439393765393036303137616133 +63363161646533653364303139383530313065306138386366633365316530386661666233643438 +33376164373537633165343332333562636637333162353939303339623635343635663732313038 +36376563343865313962383936613836303262396532316534626565663134383836333961653032 +65656538643436336361613434313131613863666330353734376530656538366339353964613131 +65333166353265613333653930646338383136646361366231343063356531363633663336316437 +63323866316134303263616234366361613766343634363166333532663733633631343761383034 +64383465396266363131366162323133653038393438623437353362323362353538666435336237 +30383235393233393632326231356332636138373233373962663637613330333832353137366337 +38326664663163323631323331323232373761353463363139646361383738316639333661313034 +35366231306165333866643638393736366361386535313337356463313264643162383336643763 +64343034636537373462396637626532653061323430636231643938323536366638373231383864 +62373065613761613234656136353235363434663939373536636234656335373231616635623430 +32333333623361313530346231306330386265373536636161323765623466306262326661343562 +37613362306565663835633665343735353139386237626135383436353163313764633930623130 +35366139616561333637643733363938663637386239646161653564633333666131343864663537 +37396534356238383633623564343039353664313930643037303635653334616133656538613962 +30656133376661383764353663303832396365616239633436356533303433373661616163623931 +38346637363431363464626239343661353035663664376639326666336337396631316566643430 +34616331646432643233333037623232653238383366313234666165613266643063386163623365 +34323437323034333734313764363461643330346633663566626134663334303361663036393333 +38353130343136306530636233623361373730613263353736333931306133383063616533636333 +36376235333736343637646134623530373236643335303135343834313939613432353337663430 +37613233346365396336386265313235663837663139386631613664343161623738396533613737 +37643162653038303937323135343336376366636439363135306331356634313162643365373234 +64663635366263316437346236643765616139396639383261636333343366343334373761643635 +64326435623839313630623036333837373462376166373166353134313032396439663937363237 +31653961653639623631306332656233363537353966306430323438353061616539336634626465 +36343762616561376530323338613333633235636439383362643836343065386436653433663135 +34663132643362663962323264386436373264666131626163633236653162313837313465666163 +37343131313161663737663836636536626665303633353932636638633130353637373632333136 +38613432313363613337643633613231346233383532343263653333636435393964366662356437 +32313963313630343265663363313265313132613433353730393461613661323738656235306161 +35363931613932393035636161633965663930613239383432616166383332626139343035636237 +65383339366232373063636264353464326232376236303130383133643232353033313961373161 +39613062636363313737316435366365633237613931316466376666336561653437363631353932 +37393439323764646631346637646236643533376130633433303266386163646338636537393037 +33386634306664356561353433313733656230303333633830383831306264326330656464313565 +39316366313862393630393236376363386464313538393832393564363732623365643737363161 +31643466316663346462373466636661653730656261343232326662376635316661626364303030 +63366566393431333934346163613461666138656232313933383761373961306263633638613331 +36613838626536396261326237643031643062666335623138316532663837353730613562643930 +34626564633630663435303864633939316262326438393361316633626162373465613032663235 +34626364366236343836663064656432623332313539623564613730393063386462356635316130 +37373834626466353232336265336164323463306536663734643962323638303961316637643232 +65653939613331363430303438393235373863333132643437623633366363666230633232616139 +34353437323935623639396262333631336136666466343936376262353230383139653762623535 +63636463366263633338636663363963393034343634383830663730643635613634346133373535 +39643162356138346535663335656364323466653433343432313734373236346233323862326230 +38643236366631333231663265323237653863376335326435623265623238653739633963333935 +64636465643333336431613230383633663432383063396566333537343461333537316362663836 +36316237303033633334336563343161383230333262623231353261323238393837313165326239 +65653166366162646331356437373037646539656636663339623236653634386630333031623432 +63643632643432353066656130383733313031633866386534653539313362323136353764353034 +66376562323730346639656131666333663563626432363637633062623130393563616464613162 +62386339316134306238623566633539393366333566356665636330363635363763663234303164 +62663933313263376436323534306464343439326261333030316231333130633864346233313332 +65386134386361356632363561653462646133383438373838376364336638623330623966663930 +37303039613235373665356432356661646331353336353665343631656232613832316435313131 +62643434633730386537643936353538373332333431366136613761653934363137386538333330 +30313539336164303936353537356131663336363937656565376233663964323435363635303237 +39363261306331623230623031333965646134393632626538386534383933333263333336623364 +35373063343630653034666362326363616631316239346462333438346532643661386132373734 +63386361373066306331653031306361393462643534396132613230383361326430383261313764 +38613464633836396133383265666263616139633861303638323461646138343037613239333332 +34613730366164383236626139636662306339313038666536393133376236663437376464316536 +66366665306532633134363361666661623962633830326630653463376565306263333538666366 +33326632333636353665343236633831623536316365326336626461663038313236393536656538 +39343965373864323232373161316363353032653232303238393639373238356566333833306666 +36373866313432386333666337646466633137333836616136333663393964373635306234616235 +34643966323934386163326635636235626133333566316461383666343766343136383733326563 +66643465353536373233333961643535653763373136396437316136646637633134376664393664 +64363266616135303233333930376666663661373361393034343931336435316364343133303264 +66333862396330306434386361613330373530373764616436636339623336643535303738366133 +30376439353262636436363031313765313462646137653264616638316531356438353561326131 +65363837626539313563373265356136343936366434303932306163393531373734623238373335 +65383865343664616537626637343637323661336331366462363666303730626534623437356561 +36616436303633363565393736643632343736336330343736616631306538646335393637396264 +33316166656462623261396436343938363161356130333735376264613931336637356336306338 +34303335343030653039333931663166333332383966643836393834356539333937383664393133 +31353131303332363635386439323464613330343031333539653766663539663832363665386363 +61343636636136626334303439646532666363343366313461343635393035393266626339323033 +66626362366531613931393530663433636334383733323237316233326537353861653062336531 +33636334356562643561346530663335613833363339613331623666343330613638353630313463 +39633364386461373363633438613831356562613064353034626439333838636236633939396562 +61373263306462623838623231333261313164386533316461646235393035653733396535333230 +37343738363332633563323866643461646565616537306462646235346262646661336132626231 +35633133373135633337303239326466613038333461393131633335633335336131653131373536 +64363538333837636361633739623730643063393438653638666139323035386464353365623930 +38616532363833323230353464666165386266643861323764353365396463396436626564373163 +39626138633238616663666537353438613061303361363362313765363233643331303236326430 +65346235386663306330333037653530386331373966323866316537666133303931343139636563 +39343066373333383235346137613336646161373961376133396130333638366262346664323633 +37303036646366316631636635613535616563323763366230366536306431353731346538353961 +38353466306536356461343062386238643137346332393835663266316637313638653462393537 +35396131343864633037646135613663316334373666326666666538633534303961356566333931 +34363465326563383464663331666230393835333436323162386135643466613133306461393330 +35393032646230306533376666646365653461383565323135613433353563663630643532333733 +33353265663634313136613961383364333562653663626639663930306236316638336262316165 +38656432346332666366633830653361383233386536363536363262633431363136333832393563 +36313131653839653363646139326461636334636632646663306633326137373735633038366634 +36383765633938363162353335313735396461336531613666623234663431353331663561376133 +31366136343737666136346461376565636362333564623931373465636363306138623039323335 +37643661303931303738396131313635636133663932363764366539393631376530323631343662 +36376237616361356262613464643162316435346437656533633830326562383962393764633336 +61393963363632346263633334666434613132646439616261323437343738653631663839633434 +37343331613366363632626366393136646233346536336236646332333863386636643339303035 +34363732616266653731363635356333333737333963656533356436613564366135373838333431 +38323331633939653135336532363635343034383030373465633432346362363636666332376335 +64373962623432396562303562663830353535653137333065396161653764353535303532376462 +31393434346231396138363133633830666664326434656664666236666331343735626266373065 +35303165396462303661393738303932383462383762326535633933363837633563643232313339 +34653631643536643662343066396337316162333635373737303337663664323966343634623362 +39663964333838333261366666653135633732643438663964336430363635643161303939646330 +39316431373239376332376432366130303137643939356538666338343137316432353565353063 +63383664383834663738636463616639666631316433626365663062643335656437326231623738 +34323132616161383533643864663932613565666561303666363438303539323838386432653530 +35386537326261343531333930373662656235323866333564303365376539613332363435336264 +63303564343633633761633562643562323066396333303635383436626564666232343939373235 +32383534633534653933613666613466393734363438306336643766303865653665346233386565 +31626437383763613163656430613239613263613531663738623163396166613763633130343538 +66376163393565646564316137633836323665373531663161333061643534626566396636383232 +36663139393732316133623938643735663663303661313365663864326164653363313939383533 +63643935383634383263343463646534616465356561346338343936643164373061316537346235 +65333033303331653465313436643333356230313561633763346339376461386266653066643138 +36656238626136366264343861623965653034353464646463336431316333663038303533346633 +65613662326637326634623234396565643237373139666461363761356262636336623538333133 +32376432633632646436353934316432663362393765343838373336623530336562393864326232 +37316531626334386633626332383633333438383337346132653530653566643764373966663836 +61626333373363313836643436353037383937613235346638373462646630663333633636326465 +39353635613763353935306137336637303864666239363230376431626135323032646166376430 +62653362373236306333636234636539383530346530636261383366313334623538646561343430 +62663336633330333463356139306337366633376131623537656163663432306231623062633463 +34316636643938623038333234346438363337333331613634393439666664386433323536663534 +64616164356139646431306565356133353031393466613833336631363761663732373932313335 +39616330323361316534363435393262326233353561643565373538336362313261643739376530 +38663932613061373663316337663762343235353132323633353739383762373231663135313965 +38376261373632613166656130366631333763393863653962306166343362326633363662663539 +64623130366138396332616339393864653439663435313133353431633138613565396331666162 +31616433613634303537333062303665363065653133306562663263313032393534633438363637 +39656538343261653937386335306635363635333438636566616237326233313431386236663365 +36663031323030633964636635633366373662356561653762613730323066336130363035383335 +31636365616438346230333062633830613937363234373233613939383663336562613230333366 +61653533366566306334616265323530316330643333393938376262353164613164303064353935 +64373265353964303261303864316237373935333932376533396665633233306363633639663761 +33636131643431333064663331306264613666303933623264346631643934306331306337353265 +62333535323135363535333935316536323762376166666334303237396365653930636363316138 +39313661633032653761636231393537643363346163326363646335326236623066353737363733 +62323631363038313563303338393738623032626630303637633835353832333839666661353965 +39303163653431323733633236376361303564343136616161366164663363346636663836666637 +61336463316666643965353132396439636634303762623661356134633664646134616565653136 +63363963653131653166366439616165343434643630376136303564363932333131393934323839 +64646437396630383734363039313464383661303131393538663038323861663736663235356361 +64656637313664653937323635616636356164393039633564376162666539623636396166313530 +32356462393832663738343331396437613033636333353630306538646633646532626231633635 +35623162316432393034363965383939633164643238353634353831383539346433383363333830 +65363462613765613061353733613332656164376539633332653236306561346232636638363031 +39393963666163356334386636393239353037656330386230643038303862383933326661303564 +36383563373137393333383436636130666436653239616335383837343934303861313732303231 +31393436316436363039303762613331663065613031343964643862383430363462303666303234 +61633561306564656136326563393830626430626436373533613032613838313936656632336632 +30643231613364623336623037313933316466346461653435386438383838613365613966643564 +34623039663261376131326331366638646135393537633163383366343331626166306130613464 +65666164303361396139366336323335313866343965663966343236356230373432623138616336 +66353566366330353461643430643536313430383865303433333965366261363332373538393332 +65646266353765633631656265316564656538336166393734396131663563616339636438613963 +34353136326664326162326261383235363837316365643566393531623265386364333962363937 +34316663613733353631363433393964303862623436653033383362663461333836386539333666 +37313463323563663565313938636563656136373434623862343038656666646138343030643631 +34623934656261623464373035653936643739393164396436656663376363666564656430303235 +36626361353135616635363831306163623238306339653762366366373132353564333337343638 +37306330376434326165336634653465376235386336663064353961373962663334653866613734 +37323030353462613333366131616431393362326161646136333164336662656361666432363831 +30353264616363333763396362323664646664373036336632663034303562623934343233313837 +33636164643931666535623065613463653561366335646566646237356435336238623330306632 +30346166643766643834316435306336356533343165333831336662623834343633616131356638 +33366437616234306265613961326130336132346166633933303637376430663837343438646337 +39383735643939383461373733366332653435393835386264613033323765323364633335616233 +34333365663032333238356531663563323832333738653163623037336531613734316433653366 +61326463383338383239323461613066386264323938336430373162643738396131313237353732 +37643061396465623535313763653965643432656666313636363536653239373563643961616538 +37333762663439623734376665323538323633323233353762626662323666626239663535623132 +61633361336436353630306333343465633961336537336531363562373936646430646165396561 +63383130623864333333346530346330646239393334313035663731653639363032613939653631 +34373830643863633133386531643964366536613631333439336438333532393166346636323230 +62333863393337316335636531326263636238663161336566633532633337663439643463643664 +33613965393539303363373736366631636332333233346361313435346366663261323132336437 +64616136643439316562643938623238313731363233306136613635616665333764633461663831 +38313662343336633466303966366266646538366266666330396230303834303736653939613532 +63383565393462303664623163623036303235343463323333306238383566643831653036313265 +33623439323361363739376433383165343364346631376435343133303762303932343936396238 +63383637653262616261386338646331636166336433366263303435666663313764333665653066 +33626532353464653736313638366634343631626434396364326130363237386639346534643232 +36363166666130663435363236393230336132336637393464356163633865396363633137663239 +37616239303961323334643030363566373634643638316563373939643339666231393636656531 +36376232383061623162353364313131656635306636373461386438376331353362663938316636 +61386364633730326338373965316131656362633334666531383836653238346137333262663039 +65646131653236656662386131383866353038343731646439376633313237316337333539356162 +65633033393565336639613531316663383762393865663261323730306335343238316231643635 +37326235373135313964616264333564323635363137303039653130333133393332353432336537 +39333930353063383538316164633238363066333962376234363636383632643934363238346664 +33353961383335313834393035643038613134373934666664303362326462633231306461363730 +63376361663735666132623235383765653165326362363135366532346535323637353362346430 +64326536353739646137643862373235316265633563613663613338613962363937383836636637 +37313862663330366535666431343339333931333538353937323032633961663464633862323834 +30343935373739306232353137636463376138633839636539353634616461363739356361363437 +35303865626133326138336563316566323831396362343637623739666230306536663765396531 +30616232633330653261313865616563313039376339653464393436383331366335373633616639 +38323662323336383364306430613937353062616261383234303162643665633032323165633231 +34313034373636383735643534633935613537323736363932333063663661623031303265366234 +30613631376333363132666638623062343333333666636236343131643537323338333033346536 +36343237336431373735626333303366396539393131663838336635353061643532656131336564 +35363537663238313666653163336462633236343539363639626332643466646639613634366333 +33663964303063623062383339346164343039313737336237653161356234386235326235396530 +61626235393561386231393562313734636639633365623239613132336532346465616236343338 +65623565336139336666653232393762373334333532353239373536623666316166633134363463 +63646430383937386661626161343331633131653530336438393939346365356538386633623032 +63366263393561316232333837633665353731663539613839323661343034646261333330376537 +66323831386162623431633839323964323066396639633562353731623765313931396537623763 +66623238396164383963636231356636663961373363313061616339353331313038653863633739 +33326264386264316330313230383533383032343636336665303236353138313361663233643630 +62613433633034346331323065636363333661663037396463383533396436303032383132353934 +36363436353736343861333966303535313733643333653734623364323230393636343032643335 +62646261333834656636626539643030643661383431613933656434373664653133313266326230 +61636330626639623731626338343630356138616166616462353839616337336139333033343134 +39356665343939623333366461383463633933363634653635383636663637346537396235333366 +64613233353535643063376264616365636164356531323932646166663061323337653437356138 +63346266633737616461643534376463376335663331326639316233613766303736623862356430 +35643464663232323766396564646534353138373261386363616164663763653266323230623662 +37306564396463656162353935383266356533333866396539323434306433326662316165396230 +63666232653238323561663933646531306234313839366664613830643763663339633465346235 +31353733653434643633653633383965356434363535343730316231323863653433323064323236 +39383934623661336438663739306638363034333661393230313361313430373933323435373162 +37373165386266383938666432386435373139376563346464393731396166306465376131366538 +38313665343564363531616135363363656637656636646537643539376139623631303061616433 +63353732343064353063323766626430633863313831306535643236663663613939623937636131 +38303836356534393261666339623461623438666630653265633035653438396265323337616338 +65303561653831653737393165363333373163643237326133336632396165616661616639333532 +35353435323562393462383238383534373933386434343434363435386436326466383030616364 +39396430333263616165363838613031323739616333326230356633346430303464616264306337 +36313130306439313466356138633237316365626134653234356161366239383639666632303137 +38313834333935303562623435353831303930663665613761336537643964326466383934343335 +32663130376134306330373533616563316364383335666666393031663434613463343962373735 +32313139343439646637353563613734333337633764343935333630346130383737343936653639 +38623935333361323833663938333734316539613266616563323339636436623532343536623863 +35633432623636313238333932326537366633623432303735383238663062353063326437303037 +38336530333932643661643863623236333963623037373265336232663435323935356636353861 +38663237613263363837343131373231333038313930316337353134303365643962343337643764 +63323032653461353434343934373666303566376465363930636664313764336332343735663836 +65343136323730653334373932336335346630623066363634346330306231663937646233353135 +39326332306637313339636236393439353065613962343464326430613265386363323963326465 +62343564616138303133663239313764383536663164343865666636313232346361643438346565 +38623633333635333063336336393463366237313337313238623036393836396162306366336639 +38613366366366373662303462636439393137626236393738653462646537313666636561623439 +33663036626362366234303130343333663934613434663431633039653530333639666633656665 +30613439376264623931343663373736643264613635343536316364333635663436343834656132 +65623337623564613636663736643731363063336132613133653162653332343266363035303566 +63353235623763343138666665393765666533313934616135626634653131633165376465636666 +32613233306436313065373564613732393036306535383637336336303462306637643438623239 +66326337316538366237666465616566323635666136386563353638616330346330666339323262 +32393139333762326166643366623932393861363730336638613233396463373533633437643035 +33653333303537326461393233383938323533363365663733633832303334653163373262623564 +35613365636333366539366233313435613564333132313133386134633236373761313661313534 +66666631393661343638623032323865623334333830363131646630646135646666383639336165 +39643563313935393464306237303837336237383566333633626632396237343230316564643130 +36363339616164363762323439386133653239323735306638346538623465633431373234313766 +32343134313466333735653563636230656264663862373537666562303433383938666636306435 +38313931643065356361656236353635373339626431353062653738613031393636613232323339 +61623532313639666231326565656439636434643664323731613165323463363436393462616234 +62633864353535626465396631656539386336333861333439663161386137366130336533333961 +38623839313231646332643333323365333663383563393237353233643336386264663230626633 +62646233396162383635386235383334383031386536626566633339663735386236653838613933 +31336638643262626231616239623632373935343937616164393334366561623665353534333962 +33373531353266646236633530396433316436663135363138633532623033363338326634336363 +35333363663331303265656563356261643234656133313661666338663535633236323961356337 +65623238393562643135393962356361396231616334333564393034613937323934643034386164 +36663534313964643936636465346238373262643935366562376432313630333430373564326237 +36393064373631303133633630646639313232383530653765323439396133313236303061663030 +31333963393961376134623737636166333839316337636639343066383930663531353166623437 +65646265336434393337386438613261376139383334366266393030326135613861333262393865 +39333762386564376531303733383432633464343862643262353462383233336265646239303638 +66303532633836653663613866303936343466326565306138656364643435343231323666643039 +38313939643939613231613837646236396434363831626136613361616666653233626663383437 +33663338666164393038356439383735666161366332363466346461646539636131356662346539 +65303433393766316539646432323266303462626130386236633437643836333530386563666633 +31306562363339373863626536326364383832623839653034633630316630373032646161333464 +35383338643562653838323136646130326533363933343237306564656333653564343235346664 +32383133303739313735666361313234353031303533393338343235663539316230363465626235 +34613632396533326536373561643930333565323661356339613361396539313965326565326630 +64383165353365303133616635386466393132613466326165663733646330336463383261663933 +33623736373836666363393161383636306433346530623561353333383161626130646336353532 +32623162633061393836343437343363343734333236303063353439646539386662626364363661 +65383963333832646132373938306466633062646132386435313966626234316137643536333732 +31306132633935333861396438313463623834353931383631343831623564376334386665313936 +64303536343064353133303436303534366463373965333439643538666666313264346534616638 +62326438643536653737326138376633623436353465353565613564633639383139363166633233 +32353634393734343963343365613964333461386566613437363664376331386463373563363632 +62373338623633303062303466666432333662613964343238313931343566666432646133636463 +61343866653236343739666139393933376232303038343363323061366362393361633330333934 +62356534613964666365343031323563323434373635356130303436336565643761663939333961 +37366137613163636465303432383537333031653733646635626633366462333432326135633861 +39363335653461393837393765303239393437366666623033373133366561373239313938636266 +35353239376334303735303564363861316163323065396334363163323334343266626162303439 +31633538393265333961346362613864616266323734316335343031313561626565656563636461 +64396461363665633637653038363339653965383630303935626139386466613237653538356165 +64343636386165353364303539366465353063393163313833643939363336333432613238656430 +66333465653131336366383165663937383632306436633333363234313135616538356562343162 +34303334663364363862353938656430623434663436626635396562643963353332633033613739 +35383439626665643735663439386338306331333061343865373562343766383131303934313739 +34323034643536643461613638626237303961393937333439356531336662306138626433326562 +33356334653235303137346666613235343537656239323237646334313063373137396136363530 +33393234656134333332333363323962643537336363336261613439356434343335313766373463 +37643239303238346338613531643165336165326333633034326236663538383161646165633064 +64376462366132626265313731356161626332383233663538386434373332346536346639613163 +35316131373737663436356238633937363433626235323263626438653631353730393630336237 +65356130346332353431646161303035333733643365633065663765363863363630656138336162 +38383963363033356437336161333535316166343439613536316439653762356636303934613836 +61663439653435653933333239643566643264353265633933313334306437633337333465656362 +65623462633062646439393235393262343561633436373836666636363764326230636264303531 +33336635626631313363316336616533396134333062636365623331336337643338336333313833 +64363537383532343739333236323538353037313261303862643436636237316366656231363139 +61366563663530356664346538333238633632313135636331326132363862653234323661656563 +64336636323339333832616566323061323934653663656663383636323537313836613761613962 +32663664623430636231343766633336666339336637343262613734373030636431323739366336 +62646665376662323434366639373033396665353130396162653961616261356262636564626532 +63633131663665363363396336313432663730366433613537393134316536653566613438376237 +33633537616430353866616636393262356635373065643766306531356535306137393761623036 +32363237373165656332336236323533653639623833313634303337663361616634653763316235 +36343563323934376337343539383463303363303834373162363939653761333064353638373961 +63636434333766316161613634393261646564333030613235393236326530643935626334653435 +39373861336266376638333238623261386335653237633263623737313338333336323331316661 +35343863613533373833363536663865343936663936363033333630663262326466306439383861 +61336130326131386335643539343232636565326435356534653031303161363966643338633763 +61323633653238666335356139363762656534303830383536633736396336336439356134353232 +65343036336331396532353161666266663336653739356565663531363961653037633361353431 +32313064303030303733613030386334373937346238666136623932336362316562613037643238 +66343561316434393265336139663765643062326335663731376662636165343334346236326237 +64383738303530386132346132316466323836656562386539356638613164626139326264313531 +38326164623032623838333639656232666432373132643939376432376564613333363835663563 +66353838383330393164646530326239333461323661313463393932346333663764343733366435 +32333266626565383431626363316539323332346466653336303637363932366637376135666133 +65623138366564373763323163343239313861623831626630643530666161623061366435633238 +31663064636631366331393363346435626663663331633031656663643430303133626662653966 +38303861316333373730653731646430343666626634636134656131396661616333653366616464 +66376366346136396430363263643334373030666632366461366464646366303464343333613038 +63343531303534363231623831636238306231633036363935636136643862633765366437393738 +30346630653032306533633939346462646566386339626437393432313766376236386333316130 +61376336353634633838633964343236393739373466653766396230643362356339343736663232 +64663464373337623938613931623038386235643638663765386164333331396639386566333537 +62393131663634623732363763663736336539343231346131376466633465393861393737613832 +66633530396535326333643665343261396138363936633661653831353233616338303232333463 +30643964373532646431333536333836336133383432613063623066313930643661396264366466 +65353039396363636264613438613132616239626636316435643164393039376438366538333464 +63363335663530356464366135363064363735323466636139643730393363643431373734363036 +65643634663930356361316364633133336566383963633565363631303037303834333663653765 +36343234393539316336313463383430393665383636303063353638323731383764653831383336 +65643661646361386634643364666230363830623365376537366534336465373532643937646436 +62383465363134353665633763616263643238643733663939613035366662656537373837386261 +65653365336135373566343164356161613963626362616534646266383036383736623932346232 +66386665633663396630643431336663373865346530383463343861626430326364366363303961 +37636531336338383532313339366334313631366631353664346162663538663861303933663739 +63666133306434376130363966383466326266323634306634613466386535666366626662636462 +63656231653534353336613133636238363833336336666161636330663834643730373763656236 +39626131616163633238316134353332653963383666646366346536643837643736646434396633 +30633132396136333562343463393566333165393161623966383763393837326133343661313463 +36383839636438346165346336616438613131643734313938306266663463653236666438636531 +32356262396534343732316536313565353366386334333935343962346539306337376461616161 +31346437306539623564653666613764396230323163633566386639396231653832623835313731 +39376130323034353566313965363932316633626332666261353561323839633637393730393066 +61313138343231366232363765666532303032346337323837323063636637326162613231336639 +30666564656631383864623030613866653161386232356639663562393533386233326231333731 +38316365303336613637306664313731626364376639353262626335316563333364373637343732 +39623439363665336134643336336338356431333230373161653433386562613533353131386533 +38333237303332613238306435363363353035663039653064613037643838396639666337363333 +34303163363037336438353831303431393261303832353966303130613931383439653934303163 +63373534303938333431643639663632666433636166653339366531643734323265363432373132 +30376464643862306232656631653338313631653863386138323266333930623762656538636563 +62653034366233353337336236666530646461353535373362666663613637306164373131313530 +62396333633163306131393165303332346263303232323337313161303965303463383064643331 +32653963623861363937363064616237313331383638316539373435393764666630363464306665 +37326565333430353162633265316139373365616537326630323333396338323435323737316132 +38646436313739613637656238653334383232333033633330653534646533343033333536346561 +34313037626134656231303834663038646437626361353261613661306566396265326437373137 +39343831633666623637663664393837303034653066626337363864663933626239636363623462 +30326135356566366438636130616131346235643536633065633262616233333562303034633033 +33663433643361383561626361343662623063636635313136656532646634326431613563363763 +37393037363532393336663063336161336236393738373765333837313863383636623038323962 +37663666323166313764343835313262363338306436346637633262396336386235623237613535 +62643763613162643030663663666161623632653361333635373965626533623233616266393362 +39336434373763336631616437646166663561633631396635383032653262376465333338613162 +66363566623535666463616337383663376536653338343236393630306638646161376233626661 +61353938633862333135373037653731346439366138656566313138343439636333393066636633 +33316234393339313231393738323763323031356466303139326330633136656638323633643939 +63393339633932383231643635316134366362306638663263643432633135333835623939313561 +65366230646231323864623033333733356361613032336163623764636632323563313362666538 +32666566336363313438383364373338363062346632356434613466383934336430306130636131 +34663061613762393533313265626662313235666162623632393033313666393830623665313666 +31393532386264666462616532623936343864646639386432343463663238376634303132646562 +66633234343465333131636531633237643932653465393833633837373465623930333938313734 +65393031663536353665396264316639663932333363656535666362336265643937373062613062 +36306638343661646233313635333965633734306239653039336366663761356439626339323163 +66333465336163376235303534633039626663376534366133613663633239623838396432323039 +38613066353536393731646664353638303563646337613033366466346530383965616265656331 +65323965393064376133393334636630386263643531623630316665333766656533646463376635 +35336530383864346439633137383433656130316134333834653333623261363565626137643730 +63313634613138386138393366373735623537663730303038303133343365323462343066356566 +33633334373364613635653134323232303336626234336264623430643936303132646239646637 +32636131623265363635333135646433373061663337616536303836386235346661336639326532 +61383739383839653938613939363364353833303566313038383034393166656361326439646331 +33656332393238626130626335356132366135386231636536373436313533363364356166653264 +64323031303364623335303436616533333165396661613534663431383139343439306331346533 +36366534356435636663363231613738306161323632343137333464653833346230393034613335 +33393666616363303437616539366363343030663135376239623263316232313464373638656462 +35333239346636336532383733313932646431356233643666376531633733326536626665636363 +65333633313030633038306666386664643961323436353863303361633235333262383333613464 +39626339386238663766316233373937353832626366653930386634353762636633626465303932 +32396261373437323931623930626565313664366539616365316331336436323062656461316664 +62346665643163626237303861653832363763333831356463373835333038393032653730303337 +35353262633935656438663837633830323135343037393265626636646564656265343835663237 +65376163356463326530383264656233656666383830623531336330383139326464653230363534 +31323430616563623639663738643930373362343532323637326139616339373435373235363566 +34636330636163323037376433643037373930643133373563343565636336353566313134323862 +36393465393364316561353133346136373463303832306665313066373031386139303035303135 +37313635646530316436343564333561653065643664323832356466633238363038623661333063 +33323334616433336165376363303737333465616438616266396531316432653464323664333264 +30346164663130616233303362626365303831656332393362303436636239333230373165613332 +62303261643161333838623237626439626638613337386364333032373930646364333261343739 +66353238663737656139386662356537376263323734346661623536363831656632666561346333 +39396635663963383439656232356564326337316139656631396530653164666330623039393663 +65356362363935393239333032393437386237376266353736356437623130653763636362613135 +63383564336465626134393534356566353637623738613331663135353230653564643636396632 +33616630393462353737623064623561666539343739376364313939656237316439326437396433 +35346335336561373634633136643139333365326330333734613930646365376435663166616130 +38313137613662366662303635666233643931323731626633646435646365313232623930316531 +65306332383033666536336163346464666636306561613530643234646232313462613430643861 +31333165383634333333653461326337383731636536633830393666373833626539353136653735 +61313531626263313136323534633463626462373766383866343437666631626563653633636665 +61303535343830333562623531353063616330663538643539376633633966343964356366313861 +32613739393461643365633163323265643934353663613033313263656466383064363437623263 +61316238393536306435353438656536313338633532383361363266646562396235396134363239 +63333534666339316533393561326138353538333165313639336536353639636162626635653737 +62343432316262346334616435366665653234616466356562323763303738623462353835376161 +36353533633130633333323465383434396263663836613330396438343737353237633439366363 +62383463393733663865373838393032353830623738623464376336303430633661323238366330 +37373430313931336536306434373765343762656431363564333030353366393962626262396436 +62623137613539663364633366383035306633303136646565353464383065623065666235316564 +65376439663165666433616137316631346337356532326337313763336235616365306236396532 +38303232626231616337663535326664363864653239636638663364323765356164623839633864 +34613738653261373432343835356661356234363062613665353439303964303661613939616331 +33303264333734363731396138623261353063393332366538323139313063656635656265613231 +63373031306639636631633230333261323362643966343462633864333930396632316166626136 +35643839633734366361643835303236366332353165313636376164326636363265656636313635 +33333635343330646534366262356136356434666333356263633766646534633562626439376235 +37623963366233393166636466376130636636363133613632366264316631356134633936323731 +61346139316334313737303531313538373866646332356464616164626361306539343436633839 +66326336306161393363383664616365333231393365653632663133383462346331346333613564 +65373761396532363862613631643839353265653036303966366438616132666264353730383564 +62303134346563616538386661626135323465643833353939313834643666653531393035376138 +61636434366561613330623130336462626230656439633931333435393235663030336166393465 +66356632363837613164633464623164623637623338326662306333386230613036653435663564 +37373837373365613733343764633036386464346338306435376266336538383366303132623136 +37366137663231396438376363383763353062633638336538323639306661396262316437366230 +36303134393137356566636635383232363532313331623066373835353962376365666263626334 +33333833626336613534333337633139323164373061353639346533383261396137636566386166 +36616136633562646361363732613636316233373061356637643231616136646464636561373338 +36393732653835346132666133616431653338383861663561333064623932313434346438633266 +66313634613665363330326636313866373266666264356138316564636637313465373734323732 +38343539636462336665323165333536666638663534346538323235653765613433316561626238 +64343864613737316536366364353664626633383231646231653336316339343332303038353734 +36353036323432383666613365396564666631353231616465336637303730613537666639636539 +33363337306165636463666333376662343165613835363161633365343864373461623965333833 +62396434303936313836623930653932346462353234323130626539613464633332303037383831 +64616539646461613236663133643436613433626265383361353464366566363134633337353264 +65633162376462616466643238336262316234383666643637323239323835306530316365396665 +31323032643835323262333461646530306264303437656464323430373761623839623030653263 +32333336616162333463306138313435396665303161316530646661623737633637353934343638 +30366462376561366331333533313138623362373633636461646633613432396238393632626231 +39373532663637636633396364653066336335663135383232653137313861343330636461613334 +38653163323734376662316461666230313166373864313937303462313633626462313533333233 +37333963663361326265373030633633653761313231326661363433303062396138626163343337 +36666632393736666537366335363036306262653732396162313066393538373562363561333062 +64666533313864656362646536306133626335336334643264393538356361323366333237346436 +33313337323030313338633537656561393436303633646664623932343934383461386261366137 +32643137666166653661626430643763363934663838366330616233303930323935336532636634 +37633066363338633665346231646366346139653739383833313165626533396435666632373039 +64363861636563356163363962303832663733336337613033636261393134626162393634643835 +31313661656538326638616365393434666338363731666665633762336163333633353133333666 +62643238623865643638376633303535333262366661616366653262633734363566373963646561 +38393336666165613632636232663434616639303235666166663132663463663839313437663132 +32653733333833666666643530613665306435666666393235353062313335636665613239636234 +65653863396334653638623061333563356437313831643534376238316335323463343834316435 +33383263363533356365383939373537383566336131383837633863633036373932323161633435 +32373734356261616361366337646539333934646335373663316566633534376332656165646163 +65633539373736333137386666666261366434353434643761356530646265653461323332313565 +31613061383136373463333738383235343937653732303833366336336664393633353032363035 +34343065653332653364323133396633316163336638346563353264303139356536353130393266 +39326431313430636366313835303537306236303235633737663932313135653834303037643263 +39333663346630656635316335623163636263303134663037313466623634623738333162346336 +37343633366663623938646630666638356663643963376563323438383538636665376232663634 +32336633633435393036643139623536633135343334366134643434393231613339623537353764 +35316364323634383866313337306464666130613966303032623237663665643066623735366663 +38363935346464313362333134323031326132306533373335393262336361666161613135303339 +65623563356535303963363836616236366236316538316537623662336437656131373531313236 +35653162366335633135623866356332303533313166633364356438323731613765316463303333 +64336635663032666631393639613238646637646662623162396330333765343066636134393235 +35303430386263663135383563326665616364663336313936343730623661383737643730646665 +30386266363466353761306433613661306165653135376563376531643361623539333861356662 +62333136386238316236396465333335643363333034343233363966343937646636313463363937 +62326664666538613036653539396231363038363637636535376435353539326331333664323136 +66323234343961343733343632343061616334613031653462643061386236306531333033313462 +39396631306130303435303462313866383034613033366231343630613138626366356237363063 +63313261623135363435346634333632373633326435356631316632336530643264333033653133 +30626437363565363264383633336138363632303034303932626331663630303564343535313866 +37333736636361376663333432373530663139643132643738326134363433656561333639613833 +62333130333765626561306338303766323065316239303137633531363231653330656362333932 +62626531363737653062363033643863363733316234353139356431353438303063613137613033 +34616635346639623965366334373762303436366161306335383666633263373432636262373063 +36366633316266393761663966303133336261636539393633396331376365623331386635636163 +38623734323765336339303631323431326237656437356536353632646339363266633430333866 +63663063373439666263623563656334326138373732656537353638393832333333633834386665 +65356230636234663863393530346539313034643863373530656238613963356565346138636132 +36313761393037626463656362303366333361303034363866636361356531663562656165666265 +31386162356639646536616663313963636339386230393438363539313235363735323438663461 +63373136343438306633626532376232346239656362393132663730633765373137343565303661 +33616634383361313437393937646130653634346366376561636530373666353962656231336462 +64653562643533303966333666356663633339643664366536353639653863613232626533306335 +62363365613839306438613964303361343130653937653839373034633431396663363839303466 +63616439393939666131373631323261633066666563353536643962613865313339383935396531 +38613331346361643663643530393938356435373830626366643638363061633739396433643563 +66643539313865666666393637393139613535616233353534356264313630623931626131353366 +62323839396633363434323331636165303861613139316366306435313935633663393235303061 +33313537373635306338643765613736316238356337396330326238633764393331633962383361 +33396264633364643032636431666361323063613036623166633766656563316636316135356636 +66386135333461666532396638636633396537326464393762376564616339376331333637363831 +30356564323937636232386436623762393064316563343637363432326636303831336666616237 +34663634346533333365626165363039666430616631373439316364316333303432363838616239 +36313736343330663738353764616138663933386231626635346162376135326431383139633732 +61373532356638393435313465343064626434346133666665356666633066323135393062306435 +65383335323062373337316636663438623434313362623137366166373961666233653765346330 +32303838636162636538373431376131613963333037383532303037666338313834643736356231 +63646238323136363633663531643861346233306366353437396165343833663131333938623766 +37386463616238316237336336393033363735373435363561666537373065626336646661616336 +66643862373266643165356632373236616131313262323938333565393364666133373439306161 +61323438663962626438613339313134326164633561336237363531346135383961646137356265 +62326166623137393138623638313432376261393938653430376339396464643063333738633834 +65663535346339363764663530306631633930666533626536343662653662303237333766313639 +37643433383063633862383032356531353862643835323766313664626632346532363838396538 +35623866303562653330323039303662313432326461616433386434346535323935393438376330 +64393565616530636236653861366335653734613861306665643436323362336132643066346464 +66353439333562383163336632366562313532396563663164323038333936323736373762646661 +36313061376632626633316665363631393036663137616234346539383837343331313033316636 +39386539353233333565386230666433383866373466633538633665356535333166653135313134 +65336538373332616466633065303936643430653663656264343463666666653861383738663031 +34366662636138383064343034383863396631633834336138633065363436323633633338313638 +66366665313535373339373236623761666639376231313438326536386338633433613932396237 +30303861613736623532653838623638313064303765393833656139613637646164316461306239 +30393737353435303838393635643033356237306664656237323639323535396531356339636136 +31336166633836623365336265336233613131633238383838383036306534353465383037323139 +65383531613965646563366435613736343566326166393432336238303461653131343433336530 +38346563616466303864646232323261633637333433616438303436306165383366383730353039 +36623838633436663861653237626263626636393266656131383830373035653932363739643961 +62646663386261626537663839666634366235343930616164623966656162336464366563326439 +66623433316333666236303134353261666638383461393766323634396436393664386331623532 +36323335663861663635323165333461346664343361366339353538356632393266386662633864 +39376164323366393135643434613466306438353661373162353138656566386430643563656632 +35316534316234386432303761313032306431313433663132363332643963343735366337643733 +38666630353661386661633237623537353164313432646430333933303464373366393334363466 +33343431353337643566646131653431323433623930363762333037663430613831336634323036 +37636635316531313933326134386261333562653535353434616235356634396237623339343133 +31383337623835353233373531313338656430306535323438343234653230663333393361363738 +31333633346336353434653530646332623762623034393530316263343761343530656630623761 +65303262333666366134656364376435346563373935663364353566323661353438366661343938 +65393461383432653433363765636130626536393538643463396239323232666261326138346161 +34343665343533386465366661383035323662646661613463623831393137323162373534353661 +61633138373763643739636239643930363765386639386262303935356134636239383836616632 +37323661643832393365343332343664656332313064623337353837623234626136346338333439 +66633937336364386137386137396433636639366635363861623738393137373337346433313561 +30643738646566303538316363363839333132313064346236343534333665386238313764646636 +66333762613461316135653733666666633234623466303831373462336438626365336362643334 +31363237633363656631393433323464616633306636623866623933393835343264313763326665 +34343733613766623061643230303837626265356162636131316333333832333665333065653331 +65656337346534303463613231643130346664613637326462353664663133383530326136626532 +37346431623834363563353663663037633466393138313238653661333839303863666262633837 +66346165613031363363323863393263653937353738363634373064356531373831646566336238 +64643539646262626436623563373765353631306563623135343230313761626131656132646366 +65326562636365323164306462346331653064393662396165346132353031656438386434396433 +65646265303934333938613661643730646532613536646432333736363034636239306362383630 +33396634653039656239316236663637303734646461376631383639656239626662353338613538 +31363038343066396362383034373734663430646137653738313133633235623034656230626363 +33663334383933386433313766333832623235346430323531393366616135326565333666333030 +32353234373432626534386465303636353663373637386461336161383232326363326162393861 +66306435316665376166643465626335633333643937346134356231343439343237653066646538 +64333761326363373232653634393765393633383034386633346163353532616262383935313739 +66306263363663643736636630303830346233343434626163316537383438303433663031663638 +33613263343666303066646437323966346262383063333735393235396263656635616566653664 +36353038323462306432333162343065376135396366353931366635363931363839393139313661 +35666635643266383561393031366662623636626166303736333563316266343665633631373630 +61653633313333386661363434333963323264636634336664363637663431373062343961373566 +30643132643133346365363832303031383932633034623762366230356262303838363532373037 +35393361323565383962383262336231646336376232663066666462386461363738303933623130 +34386462333439303963393566383736643237656162643832616232366361613032616236366630 +63666639643836643334306266643136366636633761386639663639306464333238633431636437 +66396232303964653662636132376634353364353566616639323631373133613139393139333136 +62313130653935353161633435626139663161623862313363363665613838666636663038346430 +30643933323664353564663135653865366530346635373937623831656137633037633732343661 +30613333653762366635663761313764613933623662626532383431353265366262613833396136 +37333561366139643335363631323666346665613939393233326663383261353933396336323364 +31303237333433643836613931393237633030316562643138346639353833333437393032663064 +65663534623032343235393934313865646362323566383733336462356639623831646138373665 +38643634333831326637663136396336653666663839666334396666383561633635336233376165 +64316662393566306663393861326637333761356664343666666635366461306637353766303966 +37346465656331346133333365666663663039626135326666386166383230616164633937663362 +62343537666666363537643238316230636564383431366539653239383031306632343430353735 +38666566333164323664313030313864336364366164623234363338636337393430346465353939 +32633839333635363838353837666339333964626631393731333865333333643933653437326437 +63623339616363346164343461393165643934326562356432313539346463343335306564613830 +36306163386631313830336236663830653736326233633963363363353261346631316137333030 +65393465396530393066383431666330633535313738396132666630653763313937623931373834 +31343233373133363961333461616262333230666561663930373732303639343331643631323733 +36616662613733346530653237633838316233626366646436633939346637316535303330373664 +62643833373336383465333634386236333439643031396562613864313038363533326664353634 +63323538616561623937343231663465366537376239636131613834306166353733666230383535 +62336135336162353837313564376531613031303139323564363034353965613139623962643865 +36666664333733323736306134346463613532393331393165646537393636616163636635313064 +39326665313231306565363834323739393831623764323062313034373461636537633164376334 +32633437313039656131326530366531623164613032316562396531363538326633333436313561 +66656134326636353162313665613432333232636462653837653936313635346338646466643232 +66643937336133646639303966386332393932363535333537396364383439373464366438373265 +32376537303636656530663966623631643163343066396232383039313964636565386438353762 +39636333313935316534316236393731363235643935656461653464393865393834366435643631 +34663963663333373765383834306532393238386432643339396637353830313166326436666363 +65643237663464326637623438613831633863396330643638633233633565323164633765356630 +62353038316639663138323530303937623037633139383030623736373562623031633634323964 +65643839363533303437383837663263666463393135393837653961656233396434356663663135 +33663161613434366538373437383336376136666438623732396633343963326432623534346362 +34393663363139613135663430316561383131356666366330666562303434386661623136646564 +34336235343932343466326630353862616537316335333834656635313738343437616630643364 +37396539366630353030636538316436383865663531613730626239643832313031383566303237 +62373938666365336365346330663136363563323031643235353061663233666339386163306434 +31306531313138373333623933643131353833306162316335623766313763343830636136363331 +37643362613531376464636661363263396432316266316461353866383534386138643333333935 +33653631396532653632643531383266663663313831343466316333373733393831616135313866 +32373432646631363137643963376338383061656530386365306239366363303061306435393861 +39323231623133666236346330313134383036306533363430306532303936623739366239636433 +39316636363663663533623464306662353933313365333836653261396332386238666536383161 +62343231323036343164626166636231393966666662343739333561393231653035393532363830 +63316333386562623562393432643266646662353139666135306339323663613734346361326365 +61663732383332393365643033316532326666323837386664393334313136316333633464316236 +61383433373964383065316432626366373832646265333237343539303435373136653164633236 +39303765346330646130383137323565356335363030356366333938633539363532643734343733 +65356164653833313562333432656437376533323337326666306261306663376639303665346639 +30376166356331356335616432396632333736323733623830323066336130623361636535356138 +61386163623962393864313936373864306634633535313931623131303235636539353333636335 +33373437663332303862336636636532656163303331613533323937343139346163336364663934 +64616363656539313231623836323138633033613366633863643663383663386163616561623764 +66346336316635373836306532333032643363333036346362356463326635656365333266643632 +66336239623461656438373166666365666665313466613565333763373132623065626562323363 +37353836623438646339633935353135373864656430353836396432313736663762326265626633 +62306166643338393064363935656336626166666431623633386430323539396431346531623466 +32383664623536666131303038363836653731343634333732633561323562623161363033333537 +64336431303364373630636363653061646235393362386535346531396133303364633130356131 +32346264306639613333613736323030656237613930383166623665363733303466333061623336 +31613465623137356564393261623132633830323430643139373564353133643732336331343731 +36623636396238363136306462343934636131613537303035356534393265316463343830646236 +63363135363561623931616665303665363663333439343937373365366563613963633633366131 +65343633323962633438306163643739633963653261633134613163316430353634306636353135 +64303232343933643162306262343261613162333164383239663234393866633736383963363231 +30316365376134623236613866326536636365383833313233383433346230333864383837633436 +65336139393830323461326264643163326131393239353833313036666231333364346462613135 +62303639653433343161376135633739656365323362393932306132353936376230343761346164 +62373061373235616164313933323062356361336637656533396665633139326531353363376336 +37656439363261303861313264303538623762303831383936633262353031666462323633326539 +32313561346135633162343534366631336532333939376531356634306534313836643136373932 +35633166613261613135346162613030613164643234366235376336373961656437643763383738 +62613461636339336331643263326236636463623765633161383737326637663863376633373130 +35366436386266633465353238613463353735666333356265306462373037356265646366306366 +37333365393339323033633165343137383238616338343466663066363631396664326362636138 +33363038316635633634643165633134386539623535326530366133303531323364633762306161 +38373736326165303339393232656435636361316363393364366132323461346639646531623465 +63356237386433623332643133333931396537363637646633396536313266616532333630643035 +32383332383436613464386439383836363562373966323166346332353062303239643964663730 +35363961363136653131383361636232326163613432383262666362363063333732366138373939 +35306664363137353962323635386362323735383639383032636263646665393961613030656531 +37303931386233656630623961353838663033333738646635353862316239396162323261386332 +33333435356535303139636536316238323137336263613430373135376435666130623632653432 +36306235333465363363623836396464653038323464326633366262663237663165613564313232 +34396665396461323466323033663235646464366130663531333365393738363063326130643232 +30366136363438353137366135653234653163656635663938643737656163616534356536636637 +33383365663265646132333634333632623439363132346265626332643037386361396566376332 +34353362383632666334396462626533356639353834383836643066373565626435346335346136 +39386264313335636538643133396536633161613134313263633864643462636361623830636534 +33343961393230396338633565343838356430393161366562323263396464326664666263373433 +34656465353365383466656162386337646138633434613230666537663663656161376532333839 +35323264656438646661323263303362373462363464653264323438306232653733643337363466 +30613731353666643163653131643431643666356631353732613164316663653330383563356338 +30326333383938363264343361396462616439383535653362386634656361633937636633356262 +62393836386364376565326230646163636237646633336136373265653830623062666238313431 +35366365303738383439613432636537643833363737303264306439623063363931396263653032 +65323664373131623866666632376337613830346266383130306364313063633836393631386363 +63316139626135353839396235366563316661313937366439313731353364326133383661636532 +31326463303833363936653864353534393233393466643666333031356334316438383961383463 +61373035393633353061376135643832363632363732356339363133303934666135333639306332 +32663736613131393863373537633439346361373633336264313963386438356638656339313436 +61633337386531613432303434653064326566613166353633346337356638663333336665313033 +39626266636232653033666432363065656338323833313039343563353364346234363832666139 +63643065336439353163653830336436373563376438396563626630333230656132373632633532 +32366162613434376234653861366633306561343132316337336439383638363062363836653664 +37386363663337393065393533646330343762353064653731383031363532616261326132323537 +62366637656534326237336530646161623139643531653433356362663562613037343366633533 +32626136656536623866326161623239623262646336666461626364346338323465336264623532 +34613739333463393734313331353161663030333561393066653062666365646538323265303439 +36336165666438643536313134346538316337393862393632326134653766666163643966363439 +62623632323764303464643534363534363039626431373961633636623930363535346432646264 +36623663663032616564323964333139383530313031653262663066356466623033656362363866 +37626437366339343338323234646366323030653234613062643566353731366231323537396261 +37346234646334663037363264623930666331393161363463323137653863316264353364336234 +33653664633531323235336439643562663165643761653237336239383961316666653738666566 +30316139366465613966653237663964613236323636333430396630303530336536653231303335 +64356437353839343533613062393664636232346639613564343833343363343232316265646661 +30313563646436313964613861643034346335633436363664366430643765383237646537633061 +33633037306330646361663965636362353035613134393635616332316630623032653935626634 +39313766633236663461613065633835636461313863643930356437626239356330633661613635 +39656536373731613236616332363366373337623536636631656632316132396465383435363661 +39633537626231383834623932376237643262326532333431383130396334633665383037333930 +65333237666438643766303431326534353933346631386466393730656131333735303533373463 +34323461313861363736343530336537353032323634353366363562633331356264383865356432 +38323966376561653766303037333132666239316531626264333630613536653635356565613839 +35646162626264313939373536373065626565376538623036323664613863616434396238353137 +37343137646330623563353066373662666133613235316362626364396634633330616638316366 +37363632623862336261663032653934363036333435363566373138363463643863643032336462 +66326531626532613664643532393666393334366531623433313139626363376366343139376638 +33306365343765383237393939373466386436333766336363383736613465323764646437396233 +32373936336166643330643464613230393565383766663465366133306331376437613234313839 +37386164333839343739376533343635353235613365323237383461316238373138383739376134 +64393535616635663434666534363033373833313935373939643130653464623766636163343666 +66393535316533383161626431333137656431616430376164336636633739366465643231396431 +39343630386630383734313366373135633966353930323039356434386534353864386338636466 +38653763626239633466366264373335323733643631376633313834646661356661306332623864 +36313437393764663761353165346238666334353438646539633036653735663939663564356234 +62623133633633343165373061376333643732346264383862343038663130343030376537346133 +63663662366433623765396536666338343964376638303363306363386633646638613236656234 +34303234313638376230376532326436626164663131326164396536623037373632663937353432 +35633162313364383836353937633839383665613332623834383539376366363431323239343230 +30373763643532393036373563383434303834383233383832386633393766396266383462383931 +64613036383565393739616539376337383361343065346461656331316663386466353765313134 +30376134353237633832626264613230323466376230623835343130393038313062313030323431 +34323765353937356163353564653537623466303032366561343664383463623637636437363132 +66393861663064373530616432356131343037323965306238653536623564623030393538383632 +66303664613364613333303464376138303065333834386637626138663034393531316538343735 +61376132393634353330323766383033373938383039303865323665353462313837636131636436 +35313163366334383230323265326663373966373234373137313963323331653932383365363332 +31336335653737323964656465373037353366613839303733373339303161643230306232656365 +63393466323239396235643061313333313965336464396465643733396466303465393265393138 +37303634613537386361363336613765626330386462643033663664303339313264353732353236 +31636532646630323264613738306264343133386530306366396539616163363831306430383239 +34623064386461326162656439623235666464613734393235653664633238616237636665626166 +64643139616237333166396438633464346261653864626631623461613130333763383831353138 +64366230393561396130643164306462633038373339303963303766386330613234393764383736 +36353861323534376237653130366466653361393838343766363638393261396332383362623635 +61636134373631613966333363643537616335646230343135303763623435376566313337356537 +37663932363139323938363765376366303832626264333862396535313430353036323737623366 +38623966303138363738626362363738323665386239663064343337393535666566343166323731 +38336438383136366564663263396439663063396236383337646663323333353166333737633735 +62343062306432353164636436653432363930346265393665653662613633636266386663633934 +36626430373137636532633933663761346537353432646563313434663136336430333035393462 +35356331373236353162376632303433373366353334386163643465326665633638393461346366 +66613765336337373263653534373531663837653337303932386666376234386530643161356635 +38393164316437376438616264623065656266663561653534643461303465666434656139653632 +33346237653162353266326664646132383232643131306331636132363862646533636165386332 +61353065396264303232303662623063303264333766303230393264373432386261633235363733 +35663761346137623332366532313036386461343835363063623434643766666631386531386339 +62373561663432343162366135643665336132356636353438613666386438656261353731633938 +31383432323065343135663630633634353832366530373539326665633937393230316433343034 +34633161306134353762643939353038363734363763653330656230306637613039363436636237 +36363830303838613039653235333463376338343364636531663064613763343338363435626538 +31643639393935373035383436353761356535373937346232316234353064376633626430666437 +64666134383834333465323766373361393338353933303230663531383666323966303335386232 +38653438663131306436396135666461353930396132353930613834353039336533643464656631 +30636330373065383830613232383566616661386638393133346565613137623138376330326462 +32653265326264366437346264366438336662376338643835393935376461363934346330623139 +63623566633739313531373937653662633064626235363139653164313664646339306165386639 +30383665386638393366313633653861626461343462613839663664363533366164393938323162 +65663735326536386564616636376662646230336339303835363131346665656332306431363139 +66353536663535636637643539313439613566373563386332616233376131363332393563376138 +35386266313461623631373631363234303165613863303236363030306263346465393434643338 +66313238653730363838306332356566356361373362313333353330663862343033333032636237 +30376435393037653062383936613130623839623663613961313663656633366263646361393335 +63386665623434343362616239396639313934353335343865393065316662633939316266633262 +64623932313565616434653864343134623832626665613164363436643536613232306434386137 +39326561353834316331643836333638613733646266653962626433313964633661613238613634 +32373233373830643861623630336265376639643262393133633233363538636361623733636365 +30396332386466613135613732646138323965396134643265626134363735383262333335613362 +33383239623264313466653062323439313463336138626335343263313266396162316138373964 +32353464663438353232653964336562666364623630373466303231376430613866396366353139 +33643265646365326164663035316264623435396166633636306330646135343232643330383030 +37316435626435623531353531353963366435646333366230623434656339356630316330663134 +33393163656166353761353336386431626135343737303730613730633834363133633664343562 +63393338643234393033663566343935313264393230623931616565623337323738306162383065 +30656438653466376133336533623530376534366130306261373534386165316262653331383635 +33393232383735306661636364623135373032663735396266633735313135613231356266343930 +65306430363064646265396665323266366131633365393031643033323063353130373964323239 +35663436306563393464343663646132383565383265376637653939386230343965613561336630 +39366533393537663536363833653264353062376338656632623164346333333932386464336365 +34346234653139376538333732323138333566636266656361623332626665393963623166386461 +38633562313666613835343261336634396236633837393735623830623162353363313662663439 +64363438666462343861633835306261663864663035366565353136303036323766613231653063 +31303066646233613861366266336561366536333133313438356636626333313130346136353534 +39626137376131613135306630666339313134376265613031646262323530653637613335366462 +64386539383835646337623937373761343137373731353862666532333433366266386331323231 +63616330383061666533653736383163326565376136306630333730316230396331666132353036 +65616639353039343762393264363366623263616565373131353830633561643539393433356162 +30363530303166303162323136626364356432306634366331653839353362353766663831383733 +36313262366165656666666430386536383166376435633635363761653932646131643965353062 +63666639353634613862636431346539613031363866366338383933393634346664373938383932 +64333739633330646539326362616231313365323235313234343337376634643964306136316561 +63633566633662313431653239623662616130663036393463386232316431383331303161626332 +64303533336465336538613662666435386262666534333433333265333835626635333632643532 +35623931643036643337383938373436373934663230333239313933333765623335623664646532 +61343463303666613331343263653934303262653531643533653766663136633264383233623866 +66653635346239636166373932643839393331613137616262353037643630363666646236303536 +63383162363931626265313138303832316563356562386266663965613636303464333566353363 +37323930656432313437656361313037306432366536316339306234643766326338313035396238 +65323037376330333936306265616633393862633465646531313037633330333137313237666562 +39616364376436393733393863366261643964646465363861396234306433653266393766623730 +35613436613266613533306139353034393037353034363539346666616266333663383337613934 +66356462323538316461346562393736353464376637303263663330343534306630353039343235 +65306439643264616630393064343539613133333231306463383531363637633639386265306630 +65616232656635303264376537353036353637333939623433306438373337393433373133623034 +61386664303035396661393364646435336432393263333065323065396464636262376234666332 +63306238393632363033383030613366343765373262313137653163653837316536623666336539 +31373436646636346438333464373832656164633164313934636136383965633962623563303262 +33346435383131343335323938613838343266376338386139363463383838306535666234666663 +62653332333961613266633231646564326638303534656165633932373539326436393038313131 +36303062303930366264393166303639646432326533383962316166383537313365323038306330 +31303831386239326435363438303135323932353737353138356132613337393930626336376561 +35353435393734613330333961633737366561313831343230643765366133633434613166646166 +39306431633333326233343333323566343766303137396164626239656264373734313332353331 +61303634313764323965346139393637663333373165643565616664656266383735373930633066 +66373936363562636334303736363539336532326334616132323333393631623637616331623639 +62623661663138623632333633316139396263663637633833653936623561366365316664393535 +33666434316366633464636431396666653666663365373066633739376632326132653563653462 +30653730663565383538306462373563353139323035636533396135323939353764643332653036 +36653731623435373961353436626132623165376434346634383331376166643539346138313162 +32366439366439656136323034313362663865303138363633336632383761326563666364646632 +38316132646539353739626134616337383234383631633535313831326637326433376361363166 +34356636633266383732373465646534613465303862656238333032653966623632613935316337 +31326637326262373063336231316131613865393934613533353033313736326334353063643561 +36373434653330666130623636323030333039366364343032663336356164626639613066666531 +61613838376564643630613233376563386334363863616538656434376663383563326434393736 +37383338666335633936643530366633303031613131656138323863303332313865623965326164 +61386538343733323839333664323938313633616638393762626363373635363864323961663063 +62333564666334646436303532356538666636336463383637363862323934313535646561363735 +31613435313661643462623334353230313437663261373762393035666161303262313063313737 +30303665313863336263303037623837636232663166306462353065616337646339313562343964 +37393965383332613632313736653335626335666430313563623931353437376465623964343739 +64623737316663383535623162643230656530333934626338613236613332653934623366303763 +34393865336333323838373438396561643863643439303634323532356166616433646363336634 +39616232396332366366303964663265643039356565666335316435633337623734373861333134 +66386362343137366564323931353362313263383364656664373766303834303564346637343361 +63306138366333373430366561313863323431333062656566623961646330613431656639393932 +39303665366363303730663965393337346366333430333931656331626238323939333838396232 +31323463323061613035646666353631326235376562623966316139393232306632613463393137 +37326362663238333536613761613839383137336535663466303933646138323238313735646636 +31346438633035343430363838323730323336616538353235613365666265373566373762616134 +64306133653138326536643737353065326562303562656635613763343831326436623230396434 +64383232386434336338643362653632616462643337393366656338313166396339626435393563 +30633265333538313363343630333731323462346466333662393066393231663135386162313866 +66656334663733383761616637313834633563383766383632316535323837343836303233333861 +62303861396564306366633935333163616230643034323439306335376663623663613138616563 +34626232366461333032363432356230316234636432333431653337346230616236343166383432 +34626138666262306334653066333533653462313932323863636636393533623036636262643334 +39643064656431616330396665396436333134363966313938653066613132316366386638383735 +33316230396137333162383931393362666633623934396461333738643530646564636134643061 +35643830383432303663383465356336663636353566333364303036326561393831656533343538 +63663264323461393433323061633438653035663032623435313431623833663432323133393662 +31306431633233353536333832616131363139356138366637663939333435646537333466386261 +37663930323562626465313239646462363634383033646338333530666331343966613462643738 +39653736376264616535353138643836356235633133626535313264643239366435373261633632 +33393835366531396163643962326630636661386538633136313339316533303361336430623564 +32653130313434336163323063343535363439303132333763363136333233336331623038303337 +62353461343166333035303963633734653239363332323239393139656436616237356633653337 +33356136303335653733353536383464326264343330366165386166363632326237343332383638 +33313935666634343462663862393164316664646463643362376462396236393530643366323165 +30613266613961643532626639323936643266626233306434393831373366353834353632666365 +36346339313731656262373138666537666130633731346530373866303562373362623566663637 +30653464663736353364303835333139323134643839636331303437343133626664663038656463 +32326630303936616231356662653433336136373266616232343933636435633131333765383339 +33366264333563666439376262323435376339343731366233366238663737383639643762303465 +39383862643336383764636535343630393034396534623835623132663565633032313437353138 +62663036363538383738333639366231663331633265613336346233363738383861373936346431 +65383030363039346639633332326331656439343463366465643163353461326531376432666538 +36353566333037643162646433373562626331643032313230633436336161353939646432653263 +30303662333461383066623133336434626236333265336437383136656437356161303731643537 +32376265636661336534363734646663613564663963633366303131363732323366306561626262 +62653933356336396662353461383262663430663938616365633031633262653837646366653631 +34333738656238313936386464616365653135653733343338663232643338396162303964313939 +62313732343733633462666632396439663164653832353564303837663839363165303261333532 +61333530326136343065616565326136613332316563623235656237356330346465386463663536 +66306264633530633463643661396566626466633930323731333635633066656436336235613966 +39333861656235643762613031363763343532313835356331363933333136393365346534633762 +66633334373431383364346163323738656138636239646231376664656266626362656263653864 +36646666323739323034343338616535643663346461613166636165303566353163636266383036 +64363634663333396233386264626438343065616130376266623165346131316465323635653537 +62333566656338353538656636643435383664353066303465346537623935343438653336353635 +65656433313661323538343834316530343031633065363133363334356366326431343263623130 +30393466323138346264353136626435626130306439643464323665393664363662383639353066 +30643862626234373661653237653839616238653933376363633937303662383134653336666265 +39633663313630343834343266653865353766353430383734613737343130363262363166646137 +63346538303338323632643034646633633261373734346165313831383733373134346562383665 +65636131373037333733376539653565313835393537396138636238373966323330373030396334 +32316161333563613565343637383333373866633432363239343832373738623635306165363030 +62633137363262383863316465633762396334363364656631343330326332653139666632633736 +35636237353539306463646136633937393363323866626638663830666434346339323038333162 +31373562333637386661366165643963356164303436626638383437633437313262386661643763 +30613163383334303135313436383731383133633930303239336238393234356563613561346563 +37346634376361343565663538353339393864363566316365376131303038353736343362636635 +33313365353962386531303139666138373236393830336532623137313562386663613539343362 +66343238383866363364626161323461366636626464383765376232626531333466306136333639 +63336239373666626330366430646637386433363565363133313838373163306564643362646261 +63313961616336393335383864353036373033383232323237613139323834616335363638633036 +34653436643130663230316564653637643365313261313561383539613534626263633736623834 +39626264646566383930346263376362653536346530363633333238363566356666663134333131 +65613835633365636563613337396261363265656139653638323466346236353033616433343964 +34333134366433316232393438643038313066323265636266653866323438376238633232623761 +35626362306234666131383337366464333234613666616130326665366533383232306465633236 +64643966303763666236373766636664316365353862303031333437613262656638653234636564 +33373962636231633261623332613765313862656264303438343933343963376237383534353435 +38656666376662666133623362633135356663363836313831616534333464313436373939313963 +30326333366332363639616330643363376663643162333038623338396132303862383438326237 +61393062633638383463623438326439663539646437613737323464643364363036336164346533 +30636131383037626636313464333032376239323937663834373564653631656165613466373930 +65336565353366353931343639373734336461653836643530303032613639396133326265613233 +30376662373263316463343930616539373839306261353237656661316663343139396564363534 +35626333663636353062326339386465373938333933623961323639666638323330633162643763 +61393733343065656634623735663431363237376135623264653565353633353039353439303733 +64303465646331343930666462336538663362386230623439356661336361326261366338316561 +35666436383937353539623435363832376564633063343162306437373562653130336364663461 +31653064363336346235633737353631386265616338386237646263653331333966343031383362 +33313161363562356632383735663934623635303033383730353134613664373066653339363131 +64313235643735323132333035643661386139386162316233313831653266356165383539306566 +64663231366437383636626138363730626339396366383232363539616331333436626538636330 +33316637643437363138376265396461646265333532386363316632356664613362663063656462 +64666532323633333037303433373930313536363364623564643134353531636364346633323937 +33353132613262303564633338383761326461633130613764353464626264353133353138366237 +32323239346230613438343666363934333430303733623634366665643963343131666436393563 +31653164646662646663623962396630303263343339313335363539393566323738373263316537 +38353235346633353866393462633136383339386436353761303266663039393439663630306565 +35396362393039623138353062373762353630626333316630336632383232653431323566386664 +62393333653930376165613838333136643436303764363630363334363362623734333364656566 +62663565323135616636623738643137326562303337303964396263303364376465306532663964 +61303264386335323936346464656638613633393231636134643335663661393362346132643632 +36383961356265323034363566383064383363656337333563376564333263623463306531386338 +62326132666339333833346665666434653163613339666635353430396363643262613139323262 +35663731396431323865303863323064383663666130336632313961373034656535356539363336 +64653033336361656336383363333939623230376431393363643364626461343063393565363738 +31666130363839376437393936636663626465326233326538613261376465616361313533383632 +34653139353061326366373537646265666232333063343634303265653639636463623533653837 +38346237303934366431306565363635336565353863303236326134646365633361303961653932 +35393465346161646330356531343734646362353163663361316664373639356466666362383363 +33336339343531326635366366353533366663303238616136643163346638666438653434623231 +32356461653064393564326531363433343964363639626266616363313832363833393738303061 +35373637396365656665323165373239306230323461653033313936323731653238323733636136 +64653630333661633532356634343939616666616331623565613363633532303434333631626632 +36653236613662626462356265346431663862616161346138313566316631326366326665326566 +33333261356438633839353862373232623637363965396664366635633631346461633330333266 +35313835636234666236316266363662303365636137616331363630313438623236646334326563 +64306465616662626533303962383536653237353364373465656161376362653838626664326666 +65646130373963636238386231346462623630613961623335633066653831633366313964353233 +64363139366166663836663031353238383962306431306330613363383538613262653533643966 +66613932316332333632323364323363626461373133613663643632356536393336363632613562 +38316131396535353532356539643962626361376164393366626166613566336366393836386465 +61343935366237646430323230656539376138346331663234303863316361623466313134313366 +32623162613734386531333563653530383563613437343839326633383365383061376234303630 +65363932363334383064356266373065636663316566343665386436653437386337333861306531 +37666634336461363737663332656665313338613133616239616265346164353534623638663038 +65643366616565356337383938666363326165653466653036366532366262613262333962636335 +61303230393235653165633535356562333434343562613837363735666365353332666264336262 +36333534356432353661356336613733653033656638623631336165666535346566356166633562 +37313566363238646334653264633038333763626162373231353735363963626664653932376337 +35626562613337393362613331333261393764316232386566356263636134623335643535396238 +33623361613261353233346364646536343639613130316638393066623462303461613664313333 +32656562616434666464383738666436643766326532633636636339623465393233366239346130 +63366163353166386237653735376265316230626361623933393362356266313339303035303963 +31666333333635643261383033323339376436356431396339386532316463343461326561656534 +66623332336633326361326333343738343235623236656161326531393939363363303164343536 +32613432383433626530313438316537633032336434373333383837343264373063343961346135 +31333363633835373432333435393835366134306337626232653236626633623665656138643137 +36633134336131396533376561633036303038643938393333643935373864636535363232313764 +64356532373135393639333163346534343463393536323961383431313732636131353265643964 +30633936343738346362653466313965366536653765656632333966343262386462313135306137 +61356462633134643761373666366665636639343766323761393139373061313666613437323836 +38663866343037373638306364333837323935333939666233643238396466633632306164323235 +65366330613330336665636264623761303339623932613537353563303339616437343964653764 +65356432303634383066663063636439393635303563396532666136643161613235316331623136 +30636233346366323731613739663864386538643336373761316238303830383863333530373865 +61663362623134613538663166616364363730393333666133376631373964363935333464616362 +36356664323239663365666435623863663439653733306266663136313732623637653866643139 +32623037333763663935356163363063663564303434336136336536666432376234363164343233 +31623832383865643839333432353230363334616336316138316237376166623665386434383937 +39386231366662653065613835313463616261353866663133663666656264393463376362623736 +37353665353430353765633766363139666262393730383935663432313937366636346135646162 +39326330356130386638353533666333613538613831376639393365646539643237653337633933 +34343862643962613234656566323535343063626138323132363639643535346437623334303763 +34616330383530663964396535616466333866336236636665356362373733353438333437666566 +64383565656366316536336237303461663564626638386533366631666565336365613539616261 +38323239646565353231663438366236323563653764663033386330383630333538653330643838 +31623738623763353335323566303235333663383339393836336163323932333731353430363838 +62363235353030363261386534633163633136613832653339623131326437653139303038346266 +63363863316535313638383963333965633937346261326135643431656361623635326561613265 +38353862326238383362626135333234366563323262316637373664333139373330343463363466 +36326137363133326266386264376466346137643738306131333061306238396630396364333535 +39306238383730363930313064666537343164656262336238636236356231353939316436366266 +32643563613261363264366533333233323533336564323733623739303066346531313434396262 +37303037316130373235333435396462363533616534363236666633303062313661643332643065 +38393863306433343839343938353961353463613734303866323935636364633933323638303662 +34313930373565646335393631306632666239373263383838626365353431336239393966633839 +63363238346166356461333763633961343166383862623264346633623036393662313061376533 +66646338363735333763326639663832353635613162323631336135326534306565396539623434 +30353632643265643632313934373462336334356339643134316431623161663536343635346436 +33316338646234633466653264613161383235383461336231336562343339643861373764353862 +63643863343731376565613765393466626462323637626665326261613737323838383262626264 +65396561353164376632376430313537653537333436373162353666623637623531356161373638 +66666138666634326532313831303135366535386663323432373961356531626365613933363931 +38663439373065613334623235353763663835623430396135343539656664353730326264323761 +37643438323232393736343134653630393535633964383961613230633839323864383366323230 +63393963393064333665353039393336313033303136623639623533633933643539376462363734 +61363834313562626464396533616134346538303135633266656661636538386566343234653838 +33326637643632343336623635646534313537373961666334636265656366303232643364346331 +32306663356531366131616163386366366337666438346133663965373835363365653464323536 +65653135633130623235373939313539396230343639393932323330333362663961393930353763 +36353037623031313264346532303836653030363665616239316239353531643837323231643534 +64353931356237376132326431316533356461663939653366316236613061393734613661306330 +30323136316532666163646132363862363436646435313532393866323735343362663763326434 +65303032366335653336323438376330623066643439383531636565633934366630633231363061 +64613163383731306262356134626237326533376134636330393234646164383461666237643866 +36646435306331353538366432303630333765666563343531363538383132653661333336363138 +63393862363330343439363463363835303066336464313232303333373664343439663336336331 +36643866613333646633383737386431373162356533346531656666353733353831323839393739 +62363365383463316135643835633036663564323237353938613731346231626432346164396231 +62376333343063396236313461616530346239636464313636303666643232303861343065373530 +66643464313965633638633931393738353361663731393434356431396662363962303861643230 +33373962376131356663386665306136636563663665366230356530303330346239333666646464 +66646261393064323337303431306236643561613366636633656530313733643030373433303239 +61616433356639376135636537643137303439653535303036393931623438356436616436613963 +61366531653532636132323336633130376338353265663465363535393461633361313438393438 +39646262303839633137393263646236646661346662643564383330333264346436313835636635 +38383632623335386338363666383636353730666138623062636435316564393338363535326636 +37656239346136366464646237373531323365386461303930383961373339633434393562393632 +38343236383461306166363434363465313737653832633163303139386431386362336366633930 +39653365323633343937663763623330356133386636343331346331346565613663303435393330 +62326261316665356161383462313063363566346662313336333238316562663235663932343738 +61646537653636323266353436623033633137356431363839383737633032656363623465623166 +30653563386531393631666236306439383132303132323866396637656161646431363231396361 +64353834383064333962346461666138653966616231313263313735376433323534303262396162 +61633336326665353066613134303731313436373062306561373633376363346633313762643838 +31396139316432373264373430346362376531323064393430306265356237323464383335613032 +66663463663363333332656463343866333566373331353961653836666235616435666162666166 +37383936303835346266306663376436386662353333333033656537393266646662333435383862 +33363431363963396361623036643561363038356434383037353938306166353537363630323931 +64623737646137333836393636303763326137316166623665636434336364656463356332343836 +33653231383662393363333763303536373564353664326365653764353930353838326231393130 +37373831373061343135663963323063353562656163626430343964373038316265383962323734 +36363565393533333563643637323866366164643033346465363538333633326365623837333365 +39613936323962643133636665373233336138303366353731313362353466353765656261353931 +34656636323635326366653661393862623137346534643839643035353533653332666531383936 +39353438316434656639663734363639306133343133636239326235306335646135373230633638 +64343761383539653164373631346537326363303131666537393864323364326335616433316461 +38383933383930366330393133346330653232623666313635613563656137326532333733316130 +38396265346632653934363735643238666461383266333661306165636237313366323062363263 +35663630313061386462373431366462313833633835346335333062623730306430363433303631 +61633938346632356432623263613634643237383836356565303163343336613830346637633566 +36333462386630626434363561653232313466333665653738653237346135336362343439393036 +64316139333134653134393538393331633632363630393035333935663332376433343433346535 +61663133383137383539353630313363383530356331343330633934343135386464653837313933 +62346639646338343539333736343861396531373462343839323739333834306336323265356261 +31396638376162653837616536333035636234333563613432666266306565336432623161333163 +32613731356665373561306134633830343733623266623630666334363866363934333966663332 +65363835363464383632396661396236653430326130646164623166666561313537643662313862 +61616639323539663562653263653763626431376131333966383965653937333230633863363064 +65663238353661346331643538666663666535663034363237356535623238343064356432386264 +63343336336330633132323732323331346361316337656364336230323662653436326166396535 +38633061613137663861636131633031623930383562383730633962643634326565303635383262 +31653538626632383739336235303332383132663965343235643833613032373836343063356432 +63313232343934616363336263666637336632316437613566363930643236303437336662633134 +62343335363665336338383934383964356639666235346166343766393862643332636633313932 +63643933323138313365306134343331646639613032623738646633306661356537356561366666 +38666133353039313963306431323235653365333538643939653330623135353034613061623866 +35363937363633633531643932656335633433383636343332383531663664396163333639313336 +61633336393239323436666636666131356561363036363864353266656361663463646232646165 +35636362333336343764393362633734656533646663376362346663386336373264343565343764 +32666330653533383731383362373532346339333861656334633731353339343331373433323136 +35313865616463616339613665303737363731356263363135663935313637313333363930316639 +64323661363638613837333734636465616132363734366432663734363134646139613562303766 +31626537633330613030643733336237626566396664666130656563386233336135653434663961 +61313666346533303062393564643232306165623862613562326366363464616661373232343934 +61656133663236306365376165366166333439363365353466663238303661333963663831313562 +66363231623937633735356332333733623237353331613961386338323138333961626334323432 +36326165333231663762323039626361373636653030323932393532656465323665316666366132 +32343933313364343635323439643831613333663866613135333634353563316435663631666231 +31356635633433373432626432323036333332336237323335626136663331383630383738303361 +32356266323462316533663064623361326137613863303735646461353765633835373966613039 +38353032376232346338643566376239656662303037326265393462623264663935373265653463 +33313137356163353135323735356230353431663363323362386363383664313134666263666134 +35333830633439303066346564646633356561383966366434653636306463396139633933666637 +66376632636138373266656235396362656631336664373265353962636230656466353831653030 +64616333343463656465636633373637373834306466383865386365373466623462663865613537 +65663130653462363761356566353761306539363435323538373335383162663534383235613739 +36363732633431386535333434343862643031613934383936616534646531373161373936363937 +64623230323432646661663462663437646135616363323237633662636134636439656433353664 +37316333366138313731663134393536633432333139313063316237363364353031336137333361 +65633964613630336434616336363036393930646464666464313561346631663331396465393962 +31623631646365383036623435326363323438393066356436356432616163353931313162613036 +63653639633338346431613365643537376163616432643339653837316331383534353938663561 +61623432353037643635363865623162656135343262313637383565343364353561383737393737 +35663662633333363231623765303236656663646533653039343066376266356435653764643464 +62653836373132373661316138633833396335663835633866353935343961633265656636306264 +33306164346336373164633834646366623665633038306266346164613938303664386339346236 +37383064633436356466396462373765373665646463346536366237666535343938303866666435 +36653763636366356133613235666431323536393162313163613638663033303239653532376639 +38626338343130383030653464633632353332373765343838626138383662383366363031656663 +64343066306431323232316663353466383566336135623331613436313435363161626663643134 +38396333653162643263623564626232303737336532633439366238386235396438633864613565 +32306637646232613865663661396534303738343636636666386239333130656632303739353264 +66653533393534373338393964336632303263636332316430383834306536666339613232646632 +64313036643137306663636534386130636165323031643633393564633038336130386134313366 +62366338313538623461646362383336626535353766643530343466356564623136393461643135 +64386631373264316566643238663735393564633163643233343532383965333662313031316661 +33303138396661343930636634323863613937633662396632643433636138363339623134333062 +38343463653734396531323365363932373034383339633363653134383130336261666464313332 +37373531366437633731376639653134653636623433396631363139663364363534623734373962 +30643138383034346634356131663366636438336164613735323761633165383966346461343832 +30363030393532653033323261323538623639303863356163333364383436656635343639613930 +38333735666531313131373061333062353136666161613765636363376339386237346439636261 +61343532333438636263333366396261333536323935303832383263336363393438653439616438 +31643662653362363732373633356636643136323732363931346637623037396439343361343365 +36303435626534653431643439313838613865646532623162363631373330383631666136383534 +61643665313437346463376638323233653736303332383062376333303931623735376234323536 +34306137363464336231616563643364626135323934633239373863326230663632653366633264 +38626365333466396664366461343965323161346263653833363039333437616337346665356138 +30353439333562376434353862343330323433633562613430393434616138333033323062613563 +37303864316337333935343666623431363062326261326162353761643861336537313536303466 +30623036356231386435373437326164646363646539343763303130373962626366623739366237 +36346533653131613763643539306338356131373836316366343961653138303130313965643139 +61316263343239396533666436616164323761633063303466643136626262613232383364366165 +66343634313438353938653162316432303732616266376463666338663561326463623438623061 +62303261613437306232306566653565636364366538333332393663623739636363323333373538 +33353435303266616663353138373561353362323936306339613137666538396537373838383039 +33386531633732383161613261313834353561323338643033386562363665643866386636353863 +37663432363666613263343164663833656564343536666366633035653535333165306635323935 +32643732343265663737663761626634363339306166643431653034646638656230366330636665 +32323934313964376439643734396438653963326261313631356133383334653432666132396337 +64356536613637633035376264336133626463653434313536343030646365353261356666393635 +37613737333862643134626633393633336136366630326466313838666261633038656163666533 +35636533636130396364636132633163353964656163623262616132303331663032323633613063 +30653532616434343531343533613630383662663862366163373462616231346337356632666438 +63366530616230343731393832623665303235366362643139383764656133616463353134326139 +62646237393961383439383664646163356466613764393837663339663333363436376263373862 +36383965653562303938623236303362353764356562393834633464653664396336666139393634 +30356635373538376264616430373966663233663030313433663931393932353262386237643234 +33343837653231396562323564313365383965663934623633623464626363346466643432366162 +38343032653965386166663636623336343036633038306434303938333539353334333236653837 +61356462333561396338613831363739346362653665323035663130613333306161383961643964 +33353338306665376136376430343934383064356334313964656432313461663366636535376530 +32663636383066643862323064323762396537343361663366346532336164656338373436343033 +39363664666335306539346330333931613137646336643562393063366634353438626261663132 +66623334633530303135343764636135313964616434343861663434343235616139326536666163 +61323866313932386437396432656132313434656165346437646437373633663634663461326537 +39373932613535396134396530653532666638623763343933353463333432313934336563353538 +31326331323039396665623837666638666662623531373534353233343765366463333864323031 +37626464366232663538613336616463386136396235636533636534316337636361383030396163 +35326164613265306135323234306166386362383437373737323439393934323730623363346630 +32363266636264313338363335623435356630303431373365626634363161646661643030303337 +38373339636335616231373333666531393330643337396166643664346336333162366631323763 +38653662653566313932663662386466306139656662376339366637366461373035333063653934 +34646533633330393538616162376361636635663336656465323036323938646133376130626237 +33613064363837336662633533316464666636666361323561616138363162393431363966656134 +31363536623936363233336366336433326130366533346331653331303137303562666230616165 +61646236373732316263393731383930393338356634306531343832636337313837323637343437 +63363465303233373537333234363661366130623864393834663363336163303166396562626435 +64333731656438663262626139626332363639343032383737323363666266353331633363376137 +65323737636263656665643764663566366631366536636232623864636263356138373432326435 +37343564363739383366616535316431356533636635303164623461656364666336356566313434 +63623937623632653966626338656536653136306533623538663235666631393139386632393535 +63643561333930373834613336626330303163326132626437383437323730653032643264356339 +34643530373035353964643230326536356262663332373734363266376337396236333466356634 +31663431643662306437613463383066363365636466373532356433616364653238313765343038 +31386264653965363130326264323635646332633666633738653436323539323165356661653865 +31653133633462373835353237356564323161396666373934636363396438633730633366623333 +66396364656137633633363030343430303233383063353934313736373163373133393238643830 +66383035343837623662323938656430613738323837313465303936343332633466613634336333 +39353039393832396638336432363639623733323737663036636233316163656666616636636232 +34343533326662363537333165346638653363626334653764396666656535633533303331623663 +63623664386562356530386138303437363434636266666665616364616361366439643562663136 +63326463343730343535383961383363353864333038373035323765666336613639393134353839 +39373830303435373038336562616632643438353431343735656665653063393334363535633732 +63613839323764386565666437643238646534353930323636636634303333343166356466346333 +35343365396231323234306166666632326138666431326462376335326236343931353635663464 +61303063373333636161613062313738343832653665643737643738313666626535336563623434 +35393266633933616562336330356165656637353834653831303063366366396564373665323963 +64386266623833353166303731313332656432663263623761613838663734373739393363336266 +61656134653739663866653362323239616539653236316336303433333739353837363633653435 +63326266363835643630633338383162393437306262663965646463663265343565653039666162 +63343339343730623762363932623862383166653761316136373731383737616135653430656363 +39323433303037616132653936356437313862363134333331363937376337313831396263313233 +61303932346639393330393163373932653739383161626466376238616362666539646236653832 +33353138386666653436316164343039306236646530363432386365663839656234633033663765 +62383864336438386461623034353737653730393964393432666632306330323631313164376237 +39666231363065383962326533366161323132393439323433643936306430636333613966663933 +65653864333432313461653264666432396462336266613161323332343964363139376233326138 +65643931653862363631396331643231306639373630666338626266383236363263623634313862 +31343564366661656137303231383266623238333465336266313061623563643539656366633737 +36303634326164613936313765323030343231363339373935383730313137333563343134323966 +36356638366362656632373131376433366532396632633736323365346361653533626439656236 +37343136373164313464326339373765393765333337383137376538343332373062666238613933 +37323833333933633433383566333139303031653336336234303464633462306438363933663538 +66646530303065316333323765663531336130313362633032316434356130393665373333623539 +63333636303063616335386335636337623265613162613865626334313431663462626365363437 +64643838323430383136666336393538373430373665376365343564646336383635666436616163 +62363539306133653365313130353064373263303730303861306138653231633638613665623736 +32393239373435336166356637613466333435313834383739373934633931363832376135346432 +34616433303938636335333365616430393233333139663561373835383430386562386266333265 +34353835643465306166323339353236333965666162643736336561363137386435643366323132 +62636138343535623837343561663333643965333062383036343366353033626362323437643264 +38373963343133353338373966326331383162633937613561653961353730353033306162396165 +30396266363239356232666233386331666235656462346164623734323862626637626136333233 +38323063306161633266646465353837346564303563393037303263323963666632326134326131 +39633262333034613230373363393939393162623432373737356635626364396339366336663763 +62313439633835363537363163323437313933366361643237353365356663646131643963306531 +31306335636434326330643431376630353734376162633333396533366663356632633863363363 +65623664343932356335613434396137656666353264636637323465633433323566346138636632 +31336165336365316233376231663036393538633466353366316331343161666432316266336437 +32333562313164316132623735626338373439346265346535363735613164633965636236373834 +31313733623033313665646631623933376364653535323764643363323265376230326437346364 +30313866663039663462356362636163386433613361313461636137353132333737626464393934 +63326534386166343636666531663834373834346262356261376132373764656339353436366633 +63663264333265306361636433613066626338373338303438646133353030623937383231613635 +31393463386335313866383064303964343331323162623533386262643662386439353436616161 +63616463383334653739326266383430656132356366346437656630386566356133616631333738 +39313635383465316361643936623636616131376164303439396465346333383465313833373631 +36386364393339333263363766623038356630353238386533383635643038363931316164613664 +32313165646262346661336234613162643331343665653736626365623336663263643861353833 +38623839623739646232393431306465663766363835376339333162323935323865656564626434 +30333735356562633331353235613938356239633462376634373539643836646636643437323539 +38653464313535343934326266356636346565363035623161336662386135303831653863363232 +37396137643466666634626662376436613066643534366165643664623862396263653261336436 +39363530623936366635323961343562653863383065346336393530373837646162333631643733 +38306436336565626330636263656434633437336635343738656534653466383430333166663232 +31643361633935333932643933316336626666306538383962636163333461633162653839356166 +35383136346330626631316332633437386136616362666436623032303737666463313063383736 +31653138306434356333326236343239616366316261633037633066383632623030663263626338 +33623964666631643638323933646661656161373162633438303035326435313338306431653661 +36323834353463653639643435393762663535333838643961373536363533643835366164336538 +39323237343737316139306163623238643335373132393639643739626235613834366636316638 +37663434613636646139323431646663366331373431656662363732626461643465633562373230 +38653966666132346666353139316439626330376336376437306638326134613963313564633762 +38633763353764313566396366313239383263623531346133383438376332303965663261663662 +31393065353734313763646136643562343762333564653434663265633061666665393962303634 +37333061663534653462313464323166393766653232353634383363356135666365653932333530 +33633566346637303965666564303839643034333761353264633765356234333262646235336132 +33613637373462323335366366356264316338343835323635323861363735616165386234623865 +36396261663666326533626533626536303838326331316232643038333737616335663731656430 +38343033393863633137376665656563666630646539613130333666616237326530326463613231 +33373065623932346537616631626265663331653762363030303237663835643735373461653734 +37616563343438313662303638323337613961633837666630326163336632376436343637303532 +35356631643032626236343036333935633339313663316234383366326332656661363562323166 +35383066626466343739323936333533626437613766383566393633316634623837666237343637 +34636131343137343932326534623432306538336339383764633938383035303733323861666531 +38616339646138333730656235376139363935616231343038383762383065326630343135663735 +37333139663766373862356233303463343861343132623133613764653963333738333863643838 +66376437633637636135656264393266663866313565633938306235613565643337363639623032 +32386566616135396239336361633564666562656134306233373537303533383063613839626430 +34623934323239656637336239386466383134353866333262313332363632633131386330323737 +66613734366634303666643038343531663032626365303833636235616666643161663038623533 +38626563636138636333313737653933343231323436356536353738663865643664643631316233 +35333932333261633030366136663535383639346666623931383130336262643937616131353134 +33393962376635363734643361313662633463303634353163636235303065386439386437626630 +30626163633736616431343165653263333132633030366430646134313533626564313137393665 +32333239643665636138613064386639326534613833393930393336303730633936636338303132 +66633632323565313535646564656565373438626566373865303936333237353933356362383366 +61353034316262373362323939313066376334653462383534346563353639353136653061613066 +34396535303066326639343835663932636636373161386238613562633531333932646135353732 +33303930353632646233396433383766653839393435633664356237353963636430333439393733 +65376333306466633965646532353833366334666433326537663239336434363731616463383832 +39633330613432653438376666656631353164643365303235653332356561623536663663353062 +36653337376233363433393262313630313163306535303332376664353630636430646439663638 +34353166386235346330656139663130633837313766666261396564656263636365336666393166 +30656239393736626539653366326561356165663830316634373361303931623533333164333939 +31383835393731356539343338666564376461366563626262643936393438376265643465303830 +66643235336365616662653833636165643535343638323864666161306334646666313163303437 +36616462636233626464643433343838313232383936623664666339346338663931303164386565 +38343666613738656432353266393139356163303035306333396530623836363934303165363233 +31313864623962393032313536323863373836323030633139656132663838653937373462383361 +66633338396261613935396239646335626237343931383135363335363235303464363232646366 +31323265343736653362373938376264383836383731663533363435643963663265633436383539 +64663561623439363634333963346262336439373934386161316530643636643234653238373066 +31343036386161613538313463383834623839663961643130383234346338393632626136623136 +62363932633136616633396566396239363439663964646630313931636261343436383434353537 +38646436353362633335663831643632336664343565313035353766656464393637323061323732 +35393535396661323439303233613836613235356236633432663533653031383833643762663762 +37633636666261353930623430373932383932343461653832373032326535336432343834633433 +33333930313964323431633736656634396534323864323430656635353637353731653732346637 +31653331343365653761326134616632356162373863323636663462623231626537323165613331 +36356163316263626432303238643339346362316637633066366265643931646631356665343533 +62373265666538666263643737643639306662373164633138373663653864313463366632353938 +37643437306634353564336339636535363335386466386539653661626534366562313930373430 +62396334653736376231396132376235613966323062656561343237343931626530383337333336 +33383031336562636431653630316531336562316265306530373261306438646433666161353834 +35353431323265363336303638393932313638613665666537363261366137323531616335303837 +65623237363162633166636165626261666665633731386636663430653433323133643662363832 +62623939633432663832646362633765383530646166353162663361653466613638306631666561 +34306262356163616237303132313231333238316339653261613362363165623834353135393035 +37303031313265386365353837363130343034333032646338353930373936623530313632323436 +61363466656539363566653431336637623065353535386533643138356364386361376132666336 +63656165636335323835393230613933643631386663326466396663646566323763346438383533 +37336337633863383264616636643764623837323736383865373935646637636364313766306434 +38373665396166356638343465333130646335613663666263333235376535646633346432616139 +34353135353937633461373635653963326533613235303465643363346166343130633035626632 +37623334656564633033646132383832666463323762346437366561356562396232343138396438 +62363932343732616332383265323637633032646332373231353563326566623036313034636331 +34353338343064336631383763323936656231323433313837306665346136646336636130616331 +64316362666362313362323237396264316564613939306661646666643962646466343565643739 +34313763653636376138383831376237376331613366306437316364383134346231363735656436 +65343631313031396361343339393832306330626638326639366531326235323361666337623461 +65623638636233323131343032336261396339666137636466613730613339326131393332316635 +35663565633136396461336362613965376562396632613237323137656633393830383438656261 +65313935366237313934666634633162626130376636623039646233346133313932666665356633 +31386264633839346131353661643465343465376535356631363366343537326166386361646566 +31663334633862653432383235353834653231326166666630323533626330396466643833303162 +30643535343933356237643965376137646333626232316463353136633532363365323136336135 +37616331313436646139616662656139666336303764326163653738303638346163303861383839 +31646232326361363134343132653430313063636630623934323762626130636466326566373962 +31363862396662353966343362326162386439356136346365363735623235643265666238316266 +63336362663136383863363665666264323833623230383935303930336236303465343935623863 +62306537393665303563393064633262313465636563646630616137383338376161336534316239 +61666631303536653637653965633761626265323931346533313137373338383866633132343635 +32623235653661663833383837373134663563333634643232353933663335663865306339666633 +37353436353835636465383932373765663738363137643130326437333434616364343861373539 +63396263633263666130626332396165366365353535393931366339333636343430323032343966 +37643937663635323765366538623136373261373030376539613261616666323064363737336436 +39393135363738623964613162356439623530316166303163323166623164633761623534643163 +38323532356639383838646363363436303039643361393435313865333561353833396434346463 +61373566323761383334623536613337323630646363336537646435363834653733353331653638 +33336665303239623239383039653433353464376239393339666230356531656530666461643738 +37306637373366383938383139386532333866636463636664656134303964396663613965336133 +61303635643734333466663162306435366132366139353635363661353062636264396632383161 +30633036306133636264336561316132393332383235633334666236663733393465393839616235 +39656439383931653935333061363736613663623638326136656432326565393234383062306434 +61643866383233353930303831666361373535646264313663363161613430356361663330383337 +30653837636338363764346366316563653436663933363336366262323738333861656130383630 +34373239653165373139636532376536373665663762346265663734373161653632666635653330 +64383161626462303138656262633834326539623162646266626130333634306462323464656565 +38653866306539303534313934363336633130666437613362663133613966643964353465663235 +33643738333035383261343734386237353135623561633262366261643237303061663830656131 +36663632646331303366666130373030313933613336333661356637376132636434313739633166 +63323733663335666636343832613362363830663963623166383838353737363961333464376131 +30626261663735376462323264313764393131353635366330636232363333353361623135363962 +61316339386661366332326465616231396133363862376238616134313864346239666137363435 +34323936376265383765653936366561316335303662663631326538323064393362633638633864 +30326338303337643431653235336536643739623762346361336530386330396539346165373162 +39323337356363653735636635323234353466313436383238663635326365653139376331326135 +64633938343734343739663436366238396335343361343636383838636264393066633063643261 +34346363353437663330366138656165616536633166366563633865613938323839323531633431 +32356166346538336561373039636161613866353232616437636665366262643236633431336666 +65626236646233353265663232306235643034343738363362626332653861626134396365316462 +30613937303561356432636261343733303837336365633238623734303161343361366465343165 +62323461626430326464643863316362336531336461386439343238363632333861353636653362 +38363564326266333438323836346434303232663332306235333966646131393235346633343539 +32336637336333313431303562363262323533623130306361346662663034336266336637363534 +64393838356663646231316337386536336437616633646133366465336464333864383564653863 +33383262393538343265353234643632343638313830383163346133323762383737636131653534 +31363231653566393639313334353766663433666635303766363062396562376661653035643037 +38336639303431383462366561323564623361633035646262383439666134636438613561663533 +37366232393263633166366666343036353930626436326531356563376266316130633361346131 +61303962646233326435656564663964356364643264343066343834366664633566313461383934 +39343366653934333161376533623766353661383438653361623462393033653138393163393239 +35616237666566363637623936373238306132623965393938353230373564303331383733346532 +36306237376162393732366230386562303034633864393061393632653338323137653636353163 +37613939336438306131616530336561303032646464653565333766626539353737626533333263 +38303937643633306263363633383363356333653331633764636564353665333331666338353662 +39386239646536396666373130326562306131396364353632343638666236666463363565343762 +35353731323635646234363266613035333166336537643633303565616435646438636232613732 +65663762303531353566323539626431396535326630393335643736653161333165663366613765 +61366437316366306363653335396533636663306539316139343765346666623061383562633734 +36326166666237343934656163376163303163353839323764346634373136333731323064623130 +34653736386263633933376465386531306130623733626533613933623231626632306464383232 +34376463626136383239653835383238636166356139336235623134613639383936633431323930 +65646633356433343061313061363131333230333334636630386563326532376164306233386462 +34323335316637646265636635363837656434656332333462306237646430643830333361633763 +33636165623632656230383532383435663038613439303239333565356662663137623639633630 +31386138633961653039386266613135336235356331326162366134636631613461333964393239 +36386434303331396133303734373037616331373066353936393863373862326434626639386437 +65313436343333643230383836353438353061636461376230386664323431333636323736656630 +63383537656231346432326432623763623236343138306437363263643130333139396437333164 +63316231323638613462306366386438306363663830626632326539306433323162343861376536 +66653563346435313934373338353763323236656434353965346263393333353535616534333164 +36306464383335663865616439333936663162633735396261383930653964336363633065333461 +39303738323934613236313761666664343030623834663937663730646261353037636632373165 +35326233376337666236393837656239343236383530303432633061666264346666376237666333 +30316663326431396432663264613163613461326564313532656665383030653439663135343865 +64656162376665663434633439373538643432663433316139663463656534343930626436356662 +39316463316436386431313637336231393938323931316465376536336265356562333662653763 +31306331396139353732373962386138656137363064623437623964376133333361373061666230 +30326166376635623132316339656330333034366562653565663762626232323038356335356433 +61646634663364373533373333313339383235643833663737636534376633373630336162633661 +31633031623231366138333136323335326330316532383630633764643630663534616334333339 +35323736376231666139343262613962313432653464306333306364313533333430376262333462 +36383833303763623934626663653831666234653131306439636362656330616664616662323164 +32396664666265343738646630396239343966323035323566353865343230363331626264633065 +33353034363861333233666534383236303631663264323533626333313066666332633531306237 +65616666633138356431343165313864366238616437643030386635643533393731303735393666 +65313332613434306631373235616433393132346433346539326139303361643064373231343539 +36313861623337646438353337363030326539623365323561643835383138373565303332636363 +63663535363263313434373239333836386664613365313366666465343266643935343933343764 +39633831623734396264646133623335663134323765386461333562653031653265633734646539 +34613634306362343732316562666164313866373038303035393132303761323362636231383965 +30623338636130653830633565323135643561653438323265356136363766653339656431616438 +34343535663366386331353265663030366263353833623665636632613838376630646666363735 +38613934346338353133366234383738646634643466636633633830373762636239646134303362 +62393336616465646132383630666330373733336663353832616437343362623361306235613962 +35366163313331386362623835326639306364373861666262653132643331343731396362396133 +31393264636665303237383536653737623338396232366633346532616564336134663762346636 +31613461623436343661316632366131396230356537616436353234636335373562626163653534 +62316438373732356465326338346533626337666432343936626365353431373535663263346262 +62646633376432383831623061316462653063393338303766616638323232323733623635386364 +38306537643633393039663362613732323038613537666235383862363364623139363533346631 +37626661633566316337346238333837396162376130393334653164393037323061643735333963 +35373366616533353762373336373539356264613132323532303966613365313130383164636431 +39636664653730653234363835663134346236383961636438313930313335303334376632386666 +34646163333637393930363332623365303266653233336166383866636533646636343439323965 +39646435656639663465316435376365343137633434346230643231383133366536303530373835 +33393066306466336466663932373838633163366133316263383239373661613965663134353762 +30373238636138373739313466386634663762346339616636306165303232623261623234613964 +63386364383332393130386538383863376462396566303833353363363031653962616137353934 +61393533373662343034653762336662393531353666643636376534316566323939363238316563 +39666663636532663561346365326134396430356166303461363861333231303634323437383962 +65613935336238356335393430623865343530333334623263643136363034616165663239356432 +38353437343335323832303265386530613438303438323966353861623766373435396239633237 +37393764326534376132633361383662363265336531646232616365323531376536353963306633 +31396435356634653130633737626231343635656331616665313730633837333733613865623763 +33376261363564366239373163393562646630323562303332366435363032343334356566616239 +37376431643666313334303766383833393036363935663131326436303131383361363663333933 +34643665393937356536306535396664366137636333656238323663376431653564353632393539 +65366164346562663666373839636639363935633739663135666365616563373061393462643333 +63373235313437393661386163313237623165323137653831636130333235646664636434646639 +38336234666564616466656664373062366463323638346637653237616631613363633932376139 +34376635363936643331393661666332393161303037366266646436613239313466303664666331 +37353735393834363030376333306136613263393565393164633431333264666365613966373931 +63663732613163646537366133643132336632343062386261363339343939343539366465306662 +34383366353138393664373634363231373839633864666566643865656430616631306663363739 +66343636646166323634373337663531313336643065623834376632613939386632353239623430 +39326634613666323734643563623232313831306263376565356632393737386266633463363037 +35386231643163656563623964386561363939666561336434653362333339306332353232346465 +62663461336662383639306536353565363832653330336361336136666238336135353734343334 +31303832323363373866626433633662636236326664643134383465326434336461616231393761 +65643836356138666462303333656331356663373536366364386265346434326330633837346462 +63616561323539653864383732613738356635346132653234343537663466373936356134666338 +62656232353535393731626537633132366237383962386561373638396265383732656433373765 +66313437383539316133646531646133613330643361393066333835633830373538633461393338 +35376161623634316665343262383830343930666234333563616666316234333863613134356136 +31343739653238633539333736373465303262386130326164653832326161393132356436616438 +30376566376337336366343461313037393162346631393135616537643234353330636631323231 +33383339376333323838316639363561353832656462323866623139613263623265366333356535 +37613030366364313132323432336634383339356438303962663361626563643664666333633931 +32646239393436323936323438656434613465363938326562333661396333373132376431656431 +62316262303230323465613731396331343566373034383538373939653064303131646538373434 +31306233633835663965633734636132313738343038616636303138353862666437626335623061 +63313037303839646136393235373465636638643132643465656438313238303634373337393335 +35626165643366633362333464333566376536376333383830376665306334643730626262616130 +38666138363665356165643139353036363830656331303632306566643635646163363530313863 +66366662343037643461336464373965306435653937613834633163326137643765353035336135 +33313830633537356232653335636431653066353265303361303536363931333734646336326361 +34616338323839343665633733323132343836356561616334393864386465663961386134383762 +64383637393736353432303365646136663035626439643738633065323665643238356563663166 +37333238633936653833366539613961666137313664616238636230383135636233613364373664 +63666332343061303665663930336337353461323233386564383336626235343561636537623762 +32396163396337376563303863623837333031333131316636363665393930343762623065363163 +30353930623361383862313236333730613232303266363331333264656331616562356163383964 +34306533633163333961366333326362333731343531386538356131393938306566393233383032 +61623465366334363562663335663833353539353632303466653666353437393463353532366130 +62363136626638633530343465616131633330623065313534373333343664376434303935393531 +38333939396539656230323837306562653530386663353232363436383334663534386466336135 +66346661333139346532376135623431393164303937653930343536306238393036396636386339 +37313562306461656134313766656264366433623061306131353564303139363365323861663763 +66376564626131663061346139666162333935666635383636313932343435646230656662373437 +62626164636531623164623437653435633161313334363835363964646639363037633137346366 +64623639663739353938306339333331393863363236646337663161373738643530626230626136 +63346166626562646439353736343364336236393935613930346336303166386339393862363037 +31373533353761356531643034363138356664366365313462633635373835626562633065643531 +61353735313161633461656438393761326363363661633334623231366638393634383634333461 +35376261303366366231663938336631323439303363366131373436323937306366353364363435 +33323331643763303434663165336566653737303961636332393737396232643938646466393238 +61343565363331313462363135383365353133303431626430613263323933323064343237353231 +30623436303062343062616539343036636662656137383065643364396333396437646238363739 +37393038356166613434663436663963323762316566633138613161343366353634393838333030 +63386463343063333733373338343733376435373866323436336362383630643637366237626463 +33313734366461616630343631666531323032633638656565653138356265646664313134623761 +34633230663363316566333230356262333235613361386262396565393334613662623734386163 +66383738326132316235316565646434373065623231356532663838666134366161626363323230 +37383231353330666661393766646665353832353238356662333935636537393766373439613866 +35616564396139623131613966363039376435316639373238613335356338373938376266653762 +34663538653166373361343633313432343537343034303463653333373734346138303630366561 +66303932313932613964346562313134633631363863383232613538393937383231646464653737 +31343133383864356663303533343666613330633761363339616130383432326361666137373066 +61633631303736343331653934663831353736623334376532396433323734346534356566643739 +63323762376165613462333939376331373637343561333935336430346330633664616362306337 +30613430393239636465346262663131643066636632353766623130376161373735626538626539 +61623161643835363935656532656462333736376633303466393465326664396137623136623236 +61313165656562663661306262366535613839633033373864316532643430663561613362353661 +30313962313537326163326366326464636364333964656537323933646565356165346362366130 +38323561356164316133303831623662396466643430626531613434636161663663663364343539 +34356337313839353565626533616230633932653463636231313937316333353165616366363934 +64373736313433666339633832346561373761363235383564323034343861316334306636653430 +31386632646237393536616333616131643436643236363061633234376366396666333136633264 +32333431316265653932663761363830333862616334383763643138336531383732323265633338 +62613330363633616335326535313630313236613939326630333234616432313333333063373138 +38643865343863623339313635303261653564633466363562636134323834623036323334383566 +61353464636564346134643838303239323233613039376131656435633130333765353933326433 +34336334376630636331663064653261646661626237356135396333346536663939333830333834 +62333261626464343061613834373961306564393264393761616463336532363433383235356263 +33353232313736336630343765323538323530313261613139623039373661373430323134336538 +34633961343161356230383235663861306134623739323233386131356338663065656363613561 +64666332376236613738326638626261306661343138613465643562383238326435303630666464 +32376232653430313332376435343132643935623038636461656266643430363130386165323161 +62653830396637303363386466366338376562343131313031343736646131346438616632373335 +32396135393931666561353062666431306435666434366466316538663335333863613634383831 +33313438323763653063393063336335383134656638376132363831303662353035306436353064 +35316531336662373631626335353362343633643035303630633539386362303264323037393462 +32346361663665633962373130643465336365383539373739366637396532616364623936623961 +39316632323935313761393335363838316237386138336231383038653630656363393261643432 +64343162373964346263336365613430393664383062666263303738663931623737343062303635 +31353161306634333839396538313564623231663762326266323138316335303436373538376164 +66353837336636653461663231643562303531316338643732303463333161346539653339653233 +31323165303432313932666333336465636435653539646462636536376239356264646264373238 +38363630306566633539626561343836626333656434383136643463353064646134643331313961 +63666663393033333964666631633166323264363939396564386533376331393336656333653833 +39613663386631303862616435636435326263353961343237633036663562656337636533353336 +33336534383135396638303839666433303834633066373737336562666538623563616234313263 +37316430386263636431383434643437373834306363393434623666663761326634323139343162 +61383338643434656633653232393932656136643035383065343832363532336639356262616239 +34336538623335363761343166326437666232613563306333326366363564653630373335313465 +61336162303337626237333538663035653538353039646363666563383831623161373231663766 +32663239316137633232376263623930383962636234376538386439313834643336616366663334 +34353330386364373433663566326130613966633038633035333932393364313664396136323663 +34386133323763343065613737616666653361306637356632653639363134333730616634653566 +34363630626631353235343132396233336530656364356434623064666332396630396139353537 +39306562393662396431303637333562343038313866393964356131326162646663616433656632 +31643135346466643864343837336630333037616335633238633537373939336233336537303837 +65646432336133666131623031633133643636656462313661303232303763616231313437623163 +66316462313066633163393438303763626438376661343061626132303562363561613765363134 +64353261333930386536313732363030343530346666343062363634306664363635653339306430 +66323862316534336262633432396338343663653334333866623239623835313833303661343864 +38373862303938636633666462393933303563333438346561366532656164396365303738623235 +36313035643730336133623664356163356264623336333636346233323866306634323662393634 +31343135663465633264623761303439333739303564623530306665303839333136376134353731 +37393235383262383939376639376437663266333763313562636466383736643862336664326166 +65633630616130623136646265383064633565346333366231613063323934636366393836663530 +33346466303336326238666362653062366563656333373662633734663365386637346531643038 +36343833376130343763313336353130343235356232643233666464663436623132386165643665 +37333361333664356537393434343234303466346130313435336564323132323437613965396662 +39313532353662373835663034316436396365356166346164363836623133383638386430366637 +36323233353566343432626435393033623464343261323032326335396335363638353764303539 +61636430373331376338376465643339653439633035343132663464313934356532636639643531 +37393961383630323537643838323531373837376666656337636330313937333032353239313166 +38636263326663616637343338616638643935363863326166623566653932323639626635626336 +64343734636663336234333332656238313937653936626139336338316130636162613633613430 +61326237303638333734616362366538663831356537373139383739303734336564623562306237 +65323038353939643766653963336632636139393237323462303736613338656332616439663663 +61363062343035663363666465303439373463376433613538353038386337623133643433646566 +65343365353662653031663632326335376337643632333566663363303163656565636361303031 +33323262323061346433633033363132353533633461353265653638636333356466353662393736 +39363161666662303966393634393863626632336231626238383062626430386239383633313863 +39653631373930386463366266313865373332363636633133376334393338653434383165353835 +64363532303234366262333238373932656634373064313032643330393865333731353733393333 +33373334653963636239633136623337643431383931343238626538623235666236656166326136 +39336461323030396161343962643234333861633566363066646535323862643766646465303435 +35313137386139393236343366353264333934653035636133373038633365616535633437373033 +30343330393763376662656637613361653962326534656137663132393134653439333061323465 +34653936613935636637663236356461383736616632383162643930383265323231643538656235 +38373461396135383539623732376235303532646434653465656634366562626562633066386333 +30383230396364613463303334666266623735303066626131633135663832623038646330373361 +36333039353065663534326536356361303135363031386130303964303030633731643164393331 +66333136383364373364316630333364656638306163373164663861643735663362393834326638 +66643530666164643333353736346365376430616566313835393938643635323039306535626531 +39663739333333366332643934396166646532356161616136343566386566323461633735616339 +37366130396266353566663365376262663738663964306437376638326233303234326431366365 +34346563626336396361333435303932646662366266623235636431356132663438303234333939 +35636433343431616366636331366365653832343233313764306637393838623362346433313465 +30353631616431616165613033663764666335666232623130323732376564613061353162663736 +30313862396431356639623061653233616539623230386539626336353838633663346262633261 +33636136643662353131353839623532383237376533303262613266396466366332636634396432 +66323036383365646164623637393930363662613365373931353133663334346630373662616337 +61633839393436303733346433366431663835636265343061633037373238633261386330623831 +39373830373065303838663236633239313066363265636534626263343833346231656639633465 +30326234323231316565313266663531643466303039313933396431306462376337343430393034 +30393735353762623531623330653230623632616665313262643633303738663239666639663630 +38326533623739336437396131373766663836653230613965633237306439346335323762333634 +66663539316361326635343237633539356333373663303335353762323135393334386135653138 +63643131386461633161633830366166666365383633373136616131653566326562376563653763 +33323462393831323239313533346234663861353964653930643732323539396436633134333132 +36623931393937346566353064386635373633613064656133623434313037643539333632633862 +64656336306631643937613362616437333731613939643230346565303838613932323836323532 +63363366386266623366366564303731376233383837333937386436316666346666303464366564 +30386466623166636164363564346536306139313735303765366163396535613835613035333764 +63356634393463643538336231343030396130663235643939383635373163373631363731303431 +31316539383938633236623838333238626437646132343766326562333038336430376334663133 +36636138383939633066616165613431336661623037376165316333303334393832366330336231 +65643365633363316265346436643831656365666137623638353634333539373232646665376163 +33656137303933623133656230656266386434356565363439653661343736343032653239623837 +33326366336364396333386333626536633066303138363535323138393632643539656665303430 +34393866653838383461363635646564333633353738653565663637653166346332306562306131 +65613836656437633466653661396331393366386238313765663731316438616161326634663936 +37366135393865373465386563636662666433313334633931353762386462343839343939373436 +36333565363734656439316632333131323030346636313634663037613035666139393238636161 +33303632613430373236666236346532373162366236316531396164323864376535343964343862 +33316235333365663762353430313935663630306331623437646464316436613331336565666534 +61396439343865623232646639323764333235383663356432326462613231383733636361383961 +64333366333038363739663263383333396631613137643438633039383630616638323539633733 +34363538656531333339626564643539383139663936313966663763396332643536643431653138 +66333237336661316336656262356466376534393664346665316539313136323539373563383264 +63323438353634323237306264613664306461303131633661666635643830366363313937656132 +31303762623538633434393530353963343561316664353061313936633135623439663262626531 +39363661356262376663303865626264626166376363626237616134623666353563373930393836 +31353839313736316131303862316130363131376538303032663639396434353664346434323936 +37666237306337653239356533326365313030646138363962633965663032336462333061633866 +61323565396265383137323230313438646361396165393038386463343530626161653535346431 +64633537353537623132373263663234383632633461653861393837646166623439393061643832 +66663839376131343163656365643762353062353236663061353734323531336562326633356666 +32346530303637326239313730666563633933323863643138613461363233643065656637633864 +61343861643466363430653933333039633134396337376134376138653830386237636162343161 +38323661623861303361306561643864393032653439626663663866346335343533363530353666 +30393437303137343563373133376162356433376339323131356363646266636463333161613235 +66336135366639616131346565316239613035343936636666376232643466653362623566623538 +33353838656165353162396138653939383164323737653131336266323166336138626138386536 +64656263383165633336333863653535383635383339393965303661346433393862636534616434 +35646462623865313535396465353539313030343665393464336363316537633131633634333863 +65623839326333353161363466306164343864303564393566353637616566326135623865633363 +66333166633261306531616164363436383736313866306437653535303635306235386636366237 +38303736663038376538306335663761306133653265393839636434306363643036383735613864 +65386263623534306231366366623234326434623937306632333466353933303839656539333439 +32353538653532303535363438616662613534313431336632376537316464353763303463386663 +33356139363439353538366134633661313932313962343466623064656536386639306536393630 +39626131346265663434636539393037643330313732643765373766393766353830633333633133 +39333532373439393266663331313533663731323461643631356538666232626464313136343232 +39336238623466363964333738313535363134613135303030663433303634663762646664373234 +36323537636662386266623739613661363366396361323034623734303332623664383731633261 +32326638313034653864663839333934386233393937306263346665386535656637656133343236 +65643435666662336234396135366633326531316561306235323935363834316164646561656662 +66363332666338343162353734346232306634636131656339663836643031333837356564363234 +34396533336564393265376135356439333936393339353062356332383666303033643032306361 +31636165656334346562626236326161633337393266363737353231633237356433633235353966 +30313432333665636365643061336237353631326436633632616161613065613235656636666439 +62653462393831373263636634653734623965336631323965356562646266346162356534343136 +65343935666235623563666638323837623166613138343133393162356330343932646134353137 +61626465633263616164653839316632623562343830613161326265313962333464613064646233 +32323766326236386165623638626534333834653935663436643932626566656334316462353835 +64346633363931343166363962323236663131373936633131353966323362643839313764626531 +66323434386336316166313964336236643837376134643933393666636639303662363636653434 +39316435626132373262383131343162666263663036636439343066653966336561386434333234 +30623834333030646431336336313035373661303265383439313834623863663734336133303334 +65306136363232323433386338343032646463636436373933313236373237666162356262613136 +36336537366363633030653366366639313931613034343131646436313761656366333161646664 +30333736666333356537386134313062396430626135643763663838643536616530383661363736 +37323363633864396366643261393136373333653332313964383534383964646431316332306339 +61363964376161303763643462303333623535613830303861616538663462366635303137643234 +30313063646439356431333961313131353237343163626438663530663161613836363836623433 +63646364336531613166343932306263656432633336623736386563626237653664666562353333 +33666235393830613066326639366333653739623537616236353332366537323663373334363535 +39323631336135373034653635363763323433393737356665633137663634623264323063616631 +37646331626432623137393531393131323731386463353234356364643464363133343334316237 +35333266646161336464363430376436346233613635306463383561616233656533383139363633 +35376333346665343663613664613462363566356365363232393536313564343937373431323538 +32393963326166336331303837623963633234323832656532333037343734626338333536336638 +65343664613361366338333937346462343864373838313239343837333465373537626564653365 +64346261653039613936373332393833366532653432356263666139376265346233386163613732 +65383031303838323935336263353661303639376565636332366432393332666338376233353737 +33656463656331363338616134623334313665623333623738626237373365623837383739363562 +64366432373865653139386535623265306363333531323031623961373137613130326537623439 +38626532373162376339373263666664383139393364316363376661613236346365666432323833 +37616339356633373038643738616132646232613131356264333639376465616263353865666337 +31386631343736306637356132356537353830323364633164373539626339653563353832636633 +33376237306436633434386265386135633465656664383566343137323239326462393663653061 +37653539656263363335376164643039636636383163613065383362363263303637356136383966 +66646563633339653031313161636266353161336666633261633764613766636331626631323964 +39303430373632306638356536653662343536646130316233343461633164323166343366616635 +64343433643839366366383031656561633164663335306164353531356666636364306434646536 +32366534373865346363623434383634383930343631396666646162303666353735356161376231 +38343438626439363539396436626164303461303637386139376130346332616438323131363538 +62643635653131633330343533313162303066343933633831643764333064366135313832613462 +36353062373966386633343030326232326632383661303334336131643238373231613266326138 +64666632396266356465316663646563393831636639303830643561643334313038353966626463 +30353133386433616539393537333065396563343539383430663263666237643639356261333965 +32663766626166636664646164383930636363623632333361636632323439613230353661663737 +66336164303636343962633065626233643062613439653264613636623232326234383334643031 +64383435393032336165393763636637363962336636326162393037343164636163303731366163 +61326432646565363936303462336331313934623065303930656664653938343138633932306136 +39613638373134323632313132333631613237333733623637623164316561613138653231346638 +65306665323132616565356262656661623461616331306638386237316432613734303665636337 +33366563343039313539616538353631336132326635343333356361306361393261346461343564 +31626638343963666562316364636161396535366233626262373636316266346636633665653336 +35663162393738346339363136303738653733613565663630623235643734616662303035373238 +37643265343334643232643064373530306661346632303438666466633165363665633630383231 +33623939393766323765356531353832396164613066636434656434333062623837656439663564 +63383737303631326330656263363438386664303836303563353133303430666561303139313035 +33386162626436616439313434376333383466316335343733356564356635386239303062353034 +30303631643766633538623065346132366435626331356563333662613539383064653237333565 +32313463336432623061643431343335343439346230643861663732393738623932356134316438 +35656561333530336665336537643661366131663530353764613136323262313434646666303736 +65303664646434326161393139663266633961386432306466363633336162336266303939386531 +31383532366639353265333464653039313635333366396638343836353539306465383431333232 +33653464323564323234313636306138303435393433386532643662346639653134366638633735 +30313264373830316237393462336639383361663832643238313938343663633636663832313534 +64306666626437643639613966613835396163643231653535303964313164323662613062633439 +39333761646533636236353039616261646262616530346663323861383237306538323434316239 +36613636663461363163646164623736653562633066343932346635343665313061393163343739 +66663335666139346161623262633733343739633464643131343831633565306462366531333166 +61306661373237393836366666353034333235636639313662613864333531316231343838306538 +66333534636364326532366165316161303138613538353334336466666632646431373061313739 +65633062316561393338383134326131306338653831373335646133336433643933356564663431 +37323465643937613763636531383133633463663339366430306338663363323830323138653362 +64303131363838343337626261613563366465376561393462346332393863313261383738666136 +30623034306535616164613439393862373632313864393831656361353935306136336534376464 +38613963316261663235343930313934336534613839653330373834636632393665353736646362 +36376564643035306434313937366665373032663137636263326266633637313061663738323733 +62313437326537643033653062663731336231323265386438336538356464383466333434376437 +65366138656332633138323239653963313739366432346165323537383261633066303435633339 +30393963643966363335623265636333656533303334383734313730346239613565326534643539 +62633962656534663038313135653762656536313462653965383730623865633337643062323262 +32333763326266613833303864393235373765326131363362303466353366666639383036353631 +30353565613736383033636436653866643634666663303337343166383466313737366235326432 +61343763396562396531376530663931346332303336316365383337306663336332356465303238 +63323366666233383438636264373530323131396266383265623332323261383963393336643866 +38663534616136623933613337363733393839633166383730363230323261663161633436666466 +37396235313961356365636463636135656531313532323630336634323934613535386436353762 +31663231363833616538336464303132366366343738323462656130343631663338633961363030 +62666232653565376532303739326633363461313666666664336436626332653838373666313462 +64613761313865303537343838633639613234646661303134326139616563333835306637393430 +34326361663631313537326463353736333662313933316364333533396134323435326630653636 +32363130303632393865303166633639373461353462363566323131626432313732616466623932 +31666163633163616535373966386561366232316137653565613566616235613661363236633565 +35303738666166646665626530393663313764333566636333363461346666643434363561373965 +65373563303833643633636332363863616238653066363937356365343036383037373833306337 +66333766363937396437306534643234663030643065393131323132393133653230386136393931 +34663966666532636465306233343437666637376135623432323962623765656439373332336361 +39643730383264336265333761623239633662363733303337343561393861303361333435363631 +62376338613239626464613535656531343633653330353665616638326561656236643262306564 +63613732363261336238376238623561656531343062643165616465666135643130316137653830 +63336562633534376466396235363438326364663233636162346664616532373332316238303562 +62623831303934303330396331666565363437616339376534333039393938323561353332313135 +39626539323134653530643833343333313835353435333833306661303731303731636430353537 +63383762373639653137666636376130636635303934656561623535616232323565623833356566 +31323134633161633436393861326263303337383164346137323433633634336362333061653430 +62636333313130626561656333323462663366363032373835363766626533613961623331613463 +34613763323739363766393733306232316238356238356130383964623931613261633761383033 +39346333303139366162623131633536383063343732336639363134613538323361343831313332 +36333661636364643631653064306633336631383839306162336136653933313436396561313430 +35653839396338336632373533383639343664646137663331643834316362393432373533303162 +63313634353131626332646263363435643963646638373966303566313461643132333532653435 +38396365663761363763666163376531616336643661383739326165313332323136383432396438 +32636262636566326632643136373432386432623436333932323435326233396265386262313038 +38323437343261323232343633613737396630656165343833663463366539393738313865306433 +32643238653238316635653233383338386639613634643235393365393264373231353234633362 +33383939633230663538656530313235323566313931353537623262666662666438663138613137 +62633238366562633666636565316533356264303239386632306462653832343133663130646666 +31373534313136313537633039616463663661356539323138613530346135343330636539636365 +30663837653337323361653738633763383266333734396534363232656266306436316366373732 +32333636373439623430633836636637356636666666663933636631623065353439663266333336 +62343963623464636238346463636630656661323034373763613535373935363137316534396536 +30653336333461333466633133363932393066306134383734303439356630353262313832666132 +61343066353264303337356565313565353535353265313338333661396638653731313736346363 +38366437383435663039373939623366626365633733356366346561326436616266646462336466 +37613765306565353535613438623435336134356264313838363061653562376263633230633062 +61376639373636306362636133663066336264313964613661623930616661323363366661623030 +31303935343566646534306631626164613038363233653163383061363363626537636136316666 +32666263643135623365393131346465316665363934653632326463653666353931323737663330 +30333934653265623565393839373535363733343539376132363435356630623761316538346266 +66363631316134393234336264643238313333366134613137336562666563666463336265633437 +38303433356438613139346539633932616237626333656232646161396636653766613164323362 +32346166623261366638653538316561396263333732333863623337333464663063613164383331 +33623361353762643233363361633565303765646665376666383266666262323034326461633731 +38356462353265313233363766336564646664313761343534306362316432366236623330323961 +39616539636130396633366339333666363930343534366630653930323438383735373664663639 +30343863663665373834336132643734353832643430306665366234393931363166303338343030 +30306262373530386134613564343732343065633933316463313333323935333434376566303834 +39306466613134633061356132626539613832643363643137643034623937663661613761313662 +66373864636564656165363766316664343437626533613338303266326164323365323139386335 +34356139393064643238396633376332333934373332623530383933323238313337653164616166 +31643562626436366261326661363130306161383734343833343433353334653936653933306230 +34346131376636326533326136316233633632366338653636353234666366396532346531373035 +66313530303131396331343134353731393633313664626430333334653637303063303434653262 +33623735303639313031653430343037363732356631633138633338313734343536333263353039 +35616531306539336432393538336133313336343539313234343762646438646536373136613465 +35653561326336636631623266323661363462366165663766306438353136396565376164356562 +32393565653938343033623437653639626461376238666331613132383966636430316139306462 +64643032643565656432663761623035396435356136376339643334313264653930373334633061 +34333434333833326236346665313234666231386265333765393766623032666164623263663564 +35646632393835316631656263383236383839666434653262666237373137366263333332343062 +39343366653734343766333165336164346332393737626539333438333235653135313034356363 +35323134303436663066653735663631616162326533366134643533616232613065393361396431 +35326664343333666138306131376539656132396237373033396462356330653831323831343563 +31393230613762613133626466616565653937383632663333316263366565623837353738303462 +66666163313139653533623234643861313565303262636238323331643966386166316564363334 +31316565653133333862386465363464393361336539353163343661376161633930306664336532 +65353737383563623836306232643037633433353064656431653331623331303435633863613630 +31386266616264313233313236613361386234613561366134636434316237663637326463393464 +34383165363831303130626131336436303065656538656332633766353562343463626364623863 +37623032306532616264623866303766366633383064333531363835666136393966396336346165 +64636434326536396663326363396163316338633662326163336662646137663963386636396337 +66353633613636333363376333653537336666333734303236383163643364316166636635303936 +33393336633537616539356237626630313662633036363363626639616364373230393462633735 +32333437356461633363343232356162663136363766366466353134333461353535636336356439 +61346566306363316561383136363430376239326637306237333839653766316435376263396431 +37663665383332633463363636303466663166303166393466623963356232653531363831333261 +33356632653633383864373530626366643661393637616363336632656138663932363036656161 +32323234663031613030613830646134333664393762393736663932396239353561326132393634 +38633436313731326431346664363339333233633466373033393961383136626635323033356230 +36313236353235373935323663613839643563626165373963376333333535323035666266666230 +32313161323438396361363264346639343135363133643939323639323438663036326236666235 +36313039333830393336663033396461376336626333343035366131373364336661353435303334 +62313530663433633161623962366263356663636438353136326638336437313332623932303061 +38393832653834666136393231333533323563623935373634336638613231646335666163323735 +31613161333539366135303038376135303966356565353762643364326239663733653766373833 +36306135356332353130636236323238376239323139353537333736393663306165373065333539 +37363932393938333035623730303032336266366666303763666433396462313061646464396333 +32633739363334383035633938643033616136316564356332656663383064373333333934656431 +64313838343636653863636161643462383037633838643132643233333562383165336632303965 +33626165346131663332653636643164656662636333633837646630613137613939613665366233 +38323035643434323065663432613338303732346534663835633361653366326534393263636662 +31336262646366313332373661396330353464346665303731623932303234643634366162633030 +64373330323433663438613639303338303239383563306533396138643934376238623638633331 +65666436333436346436316637613036383736616161623336643437626163633036333766323738 +36636137663132616466663039383132363233656133613333623633643766343235373031646265 +66373064663637633366333563643135643761393435303363313731633431666361343031653038 +36633964643937313737663265663264316639316135386265393830383832343763333435393239 +37633333336536306639353435613664633433386438653432643562323437333830353436613930 +39313465376136376237616239306265343731303232343064663836313862303735386132366133 +62386434363939303636313639653936646235393265333538633439646439363238323064303834 +35653831613537333464353162613264306230653835323163333535626139333338383834653563 +37646665663236313336383463363463373062396434393766333766386531303936643730393361 +65613035643363393235633163623263373331386534346466643039343937333434633463643664 +37346432383065653336343764623865343639656535336561326138636430613533313566323033 +34373432313534323434663266346638396265663934373966356664333637663064666338313730 +35333735643163336264323863663964663464376266313230636639376464666637373734663530 +66366231383230386631376538623335363563616532316633316238363964356337366435343134 +63373033376262343461333839373131623138333062653065663137616131303636393338323038 +37326663303737643232633362626335343465663134393532316435376135656337353635333534 +34396465386561393737613632623131666164393639626461353530343937386532666636376535 +32313133386233613533303164616539353437633634623666636238363434373636363237653131 +65363235383166313035623630643865343235323166626531643130316132356235343563383632 +33613637353166313434383636646632313062393365316330356135366539396131376133373866 +34363438653131313463313439623936633461363139393661633338396236376366366338313261 +64333135633037633035386131323838313532636361636263396637363131306463633932313764 +61313330333330626136373862333661376563313633666639643462333233643039313463336334 +32623837363735373836646365633761373137616632633666643337326131623237353064636564 +31336662323763633961373132326134303363646531313266666166663236363961636232623938 +66393737663730346565396561313965616135383630366566383161326239383463623936633537 +35636337323735653361633239646338643663306531656531653066613639623833383165623937 +66333432343031616334313037353766353239353237636363613939633861646562656165613564 +36313465376639323162656632643738616666373964626532393139616566653039646462633663 +39656365373238636338363131643833373237646566393838623464313739383262326439356238 +38613430366333373663343164313631343534343833376237363339626631633263366530626565 +31643831653462666563313639343366383230363764656437373461393063366632396365383037 +37666130343433303532313531336564386137613032353938616236336437306335633830383066 +66343834636230613630323730323162383830313465613532613831373761656561663531303332 +65616237616538626466343666313637613332636462333130613037653434636537363566643261 +38346463663964353432316664616239363566333766333365306132656132346131613635306337 +33396166663931626366653736353034316266613333333163636236376265663730623432396635 +64386666383162623164613662616332653965353430656130623732326238336438313338373130 +37356232393530373864346336326265643333613966616366343764363063383630666338396234 +36396564346334333363393730353938616538373935363533333162303261626333303437303665 +38353663383838346135626237336439323335633030666562383563383232613939626235383736 +66373165643933376238626261363262353061643530306165633939353839653037313336313132 +62383531653566623035323833623539613439396639646233326238336630613764346339316231 +37356433393536633532323932386232663963363266643436393064333037636631313636653434 +30323938336166656136633064633536656264633230626663666263643961316138366663646539 +30326138653136653836306365623134396466336532343537663265633036616131303436633164 +64373766653061663834376337383738376663386266303432343139326431613031343937666232 +65646632313732376237393937643765646533653262653831613963373361373732303036303662 +66396666366464353135386262643363336563393735303336353365666566616365353662623365 +65346264386162316530383334393236363232376539333339336632326461396263356439386364 +64663866643863636264393336373963373562656466303832356132323938363631633730373066 +63623838303636343536373261323461633466646531626263303234666637376664643930336231 +32633738653736336431326665373164373738663530353962613735316565393361336333343736 +39363566626536613433383463393764636363313863393561343338386130336238393964626465 +36613764333062393238333864643765653833366166643263333034356236636461383338326161 +39663066346131623030386265613931393431646638386434623639336463313530323939636433 +66623433626164346364393934613062376532643237326430356232633632393535663433333739 +34303862346534346635373465376334333261666432663161613435326162303763336661323962 +33313663616236393831373263363436343034376461383337663661356663336534346364623934 +33306233396665383433373730326635653039613165316562663362303064623862363934666439 +37313236663331653038386231313164643035653339366366653665323565666362346665623165 +35333661303532373234386537613762373034633061313630636364366636366161323731363635 +63363664366432636336366130336661356362356434643436613962333966393331363939336235 +35363663653865373230666562386532373062343830316462353562343264333961353865396563 +30396434303937326161323937373335366534396666623663626435303665333332383834633365 +63646236396634333965656331343036343466383330306333343630346666396334663930346565 +61663033326263363761623436626266396238646264366661376630656336373638366336393463 +33316538383532396363363134393537663734653931336638363734633935646166316137373033 +37653462356465303337633363656632663539356639363834656337656366633337633638336434 +36623366336666336433336563363433323665356333376365343933306361383661306338346438 +65343331643630316536366162333733643534383364316463626431303465356138393837376535 +64383838636532313361633561326531313263326563663930343733363165656661366565663637 +34653861646238346564656530396236353233643262316130356466636562393036663637613562 +32613665313639313566323035623633356334366430383764326262343231303463326263646236 +61646634316263366638383066613337353839396336313030303234363166303761643833396535 +36633933626465393732376332626132313335336366323162376430656433333734663333363732 +66636131316561383737356632663437633533336631623663393535363231383033666332623961 +38373431613864316534373166363362626631663263353663393861393631633162343735336438 +34353931653961386132663665623464396261336161373939313432326261313631613264323361 +62336131646138303538396561303132626532626237613666656336626261633666633434383937 +61383933303031316534353730653836383531633830396330336437656163326364616435613832 +65323635646464623766363030656465633763633837653934633230346437316130313931373062 +32663033363932663430346662353262373935643130353735346233326235346532633165316266 +62643030346366353163646237626135383365333366373738656162303362646234653335313635 +31353162623434363136343134336664656530353732353265383733363566303961303964333066 +35336333346266363936323766386338376132313832343033613661613366613937393465373865 +39616432646633663039633031646334383336376166623831623538313032326165303830383366 +65613630646261643832666164353461363733353539636635316535336264626363373138636562 +64653962613766656535363866653530306230393738383831663662653132343337396239616230 +39336637643336333066303565613437353332633739623765376266646137376339383063663335 +65623132356265633662316562303539343138343964336539376566313561613033396636653634 +36353334333865386133316563646661656437643535623564363132356532623163376565663237 +63383865356634643833383964303264646134376563663933373161313130346133623166636664 +33646363353065396433623530316331646264616665663433393734616132613734386634633033 +30383531616338306630633238313734353333666331653537376565393162383830376533353762 +64343966393664363334633337333465343831303935623137306135333530356561343630356330 +35646337333563613239353739373864636262643430343461383761313233373832393662363365 +37393565396365613461616439313734663035666164633464376330636437393564663761373462 +31323436353931623339363230346534363464393639613261373330623362353734393433633736 +33666533353365323035313965333932306364646138623466346139336439383435383664616330 +63383537393139353630313564666238323439363165633230313565666430613837336565323330 +61303962303932623432653436303333376362303435643063383134393639646662323666636234 +64633761336434323366656336343734336337653165306636336234666561386630613539343933 +34353139656234316539623136386238353232623239653966373061396536643036616463656333 +31636264383066613664396561363962346436643232633665326436356435663165643732663163 +63343237373639343365343531383635336464323562396461613737316164383234313934323466 +33343265643737376533633934366663336463333663326631633665343735616238373536636462 +36333237393366383039383234323831393864636661633731356164323437383164346533643265 +33323232653266613566396663636565353636326364346539656166633338613936336436623062 +65313938656634303032653734356335626233363331373934346134333238356434633663663265 +32663930383838393264346135353165613530353635666636323735653365626437383336316561 +65366662623662383730393063313632383532393739353531336332656261313334316562336338 +38383563333633653130643661616361636332383536383135616262633666306536356137303039 +66336238376462626363366464653938623762396635663339643134313637623735323932623437 +36323463323832303861333761363135633439656631653430323938313761646661366463393563 +36653963646663373338326361346336363664313330623534653062393832313338366537343735 +37656334613662306139326461336236663061306138366165353737663530393461613265343438 +31386439333337323164363232326361646335646164393936303666306435373730633531366331 +65363530373233306233623937326138363035353233343830343731313439633031393466303564 +62643633303865383663303636666539393935376166336137313964383534383534323832343861 +66623238326239626331393263306665653366303530393962326334373335373930636337383965 +65643766303038656433663564656637386636656133393332313062666438653836363966663834 +61653864386263636665313639366638316365363464616238656636653837633666626166653864 +34643635653165666361633130313136343633653062363134343338363062356434303566636664 +31393630663165366664373064646139646337623637376638373439333231643066306338363363 +30643930613666653261376430636564613132386363316163396639623361373036386363623539 +33373639366266633332333634373261323132646635343331626462646138356231623831633235 +35373861633162303539356665316662373161373135316432653233393332363034323363326239 +64326266316636653232306538363266613334626139666132633065373862643865633637646462 +39353431396239323532653366323036363965343339346461323738306333613761306466303631 +65336261666530376166346335353261383463313164616430353037373030353565643461376131 +61326565373363626163333337373466313935636336356233343963616266386537303332323966 +31633561373130623633356262643338653463336434363761653137313830373730326461316264 +32383463333964343564306462383363346334303635366233383265373336363230303839346536 +63383661363464666436356166336431636432306638353333383064306264353633393362356534 +64616130356362373463633431326539373938613437646363613936393732373237353733636137 +32613632326361363038633731366331333063633634313234363433613466383438646165376437 +32653031383833613738363031316461373066393734366536356333316362383966636135303063 +39346664343163353839306266386138303230303634383366333134336461323039643739663233 +30666461666431656434393932366234363464626331666333393735333030613633636532353537 +39633531653431653562663737306339393234386138356266333039316662663331383532623430 +65666338353836633536303466373164386431613263306335653334623735343532373334616138 +30333561313731666530626433653532373139376435386563363434643534323734643134376638 +62616634333533633331616566336665356363626364613932636664393233376135383131663866 +65623334386331356438653762306464336230623432393666323533333161333034303535333564 +62386630343137303062396538373930666632636461666133616566366232626431626235383232 +65363234376336383763356263316164633662636131653036376565353762353734326562326539 +33663833613039386664306631643435366463643461613232396163353061353665396330663562 +66393366376135636535336430613162336565373862336137613935666161306231663530666566 +31623966333162356233346435613665643466376537306532326134623635356236656261373262 +37616263396462346435343662333435363334353362633039383065636564636164316633363734 +61663363383034323066303034643531613839363030323865303937353436626430343835303262 +32333463363134663765646664313531323062383331326231396362626332313932623063666235 +30346635303365653330646533383333666633613838316462313134363965623532373763316634 +61363131313932393235653937636233356262643937626235633133626666366231623539616539 +35636165373762353332666662386566363133386435353638303262336138333737613635396631 +36643863373838646165303633613462653238346538633831386461666137303766623965626439 +65656435633832623037396665363939393838643136323539323862373438376466663364613238 +32643963366130333465633663313631306330383764373133656236363632646666646330373934 +61373565616163313364326662363232313536373466616132373532303762616534613263366664 +37636438303363663330316639373832346363656565626230316431333466643732643730656639 +31653132326431623666373563303333356534373831323131623162666637613036323465353636 +37393366386436396635323533373138326337343963343464363331363530653934616162343234 +34643032656134346231613436343235353464356463643439383465373636323535363830326139 +33363362663334313766646331366434386139663130343135646532316365346335663030333433 +66616565376264396666363334393530373939643564306137653964653930663036343263323735 +31353535666237363638363139373764323331663833386534303131356334666237653334333133 +37313734343264656363636436656635333839306338626235343130316136653439356263623333 +63386262353938333830313564633533386533323237313731306561373661633635623432653065 +64353633323861636439643062656562323932656566373038326231333939306235326339306166 +65663964373836646434306635386265303934366136393232343239393134386661643465653833 +63623237646533616463656432316437636533323833616537643838313332333536383961356637 +32656538303932353330616139646132663236393666333464613537306330336238333337336166 +61303639623139303364383364643931323162363434363136323231643739656266656537336263 +33393734626237363636306236323931363439623237376339336532646664356633343436643961 +39346136663837346536663333663130373763663830326435373534373065376565306137386639 +36616566303666646133373135396438343065646436383665356539656538656136356232613530 +34393731326330393661366165623538363936343933393136363331373433643236363761646533 +61356139393236613535326234653830663265326234386666653039613862323265383862653936 +64373632343537616439333235646563303564313736343365343830323961663735363630363463 +61313463313138633561336564353530333762666538313439653639663630306632303535333338 +62613162346337373533346466633462303466333433376636663866353939303438336633613731 +36653133333433376531376431663231363865623439363137323132373134616266633433373734 +65383964376466313865616461303132616139323234393963653230313161343961366630376438 +63353361363535313065313337636333336664643262326266346661663466626633363133393535 +34643738656334633861363434313363316663316437666233326136663164653031313536653533 +31306535353862346465653630636161343638373336616433316236656135653764636239366562 +33326634323865356262313035633932663133363132393165636434393636356662336631323761 +35383731366238353564646630353130643466646265353263356533366534393032613763323032 +38343063303239643565623235646330363761386161363033393563383164313537313763343562 +63396637653562653135363037633837343864663062336661333735656139323035386331393936 +61326562326137303737363039303565653036316330666661653064633361623364663936653337 +66383065313331333934333561623038353263356132643830623366326436613166643133313238 +63316237343866636563303633313130373935316334376139373030366436376464643161383965 +36643862343436303235323837626139393362333335393334393161336434386662306630663664 +63306363323739623634373635333039323362636139386534386434623935373633633337316130 +64316639356162326535363864323136363463646639653734323964663661643163623435323665 +62326562633230626232366234393236323465343663633461313733663338656230613239613031 +63343462323736346339346134646130326366316232366237666132626333393238373335323064 +38656639646464643666356137316536386530363332363238346434626163376231323965626663 +62373663313633613036383633663832366235326138353030306565333564353630643039373465 +36306130366632373233663064643661383864366230373839616630323339656365626363383934 +39663239303235313234366332656632636665376462393533333532303530623333666163396164 +65326539623162393731633330373230323532336364323336643836663033333761353466353862 +36346237386430356235383839393134373338376461636339666334353036373666316361373937 +33633164346663393936356164356463353562613231386364656233666461326364333163616430 +33383432656261623265666531613266633937363930623630613835663638616436386339323964 +62633030613134363634633735373963373862633034663766653664633761383437333837656535 +36323832663031373364616464323735386535323761653632643561663033363662336138336438 +35323936306536323231646130616162663435613666373532376138656337373437366465643236 +62663663343464613666386235393437633039653136363930383631656432626564373566646362 +66343237616137306239643163643936333031653130383762646134383661396631666432613162 +31336134616233663765636232303437643862313862373638666637646137653832323235653564 +32613532346437323234356438363165396135663434333238383961373064326366363936383739 +33373532636239373834373636393533396466376535333632396234623232373633323034616238 +37653664666661623962616462646137653362643932393730343861396230646164646638373634 +31383733316363323430346639366436623534613430396537336136376366343730656633363961 +32663566616661656632633461363261366232613032663338343637383134303432316638666165 +65656366313538643036393064353064343332666430323633643133653466653066316462643965 +34626430386365396433393033363666333133646435353034626133306161323436376333633132 +61373730373363656237373762666435353465396539613530366132303438386261356236323432 +31393663636333336439333031363130313839346333346261363730313966353231663062646166 +63303738333839633830616666333066343433336666313133393062356262623936386133343663 +66313932376661326136386639623637326634303135303537363031613032393361323636353437 +61303863336134333961346462336664616437653339373662333966313134653730656566636662 +66353061366561653037643361666539663966353563353064663061356634643630666231363233 +62663537373762313435313933356666613965386663646265313735626534613236393234323530 +34366564343861356139663063333363343465656663636331643264663661643836663935663462 +33626461373139323132666464373933346262323334653831336266656532643665313239386131 +63323363626434626433323039643030393364643638633739373965393761313230663035363736 +32323831353564636663383037303539653765656132333835643834366234393034636139386233 +62303537663466363736633938343664376362626139633836623537373061636533626331346139 +30633637396239366634356337613565653630313864626136386162623433383164643531646331 +62376135383763333230303030623131653635613766323864366235326538353939653762396334 +38336333346165653964306666343631343631333138363234623032666664356261303436633435 +37366362373764616363393864343435376132333766646635623335633566393964616532663633 +66656561643263663164396139363634313635323764323161383361646533336339633061363934 +32333130363166373336623237396430636463656632613163303331366432373032316631373139 +34653332626664306663636438346234633531666536316531343231353163636162636630376438 +34383539393137323763386635373662666435663266313437613762303536653634653664383432 +37663332613830353363373062366237653532363236363139633733376532633332373430636330 +62326439626639333264363965386136393933646130636235323632663335333866343831353738 +39333030333664366230653534643166323030343164346635613965323062633764383032656535 +64376634343839653164616630343431626262383264333361663361643632366561636135396533 +35333431393361306363306631653861613632653339373734653431363631313531313630346664 +33333935656134616231666461633364316665396563643638366561383165353333626238363336 +30383434623536326631626464376263343638396234653561663330643132643365336136613863 +36396238363336316264623536666431623339663465323463623561623337376430393063396232 +32393236343262336261633838386232333666366535356636356634346165326339636236386666 +65613034313464643237313634323633663864356534343537656164326165346338363161356332 +31613636626465323833616237396337366337323834373262326532613136366564326631386364 +65386134643938653465323764363430363533616164336564616136393034646161633338663235 +61393163393366356664326437303130363065653439643234643037643836623264366464666362 +66363866303133316265316536383766353466626339333137366330366263316661666530623635 +33363739663665323133393363306664373439356635313364353462333963336434356131633030 +32663666656534653261373764663830363262313661656539613266316532323738623037373862 +35313736633530323034303538313032636264376130616435393631396163383864663431333166 +37356138616464613565303161333330633036363138303061363063396138383963663232383565 +61373561333962393861316266343039613337663034323933393130666336313631623930366565 +37643561336139653539646631333833626531396138636561373733396265313337643730386631 +62323663633235396537316237336365663135306533633334386131663932653163353264393534 +61353832393361383638653637303737643361333766386263613631623437626339346665373864 +36313266656263353438613034343339323439303866366535363033333639656537353539643638 +34393630303866326136666236656466643339363962366631303530346665346630303232633232 +62653936633662303164333637363961373965653234396633613237396534653433636664643436 +62353335613861396435666361326663383766366135383238363933313830663930613939363935 +62383563333731646432613338663037323365613535656437333365386632303733353932313263 +39353362643563393134623937323333646235316365343662383638313439356563613339313963 +34366337303238363061633636356637346236343461386233303730353066346162623464326330 +36376239323230373536363238303561636632343966666464366130643231353336663338323335 +62356536646338343833653031353065373164343163313765636361323162313363626335613365 +32353539646163363561376461383937336535363932346434313463306333646461653064653837 +38326264656465653330336430386665323737646539313766646435383239613936373839313363 +63363532363464323464373538646666663866383436313338363962623266396432393832646365 +30663930396665376230316138633232333664306230323761613731373061346561616635376538 +63653636306130386264373734643563646439643262616465303637383132636537363937383262 +38336539313130386233306464623939333636393264656538333837346266336665373365393562 +32653435306535313262666538623830626461306536343266613336386438643531626535663234 +62656534383731656132646632363165343065396235656365653236633935356663356339323532 +61333031633466376163386365636130653666363264333130316133336437643536353133343431 +33396635326631646166646231323334626664333131323737613036666637343466323363656663 +39333732343838613561376334626432363566363665343730373231326339393838323336363361 +34613031666237383033663264653437333166663535323663376538386134313232653034383862 +31616530383065316663396364653366666533326262323439316134333536316264353463356539 +66643132353363366366643161383430613632373430393461373834623862353334363130326137 +31363361323565643931633961663634393135383462313536313639326430353364613237643262 +65646234313161376131376265333839356534356239613832323336373236666130313539656438 +31316666333739316461346563376134343334633632626235366564643863303237343631623832 +34306365646534643831666161636666313763333161613733623636643637633730363563306465 +63616565613465653431363439656234373363346639333962626666623334666436373033663839 +63373165613230323839346462383962383363393930303964316231326439633933646233666363 +32313037653932613035303939366461653565366161646661666437383834623334633530613338 +66356162316462333138643439393133613231326430633532356136323965386630383130616636 +66623263323935666262646337666265333937303962356661333661643531373137396139313361 +62333862373365313831633234346539303230373164386662333233346238363532386339623866 +34626364643539666662393733656339653334383063386665323363343438666161366331356165 +38353033323639353764663032303738333631393832623536366262386638363237313834623337 +35303236666439323736633665356561623765636265386262663136386661613132346433363330 +31366535313836306632643265663662376364303064323839346438656437333437336333323736 +37356639613034343763646232323230623036353131396262343261333532343731383961643435 +32346164303666373432376539303637396138623532376634626431623161353832393339323533 +64626562643035646366363664393031303439646266333432343261636365373262306133666332 +34623934623230393737303963393963323731376339626130316531616432623766353031366435 +34373361386438316363613332623762383861613566326531363735303363303363643839626163 +61353661333038616363623939313935613937386266623863616338336365346364316261636339 +33363639326563333833303134336332613332623561356531343538343263313766316664376262 +61646134306663643430623664643565653061636437303435633131353662386666326333633339 +38633239383762643565376631316439333831326363333963383964626235383263666364613035 +65353630303765616464653934316535343064626339383965353838656161356332623234343133 +33666237613864363966323333303764383066653561626337396163353232663937303064323436 +36366464653866346433383230663436613738393735363665636436656262366232393931616535 +37306232306666613661333365373363316130643964333937623138313433373937306463633533 +36653834646331373065633832633063613634653861326435623362633036646464376536393963 +66626166303639353732303636643237363964666233396161663931626139316163653464363763 +34393931363162666563373735386264323031343336383865366638313462663830636338323433 +64353163333832353033663463306539343037613333376663356633346534666233633436616232 +66613031663965633536353834396431613265333735613462613130633030393335333335613964 +33613830343335613164396661343466376536343039366666353035663732346136613666343165 +33393761346637346465386363663864343262613365393963656235343332653333393938303866 +39626138353134343136653237613537393233316530313838626130656134623135663361666266 +63393161393664373366333537373231383538373363326238393564393737643761333164326331 +65376132616665303833663936396264633462613661383361396331646666666563333464656165 +66646162316363346262333261323664373631363535353231326339346162393666373964613061 +65663766323762666632666261346165363934326336373638373561316162346630653963353037 +64363063343032323966303430396636303835663962623034636133636262313166373034633239 +66646164313062623535613964303163666638383963666161373862393464623736383730323237 +63336562333237343930363063363439363735303935393634333666363030353335616430316161 +65623062363338303838613732363231323366373231326562363163616639303063643065323336 +64373330613739396233626438633338386330353262376134636434636531323338343435393061 +35373032393139313161643764353666626664303462373064306539313130613930633238313331 +34633962366337666531393433383839353632653738333339633264336436383338373933356433 +31666338653432663365353562333335353161323731303931316361636533626331643634636331 +63663164623235643138653963303234646338376238663633636639383461393166333962613335 +62346131323239393865333033373830613065613537303739353863346236386230643864313264 +30626166643864323031306663306463616334373161303466616436313235633035373933623633 +36373538393664393063303836343438346264346633653633366264383232653134656532643933 +31636662653836646135316235333765613435616534363166323638613762393534663730376463 +35303736373964323536386564333161353437623830643638333065363030656136336233653561 +34656233636135383133353131373236376562633162626534383535626132393238383537353864 +35643930373839373464623165633163343062383039326336396239643966353162383163346434 +64356463613037656539356364353237653839613938663264346563663332616634306261303236 +63316438656630646365313266623435613933303637616533396137366639323664303336376335 +64663065323133323062653764313466643538323662393565653935353030336664303965376631 +66333466666566393766346364643437363565383838613139313835393738353266323939376230 +66373463306465316432353136336638613230613666313664393132633866373032343131363632 +36376563353761623130646662333863386464303435373731346338363437653364666333613465 +61303733326461373436613266376464366336303737613331353532663831393734663738303765 +61623731393832303236356363616635656332626163393035356430633564393136313135636438 +66366263343937653634353061373334386138623330376439383337396434306238663334653139 +33373462333832666636666535343764393761373132316564343535616362336162336432333336 +66623433636236363138656132663233663264643932363130623234373334613565373331393137 +33373964666362643033633137646264616162363730356262643930323630383037656539333930 +66646437366335616164333162343462626362393465663630303433373535363038363230333762 +38396433336331383465633366633165303437316666383664643664663665343463643138393836 +32333064373034626461306336323065383164313962386230306362656162383263643762636365 +61373665343934333839336364336362616138323637396233653930643736346462306663616562 +65653165633836613433646634633937333165323032353830343530303563316538373934303638 +34636563663363356238326332313266383534633934373531316435643133663832333664353064 +35313165376136646131313065633266346563636366306332393635656661633433653938386465 +66396535656636613731666361303134333434303033653838393266396535383639306234643832 +39376134636235663632646133656131316261346637336263396133383632343266373531633435 +31613835313334363536623661363034363231363766383636363661633363346434363037383736 +37363335393135633631303034356333313464613537653462366639333331356432646238613433 +34653166366563626165383332326130616664316239653834616534383639353638616566346336 +62316534373833373563626136333061636564623730393335626566343562363561656333383939 +31326361346132303962343062303934313265613537343766323664333039353832623165306331 +36316638313531393434333532626234323264633064663636393161303233616338363466653535 +65393761636631383466636339336639633035636138623136383438633664613530313439623135 +37393436653038616134633662393734373861616530346135653032636165333536373761626463 +39643139613737633764363136313534353831313861303635376166303866353434373338613336 +64313335393332383761386630613339353932376533343132393238383265613863373533303039 +31363563353062633731636464613931343230303738393135633766633639303838323934643530 +36386666656564316566313633386237383133623763323936323338663965646430653461363235 +65306636316631386236353134346261613138636463363037303062363136313336643366353432 +64303133663466323533643331653461396432373262643434663761633161616238383566303734 +39366665326332633461343133313264643933383339323338333361613465373064306266353030 +36306336323637643936643034343830396265623430633437646635653464636539323635633537 +39623166343438666662646438386364383331323863333531373632643166323839326535306335 +62373736383439323930356131393065366164646436626263393864373963656138396431323664 +65373463316531363934353434353438353766663437653962626563336464623362376533646465 +65353665303530356133376139356661316662386133303533303335616365306364633830623337 +61356563303637366333616363353537396564636532643864306662666131366430366263303634 +38366261393663343032346231623666666639316138613739373637376566623761393332646464 +38343037343832633535636661646266633363306136623162376562353263336666633866326639 +61653738633038623538343862333466633637326638386334306632666438666166306230373931 +32623435323438353263396237386539343831333465643635623161356634376237336138373961 +66343466646635626332653031366333636533393033646463633236313830623766613562636431 +63336162373063356262643234326561366538333861343062353133656663303039663537663231 +62333037613637613365383134653263646632376433313664313038316231343162336663303436 +65663631313239613436653162633439646362633631303163613534343563633230616563343563 +37353737336263363735363263356535653561303239653361306566336138383232626236316632 +33656464343931653639663261303565656461643434623033653436363765356535343634373431 +62643136313933376231353039383033363532663831323130656364386666353230643064323838 +65363132346237306464636265373363333666323630383864323338303138386239316133363835 +38376631386339623934323139383436336638613937363836626637343230633165646361386233 +30663538363561326666653035326461363462303832366264393936303434393439333161623766 +32333530313063336565353664313166376138306566343234313436313363393939363165613835 +34613439323333623237363834386339626362323737326634346235623963643963353364343464 +31303163343235336531633766313835316133363236653137393266323037313534393261313339 +36396464633663353934656533623235333561656461663032336435333335613065323232373836 +37396639623133316531396566653035303138636138613563366465343331353965313235346130 +39356333356234376162353762326635373932383735353663613039336134386139356532386361 +38363432363330616537616432303739373338383163653564656464636662303538306339653033 +32316136656133366430326365396532303039323736643232366665303838356164313539636638 +65653761653738393834303930613365666339356462626436343839303461353736353035666465 +35303933643137623738626532393164383066643339343439383436666235366163316661313062 +37373463663731376264353261373164393638653831363937613935393732613664653030386264 +39616535613334376432316538363030313561376364306635316565376434633862313437376366 +66616332656331386333613961653766643130613831396130373538366162616261346638633030 +31336437356461633038666636313435656632396636343935326361396663323934373838646431 +37363136643663653837646361303864336265323137386234376334633664393265633066643831 +33303262313630363562636132383664346565323635396437616539636666333065393336343366 +62386563383163356463333463323939643132646535626632613563386137646135396539343566 +61303465306531373031326366373736333166386564373563316263396435643935656365343331 +65333839663539643938656332666439393734346564373164383735613236373566323761613637 +61373262306538333839303663663532323333633533366531386366346330613561666666663031 +61656438623937613032623763313839353135616237353461616266336563313535613530373364 +37623334383762616633636232366562323566343138346335653237633234616631303339376433 +64313739323265373739666239623739333163613530613635313634656231383537633365366637 +31653036306438636165653434396563323236336537643731623537643936643934666666616565 +37663733643530643762356336376132306563633162353864333066346162656131306531663364 +38396131353732353363393765393330313831386266666434333966306231313666386436613036 +64613637393335313731623066626566376438306631613134303732366430306165633066313261 +32613237333230653261393632326432386231373435313861373538396231396632623437373038 +37613230343830303963346166653930313766643038326463396438363436393166623334653836 +36323434653139303638313266356636663930353432323661333866656134613033613532313434 +66323833326366623932356334313863353964323466396134393633343066663165383665373336 +63653532363034366536333839316632316562393831643263616531633436643830366531663839 +35353665633764623630343262323065616362333566663938623732326430356131336432356231 +65313361396237303265363738653433363365386132376166363163376664313863626336343063 +34333662333862373134366263643136626638303837323433643338636530326265303031383334 +38373964396364373233653261663134353534333366646366623034616233646365336166666632 +33623931343331613237306631663537666262306264666237306631333439346430333430646235 +62363832323138653835656264646436663632626430326564616264326538663063336637633537 +39323338343831653537363466623230633263613964303136653261343637393363313331393739 +33626335623231636235613338353638383035346433646638393837656466333365616333623131 +39363438643435623561633637336330666237646263623938356337626130326633336636343631 +32343866396637346634346638316437393530646663613162346163633564343739663134366238 +62656138306263306539306433353664353166396261316236623966363438376666626266363063 +37303936336431383864303963623762303464313564646534363539316464646632393938376635 +33323136343934656661346637623761663464316436623363653562323939363165366631656636 +64373638316230346239353363393738663766666331623738653062643764393739643938616165 +31623361656665303131356534323563343966316437316335626232313635646137336238633734 +33646266623230363431306534393036623635356630636461316464643535393635363439383338 +30343737376163343831636461636666386663366632353836383964643137653339316534643636 +63656162323831303263313062386134353737373066316464383830303236313865376538663464 +34393330666334653636373865613233353130626166373364613662353564356464656332386661 +35656631306132656232353563373632313230393764376466656336343365333536613138656362 +36343032653964336266373730303161343738393031336537373634396361663066643432396630 +64363662623034313230353732613461326435623930373264343462356136666366393565396535 +65623334366638393264396661383066346439303763666530633237323663343363646262316464 +31633432666337393831353539366262373836303338333637326566613236333366376263326265 +38396133306230613830376162386235663764636563643264343932633363326534333962393764 +34636166383634366465653665663962313565343731336631323062666131323761656366303533 +35333831356466663632393361393933623161313030373761383731386638336564333733303339 +62653963373161343037386464663938653034333537326237316330313638306664373834373261 +35353235613431666434666665303361353562666235316631656339393464343635363333643037 +38303233666137316266373464306262306433656535383530633262373733613538326435386263 +31366234663431666361396565646539336666623134343361363261353033363936373738313036 +64653433326463623433336532326262646230313633656635363432323931353032353530613936 +64303065316238313537333462623035326164313566666364626135366438623663323361306230 +33363332633066656232393931646230653237306365633966646630383436363431313931313733 +30333365636531623733373935373836323335643061363266386263383337313636366330393331 +65626434353330313937393763333136643235356137316331646634616264336164366631393239 +64356137613537643633663035326535613935333036393133363137363431326335636536306566 +39323233626335353139633064383731326664646435616363666466333063396261623136643930 +32643538636661356537376330656231626239373630373161653438323636316630396266343232 +38336231333930363366316333376262346632663162643439313130313639316538306165323839 +33663165386532306137666164346361346336376264323063346138613535646661333765316137 +34666133366134643430643063373031383462646335386564623632363537663634316362373437 +39373834346664633938383466393465616631363764633135346634303731376536393265613931 +31343764356532626136313962636465336635386462643964313237383462623434623833306335 +32393031393434656536343231346330653931323739633436336332323536333639613834393762 +62623339353834393136393630613039376166316130343263333261383930363235353330373833 +38333564663062656638343262323136626430366339313964343336626166383838643735373037 +63323730343266663730363236643061633537303863626633333436613061666339386332626638 +34623938643864366335333435373035353434333335346231343662653036643139303433303866 +65643239323434343462336265633136666266623736353931323865383338353030306237366433 +62346130353930636261643437386334646337623164623862663633326336303163356630663232 +37383337346365376137356135333632323632633435386161646637643965393164633539363037 +63643863323634343761633363363431306162383031323438613065313334386666623761623531 +61333835323737313361326636366537396134633237306166303032353833633431643033316236 +36616330633436353666326462653133376661386632313233633335643937623034386538346561 +39333037366136646465663437356364333032333438303436643739616266393463383166363538 +37633162623262393231636437336161313537656562643662316239333831376165316231623564 +34653637343739626437376233323863373664666538633937646164313435353862393139333739 +39313335336537653561633130363965653230636239376463343965326230386661396661323439 +65633664616634393664336161396132383031313632383066373239626565316338613265366634 +34303263323633666566646363626430343665363835303439363662656166313639366438306462 +66666332383433326635633137653132646464663537393432613531663662356131346130356365 +30356562383662353261393366643234613236383830373035613435373634636637363936333362 +65646133353863666333346237666262663961623766346633366233363464313032653466613333 +66386138366137363233376464386361643336656361303834303837313065366266373732626461 +63636239623531643634643237376436323733663633393731343032633732353230626332313465 +32616565376666656132366262346637636562393130333832333933366263653334363466626364 +35356565653566653464353533303161643337383330643633376130636362666261353636636332 +31626364303332323137663435343563626232323564356331613935656536363031303365383933 +61653564373533333266303765623132353838346463643132363831356161386338336232353536 +65316430323134393236313064316465333662366130346337323066326633353234363636653938 +61393938376163343063366366386636313935666233363464353261616336313338323136636336 +35373835366564356532376362333631633932653834636466336465383330636534356637353531 +33623838346234306565336361396334663336393434373139633361666662363636363435386665 +36366461313234646433393164356165383639343135613539376236366433613230363135663733 +30306132623035383735663434626631376236653736356364303239373937653162643939633863 +33623565396635616363376161376630343539643161386265333430663832633235373264323562 +62613566303238366534653463313732636431393662313532386632613361656562616432366465 +33623639626133656366346334313733383635646331666132623263393836663061643964393736 +39306365376563313637393062376564303064373034376564633834636364316362333565396232 +31303339376162363061333837626263383934613530663137346163316333306566343964656562 +63656232623838356530326131633839656637663032343536376233626136353133376233363637 +33613133366431326134396461303466306463626136303263313230373430626461386532663536 +64303334393038373732643833393632373233336533323833313463313635303638376361666363 +66663734616339333234343438366633303834653737343064353438653166306337653631316135 +62653934323532623634363336386533393462636562636232333933643133333935636436396236 +62623965386337656666373261626462373131363264643130636262366638363032613865386461 +64626463393336343239663739323761636533313162386566353431346431616265323634323738 +31333131633362396533313930346164313236656232616138373234346533333738653631343035 +39316231633932343562356466313037643434393832656231323764623862616361653663393939 +63313733633630336333376530366366386566313438373066663834343432363431633861376530 +64663064376463643461363632363339643531313232336532343862643461666232346364623536 +61663262373234356235643438613439623130623332353262313331343562643833326439623231 +66626462323761313964356661343738633663363936373633323130343635376634626532336364 +37383630616265653434663861313437303036393335376631666162326334346533353233393366 +63396364613234656232616639373730393964613936633465366330343034633036666264326662 +37663430356233326235616335613161306331356163616562303763616439393064646138623162 +39366433396631653333623264393135376637316334313832333366383138393463636532663062 +36613463616434323637313763323733656234333161633230303934353633633436613339346536 +37613064373034383137616661396530666565393161653134306131633532633865343835656133 +39333234343266613561383163363963326432376366653635613037346562653838613334313730 +36396161663966333866643163323833646136386332383939386361326638323935616264366264 +61353031616533353165383061666533643336383062313434306236333734613765303930336333 +36373065653338313535393066346366666235353733333264326336383130326339393533303632 +63623363373836326131353039313335656538646336303039363031633335323232303463396365 +62373034626466333665666437656639376134666138343363353332376565363433356136616536 +65376662363162626134623234653333613861393564636365656363646137646332633532306238 +34643164636136373037326533396233656232663765623236373163363061316661366132363061 +39343961313264633937646233616262353062643565333038396365393234323766656462303431 +35343337666432373763343137646337363961353538633436633563306662323134336538623233 +35396634663634373765666563643330363934333830393431343962643533333238313734356239 +39343763313539306239366131666236376664343862303362373933633466363732623237393736 +62663739313032366136373839363337343435343665356534336261633032393366626563653437 +38383465383832393434376666656337353738323039313662663532333832636165313163343138 +36646464303365323935623730346363393738373837363062626539333964626361663366356461 +65356462316439626636393632386237306534636432656136373334336230633837333539353731 +32396433333736323436386338643261356531353437346231393032396464333964323966316338 +30623664643137303662306437663864346462666634303536613966383039366661316436386530 +37383833366133353332643562613864363066353933323638303865343465383964383461613231 +61383030626262386536353431353531363035376134316362363530613562306162376139303237 +30623964653036653662633333636131653164663034636261353632373365383934356638616434 +62353236303735303137316434316335373436323639336134656233313537663535386538666365 +61346638356163663335353234616464333266666166626231646239323862393263376536346230 +64333232383965303136623737333933643861626436313465653235643165356536386131643031 +62353839653164316362633864646230393362306236623963393330333533656435363330363830 +32663131383530656538366433363338383966386364633363366433323463393239393566313632 +38616237663337633365333335663662326639343163393231333331343334313437373564393061 +31303634346333613461323566323765633266336639373861623639353562393437346461643664 +63666339646230356439343333363939616164393633383330353063656638373736616462326437 +65336566363262656165343635663562383638376634343232373235316564613166393162366566 +63326262363039313938656531343661326130336432323136623331653161616632326430366236 +39393262333231643935366130656338623734336334653937383733633431313064356261363966 +32613535646236326530383864643962366334353035646461303530613136313439623433333335 +61393837636661646337386162336531393336366638383566643863633733663338383532646636 +65636164326561653132343138366566616261633131313664363336623938373132393862616433 +34303839313861313730353666613065643238626431363032366262666166366137616464393933 +66616234316133653936353431616334356330363933613635383666343738663431333030346335 +36353731646665303730323831623561663834653138303233613764396535633337643766623732 +34366434386436386562386366373239343536356232383732373163376463303030623564343432 +37313661306234386165656636663565633837353037336439346461653864643531316230663137 +62653436386234323964396230633666323563663138376335353236643130636635353437303233 +33663361643566666336653862633535633737313663646462663739383639626430653332643338 +35656239343339396463373630353265386531343564353330656662366639393362326334386433 +34666330366433333835356462356138373039633633666538396266383264653932343662373734 +31323664626635383138356539666466633333363538666438333733303530363866653533323435 +38633864666439646639396266376363313138653564366462353066353631373433306666666165 +37346239663662366430303837643330306666373261316663623832333630353961366130333832 +32626230646337623964326265316433303132313965656639663433383261656134303261373736 +35323430303263623362346363363433616465396530303035343561376265343264356438333661 +30653538383532623332323862313436306338303834393032353662646230656261386530386237 +63626332613239623963643561373135653465363738343135303630623936353934663961643234 +37333232353535646138373736393838306234386233383934323463373664646635373034383639 +38366531313736653236623935313539373933306432653637353663383565363131373634316230 +32353431316366643139623938613336363033653234396333386236376366616435373136663230 +63356435613636356330656535316132353634376363316565613139346131346563383635353166 +33346564366463613630613965363730633930353264646331633563636530393031353937363464 +36363765613731326565623331313230636537656332306334656634313061653830316666653332 +32643338303236313832656166383032613934393862336131626533333334346466306462396533 +39306436626131373330666136323464373738336566373936333832643633353362653232303738 +33303563623965643962396333636462316464303763396231313835363930393538316166303430 +34663865393535623237313761626535653138363030343564356636633036303534643738616330 +32376163373938656266643831353063643933643865636363316538326465643664326237613238 +62323034303634373134366262363561656135323930613638626264663531323439636165323838 +62303436346331623164303732373065666335626430343933393938653330353764333635393866 +32303838363938643930333633313739663936393661353030346330643765656432306337303938 +61346130383233626232313166326331646537623231363836633564363530643333666361653539 +32316664356166363136646230373332646131376632316239633734336332353932356433333037 +64366163313539613536346664366538663331343835306261633930616132633735646236613937 +63333661306230303938366437643739303862373038376334393335646131386435343431633261 +61626434656136383166616233303764313963653366363936316339633862613961613533653234 +63653064306139313066646536666662373237623432623165303962386361306465303633393332 +64366331393633656661326262383066376339363633353534333736663966373261666334636662 +64326234653965383930376431393962636535393731613463616538636232333031666566383730 +66663664356334386633333132346638386466383663326239376534633830616434393832333562 +65623630333834383961333039363833613237636237306535653731633364303565376662653130 +39656133323938643866333732363862366438663930336239336164396232663237663763313833 +36633662653434643966353435656432643536656639323330396633363239363238316536303961 +38363230396134363361343866623666396439393331366261613464343532653631633930316261 +37343831326238313863346463323861333666373865363831326363393732366536636238386631 +30323431613663656663623965336337356335633339326263386537313463353335303766376535 +30313761313332633234653232616437386539383635356130396135356464306464663666613539 +37323834613934333138393562383238646236626664326430646261623332636138363838316463 +35303639623638633263326663636134653230653865383734663631636466346166633631386265 +39396334326466653163316538396237393763616633393939623833633934303565663730303336 +36633136383435353931643530346433383733383230303233306236343333353762653236616663 +30373934663834623935313962653633393031333861343964356663303031386632663838663933 +32363336323231313863616536373666313134326366653632363961386536356163636664373637 +63306637653430333032666638386135376337623965353063623531656133333231613238333464 +36363536623566653430396535326331343564373633653131303432386535393631393435666561 +64376166653362373632343130393234336237383938656630396162623664666437666333376566 +65336337386633343835656338366632353637396138313530356265383732323264626662326430 +62383430653935386465633731326433366233613966356164646330343230353638323263353266 +34313936373638346533326339323731663462316339383938303830396633663263373432646362 +32653136396435333332356562313939323937343331303435626239613163366332643237643733 +65323562633733643833363838336337396239613162646132326464383139303833383666393338 +61343136353635613462333563356136633962313136393331663934656532363936643461663534 +38346362643736663936336235376661353337366336643032353963653936343163613931343561 +30633165633533353266656163323130626365356338623130666433633762303737313935363132 +62303636356537313431313037626361653132333162663032626133323064383264323165613334 +64383133663834613033383733316530333931663862616439613166626437356233346238343537 +35333165343837326666643331363761333963643164373062653231323336636462386664316138 +64386664366238626664323039323965313030666631306435326432663034656432623962643432 +33396336653934323234353534323734393131306231616130366635323261636532626163626430 +34366433333261333437313339383732353031656338613239633462386663383734363862363965 +62303761623239333735346462326231316439626461313063366636323430333061376534303136 +38666562656163323464333331316131316162636464633230646632363761323262653032623061 +65356362653237616466316432323836653137663534386365636335653138663337313266393363 +31613036643230376435643965343861636133616564393065623461663234333934356330353064 +61333132316635633435616631316336393266396139383163656565396334333233363137626462 +34393438326663646534353330353933653738653166353634393437626235653466346566363036 +38393533303366373939353631336533346331653033316232393931316336383339383866356135 +66613661303932343161313763366165333433326433383530636634666363653635313636323038 +33333266636637633462396430623761383364386561393636366630363864313565656361646439 +32373366653031323039306638336333613666613761333139356561333332383832303365323964 +32336130376235393765393734376439633431313032636531323737333935303634626636343439 +66343435653962653466626262623434376664303436373361363030343632373062633633373063 +66613335386235336338313633373261376335303765623562653931376638326336616664633237 +39656166303635643536613431646630613064326666353432303231363838366537363963346136 +62363164656430343838366238303462383364356538383761663737636561363266313536303930 +34623639623936653761336334646133653965653231386164333835623164363962346165343032 +65313039643938336637303262353236353263363734626464396166303365333437633631653138 +35633631326639613937393738303930366134643161376266613465396434373736373332663261 +34623730313936653538386531326164343038323533323332303863653930656161316437373836 +39366231623863656464663865656262643335633735303634386530343830306535336437376335 +38316438383565643135373661633837616630363630306238656138666537646634336631316466 +61313132393532386663616665646536393233666261333564346138373764613965323839356131 +64386335383865326165353138363534326637636662626366643333343132616564303764666665 +62656536363130313666346262643631386364333939663639643036643432653036333163303737 +37306235613663346437313865343263373038316665323762626263643366626266323934376638 +31633862353234306530336366343463346535623666303438646161373664363830653535613833 +39336566633663643862643237333262623131316137386634643365613438383834616533616432 +32613566646330656230366165393833326138396230393131333432356234323033653837386330 +38373731643066373635353863353665396236326166333639623764386366306536316462373262 +65613565643135323937363433306163626234393536643962323833393237333430313730356266 +33643533643033353266353866313436633334333866323963633563376163363331376234633736 +64346136633937386666303339393639303033653730326139386139366431663663373966633861 +33303634626163333965333735653565333961383737353366386338616166663966326235396261 +31663366346563356537396464303464393538613131313831333232376664393863393131323438 +32613863646232313735616363383330323039363561306265613439386333363930636335333965 +38653530616637376633333064313661643835313465663664306464343166633936346266316264 +63333232616338336437663434366637393131626266356234646165316361336637616164323732 +32323831366435333063393434346539633265313035313431373936636337383764633761333664 +32356334666533333432633432643534643034656233643238666132343663323635623831396561 +36633565626662643936313033656463636639643038396238666265623062666236353134613563 +63653766353261663934383664646165646131663335316632336235386139616235366261653739 +62323261316536366365633238316338336437393766343664376338323633386164653231383435 +34396135313165663935363230393635643563663262643535356264323836353230336365336335 +30326432613039303131663265613165313564343663323031636330316562616661663564316164 +61616164306461353238306238643065643965383530633866386531333538656464376561653364 +30643332643833353634353838636332353135333664363837633931353163636536643661643361 +39613739636461323161303737643337333438643130393163353037326539343037373330376565 +62373130333764363839386532366265626438386139396166383436316132613261396330636261 +33393131643531333830316433333063363365643163363037356531656237633535383866316465 +63633135386465343831633938326338306132613537636532656438373664326538633637616637 +37373237666134353766316666666265633737326232653430653864373437313138636466613336 +66656530343164663939643935346439373334376665336331336436363766393635613866633433 +34346262393662356431356534633163373230636364616131613230333836366536306636636538 +30656462363035333533623363353230646237653737383839353335383135313532633539323331 +30386134316536323663303430313462303733336537363463646337656332383539386333393035 +34333565666564363664363863643264346639323961643961303638373939376134626537333166 +62346630656565333637666138393630333136383062633533316666326232323062653762663239 +36646330383861333566626539633333333736626463383337346535373261656161313336626233 +33636333306439396631326638613430303930613465663138396331616163643234363135393835 +31633938313963313931393962393834356637653633306165626131613537636238643262353638 +63643038306464626230623763653865663535333835613130353762366165613237616465343763 +63323234656239373038386435396633623361653462396531343764656666353937653065316263 +39363939353035653431376538373362333930323730646433353036383332343835616138363666 +37313430663332333233626537386464633435333336653838653132616537643337616531613162 +33383037323962363137626631326338336237373030646636653637333365316133363133343662 +35313530336462383039316632393934656531326335313632353639616434613530326537646432 +34313236626536346439323739343965303364613162613339333935636133356435336433383630 +63653831333061653534613938636431393163656561316463336465393933373739396533616533 +32356433303839343662613435373965373363303564316637653466386438343062636334323164 +36653365393336363166623133303937313035346330636665363039386365383966666162393030 +32306235303439623530306433336565643233663165316363306261613431396334313362643836 +66633064363432626636386438323362623332623039646134396563316564383139613732306365 +32306134393437396337373239643761633039386432303837323738313631376363373865306435 +65633863636634336461636230636462396235653131383138646432613037386337353561666364 +31383939393163666334356362663432396335653563343932646238646435366339666530633331 +36623064653166353133653131376564663165356336383261353832376462343530643734343930 +31373336303530366563646335326565343032663036316565353737316663656363356562636631 +37323764633965636132646632663837303035396231386338343938333231616438633536333433 +32313639663433353638613165353036356235346533313462323533326565363739643962623664 +64353634623131393539613938303931653033333335613836353766616163653164666662656634 +38393237396331626439666266646631303832393763353939646165316533623538653966633761 +32633235383335663134363931393436343761343562383766613966383239653233323862396334 +66326333323137623264333261306530633134373937343562633730393734376430316535303338 +30656666623965656565346332323232616537666130356364393530363562393833396539386566 +34316430346362306631613439653765343835323362376334316161616665306535316236646437 +34663664306136326330343735373434393434656163656338393533366131643339653634373536 +63633030663931633063616235613833393133663965336532633331386233373937383131666635 +33303233383666363837353835663830663962653230326465376438333764613936373239666561 +62316164666533326337306263336563623436666537633632323461633734653362643936353039 +33306362333561613834383137353432343665666464316265383262623037306262653737396665 +64633562643836646561643363643538303830663165386234333639303230393236343230663632 +34363932626535323935653034346365313063663339363537306333663364313564366165663064 +36633835653737303662356632376132346533396233313638346538336537643132656333343366 +34616232613836613431663930363035306566346362613038363337663736643066313834303639 +63366433333731663732306631323835373161303433633462653437613739336665613663383930 +37323362303136363865313836646532663136666134333539333934663163626239663736633236 +30393362363539663061346661313130316266633061633734343064306530393864366134386338 +64363631363637613336386266393539636633366435376433356537626264323530616664306465 +66383462653231363034656339353434336136363066636536313633356531653862643862336430 +31333932356262326365383031376136383439376431626361303366373830623861363933353734 +39313533303438646432303865653664306133613733653565366131633934373066663531633338 +36313738613033326136383130376564326264633261613635626266343531313839356364323335 +31613231666261333833623464643639653463373366383862346366653462376530643331383633 +66306633313161316434336364643630663834363132306531643136396262346438653532393363 +37396365336439653663616462363461386332613766363032363838316239663937616430633164 +65383831396334336530613464336662383961663063656139366538386261626330386430383931 +37363664313166653162376538303133333036393136626330356238613234303836653338376538 +63383038663030313036643835336233333337343066646636663561663164383334393330656566 +33376236613831366165623565393861396261373636323233613239316234616137646664623534 +64313864383031343139643036626263313762316531666265643865393538396564636562613762 +39613761396633393132343530653663653766313338366661326163616665626664323566636537 +31353964326561666636333933316536343038313463323233336637313433336136623762353536 +64343464613964663335353739366266303365363136646333643666626133666265313831303561 +39393464333063383530383736626236356261316664616539643936336634326234343534623364 +39303265383964373734343536623937366631353262626262346662363961653564653337636563 +62623134303463383561386338306366366562393764663033393838396532326666646166343937 +66666435323534656436343861386232323230616533666334613937333839343066363634333265 +30316636393931623535636362653162383361666134383636303464623262313163343866666533 +36313666373237303738643439616439666435343364626536346138323464616531326362633932 +63663565653931313966336535303466343766366139303033383637316361376332626433636465 +62303237303238623433313364376536613636316234343766323839623838323430333963356137 +32363963613234363438613431613661643632383035643137306536306232393037393662376234 +62323133613432373966643837336662303063383436393237666530376264313265383833623365 +32343066303530623938393435356465343534653737306435333137313334663433383561623266 +32303765306662636431623966313939356461393162633432353532393661333864363437376339 +61613962616533306336353230656530393139323335653139313763616366636539333535326335 +66643736336635633561306231376434356435383962316530656563666535613261306336346438 +33663462623331313431616334336435636166646239643163343334666338373965343638383831 +32373738306131376266303934306566646136326439383230623634643638666362656266303036 +36383439346235343733613263383365396533306661366462356633346633323066623839393364 +32343563336130383531373832623931343561323337656639333630346336363762346139303461 +66346430653731623839643165303632316437393866313939323563373539356161346233363564 +37353538643431313333393261656638646633373166323165663437633639653764306131323633 +63363932326464646330333166313337303864333835626535303232363135333863653133366435 +34633363623630353538363537336161353464663438383439356334616435343662663034373766 +34643430336239303662353039373333666439633864363137336539613838356233303564366661 +37336162326337383239626134623538306432323633653736656535323333613530396161336539 +37303034336662636538333061366266373738663432363134623062336638633830393165356262 +64393433313234336436386637323765666462623266343564363636653564616265646465386666 +38363865383536633439663661656339653563356266326461396338633861323737323037313233 +64363738323261346539363730356161376437636335656331353061663637323235663231396136 +65666362393936633964653165653232363962643331343166653539336138326232313338613033 +66656633613366623839366565323866623634363034393737313237633264626531306133373336 +33656133303832626530373438353466643430373239373066393366363030666636313230306132 +39363332393832316465366461363336313432386335616264353661626136333733626234663961 +61326538353261346166306465383833313038386466323232323461313932626465373933313966 +33663265303366646536666630376539313038653261653436656534393332666261343832616632 +35343735313462623063343431353666363263623965366536646462373435653663393339666466 +64373962333564663832343261363539343463643338373330346664613434653936623164633331 +32613230636234626530666231386161303165646330376637633834333862353335333137323332 +36336235666534353437313163656436373635366139366364303933346630343165303938656438 +64656632626663653439653933653466636532313134393163613635383162306635346635663865 +35396433623263643536636161336135626433313662323239366130336563363735396130623662 +65396438626664333165396231666534303765376131383136643736316663393163623534346532 +30663930333237313836643538643334386264386137373435356464643638316535386535363066 +66303238323535623538346664386331343931353332666635353233323836323235643632626466 +30363431636661346665393661323339373063643466656665623130333735336339393861623434 +37306233656366356536353666353462653932373165376435656666346336663462333464643734 +34303366353065346639366436303661386339653636383164353330663265356466646637613539 +63343865323134653133663530643435383434356265343731376431663938326339383637303331 +32373364633539333331626164356634373338613230636364346636663738336161306332326233 +38363039633931363533333165616364663262326266626664363437663237616238356165343131 +62376563313365636135633361646539326133623164663139326464326336636633643034386330 +37643734333463633933396331666666623062353832623539336665316264363638656132303132 +61326138383633616239356239326563343032383631626166336434383235336231313132623734 +61666331336164636537393930343437393438363961343163353437393136646463636264343236 +66626265666264306133373532386461363539643965346639353562346633653164643138396562 +33316538616661646232336535633933646266613437626663366430656230656236303762386533 +61636437356166336464666233326335303737306664656532393465643864653830643837333934 +35323036303534663933383835633538396536626339633762316164643635336464366133643039 +32633562393934303537616239306436383033366534626436313335306230393231616132336161 +32373265353566396664643838303435393839333934383931323934613566393033666236623730 +34313237376663376530383231663231653063616434376438643133376533373335656430383934 +63336561653336666338323938343663666439616463353334313237333364383032626534306234 +63643135383563636135353030373730633462326430633738663163373232643133396436333263 +30353461643033373336613831633736636564343339666131393431653433323966363463613735 +32646536353965616239333461323834613261353730326232633863323437643139656532363465 +37373230313662323130346566626338333530376164306565633331326663376337393436316562 +34653634393330383064623237633965653530656339366637396336336562303532363035353936 +38386162306633653139313035613361333264326332623566373165653437393265623734363633 +65613337353363343330303331626338656138356438303265373139626561356337323534316364 +32303539393539323630616364656634626538386234643532613539333662653462373531313266 +63633739386631396331623337376465653864313632353838613965373437356635343930366436 +65653736376134366331343634363031653138353261373561396362373032653464313438396266 +64396363386139633033343537343734346262616461343336623963616162333134636665336362 +33393234613365623339663961646539653333643330353937363361396335303539323531633561 +36646334666165663838343034623839626133643164363933356563336465346437653630393836 +37363031326562356162323533326234636163656139613165346363373364643838643435303537 +39323634333262303135396238663938373130623439396165313735346633316665386132656131 +38373831356461633035323130343435663962643933376338303137373366336632643630656438 +64353333346463623932656535313564653534396566656337366165383939356662653736663433 +34333265343835366665323339346135663563636133396663633235396239613265363135323430 +63326562376237393965303964376533393062383763303037623331303765373934363137313632 +31623239663431653661313463323366626664323931313339313332613438303063663462343363 +64633231646434343630356166396264363964383636636235633934386535623063393266616161 +32343539303735396465653339323464323932636335616563613561343761353434636536353733 +30346561373461646562303539383261373962613333633963373365623930656138323763633936 +37613336323063643333343364303163646339663430376137346235656531346336393632373138 +61383036636230363733383662373637313736626532303938333066363338366131396331363837 +31623465313763306266356565663036346131393066643330303761623039303833363834336133 +65366535333265643035656463333032303761613737393532353537386431613761356362636362 +39343234616363336431386262653132383063393865383364313832333832666564323964656365 +36306332613432373835356361383066386263336266646630613966316133313361373666303563 +62303032326162393361666531373763383961353864633966346662393435613762653532386464 +37636632363761356465353062386361383234333337636635653631373330363035663665353135 +34663565653730316164626333613830356262633733373437323331666264313563383364346630 +35373632396563306632306338653863376134616239353036313561613434383132363163623565 +31666463396565363336646533333264623330393937666361383863663361623433313437333565 +63396665306531376235363165393933316438306631313666313461383562393039323637623330 +30316433313063363561343230646537363531633832326534363337386639366136623265633563 +64643435386139643933633462316532303761326231343463636264326664386433356130623364 +35643139383663396634643932333233633032336237666230633139386461343362646132363533 +61313633326461643166346537313838643237303162643062336532336635376330333561396566 +35613363363763366138393765383166653734383763623962356236633035336663396233343530 +64666636303266353234376464326633616332306238376239373963633365306362373066333764 +65396164343162653734386236633535383161646431353135353966663661643030633661363162 +66396664653630616336636637326162386264663265363338326662313438653339353838626239 +62363665316639306336623138613435616665653665346566383832613264663163656630666565 +63386133643736653739656430303966346133363461373632383839653335343863306231383131 +38303061323434616566373735383130643762326531353635353937326537306664653663333838 +36646336393962636435353865636533633063383466353638326234643130623732633733343964 +32653062313231363131373764343536346536373863306234363536363030653231663966383164 +64623932373538323263383265323736373266643935393565666430643962356464323035343838 +66363934333931666330653765386433316263643964643334663537383932303166396166353130 +36623730363761376337333535346266316664633261326561636530616363643330666561393165 +37336531366262316430373561356237346233643236373862336462646265393731333731363265 +61383732353431353938623133336537313761653362393237326332663137373337616563343263 +34353430623736373331393936646563366465636431353937366133353038316162643230373462 +39363631656435626435383439326461356466333033306665663031306236313734363232363933 +65383063323531303036323265393463646436373239633866643861373062656164643135306635 +31336232623361623830326232303536616439333432303130306163306462663936643734666565 +62343831663037623831646135326265383737643831373463383832376438636138613932333962 +66663035383536663035353265613630323562383335303636663730623064646235383636393333 +30623366306130333138643239383161396564353265323964323765366561313435616138393136 +63656339346538633162666236383436663234386332313336643362313834383536316437643065 +36633533623937636130373135373562386437613239313135633530366230313533613463366665 +61633234373330643765646534386538363262366562653532306266633131646239656461313237 +34656538336161376332373962373536623534393138383862643238393436373033376530393631 +62363534623236613438653066653535653938326266373738626338353462346162643431643965 +36366162653966626661643830366233393833316235653331663639333963613138666236333738 +65313565626633313739646332336462376364363335353539376330303039396638633332633432 +63383061316537346132616264376561613836366138353935336633343266623337333662316235 +37666165326266646434663766313737383138623362646439643636366166316436323463623066 +63323634333135363264323231653666366633666164643639656265303638643330666533633830 +33316437396238633161303537366635626533663939643130386337363562666135303031616339 +34336434303430383738373634333461326263643262656237383164363935613966623936663062 +37376535653236666433313533326130626631633662633230326565613330396166356432643366 +35356432353966386139303834346534333232363766343831626163623237613763333930356235 +37316139633863313661316537386530643138343838393933633862343935303639373661623530 +37333234613030336235393063653330313431346462623337636233343737643064306162643466 +65313733303064333035333738623136666139633838316562393766316434616236376663666139 +35386666323935663436343331303132663830363235306537636464643537663130363664396464 +32396631343233366163306630333564323130633365636634386131343262383463353431393232 +30663431393932383035316264396530633936316430643962623534396466393466306664636431 +39303537373738353032386132626532353537346138366234383061373638316364613331343065 +33386565303534326262653663383833333538373730373236333036666331363535613131646439 +38346630646230316539646263666635623864376566613962633739653965336163373931653138 +32333330376334643033323665613565323638663166386336613739373166326330366135633365 +65623535663166333634393864343334336436353035326239383762343563343330383664313732 +37383638643838326435373936363166623533343138646632313839376334316564383836653264 +38626463666333383762633633646362663933656530303335313836353133383462373739646336 +36646664323762373833326539336661633734666137376131336361643837373237636335373230 +31363433366335653731353765356335626235656462643163393035663863626534636335386333 +38336230373161313561313764663861656661626263646232313865363961666161646138346333 +63343636313531623730363635373264343036303061303237663365356330346562303366313861 +30656333323031643939613235633232333563363839333539623963636661663538306365616361 +66326664633038323636356566643436323430366463373666623137666163643338303062336434 +66393231343436653063366662303263393436653932303765646139643164653962303866306466 +61373662636233383539653466633061373339386431343039333137663935663264376365636565 +36633136323637326161383737313063303432303338366464393035376165636538626466666365 +63373762643335346633383732363732373066656133373265393662366262323432613665353730 +65346561393131303839393465663139636636643862393938346165366265363166373534663664 +64333639393565646466666661353339363764303264613361393538353833653661386361346233 +65316437613632333737363635333433653334633161653636383739646337316237616162643137 +36646430353634623264373739386133646462323935326631353333666566663234643266336464 +31666334613764626366396662303438393766303532303834303665356634393239323934353537 +30643563383633393438373739313563383930663538346430646135353631623435663834346138 +35333230333136353337643033316261316363343466303663333432333438316332383261646334 +39663737393164613932646236346535616466633635393932386666353932353732346436353838 +62363335343463623937643764653538343932376161393138613739326566653032626331333438 +61376230303230393633623864353435373834666361346661386635663232356139626235353339 +35353639303361353733643037383638316334393636353365346666343433373966666361336430 +38633338353934323163386266616430666439323232343434376662396331663764313562666534 +64623136326439373835636139353036623430646264623934316130373564343164643534613437 +31613238623265656532663538383536306663363435616431393131613636323662336631656265 +63613938393539636538366263663338666331336138373237396137336633663331373936646465 +65613631643138663665663366323762636462373032336537653939333764646162643062303332 +36303965383362643839366630633435373636383232653339396238353165373438326138373162 +31336633326531396461663763376135323264646536663833353235313138326530373339626465 +37626436666261303136366535333963386264386262643965326131653431383766333038613563 +65303330656265623833346363373266333865616334653335343132366161653863303465633962 +65323862363032613465666336643662306636663633313662376337653835346165633365353733 +62663261646638356563366337646264343264363565366466646132653839656262643036653639 +34353738353261313636373735346630316331613830316136396664653663643762623137653934 +30333331316333353831636636303034303661633665346464633835326135323066336638623163 +32323766383566616131396431376530393833363332343366316366643565663631303964333366 +32616235343939643465373939373364666632316634363239306531313865333264646638346636 +64383264333462373865383834366437373261636266313866643039616233366532396565643462 +38393437333963326665353761643035626336313038626239313231346638383638336263613638 +62306433336362343237313166623665663363396236396631303132616462323332313563663964 +38666636633938626666616236303432323433363730303734303235376437633165643039633961 +39373066396335336639623162306232646264616661616565646134663139376462366362333633 +64396464623965313730346465393262326530396232353865323961373064353161636430313236 +64626539653737393038623638653831396564323266656636643339306332636338643035633836 +35353362306639633533633238343639643663383433656430663661323033383337653132396131 +65636133336634663433303638323132626631333735323334353835343630373932373537303638 +66663930356136373838663836336339663537663938323434643235666137386265363961333631 +35346536643864313932343466666162623862626330643433636531643235323636663335363437 +33366165383539613938393962653366333161323834383431363030376430313836333538316239 +30343939616566373061626434646530303237346565303231656165306135396163613065633261 +34373766353839643036383631393935313063623033313862393164636431343061316261306465 +30663032383730336339363663663633313763316435663335356537363930363865353237363139 +32353763353166363938643463313438323264363331373161336139323530336135393535323936 +65353239313462653933643831356335346633393638663933316565313335633136393565636366 +32373063326565633961616562313335386163326539383935336333346435633036613161653732 +36633866383133633033346139613537313264303964383135356465393037616534316664356665 +61376135656365663834306661356634343130333265613033656634373635666230633363313330 +64396639616263623736326564623134623533343731303430653666666537616632313739363336 +61383264353733356432316537616433623361383030373764383964303233306637663437613163 +32363031613963373338643737376437653033343234303032646635373037356137363230623861 +36346638333437653262333165343362656531356537656161656433643564353231376561346139 +66306266306331303265356239396336623966383464393661353463306330643130383737303938 +34623966393633333431653162373233353336666633383933653832336235643637653430646431 +33376163313661663133616332303536616631333561343438663333646166306433343134353162 +64303334616364333363363734316639653935633030653439303539316630396364343737383533 +66653434623036663038643165306237613264613331633463336339373734356330653836393638 +32303330656662366532383361356162316362626261303537383061343636383033336564383136 +38643365656165323437346638316333323734373363376232386465663036663133353333636339 +35663265353365393933353361373664373530663762313264346130636437316536333434393663 +39373133356235376339306130326431623465666239303364363132333966636163356664346266 +62636661626335316232303437316166383832393134386161383833653935643861623563623161 +63333866366463396365363666353061383536646561316266303430393236636237363533353162 +30613438376137616435363263616137633237613136646364376633396436386664306631653532 +64323763306563666262326135623833633732636361373937333739343461656264636636353631 +32323962356666663532393233663432653039613035653761333732353134636338653639396432 +62373663343261303761626433366562643565663963323062396537343462366433653465323136 +63333135353933326438613731353061643836346137623831386364333761363834616334633736 +62323334343232626631343965333135363631633232633833366532323266303366396539616466 +32313537316438363364663134656434316330613738636362366464386164323765623135373838 +62633062336466373462396532663162323636316233616663356466643136373866396631313538 +66623166343630623033613134333135366334333564386635303739303466623662383432376536 +31653266336361383037386465366637653064653130303165373766316439653539343838303963 +37306164646263326364653934336563306536623636376563376633336231356638356432383266 +39313938356365663537653530366438336362626438353039336132653635376630646562323265 +32656365666136366634396335633732653838643935336364663233663334393262363230623733 +33313230366263373938623264356535383730363632383364653866623264313034316236303066 +31333665376335386233366231646235666664323035386231666337363836633337336661356130 +38303735356631393738643064666666313036323638646435366235343361376137343039346266 +39313933303331333539326139393863346133343765636161333766663936313439376362646431 +63636361333838396636393437333065326636643433373732366137633535636464323037386565 +63343932356336333537653666323762383064366266333264373339383463353039363066353236 +66373665613830663635313737376234626534333836656531663133653234303165356362633961 +61316631643336303732363838656636386535663236363062366430303838396332336164323064 +61623038363663623765666261386263636430393235656663633131663564333931653031396165 +33306130666663626639373138363339666334616437316436666435373338376135613961373233 +34633863363261303565346264623032613039623637303636333564386263613532326639623130 +36613036646132373838353837626362613134323966643734333837653938383130613865343937 +30643133323338646335663730323935643765383066653563613362656331376361303539306631 +66323830626639323630316134363863303438396535303439326630333461333030636165623666 +66343066303832343439353964666665346237653533363563383239313464376233386361333433 +61653033663765353833306638663533343237333436343336346134616336303164623261313332 +34376165663237386466373531353362363832653433323633346635356236666630313630323865 +62633264343436313166343432346239363936393364383361316431323239643530663634306636 +39323462373261616339346438646134343262323235636532653236366633386233613430323439 +62646363333436373831343861643165616665316139353837613532346162323266646165396463 +61636664663139316361643061373237653033396138666366373936616332343138646332333337 +66623230363832333436313332326462663439383936616135353265623330366662386433386532 +30666433343863393463386161306639353839386339333364626134353166343665633334303433 +35306333316539323533626437636433636264363362323463613331366538646131633665353832 +36376564333663633138353430363333613937653438396233303437643634666539396238393436 +36343464326364616332333036346232663166363438326332353135386461636561333231333864 +38396431336565343236643764393862653865613939636638636466313961396562336463343563 +62663136663564343834353336613466373932353637646166313964326632323165626535306230 +65353638623064353635633930353064313131643633663539393761396533356233343239633538 +62656264333465303966666565393363343736633038383035366366633537343839613235633731 +37303035623939323633386632663165663535363531343532623838636638633136313634366334 +31333662373939363636313437363534626438326135393833313835623964616662363938346664 +65666262333362313661303230336432383839383936323337653438396132366163646364343132 +36656533393166333637383731343134613238616163663161383333336565656365306236653834 +63343131656339633531373235363038353763313162323430353065353532623830313761313534 +31376631366330373733336230646538326665393531323935646137613138636534306365313237 +62623564333764633833313435366437333364396262346464646134316136643965633764626330 +31373338343137303938353734343761303364653131663661613666613831663633613033656231 +37623837383361326333373062323863376532643334373038633232313931616361623939303133 +64333139353263626363363230643863333466376565666334626235316434663436353134356637 +65323831666134306131663230613162306430356130316439343366323165336661316630663739 +64626165666435636437626636326132336330346331363766343833333734363833633931353031 +30386230323034643837623531613664393733646435643064383765303037653764663762653966 +64386532333338313737633161626237666637386333386636333632316562323336366137353462 +38333336303934633164626239303932366438633334346365323439623036663337393462313033 +30346363396436643562656537346535633237653236636434653463373633613733393766353666 +32643565383366386563616135386563393837613230633031663661633932336535653838643439 +65653330373730316265363931356163636562643661303537333264363039353636353566633434 +38303630613032366537323431373837646336313235313664613937653933376361656230326633 +34643534363539646638303733363261356564373332633636636662363630383730343166333032 +39306165356232623763383739666266633035376666613930313730643962336337303731393838 +34636664373462393164303732376337373836396666643062363866353062643632616532323335 +63386162373830363133343839336436643235313336323565636539303665393762393434656635 +63396461626131626636346639623966656461366533313130616162653164393538356232363266 +31626261303032373061663734346437326562303964333361663739326432373462393931343637 +64366633353234663434376565363837323739363062363962626161396133313639313162383034 +37313661333435666639636132356637636464643664363064656466383338373731376663393134 +35633638393762623732356662326635343433376335363635386438613130636234643033633465 +65313962623435653838386231653836613335393639613937653237663432653161323066626261 +31656539343237366165366339333438373131303633343131613861666637646137666631363138 +34646433333636366630626661613764306131353537663238613661376265353362336435393436 +30313231343130636334663435616637333435373933653337303966313539373233356261323834 +32623138616438643730653730353161343238316235656364373635363333323237313337656239 +66323333366362363766386535613338666230653331346239396665643838633061363032346235 +32313835356566623739643135373437613734316161353834326138363530636433386463666536 +38363636333938656663633865633534393364366537356561313635363639643837666364376631 +62366466323335303232333135353839613936663836333766383433643461343462656565326133 +33653932313965633033353231666231386266316637623965613631346231393336623562313433 +64353635323438373961646634386664646265643637316130613133306432616562313735663034 +35636237396337393363396163653865636461653138366438383236313137313661313164303337 +33356338343335333131643135613562396436366132646461366130666466353134346532616632 +35393239613663333533613435616231646531626235393364336239393835656535393935633639 +37656561373165633432333064653962623735366233326431396562623731353738646138383731 +35383763623332333964343432313763366536306663666236353362653930656630366439646465 +30333931663236663434396334623461636131386635663463326538396439666238623563396363 +36343030376263333064316237353165636663613365376139353564333939363832626636653533 +37303937623431386537646236643034663637313262633232303632663265663765373065346137 +62333131666136316231353362313765643530393931653662363738366535373633303461636263 +65626239633334336262373534316132323964313139306564313761643039346131323565663132 +36643134393936343139343038363232393036393361373231636236333764316531346561356634 +62393237323262653562313338316466653039346565623931656265333236363630353633383130 +36386563343236613334623339303838643565323235363365626166613263376564316363396230 +63336230623931666338343935613363303732363037356264666465666136333361333664323539 +32613562623334356461613261346366643231393534353432616266616137623735616461393762 +63363162653333356263363466396266643831633334656633333166633463666637656466383038 +38363331643963636335326566393737376137333337363764343361633438366663633261386631 +64373531316134643831363830366335326165303334353863316365353835333334336436623837 +65366161366261366239366665306635623436336261383361616536373331386131653335303130 +31326363343966383238323638643739363232306264656137323638646432613031303831353161 +65313936326635616266633865666439343139393637653161363138303436633965613663306139 +32346434636362633661383535346561633030653965633264643466646161343135343062326535 +37663763386263356130646233373438653663636330303264613533333831393834333530376635 +66376565376135643761346434663736653936663430306466323662626236356162303062633838 +31323134343331313236653738623237656661663639303762316464633433663664626366336339 +39643732613966383431646331373238633666633565303132643338646232623062633465313839 +31623238306332636262313936333133623936383330373932313638333664343561393430623031 +35376231373361343333356262343861666637343337373839396538323830643365303030383030 +34373962613963663633653166376331343864633734313137313835333934386362646330383330 +32326333623664396436666638326639623532326263363036633130343435313838313333656330 +34313936663935303136366339653038626431613264323263306238303231343035613330336665 +37653338353430653863613633643135303062656233343534396436656536353130656238383737 +37393766336265323931363531306336393139663738393063343333306137356466326337386231 +65313433393437613035336164313531356336336530386337336430323366666664393362626230 +36303333636566366433636638346261343837643236623036636362396564653562353036333336 +32386264306566633832386665663936633538346433646632343237363833366134663539386466 +36663538666534373665336533643637643932316430353235643062663836366161316365333639 +64316536656635353237633837313463343735643663643034303239386536636531326136396538 +35363064386230393132343366313961326435356630393330396338393136663662643363303632 +38386636386330303838646631376334663566346537616335633439393032613437333237313233 +33363230386339633165333431313537303533316638616166306539626662333931313233326638 +63613830353837336162363732356532383861623664303963366461393632303636326536363531 +65363234313639323637333439316264343537386437633433356564326631326239366332386333 +33343634636538633066616434366438303566613733313638393165346332623934663965303733 +34663965656365333265316639313232393231343961386334373736656235366430336365396332 +32623639313636646461343731636364666532303732336530633039303166643733373339646263 +32383165666135323833383638393131343464333765383730313938653965616463303361396366 +36613063363238663966383337336430306339633230303166353464303831326338393537633031 +39663834613732633932336463643239626262383939313532363637343739343333343266643933 +38376233363137643833336533313164616564643733383363356366326234643066643930316433 +39373939633561343235306137316562326366313565356437313935373962626230303037383963 +35313633373661346535623239653263366632353930636235343635363964343735363138653035 +61643364343437393336373036613065303636613834653239353030656335353366656132363037 +64356237363766323965666635633531323962323939323732643463663631633738613038376632 +66366464653636393963396161366663356232393030666562633433393936663535646230303938 +61643232386566313066663164386338306638643061393662386462333461623761353365663034 +33323266386466373066373962663631633765616566393337303962383565633663396630613030 +31623066313637646332306365323066636663303366326266616539653963626364303765646163 +36313861616432663036653664313938313463623263653538323431366331623864383539343438 +66646430653931656138393162313837396436626638666530313234663836323938376664393133 +37623630656537353866613136373633633866373436373562393732306162363930666564333032 +62333730636638373039663435353030623837333134343632396531323139643762313433346334 +62643061626634336332383238643862386134313965643631356137306230306366386164313430 +35306539383438303236393937336463653138376662393231303236656534363337663935633363 +33636539653534663534393733646264623136616239393330386432653838363566363637313662 +32383037623562653639376437356630313062663537386564633235343331646338616137633238 +39346335303930643065386131313838633235366264346635656537386462313035386464353432 +66663837313265313661366633643633653665323436636536663039643931613261613938383336 +36333063643333373132663830653238396664363438363164653437333866643264393133653836 +35363636396636343562336333376465396137343162616263646265363939343962383935396364 +32636564656665646662373831353431363664636230616563323934336166636634323563613231 +31386565386164353561396562393138366132383131396436663061663532326136323734626135 +35346436356561613139323263626264623164613237396130356235643666346464336463353835 +32646138366564636536373265383233616433633831636237343033336539613364313932663538 +30633563393432323433636264363663396633313061356235313966343935333738653663666539 +66386238353436633336366436313865373761616232323235373836313732346166623162343161 +35333239376462326132613666623936353032643965313966623539376336333033343838346465 +63616263633665383464313665316231306138366233653664663137653731656561616436323363 +61663865616339363966386433306632386132376639623166666462626631343335646162626432 +38353338353639313438653531326565353166336361636632656561366165636235623165636236 +33616538356237643161316163333930383262653430346261623934646561636236666239313566 +61353864653733336665626230616563643961316531616133383063643132666233386131643564 +38393166623865663230353266616632323463323164373561366138366630333333323230666233 +30663531646362383862303561353638376166633531393263643264363030333436346363646137 +63383739383064383634386466373166633466643433326361353465343439663833653165643338 +61626233343865333739353235613337656636643234373664626537386532656131383530316535 +31313730653063613330366434626436653161303462326365313666353135303137303761376633 +64343238316161373366356261633532363931386537303536336262393739343037643164343032 +65396364623466643430336439343533616462613735666366383134653630653239306263336665 +35623362306665366461353861666538353563333837636361646539356639646263336232383861 +65656535643338633039336236383135656530636134333038326230343934373436306533656137 +30653138343335383836613334363365326561343938616132373936383262623238303661393239 +30383034376535376365316337363366356364393663313830646337313063366331323639303365 +39666438646437623731303863633961363233643964656536396666386337386230643937373566 +35363437666433633332356231613438373732323539346533366464623665396236346666383363 +61366333363639393437623934316533333966646531333237623961303965306534353662303236 +62343937313063313661326462303733663762366239306334666166363735306135393833333766 +30623832366461363338623762356437313738326537623730663035386230353066386534633665 +61323133396536633234353938636237376635383339336238333561393536663931313833663362 +62623564346635616364633032336133343131386334616163313264373265326566373930316639 +37306537633637313065393836393238346262633765613162363437613061623665396162333962 +34363633646631623938613337663830633834656366366537626532643138376363313265303061 +63363335643833646137636332306261313161366466663266306530363837303437356163643731 +32306539376336643564656562326539613937643432343731363462633739333661313863613638 +66643339616563636239613039343535663363373962663437336263363265306465663264373435 +31363662343030663032646463373866643736616163616638353938343038666134616332373165 +31636236326135306439386531643261356166626230323661393132303563383430323432643966 +64363062616339373365346638636630653861333963393434633532656538653730343331623333 +34353565366461653931316562656133366665383031653665623739393262613264343637316639 +33626164323533666362656139646336346163376535653061386564316337653436656230316262 +37663862303562626535316365383465303032613066353739366563343662373434363866393232 +32306239633338636166366466366666383865393835323335663566366430373664663633653539 +37663134333832366165633933656566373863343035333634393362653766373530666566373365 +33643039633836383837356339343331323033656235303132396462313462346335386130636563 +34643566636536653963303238356666396536656639383364653866663264303537363939623464 +66393734386630653966396134333063306634623536373630333962326430653939363837353430 +61633165363136326234326439643866323139346432353365366266373662303638363061663337 +62326264343835656164656331303861396165323839663066373962363135386438316365346536 +35396663343461666363323637363265313234643266633164313030303566656461623461396530 +65653837353931333736616138396435313539666562633231663633326235623061343137373930 +38666235643466666333393062333765396430343537306364343232666436373035653062643030 +38336430656139366663343265363132346332656163623736643966623337373930353935333966 +30656336653261303366616265303464666335636265653466623064363334633665376464396265 +65656234306330636161306136346161373361303438613063323961373533343462393737336130 +62386364383663376538386633656431313236396362343438383338613539626430323735363033 +34396430306430316139643233336365653063303465663338353165316362386439646566353838 +39383338326365336265326233646336393161333064333939623230353261363837363763313765 +33306334656333333432303333616465346336613762623732386462636433313865656139666162 +39363131323031323064656232666435306235646463306363663235326438633165313138333437 +36663265626539326630333338633161343064343364656162613936343537346633633362343939 +39363039363966376665333337323466613934363964663239316666363161316437303236303961 +66653632323263396132666231663831306164343132623839333063303832376562333966363539 +36613636656531343863363465616433306464326663663738396235663836396439613938316162 +66646662303239663361373232626333666535303561633136343836313537643134303339613732 +62313763376362666666333263353336356665333238616130393932343134376362363164633439 +61313731643864373265623764626666386638613732633834383364383836373536303134613561 +33343632373731316365653030353265343035646133666564303331333139396665323238373164 +32666663366336356237313762393238643062343830613861636165613130393132306465623133 +34346337333634326466303735353439333731663864393537386239373330376566373562353139 +66633661616537613131333361323533333061323334386132613737353134373261373664316165 +36633730303038343332373264643433313633656432366138343033656631323431643035383836 +34343133313663373930393765636638346639303465663566643566363932376364323733343733 +65623938663761653732613261313335356439326333636238646336366333383238653137386533 +34366436366663333133636163346131643838666233353935616365306564313261623734333566 +62323664666236353362343638613239326433626339633666386563373733356466383834636230 +61626261373862643034666563303265343635373538643164316433316432393838653033613231 +37626466366663643463616464366533303837316136626132326563316135333837633062663361 +33326333343661666330643830623066616564383561376331323332356463303662666463303736 +37656435363464653531373066383934356332666366616132356236306466333361663162383131 +31663739333463653035623634353934396338383139656332376462323331306638643362386436 +34336534383739613632656664336166306634363633333033336466346462393735316239313863 +63306335333763346463313134323830343561646338633365326539303037356633303338353034 +34346134333263376562336538313766376331366264396231666634366263366439343863393363 +37313661356532376430336534363033323038373762383962323937653832383337336262333830 +61356462646137336364326266343430316561356564383630353637643030343036653964313933 +37326432626638363833323965643433396234386634646665316333396464646664633237313636 +32343063376532323764373930393230643638386665343337396461643637396563353136633830 +35383730366136356338616130363633323033363963323663393639356666663538343361323065 +37386561626261386433633063623034353430643163313762396134626230323237636633316263 +62323237303662633232316562356466663637393732613933323233386466373331636461393863 +31653563626133653634346232333561653831613131346430613964373564363762613863343864 +32363135626134353033646532376431643238316533636631353465383135646233376362613933 +62333737353164653233313536653731643237363434636261306330376463626466353439366637 +33633363613164626331376336326333643635303734323265666535333034333066386266663366 +31396334626461663036613763333262366235363236353335643736346366376363363764303033 +65666436316363386363303336353737643632333766653134353833373165653861383036663862 +37383566326132613866343063653932313961313261366666386464353939366231363635663236 +39303130373634333230313231653832306531373337353036326464326233633837323431623437 +35623732366431306630663735663333346163326563366333353934616234323532303561323831 +39303833356530343161383537633065633133356530336433643566663463396135363862353065 +66613832313132393630646263353365363666316139633966656532346163613063313166333236 +34666663356434663064376135316364316337653835393663336439363266353435346533313236 +65303632663535323932393035343864393232353039326236313137306364383937633161333066 +61376562366264346162633461636139363565623964613832393532316635306439303635626162 +31313435343561313933633435663363313665636466343136663064613864316166663562626638 +31393632633439353234386263626165333934353537396530336136616631373033383631383733 +64613430633238323635366162633330633234346138666337376637313739383865336338643232 +32366264383263623135653135666137353364343130343134303965616663656366626564343362 +34366564316334663535393433653964353531663531663063326237383461333065656563613537 +34613165646631336339623530613863663336313832386539356536376530373362616130396139 +34323832623233343534376430633466353330303236333538313061613631396639313231636466 +64663734313432663466636134626430666332383230666162613832636661353631346634313736 +66356232383761366563373065353431653433623464666136623531393030323662363632303263 +66316563646331343831333163643734646537303132376131366562633330356362396337343539 +65373039626131653335393331353061343532313038376438323863646462393237643732653631 +61656536306237346632623131623435383838616333653939666664313664343764373730346261 +61356130643865373537366661663562313463353939623731626364623134316232373861636335 +30616635383538643635613566393263616132653533386361346465386533336363383234323133 +33356538383161356535363661366361643939383939663163633165346533373536396236653562 +37393464336561313839333039393435376261663431393464353032326530353066623263316131 +32346264343834636630646562356636376530376132616435333037636439343566633136623964 +63643862626334356666663362663563313963373632343230666363323937373639643331353733 +65346137393030623036303664666664373666643464386438336438346330633335646239666131 +39383434643864393966663762346234393864663836623832303562376135363638393937623162 +63373562313266323761393965313663323736393061306635373562636462363533383539376361 +39363732393838643337303037376131336435393861343138666233643134356263393261356161 +30613266376535313630626434663434323762643938363163356639343134643534646161386532 +64376266376461343130363866643563356239616133313534643534346232616233376436353666 +65363837366436336330653465643263626363653639306263303538356365333166343936653438 +65663765633766353935316331613761613235633032306165333831623330663039323861356633 +65376465613433653339366631663062303862306664613061623664383937353330656231626432 +61626631656464363864333263386561343161396237626634356562333664306665626562343634 +62376561643132336437326133616561396364363362383832656231666534616362626465383363 +36336561376562396566303265623631323939326139313863346235326539393733616165393937 +38313562373765386337633135373233366635303865366435313035323966323565653439373830 +65613963616133383133666461323266353832373431643336363064636235643631643734626666 +64366531643664333438303031653733623035656236646164303665333261616133313964356664 +37623838633039343066353063313930353134353165643536363237326239343361616333656539 +61343135386130303064613339363539356336326135643236343935396431396233386133346436 +39326561663866636239323838653033376363313739356439396662636637363337366561326532 +63616533393862366566316332393430303561636339663862383164366465303837626365376331 +31326435396239633430623866663161646266343362623733623763333039356561633537633538 +38333132366131316436303333653666383237323733633430646264616537636134666563323162 +34336235323439326163333439363735316634376238383731376434353263623162323035643539 +31383936326539636339316463393365666465346238626130313236356363646365366233393336 +31383338333434353465343263343937363066646562326534393932366563373464613333666366 +63303431323137326433636463363431313433653131343262303132383836373032623338343436 +62393366323765303131336135333038303631326333313836653033356238363834343266383530 +30306661633439306334353032616232613462323135386438356636376335303464616263633932 +32616362333164366633316432383731616666396633353438323935616131313064386238653266 +36633165663465343064386338633366323464613037303034303463316161346663363738383938 +61653630613534383364323836366234643831656536613539376234633331353261323435336130 +63383732363238613165623231313436646662626637656432343130376563313666343430636531 +37666132653536386631356630313637346462646337313332376163646630316263353032343965 +35376166326131636462306263323365316538303933366461623434666331383764323362653437 +65373431323661306134356230636365373662663236393766313461663632636164313965326537 +38633432386537323665663331326338386431313661333763653934636562663431356662613230 +39663062666432353438623835376530376439316232346137653562643736306462303165373430 +36656261643135633231366537306634303637366135366439313332393561396630656136346331 +33613431346534323362666538323738393466376539363362386361353965336564326236653138 +30346239663036663536383662373166316430386331353630366239656361323266333566383135 +36643866653931373362383763376337646134656631303766303565303338326631653135363466 +66313565353965373463343062656138346131313337396461313363653636346466393764356438 +66653139613634396464326564366365376363306561393331326631383764396265636363316636 +38346637303264316233623931346534633066323132643964663537653265633932616531383236 +62663536346130333031646339326432653662336333333263306431373633633861636235326232 +34393234663066656662356463343532633635313931336136353762656439656666646265353235 +62636135386632363237653564383131356264386434623032633833396263373438363565636132 +33643735376630313961633362656530373537633165393631616566663232666339343861376638 +36333834373230613365303634373837623165323938623539653931626432303234373764306434 +62313763373762636430386463363335376563333363323736343033353439386362383833623937 +61396535376437653766303332366463363135373263626433343761653139656439343662313134 +35633439326132366230396564663363386530623339613733303464333132616363616635623532 +65303962313237316538326439656130303730613766376539303432323934343865636130383066 +66303539316664383233376365653139303930663634393835323661613038633237383763316630 +65386237646635633065353039383130373333333338386333386235323632313861386635396336 +38623632353134616635386337336661343939383732636466353733376233306536346533663533 +33333430373435633765393063396132333465323164366430393831646433306331636566373166 +63336534343331386232626131663065356638333137623138646233376266633635363261376230 +64656230333832633631373061643439633961336639653232316537343439336633623063353063 +34363630666363353539666138363535613136313366323830363539336637633930303637323566 +66396661353935356231353331383439643836666162333532633765386365363435306236666230 +36393365336230333637306332306139646235663432313833313038373338386136383662326265 +33383266643737343632376262303531313235633962653266663539303264653035303833663430 +32656432613939366134306161346363663736306664366161636534623133653366366336653333 +33376132343334663738303535663537346431346266643538333766383235626336303539653334 +64663337613535343730326234333233363166353534376537343736306234316162376436373530 +39313862363766346230366231616130613035306537643133336161656334363139646262666339 +64323663343233316531323536396131376334313866373733323735613639393138323166303565 +33326366653339366538353861356464623039356464653165626233626332643038333638323765 +34386335656164333532313563336139653464663935323631663164616537386439343032623434 +64386430336635623036303264663631613138343761613530666162303732386366383337666537 +61626630303532353464393030613061303031386234643331303531393630626331613739663832 +30373731363039383035366466326235373031383363663130663434396234306639303461356265 +66363262373136656435643032356634373034373837386530666565346261396230636663396336 +64303731363962366535313133306537336166346265343437326538313632643963613634313861 +62656635323933653639386138626237313733366365336339613963303564323930653266396632 +35363738643464633937313535333231653865306664326634646564623235313531386136376439 +66643031346464623862613839623765356263346664646361383637306135663236656535303333 +36336265353838383063316662323638303834343062643961666662373630363866303035636537 +62663934306365646364393937373332643138643535626566343932336263613732323665313736 +31663664633835323236363835326536323463316639653364626331613130623739623032303966 +62366663316664393132303065623332383064623639333561346365393431396330316366333534 +33633966653032316161313164386638653864616130626364353730656637326661313337386363 +38336665636432303461333239346134393731383338303032366237383039636639353866363831 +35393638633534333634656531343135333662663165326438666235306139633265346164653664 +34666162636430396165373635646532653735346436343138663231326665353763326539633962 +65653139383835336535333835356336313763346335336362643138353435316137343633333662 +66636539363862346133653832633136653665393536343734393564333366323563316134376463 +65343034616265343065343362383231636432633063616562636537343737623761323836396632 +37306430336266333563633239366535376637383534623032623230323132326535643736376237 +31313633326230303534336366316135313433373738303934393066363535633662663861646662 +31366338316432373935343137346664663164313739653864373466323132383935653166333962 +64303038393434373536323535376437303631623862646366356563373035633938383730353837 +35623333633566616232613130316635643863633535306239643937623336623238393066353466 +38383131373165363834303530653632373333373936346663376263353337643439656338616363 +63323235396537636435346665623838663564326263353265333930373366353130303663626634 +63666237373636313436666631346333303734636134333632356434363737386239623832323031 +66346339356336613466666133633932323138323234613238623930636561303538303532333336 +33373165323031356437653665613733646461303930386466636431643036656666343637393932 +66663239356562656633333439323962346232663336333739363065346163316164316461373464 +62626462663530363030383630643838646334653234343039323134313337383266336432333931 +37396234363261653039646236366462646632643263336130373964323066306262316363666437 +62346462623038373861663365646434393161633739363330626339316336373835616236366633 +33386666343262383039626664643837326336316235356537346463336433373435636132653330 +62663339613636613965393231386338373634363231356661316136643933653531396665343963 +64656262373839346664303463626536376235373263643236373030356165336134623562396364 +36376361316261323862393065663338323139643066363835613362636535643239666538323334 +39613336366438633032613037323135376532633130616462616335386263653134306236666430 +39643337343232653935356133376637613135303837373639613864303062336564393531333231 +32323533303237353530303765613262343564653532373738353036623038393766366266386536 +34323661366464643466323264633864383733623366383262656364353530303936323466666135 +33633737643637373363303466336635373762343665346234393438646137646364653139616632 +66636637663262663139616561373536636139346163646138333264656262396362653062613866 +32643165366461636364393863643338646465373265653766643331323933656435613865326434 +32303134653266363034323863643965313736633537393331636465313161653530393765643739 +32326262656430623436313663653239396665343739383764366262646261363862623065653733 +64643139346261323261646435653539323164333838363737356463613930393561643837623066 +31383466346338323530303137343564636636656163623161313863633839363632303635306536 +65663964333937393565386330653138383433393834613965366537633064316230396232396635 +31383536383337353166343337316561313064376138653234333264333635343838616131633561 +37313534376536353939343866356566313466656263636230316465376637363364653039336165 +37636663393466383634333136333030383138356661373263633930643430653530383734626466 +30303538313331636439353231343536356566363564336533363864623635616366353530656239 +30356330376664653134303334396235306331643364376337326133316439333763303734333633 +37303438633035353161353539353139376635626635396462653061383265383931623335386233 +39366335616433363762353131396430396335643138303463653763396435366464646436383666 +62376264636239373736643436353535643039386532363337663536633434383533323065623463 +65363635343261383365323961306466643766663135656134326331383137343139343331656363 +38643963613264626463626235333861333363363766326239623539346535633431363632376138 +33346339353434643166326139626565666438396263613436326261643734663466636239353462 +33393230316162653534313733613431353833663561666330646461633366613034383632386533 +65656463396534663132353434346536333538626262653963383963393536353632393236336132 +36393664353461343139386264663262383865323566663961316366333364366565346437386566 +30666530373530323838633738386662326331633933363031336636633261336539336234653364 +33396161326531373539373239343839626363666262313035653564626530376634373361396234 +63636638663161343735333937336439343135353539316133393261366162623534666335346462 +64653964653030326662623338616563623134633263383064613736643663303035626234316237 +31323435656136646436613938323131666637303436326465656162396239356237633433346163 +64393731366161343439336264316338393261343363303162646565303631333561623739396331 +39333634303562656234643231333932646234306162366366316234383630346538636461323064 +34386438326361333938626231613266313465363762333562626562653338326462653731363437 +65383130663462393634393966306464663436353333613036653339613765643437393136386237 +66643739333630353863623964653064343734343863653238633436313664343262616237666538 +37313631313631616330386366663466323339333935366463316631653737663935373466306636 +63333538636465663037333039623734623630646138643532376631646136323834376536666431 +66326430653433376236386633643163653930323839366333376638663838353537363665646235 +66343361326635356436616437613065636536393438356366316136646661363130376261623665 +37313332613163646164326463343566336465656334656634646265653335353332383361616261 +61653362626462663439316439666636313239373739386431363066373433333761383838326461 +37366464653130356638336635326365396334643732313165356462353939636239343835653236 +36643830396565633465626236363462323263383566653835636265643066376438336437383538 +39306665333432343164383134303531633639643062383461383237346132623663616466666465 +35396136316166626334336638306232343337356337393637666639373838383131366237316664 +33663835313161306662303265653336633332343463343034326231343632613036383934323038 +63333335386138323737316561633135623164363563666533653765613736303835306434366531 +62363665363061313366613134656465343035363863303064666138363763633434646631396365 +30666235616537623663353964643335613665623831653636373436386665656230303031623232 +39323664343339633430363138393232386130633137323430346631366661313837623737393062 +37333930393161663864386538356537643439313732353062623237323233623837323264663461 +35306531313635333839343239323230666263393065313765336438373164386463646161663836 +66613132396162323530333932396664306232323134373466383362336265306136373837393865 +65353236653730386237383361626161306634363435633132373330323964363633336335663739 +36613264333963353564336434333538663239653235303537613536633662366236643235353633 +33353165333239373034653631613938346261386336366265386134656538633237306633373137 +34306134383262613233666161386264663636656338333863303434653061616665663834383263 +32623364353263363165326137343662363431323239333638363632616333356135643330376331 +32626530333064323161653362376337363038633664306462633230363534316333623032363064 +31643239346436383836616431326333666135613234343033323833376562343932396635326330 +31363539343063303236633465343266366464326164376532393937313463376561616562613832 +61306662663337336231646661663962373463653232643832393465616134316535313361313364 +64363832646564333139376565653737396635383961393539326562616166373739363734656137 +65653530663566336332376639363035333036333939613639313735323138333832626462623836 +62303032356561373063376231653032646565393335373761313635313636363134306539383233 +61303364353662643763333138383930336666363636623730616566396362366539613666333034 +65633766643131376237376139376536363235653266323963366335306331343166336362666461 +32616434373439396131326436636262663135303038663739303130393033656264656634313737 +38656661353931383763613063356631333465353739666532646535383030613534656164663362 +33623861663031643337376663346137653866623734646234333230616236666561376135653536 +65646266613631663335353339376363353539313064373036383933313065343565666633386361 +65343261353035313234616462366136386362346531663735363230323933373939663336396539 +39326135316465383830633939393437373262373639653236666239373636343633646530653465 +30343634656639626338383335373432303136636138643063393664393864343831316639336335 +37633639393164666565323431633931333337646335333633333339356639623832303063623934 +65353362383636663935626130666461633661663137636631343130663364663931316464616361 +37376636323432616138303634653735316134306466396436336562393536646433343934373533 +36386264393563666662353237323835316633363466623338353365363034366130366433613736 +34326537346636623162663939353839666431623662646636313864336436626161643062356439 +61333935653633363336646237633863626663336132643361326464326536343035346561626465 +62393732623966373739323333316430636538386635346634323531333636363437313532313132 +34393966343164303835396333646537313962346461663162396461303631666331646235396433 +35626162343834303234383038373033396530646563383933323435363132373666323961373965 +33646432386563626530613332643365393438313538393965363962613661663161373461313361 +36313033323235653764313563666365373934396463306437663030646535376163316336333534 +30356562376261313734623366616635313862306331616662393136663731666537646535363637 +65656537336332326130343965316232306333636232323831313535613033613130313436613232 +31643834313766336535373933393333333633363633313838336331323163323930343333666438 +38633962333831626434663362303133326336333534643433613930663865633237366431616662 +62353561306434333264626238323531636632353239303963366336663162353337336537336664 +32646435373139363639336638386331386266303436386665663361383766396633303831646133 +32323863656166633734356463356131313333623936653266653339343534366632343335653839 +66653232313133313863373961383634316663313438383333363361643536333638383630386430 +38656166353538373533653661613939373266376630336336373562663638646331323134646435 +37393864613736363861666435636232653038343935613136373733396463633038636233656538 +62633131356532653836636661643437623261313330303039636265383366623064343163343230 +39343664363735633264353530653030373163363664376262333564316639323439363165363261 +37386432396530323237343938323366653736346534333732316636653434383139336365666536 +38346630333961303763363934363239373362366636633536623266353836653462343839363462 +39343531636130303363343662343965646333396336313065336535636461623138393137363565 +33613430623536323435333037613437623163396632363663326431653533306632363236633939 +30653632356363366236626432363565346133303531663038656433313635633637653766666632 +31353638333638626137643830616161333731643731626666636336613935666531323561646637 +65633131313236326363623537323833333936393434313237316164333434303236353034656339 +36323231343136373862643339633939653733303138333431656530303433373239663166306437 +39636231666131376131616162643436336637613062386338353830393263636531636361353064 +39373764353161386437316536643433343861653536643837623562623135613464663563643930 +62373638383036333266373064356634623531366266363431386664303837343563646535363531 +66666637666563633162653961346433633135613538333738613633346566323834316230353232 +32356133663761613066616537356534613965376137636166663063636665653834373338343638 +36336333326633613832356435393334333265363933616633616334626433383165396664646162 +33303930633339343264376564393261323132373730373836333434626435303033383930643966 +62343437343063373030383930656539613863636264333131623839373961626264383734383964 +38313435376363343038623463643166373831313838303566336133383764613561343932366463 +31623836373130363336656662363731366335366261343965623338643865626534393239383032 +64303864333339383535613739373431313135633833653438383966346232366339643237393032 +38636437336661333836643531623164306264656331333338373462313366313037306630386635 +34366436323737383365316436316136313234666337353966656265626535376631303730393835 +34303964383661363635663566313833323632336263353763383938633035633432636431393939 +33666561643562303866653363373065303664306534333034363234336331376261626132626566 +36383231313362306236393162373561386233313537626534353463366139346139666437366235 +38323137303566353032623866613237333032333235663663656437343937653932666532356464 +66653437383364623734346632643536356636633637643634336633323637653835376533643462 +66386431316132623735323031303031623835666636396163356430353366343438383864643532 +37313339656436366361336163666562663865383333376166343961383837623833343639343463 +64386534353466323534333535613566633838386136376430626539646539623865643862333737 +62366662393462323665383330393635343938346134653937363462343137666435366233303634 +30613739346162666466653266663530323339613033366238633439333836336561356239633537 +32343462323831643034373666316137633263383733363738666530373137343861353136353131 +34356333636132323134623163656362316434643563613836316161363863653631313366363034 +61383363653062393933656664613161656365356633376465333962363732356438323761386162 +66313934666563333964356161623133356464306163643536326137306566306134366664363364 +66626462666132366537346563376461326137323561313461643630623266633131623937316362 +39653232383961326531393864386538383666633532333638343463653736333565663132333735 +34633438326634323830336164396463646363393036643437613437353236373565316265656463 +30633038346437643664643439663537326132303837363531363230303133663063353763656139 +34643838623835373032343961623365346538343436363538616631383637626261313137343338 +63356463633230353166613063623462653539646134363238373434303761386233353236366336 +36356563666339633437633633363130633963383361343261616433643332663639343463343832 +61663335633434633761333834663364383532376536393062616261323735623163663865613939 +65616565303661393734336235333135636534303666363565666139373730313734346537313833 +65346636393564653338323131383334616235646165343866616566626633316665343038653734 +36663031653962393639663863646338313035346637613233643266663662346537653731333530 +35653563393832643666376439343630656233613565383964663039313937393139333665303061 +35353062366333343961653865623031623134333633616331653566373536633161613862303861 +38363534343731373463393832383937636636633735646664656330343630363038636332633939 +39623639393761633837326565646361613533303432363935393933353266623939326132623133 +32666466393638373662333535653262666432663034386261643464656235623366636633323161 +61336633393466613064643765616331663432373162313230386638663938656266373035333130 +39363433623932666265653731323031633235333761353961393330346433633965373161356464 +37386130393738343135363564333831373864383239643533306139626638323263636436323033 +65623033333834376462366366323039333933396435366461306566326338333637343935373765 +39323734626663623734316435353534313737363737383766656239353361383031633364666666 +32633234353330303630333662373462633765636636626363666662373562303934633636323038 +66303966616163303630306239376539656266653434343437313665653462333534396132396538 +62346261656237646236636536333833626561613235643132613735633366356163366462323036 +34643839646438613838656433323533383832383630626366663638373835653935376336343263 +63616438313061396565626565356236393131333762383030326337356332363239653238383135 +36333737653335356439336431666632356337643133656636396433666265386538323366393432 +62666661333934336266623166393037636261386564313038643263626332623262653365653536 +30333264663431633264376663633564623933393663633633303633303831303163306132326233 +36323761343761303063383637346134353266353930373934356463336338373138323836313735 +62613964623963373939373438323563666330666662303363396663353637633531313761306566 +36373730313233393434613664323138323832376664666565303434613964656233383232646465 +32646165396639616361333261326262383832363339613032313466663330343461373035363233 +66633133343237636434326538363130306431346365366638366335316466323536316131613137 +31613235653264363839613163343563336363643537363066303131393532316635666663383161 +61333835386365346131663933396166643636646130306366383337323865666164313734656366 +34333634663739373362653266653361313333366165303462633939343165303761333239366133 +33613366363366383763393736616637376239666261373435616533323861643439333865393533 +36633232336665323537636535303538623534623763383836636632646365613338333962353061 +65663262356336333939336339623366353538313437313533326434666161316337373962336135 +38646539643664343164316130616335383764326363616138393562643264343937666339313535 +39396163663064303632356139313834626638336437373161646463396166356163383536366338 +61306565383361613935383961666537396436613732386462363233613834383031396232613730 +65356331363139333037643435326662336331333162333832393031373065626630626335633262 +37323364316362653038623135636666633963363437636361333164633430303663623431336630 +33313939663236626639376431653831356364313466616631313466393436373134623565633333 +31386631333933316231346431636465613233376166343066323730396233623266653430666334 +39666166326430623562383261623263303432303030396361323338656262386466336561333466 +65376634616364633833626466653465656662666135616363346662343137396536666565316633 +30383838326162616532653735346261373334656533653132393862376265636337393239383864 +62343061633266363635396463613833323364323235653234313831313039613633396639613735 +62346436386635653063353638373261626234646437383239353739306462383762356462633465 +36366666363333643762373035306464633364333865373061313566363231646465323436643133 +65643032313234613061633365346432383933633537323831303639396164336236656266326639 +63383264353335623038613462346637356263646363613439373766376238653532663037303132 +34303137323134633230656265336461663234393633623730396237373134353766653934393533 +32303262343732666139643635643265666235653235326364353639336635313236333437653436 +64363462336362636338643939336665353032383231623833313831343738613462626533306532 +61393637613036326236376332383364656561623136663530393933333861316534333961323561 +64656566613133396261363966633036313238616332383466663564663166366539616334336636 +35643532346436383039376464323539356664306234373738333031663531656535326233353535 +62353432656438623336383030353861363165326262326337653534336566306461613761373366 +30386333633562373332326265343838633864663931343264323334633236663962343239393130 +34396534303133613634633233396163626565386564333739663931343537346561323337633737 +33386165623039376534313963353039653535323538326236386466306338326532356335383632 +39366166326134333562373732393431646536396237383738623132316132643731653335346330 +65623039376361366361333332353135636130663061653939623231316263623961613035656532 +62373934643963383062336334303238373234323135383062613431303433666331306138643463 +32353765326332653731316565323230313066376166303335623562646433646662363664373963 +31303838376335316430366661623532343134373761336439323964383731633532666462393962 +65333839623561393431363364386163333433383165356361326364626663326631623330313163 +32333635313031336335633862386636373934333733646162343733613166653763356431336665 +31353731363134313337366462333631613638346334646630666432333433383866636633343363 +38373937643738343466336131393865306564393062383032306239646662393065646562313061 +30306333613532306463393662613232613236396632633932623033626434623534306637383432 +62353635373133656231666335636236383065366533626231383865643539376139623263313236 +37313538356233376335663363393538646432396335343239333133313164653431393231656531 +32313331646463653366303937336361623765303061323436333161393163343531343663353136 +63616138306632383136306331636665613837393662373136616165363132326463353837363336 +32643030376633333937343862633230333763353466323032646533636462363231653136633962 +35346165343435653437386566383132653565313466306265613737313935313535303339306533 +37363833346661343732366666363266613263643666653039393062656138313030316165363838 +35373838393566353736633434376639613930646532376338376534326431613336653932373431 +32646361633265626433663363393239323631663032313366383565356335616239363832333638 +31363238356336643561353539343233303137663334306337343562306561326366383838326131 +30633334323836373134653830663630326364376264633735343762323434373936383735343863 +34623261363763343635396361623731663937316161373737636263316261343935643162333531 +34616464306663356537646537633638303662356163383835366134373535323864343864663864 +36613164303136616233666634623230653438326437386531333262646634383337333931313630 +63303964326263646539383161373736666366643366626565336564373666316433306437643939 +30346361623566633033333461346636636635633038313637376130396231626362393866616335 +35613639613833386164306363366663633864353339353761366463643764333365376463353837 +34363866656664313431393361393732346431343732306362306338386135356137363439646335 +66333263643139396466363231623866613166386133623433646636353434653839643938343665 +63396639363435613561663762383461623737653738323165663230613439386233363933626239 +39326264663334376539646639373737343062323063323937616138353261356236353536623165 +32356334643836666337656434313838626334306234353462336166643165623739376465613435 +30653033306464643738333664323066623731666338396332393233333239336165626439393936 +34303235636262303431363234323461316166613332666636343863356436313234383036306337 +33353236643233653138306138303637643236326264346164343836643265353235646264346164 +63363335633731656237353461363864623033323665386336333662333635643634626436306263 +30303232326535643337343533613665326135316234376464313866626237363934306233316462 +38343038623261343435373638613834363065323139663636643561326462643530306562303533 +36346537373131376362313061323733313931333533643436303034393936336361653632323131 +61306362326162343365353562383964313934386565633830653064643636343837343763363862 +32353039393266366538313062323535383635626365666531643035376531653631363461373435 +37373030356138656237663738363561663261396231306566383033616136383236326633343935 +61333566643730616439366364653637303630316231343766323839386532343434663233363735 +35656261336334343636313933393038316162633463653137613264353034303961356533623566 +65373932633932323936646132346630333430393130353131323635306232373730373836313632 +32613832383862626463343634626534613534383230336363316362343165613138353930353131 +65393137363664663361363562616130343531323361323338336535303364376166353936363166 +35613732363137643130373264333433303637323963626637663035636532366265353936616530 +64663932323538333863626534313266653838343136373439623864393033396630633230636164 +38303335383463343038316235333130373839383261373136323337623965353730373332663433 +31613565366434653665646637656361613933356664336134373839643435613063356465663264 +66316266626436353265633766643233636362393761333234626330393632333661666239326663 +33646337646632313237616631313139316330656333303439343430303637376366653965636536 +37393439626439613066323137666238366561653834613339626631373735393533656133333238 +37313431353762633630343239316331303236333836303732613933316639323633393730386461 +64613833336635653038386335303234326630383030356633366434613964353463646339363539 +61636530626138393539613732633764353436666334396436653535646566656637323734303334 +32656433313133646264313133623166313537333235393034303731663635303634333362383636 +32653061333962326138656530643339356138663264313931396661373037666333376235326637 +62366366333033633738356163633462666564353662346364376663326436353736343261383362 +30356435386335623062306566323235323530306432336235613362383066383835363538393065 +66313233636238353930393335356231353137383835366235613364623064623166393165643334 +37373738323934323630636264653736623766363365386530656461643064396637363531633136 +65396236393135336566623266316465316634343866356139316234663161303466653564323061 +37666139306638363236666438636564623732643837333333636636346636316334643361386538 +38356533633638663565373632653634636363313332316530373635333934653963333564623866 +38626631653764316239623438353761663232316530666261333430366466313064333534396230 +38646137646131323637366237636237613061633564376138333637616238383935316632643836 +64313131393438353332663336363263653666343963373565306230326130393662303464316538 +36366231613733643331626633383264393864323933663338366238303137633265326432663465 +37626464373737303034353561356438383364326236353536393863653035363031313936643332 +66396166373537393136393932623265373361353934636165396261663261633537353062386263 +33363461636534643636663465393061313931366532323161353230623237386463653865343761 +30353737373933333433383561636639643132393566326337633563343038383234653135623231 +62663731373161316461653433653334343939656231376438323861336665306235633765393065 +38366538613436343565623238663435646165376536366364613038336436646136333238333866 +62363537393561656138663761623231666137663034323563633835353465643038333762386265 +61333564373831326263393239613061656130333836663533633966356439313636653533353235 +66613130323964353061663939666534333436373937346438316138633965343037363066316231 +66313462626536333538353233616234323562306564386133356535666536346433666234616535 +35666538626439303162643631613736376130343363613265346437313832666466343334383034 +32653533356461653437626237346566623061333337656433393662353633666564613564383935 +62393037353939626231373534316232623864666664366636386530313663313132356461376362 +61666134373562393434663865343230646161613966333937616462353862643138343266356631 +38353039633966303733633332653330383138343037383664663033346537313334326338316436 +39333438353564643364313863633032633534353063333836643765393236643337613162366338 +36613565383236326338626335346662393530313666613266643066323333343839366230656661 +66643335316666633132323730663330663330323764383635653330633939636335396333343634 +66356432306436353131396639626339613731643937366539353863636638656330336339396539 +65383961623531313034353235313436393237396163333637333536383235373938633937313066 +35353732623537323137373535353035656466383835303135366234316332356463306331616161 +66343662373862363064616464326332336363373939643536393938623532353738633539633131 +39613164373163383332653766613935656161333035623161366432383739326461366464346363 +61336435393631656666363663356433346566623831373432353032323431386466333837333466 +65333838306438613861393166333038373832623637356435623439646237333564666338356334 +34323762643136323332346332356562303231623366653432323937643636363437386433333163 +62363338306635666161616636626436343831636230303963633462343432326237363564323464 +39383764306261326236646134303831613731376565663734623438336664336365343132386538 +37353261653439303664303633636238303865613631613864343932646161336361316338643162 +36646337376232383435326238373766646534376466363930373766386530656639316261396636 +35663864356564623634663066326432303532373037653134363264356562366639323432356639 +36383463383335663539333736626431666466343433316133346565643664636166613965396130 +39623061363866663331323334653737643134316663386566653031663234633566666164626530 +36366436366135386637656133343237623263393861316465366538653039383364383561373565 +63303766613839393432626265323666353632326432356531303533386537373532313337343763 +37373739343439366566373933623935346233366365383362383732613530343336656532313466 +65643735353830623631353235623263653239626339393661323061346234306662643365653435 +34323262393434303832656465303035333635623436663562393035326235393930333961333535 +33666330646235336237396130356139376665623938353034373831626230386166346337376163 +66613631666536303338333930666237383638363134356366396266303130613935633263373066 +64306237356534346263666134363237306334343764363234636630633138383837623763346439 +30623834653739656637616438346264653439313038633137616466383330306234366361303530 +33623161316430663630343239333263636137653538313639623865373861633665366139383166 +32326436306438373964366666373962646162653765383063353834313063663537636665636366 +36303038616564333862393438346466313232333663353565616334333636393963366430313339 +39636361376238383963303039643735303838663565343366353262653239386136643938643734 +62353636333666623664376163353265393163376330623833306338356439343338333437643465 +36653039346337316563346366336364663332353263633433303161383533326535623834363533 +30306333613933656539643837313465613964623565633165393135613666326131326262313066 +61626434373638363838366235333234306633633738326330666634316361346262626636383033 +37386665333932343864396231303339666631336362653639386635346638646365633861346266 +35623835353862656335636461393163656264303665383965336465396236366636306435373061 +62393535376332393535663734373131323365373630663336353534666330646266643233646164 +64323332313539376134393462626235353139396665326631373631643535383230376631376364 +62626237313237653136643733653937343139396466306339396631366666323963316365393665 +62393438316437356331323131396638366136316439383637623831333231353962653661376530 +62306462326138633861326435393937323265303939373864653135666564663039336533326661 +39336162353133343864363536366333633637363237656339633733626666613631656665323531 +63393636393733303163386464393239323836323137326632633236656561663733363131663261 +33303833386236396336376262316330613635623864383765306562393932633639373630346130 +39613463646465303637376462373438393535386366643739666133653931336435653332363336 +61373639616638303661393739613930333732376635346531656665363262623163303332303234 +35376464333765363634306436353863633337633263323563356635616236303231353631653632 +64383262386237363635393362373961616433636131666236353432613832353366636363663836 +61376562376166303139366336303066393565666333346639313939633364393538336563353335 +39353038666361303731616635643062636637626636626639313231636437366530623666653031 +64666536613531383131626134306165316565663264613335613131393766346562623963626534 +35653561323036643235626336366536316163353736356431343730336365383365656263333235 +30303765323630393937303335663034656531373463636438613137626432396432666630323764 +33343439383235623635366364613961356164333330306166653966313165646166653666376366 +39323632356438333265653036303638343365653163663534396664333866646432653932653462 +30346565643539616338336435376239386539383131653730643632356539653036353164396334 +63653962353561353134383062616563643639353732333765323732313330336635613030343865 +34343434363639636264643035663839376364623634626262363932643838353232626133356164 +32633536363465356639363337316139316535656434623661383034343835396463643630643931 +61386662396633353863383234626630656235383734336431633338313532356462306331323337 +62376439326339323337656662376235393936333832643263376665343961396564656366623061 +34306233316565663462636231303764626234653533616537323538623735333335646163353665 +61663438646663663935666261343366616134316365383332623866383739613265636531336134 +38333365623930393764346436353833366534333533393933316431333634346538363133386434 +63383133613430333630396531626266633834366239636235323834333537343134363536623863 +33643334623431396431363030336531386333643636333537393235643430396133396165333062 +62393539393537383737396664383561613634343765323732386162393232636437333830343161 +61373738623662653935356464306639393363633636366261383135643837313534633665343963 +64393738653532643836646233303336366230643862343864336534626334343130383134356636 +61666634623166663530623239663765646437353832323132373930353435663462393838623332 +32623261326661356463353963313935663564363438366664653936323236643038353064666231 +65643539333138356132616132623862396339616166636236663234396634616665336565363030 +30633061356636616435373135666335623032306264306139303764613433336235656234396232 +35633131623737306138616262363764633561643334633865396265323936663466633937303735 +33353336363966306539666133313566363639383538613465646536333534663931316631323230 +34376430666631646537343639366334613765306332363432616134376563373037353764386537 +37616266656464333764343235643333666266333630393366393832353565306261386663333139 +30666433343662376335343838366566383431393730303663326162643236396132653962376564 +31363136363463363366396462623964626563653637393733303230343839323337623262313066 +35366161646538313765306464323837313630396633613936643264356134666532613932346637 +39336332663336613964396461306537653863333963643437633662663634623135353735323961 +31343632636631623737643164346165623263656364383266613061663136356438326231636633 +39613237643465636630353235313164633331356333343435633435663737323966346133303137 +65623736373062306438383533653537623638613564623264363365323436373533316236323665 +34643862643063396537663830646232313565396532303735623332383066643231346135303239 +35643332333237313537316266613762663661653561393763613536646338313530366339633366 +31353037396535323038393937373466633830383833386630393832366234336338333665303936 +66656530623162346437303833323430393936396430636661326132643762613063336236336164 +33346433343335646230313433316336653837613063346537643264663664623365363465363631 +64366363376465613631356331643930626261373762663466316434373934356662666337386265 +61616161636435363431646337643835323338616536623530646138383535323536333138636466 +62343134376633363136393661323333653232303763353933316236373737316264316332363464 +66373066633166666638383263666466633731643165613930333831386466386264393035643964 +33366263663732366233383038336336653332613637656663323839616134646362343735373336 +33616334626433616235616663666439303365316439326438306331356630663732383962633763 +38623863626562663034643664303264333136333531656638373461346239316136363364346632 +36663139396532323330613634343537316335376663356134663036643863363563366137323965 +31336531396464613066636530373832663962666430333039373632613366653435366664363332 +39316236353236333638643637333834306133653833613763356365643830313733656266663835 +62613038386635623032613862633633666165643236363266313533353930396237346164636562 +64336434366630346565356638646464663231376665663666623561386333323362386161326633 +37643037363436326666316533363666373736386433336665636638306463656334393837316265 +64616532336330333238643665363765653538333335633533306165393332303434363436386365 +61613030383665316334653761383937396562363661396134376336313135666661326662636433 +30626262383635376665313162393830393162336439656539643637323031396665376630386332 +66613237353565383932383666653837666566663437323533306164663732303863353433316265 +33666638663933646330656136383033333136663539323435383566353261336665663334626662 +30363161316537333138396538643839393038363438333037626533666563306463363865623636 +65373239386263303464396239636630623264393333363336363264636135363536326133626136 +32383833323363666466356361373934393239393638333732313838396563383230666632333061 +66643961633834356466333730356636613462663239656139613432326262383034316261396166 +32356434356332386464326239613764396536343438643031316232613632313036623839383164 +38646638316136396431326364373530636530356337366634366232373431316265653038346366 +31316361306666366534313836306430636330313862396664313132396233303434656439303864 +39646232653536633465393862383534343235666430323739633332353364373532303364633632 +33646135333339306338313037383131643133643062366462643239653666636565313531386139 +64633930663363313466326538303337663839373030653036613736383731303839323462646532 +30663362666231626538306361663837313435653632306536633231616564623936323132653931 +61653761363532656663306531343438343135316563343938646463636635393030643064343031 +32373037353664313534366339366661633463326537633239363336393138643865313738393036 +38303866306265636461386162366462313031366233616635363134393230313730323766346163 +64353563646237396463363236373730613334663736633836613632636339353062633435613332 +65316337313037313436363164643136373939656538313761353536613564333238623761363961 +39663136306532643462343462376634336236623664653531613265343934343862643433373438 +35363935626162643130303936306239336334343532336162616138343231363339356666663838 +39373234366535636233653039626333626565356530616333356362656334333839346135373932 +64336663636463366136613430336530306532666130393538313139316234313834643239313935 +38323732616266623230666462643134653436343662393539383731633538353238646237316132 +35663735356636616637646336656433303865653533363161386635303433363566646262393334 +35356664313964633432383262313364393639373065663632626539396164303139353962313038 +30313165623535643636646236646533363461373639613238373439643766353865636362363738 +66636461616536393438653232356533313138366431383264646235313462313261326239333638 +32663636643236633461653636303262336531343836353737376438336535333535323737643038 +33343231376131666431616464383262393261386230396330633765653962306333633536303233 +61313537343934643864363935353239663735633763666266353139643336613361623833343364 +64323462343931383562666163383434333435653439363330663737326536323161363263373266 +62663863376661313035333536373630363961623631323266666435303738303966663537613530 +30663732633630393636383530656431636532376363306533633164333266336264383633333161 +34363837393634613536313363313136316530623864633230383466326163346437656536383662 +38396537386664353937343066316632346339333937316337613238306566336562393231306433 +34633237313933643763326130363061386237616330386366616139383232396538306239663230 +35393464663330656630316530353535653430333637636237643766613166386634373930316134 +66363035636362306639633933323463303835346562373432663330643165616562373738366465 +61356335336436386139643731626635356631666164306533343361623031343063393836366535 +66643932376438393333303036616538633734393936373661306133326339303762636465656433 +30383230333864616431666563613238326331656165376135363430346632383664343462356166 +66343834626631323733383232646233386438343632363166383166613532326338633236616230 +62333434613761616436643130343762643665323164663961623833613134613339653137356266 +37303662363766633964396338366263653731653866613163323738306565303563396335343436 +33343834333235663039653863613133396531353034636331643437663161316139393864383064 +37336135316335613334623932333962663631356535373935613166356565356532363936633862 +37623137643838393538633631333964303439643362343063373036643666643935336661313831 +33383935336462363532646137376566383162336333623730316161663733363731393036366432 +37646531373863333032346463393932663731353261663633376265303963653661363631633732 +33356166336137326433396631313637346463656165653733376534303839353035303464373238 +32336165616661616633623034633335616666326662366262363333336335306261373937366333 +38343263306461383031313332303139336364646364393431376639653766346235383561353265 +66666538373931356434613036363837333162633935393137663634383938663130323165313630 +36396234663732303066333538396463373861366361353133346634636134356666356364393038 +32616237306233613064323836646461313232353439616463316633386661396135643930306438 +37373266303865383338646365613039623265643331626431383732383264396530393564613365 +36373063343363643962613034353931336162616530393063336537333435353561303837633938 +65633933333666666662616130376230373263666565356536383036663766663861326135653539 +61613738333138643831356662653236356537346535363864376266346132393830323635663234 +32646337366234396637363463336261353239626531393439393836323137323439643632316439 +38396561666164613130383332323932643432383265306466373762633062613538323737353031 +61313661653630383663616165353431626236663463306563633739356137333561313666323963 +34313434613661346666343832653338373561303333626462366561643464383237343736333838 +35306563323131336332303461393133373063366264656238626131313533313637666666643335 +38666565323161373737363835363838323337396437386432303030646234373639646532313731 +37326639363136323864383739396239636135346465633834303737356262353436366330306132 +31636230613231633632636565336465373864343235623233313935306366326166616562313363 +35363463663861343966303339643665656636333466646138623662383338653162633566343738 +66336131663966356464343965393937656262303131626161646564363065373563636131376333 +34393463633739396437313430646438336461633836393233646130666436643661313733373962 +61343134323362333133383263636138363333363531373363383463326165366430613338613930 +61613831636266623263613238646638636363633064633336323162366538356263363039376337 +35336463613230633236306661666532616266383939353730633334303938316665313936643230 +66326136643731323830366538326533656134333064313266363537383237383365333166396236 +33383962353638393161313339313133316337393639303037396439333465653863303136633264 +36336131323231653430353132633631653831343866323334313039653330626137356437363135 +36393763386338613862623563326437626336363734373436306230363665373461613262396235 +64623936373234656438316531643362343065656339616436326332366436393339653466373832 +64346432373030303863363830626631393536323735303537313039643361343237326238336330 +61373639356333373865656333653762383833383565343165626534623265323837333538356637 +39346332363663363039326636626333356331366263616363613463396436346230313436333764 +36336333616161383164636264653231666237373364313362313639343932313163343331633564 +38616137646338316239373164663438626136353530343264393937333661353039393230623636 +38383137626230646661656237346337656262373764636163313435346336623237333863363432 +32353263323534353462386465323038333862333665663133326664626533303564616162333061 +62333261636335323737346433326332353864396433633231393638323932343031643131343565 +33356164623930626638666430646436303266396361663034353461333539643438636664353236 +34316263313763656361333336366364663866356565306634333966643536623536353035366437 +66363839623965313261396134613361386236643031643436633230306635633031323963663231 +32303261633838643135323762646265373132383164343666363637636433636538333965303861 +35333231336135636234653239343161623731373735393830636537373039663336386232623435 +33383535613235316665303863336136393466653634373630663838326462653832343238643435 +34306235383134343765636131656134313961343437393466353361303965643833363732373332 +30306636393539313464393766633030333564613839346363306565313936363136336661303038 +35333633303864323761343766346465376331646635356163613235643434396561373561363932 +30666162646635663532343938366361623433386533663335663061323738316234373364623637 +33666363373962306232646262363364313266363638386239666235333931616165313839376539 +64643039383933373034383937306637643335356236333464653562343762653032346133366630 +32303666313830316239316138333335313033386330373737393636656163393135316465656236 +66663762303064653865316163316333646166303435663338656236316337376533336362393962 +31323566633265643630373331393866343166663564336562633636376634356337636162323035 +32373261396565383333363636343831333935636131613365613038626431333534636165343932 +31616639383863626166363231646431633561353636366636613132326137636135336234666338 +66356163643337353833306538393162343163616661623236313166623338643865643233666566 +65623666383433666166666635373163313063323935323162306538623332633665303761363730 +62373239626663363562373230383461663530643464356432333933393030326139656334373931 +35353164313161646366343531326532333934323639373562353738393462323366653139353163 +36333962303032646136303262346164306139636239363965393935343739393934626565313931 +39353537393437336232386435326634393462333833363431336539373864613634373764666432 +33626533363832643462623438393430656630376261386335636234323734636330633234646637 +34376639323834616636616137393361613132613662323662396439353637643430376464626137 +37613635346664323431346439383464626538653232643938626561393234666635303037323565 +32636235636230613265623139646665636162313461663339313036303134323036333639356639 +38633338386439663432363335356266393232666537383963363964666332386335633563623634 +38363439623564396465336162666261353239653266346665666639313566633665636161323430 +36356362633634396135623531353434663438666337633863373336623530343666386531333962 +33653061303162633262386166646566366464383232363937323662663462363065326235623435 +63383864653066343436376665616466323366666563313838343631393266303134616239396539 +66313835623330303133363536373937363263326533663165333033623830623235623165323634 +32663566646639343466396233376434343139653737353238393536343765356666303066333435 +62376538316638613066633830333861663633316135303039643332326435613966366239343863 +31656133393930353135653331643636323637373436643764343438306439383230653434396363 +36623162623538643335643939623161663739306364393161306134623130306532613264613063 +65643739643866633465363733383265626161626132616537326235393437396635353763653834 +63653566346564336638333631656166643632316264373238653132613965363636616239336563 +38633266303162353931616564373663393764386535323464366530353635343766626235326532 +62656131333036393366613038653233326538653833653533376562613937323632366363343438 +31613964653430656664653032646363666637656132626435346532376564646535643236343531 +35363837616234633436613838653166366462393138633661646133353165326262653362333762 +33303861393838613063353162353336663763613834313430633939643735666631613137373962 +30326636326231313766623733333030343632666164356132656132623836323935303734653761 +62613962656138623466336332383431336663626535326533336632333731643763353366363864 +65656138373138303037666465623065363864333464383566326462323963346666303933626236 +64363166653738326439376532353665326464376435633137666632396536666361373835643064 +32313263323232373438666538363364396130636633613636346566343564663735356534393161 +33656662383065316466343638346334366164383333306261373537313263326563616137346264 +66366261633265306636343030363364613731316237663338366436313966653637356565363535 +37626565613232353338346336396136356131343538306162343963303362393931393735346332 +37356535303165626563333131313033393539653337656139356364396266313631343765393034 +33633634666365333939663866643461393435343632656261383261613564396330366561633637 +34616533303537336136356432353464363862666461373239313462663933366663656134663361 +35633264373561303339626562656634363961663164646130643130613230353062326135396636 +33623438343531653135396564653065653161346666313765643361383736366366663038303236 +30373562373435336139326163616435343263653635653461376336386436623734373934613462 +62633366666435373839326332343331353061353363393738326333636533333634663464616164 +30316134333938353566656338333738316666336632346533663764353661613130636565623435 +66663966613066303335326264326338626431613331303665373431333432616161376138323062 +32663836306535643230633939316264316662383839636663383366396136346462643461643764 +61373365643064346634356337303338323134396636636465303234663931343539396164613232 +31303134383736383436306537653339393561666635653432396161333961303964343164663838 +37383433383061313732336233353565346466363164663663393633643365626265336135373233 +64653734333134303563643266623762343964313764303334656432643761303531383431343138 +33313533313736653334643538373032333362653663396432633263326634343238643037663838 +63646538333437643431353135373239303366393664303134646366623935623938356236626335 +39313534366466333835666264313630623664626332303263383434623963623335373430643532 +64326530356638366532386662663133373931656166613039333434666365626338643436383733 +33646361356339336633383831363833303031626335386163613163386330316637613566613230 +62356635316165306233346661343439366462376162393330646534666633653264396639386337 +39633130643933366438613033326163663464313431323039386362323834366563343639333365 +62313533303965323833306639363237616636353362326636366431333162666662303139373937 +65646563373730396531333662373063373466613931313537626332393061633933326362636434 +64636365313363366461316636666233623632316431343939306564333534383163326335653930 +65326166306532666466376536376333366131323963326366386462663332633038326161306130 +39376165313365393865616636373765623134616235663166616433303333643561373563613437 +30373963323535633865633961343065303664396634623538333137366539313465333037626332 +63313930353561646432373464396264373764623735613163656264636531383538363863383831 +36313866353937666464633731316239623137656430353234616639333664383337643130396638 +31333639656564656637646264626463356536346331316134666233303536306639643263663966 +30646261383037626136333965666530643439353030373636336431633235656134653835623465 +30316339336636663631623963333337643161383633313133666639316538663131336366303462 +61393231386134386664336263616466376531633535396661343838383032336332373637373065 +31323164633461363732336639363835386332353334346164633635313738346431363563656463 +61326331333733326638623632363566313833666166316531343330393038333930306663396635 +64313733323531373465323961636433383135313638336261643736303165653237343635306638 +31353539313764363934303464376162663164366565636264393137363265646362623530366436 +61313163333266326437336331353464323032373938336133383036383435353563646638666434 +30613562313565333834376138623733303861343132303663393432663365363133343138383238 +61663931623564316365653162653633313830623634653464396161393030313336316238646131 +36323531306435386530383261393566346233643632366564653739346263316235323165323832 +36316164303836333262313438346662393638323734616266653066343437353364323364303935 +39323361343433376538646638303361336433353331623663316134653734306663343939633333 +65323164393462323565303165646331643536323432303439313531626133353562353133386638 +33376164663835626664313232313761663934666365613439373563363765303735396463623931 +37326131656131346435303037613433366530333534663130333235306431633733386362386330 +36656564386131386163616264373938383938653738623766643737306661666361383962623937 +39653965653139353738616630623932366466353134353666343263353966383066653337363035 +30633965343162303861396237633861633961616233653130326361333564303431333364666662 +35613835333030306533663134653333636465356133353739303364353861306361666164333634 +65623738323936633163316633613534656133396461353532653633326366633537623665356535 +34346537613262653737393136373636323337316430393433656538613938313766373639386361 +35343634633731623534653566626563616636393832323664373132636139313861353262633436 +33313165633931343132666333346235333938623033613532393763633237643965383765313465 +38633061326365303632623233633235303265323637323532323065373864383161353831326632 +65316437363030313736323365636563333961363238663638343361316639623238653536616366 +36643362386137383361393535303438653630396261623861306366613863626237366461653561 +30623932396437313062613666636634653562343733303238306534616435656636633733346132 +63303865353534633264313339353836323066336362643737363932386538383365326263313962 +36613465643230313539663764653430366233373035396338366536376634386236393534386666 +62636161643633316564613833313166653136623336613239383763373233353538633730616631 +64306536666163303038386130393865653338623539383335363731306333323561353935646664 +64656139356633353366376333376638316334316464353439333730663165393034623561636639 +61386330666339613332616330393639373133356634376139613334333765346139663339323838 +30626266333636663035366432333530653835376135656136613634623030636330656538396237 +37363735643739373664646335653038346361656635386132333837653763313665373938623662 +31333831626665363463653438396330396563366363643666343466393864636233616238313961 +66326337333737323131646535613065633736666137363135376134393631386464363239303239 +61623132333362353131333738316162613633623465326334316533323230626162306534633361 +37633031643436373634393066656464383232643935613932323866373765663764636663323336 +65336437613639653063316264353363653930333530383737386237343933636337633639373335 +31663039663963353733636537326439323765643232363933353939633136393836306464616539 +37376438656234663464613931663238636131313935633734613061636538643461333332313364 +38356433346561353732323961316362613031346465313761636261653435363634336665663539 +66326561383137393161353439616337303237366230336264633333386530336538613566663131 +36396236303034623831336136373431643236386236373336333738613062333035386436653164 +35346366383334663962646236613133336635663636636566663264313236646530383334623637 +34613465363465353430636535613839346130383531653264393531393733346235326634353936 +31316165353937363031353061393039343266363438323835643131633038363231336132326639 +35663831306265643631623265346637363933656137653163653962653537353639613837643337 +63623133666538343630393239663733386266636638316337336135323533353063316637383036 +38396339313930383665316638323238656133613135353566353035323834663164373839366365 +65613931383633303532616433666531626565336138366637336464656234306633363238353831 +33633739373062653931626135376264613732666632616334663538376362653832343836363165 +63353062626661316537396431313237383039323664386165376137363039376532396330323532 +35623136333331353836333763376431336238666139333766383536336638366330613535336334 +36363939343034346533653831323436373838613931303431386439356661363730366465353739 +66323561383530386132323861316531623064396166666465376438323461613338383864313432 +62633165376137663236333837373335653534663662326532326238626233323137666238383739 +35643630333465613637333330383434633762346366306165636333623832346532326536656463 +66643166323038643964613465643634396438313963653336343265373362643036366164393030 +38623437346533343264666566636362333731316431393238653537633834336163383430646634 +65643631636631383530306639633336663335373962363236616564366332336162353237333237 +65613138613063656437343531663161636535303933653262303431666163613730663433363337 +34636663323064366538656562333337616632643463666538333338623063616132366633383362 +62306161653433366666373231353463623234336338643763353530363831626635333631383735 +61626337386433393633656533383732623330363836636561316533316538666635663932323134 +32396564633766393138653763653964356664313036373531666661333734356665636632336438 +39343162653038626635393631663436623738623537343539376264623738666237333733366166 +63653837393737643639303063663530376338363835633738636439363465363337363037623137 +65353134643861373134623861653939633236343138663733373566323836643464663562336136 +36383336376130393530653136393930613837373937306439366632363032333838653935393038 +35373136353033376335303764633065363036386662393261653466383739326630363838346531 +61323337656232386663343863313563613663333962646630343861383362633239346562383236 +38323633316130373364633937333237383631393039303830383130666463613739333663363266 +31373566396235313164323035356165333638336639323438643435636538666430313139643639 +34343131333939313631623363343962383365353963373636643332333236656634373165633430 +32306134363662373362313531343439343362353830363066383637333635333832633738346235 +39633932626133333936383135376330653961663534383438666163313161643338633664343665 +39303433623461653434386537626363623064656333653739376466383234383532626238666430 +62643862663737613937343133373535323033656431353439343933323434363561366332653739 +31306131313236653663656438396232346533653633383665383933323036333339383439316130 +31653839306237323439333163356663396239383963316532346665613166396331386361666636 +32653832306432663335653136643963373737373537613431623766343030626333383636326639 +64623035623330363066643265353665393163393433373534643734373533323736363336613730 +36306637653038633062616164306464303963313233333661656563653331333662393563356338 +35386466656665646439346561326666396163343736343862356466633233393330346663626437 +31363231303333376337666361326137613931663033373734613833313436333936323832633363 +38323965373037633630616262313961323337643637363331646331653637333437303830373337 +32633938633465323834343939333736363435376361363064383264396363343330643362616438 +66653330336238336137393166316530323033396439313337613661633733303237643339633364 +33643464633632383837333564653163366139653938333230383565373566633265343435623934 +63653361393234663162633631353363383364663765393537313838353239653036626435636535 +38613339636434636364633139386162323033363261626639626339656365393038363664306531 +36366132613661303635393930306463343566326561636136653463666130386232623166653066 +32623439343766316130353530666331333037346432363135333733393935353136623630643531 +33666638366663373965373163616261376165653866666336316161353433323535303338323463 +38633662653336393361333062396265346134383532376664383636656639656633383432373163 +61386165313166386135386532303438653631333765653266336339393231323736363835333266 +30396165646430303534313031623733363833353536396130393061383265326131663662656465 +37343530626331653131323866313835653937303461366661303962323639643961306633396132 +38303431383438653362623031353066353836386131383238613231303130626232366263633864 +64623830306135323235316639383637396139633061626165363865626239396462323936326362 +39646631383666396232396132616239326633396166666138313436393662343835383461613932 +33326536373665646132666166313434643438663938386530383962353033653234333939636430 +33386338656637393135393765653639626561333035666239373632383062633039393032616133 +37663631313734646664643763353130346238643365313163353465653833373338363265646631 +37353766613964616566626531316538376237656539646364323232373763313639306166633566 +62633339376330366336353163646430666633333863653861383135333637393433393236366136 +66336536346365373935343432616138643931313133343263633131336130626234353865626239 +30313735336466363163323037313262633134383039343233333238313966386563393930393132 +66646432653037633132373534633066353064343031373734333063666430393531636332363738 +32613162643432643339646131333032343166366139613164656234353833336465353736386364 +36313535363734313833613436613139336266393765393963393934636235663237376164643538 +32666536303431656161333938386539666336343764396431303630393534336661393161616161 +34646439316564633932663162643766373663623438623366626635363664646163356537306239 +66373162363533376163366631623064343030356335613130313533313631646264653338333865 +62333439323062366365643033633165383034613833623736656631363233353232373965323533 +37326137386136613639396564306138363961623933646566343936666666623237376436666532 +31366138366666333032326232323337643866373230636432626331353833396462626539313566 +30383264326661626561626634633932333062323032323430303539613438383831373036353565 +36303266383865626664376537363237326632306265666431376532643136386266643436386565 +34383935356462396532353763373537626464366165393663616236313730373964326165613333 +32333765303130353064316665396434333135306238366530383563396262643236313165376462 +34383665303364326166636361306235336666336139306337303365666361346232303566303730 +65386333353230636463306237666239343838653865313066656466653535316636303862303331 +63646633363530336561373566653731386665353332313032383363326562653132633233643137 +37316538643966303161366131616430363730376132303437363863663533313965366563346166 +66326362633561356666613735393761613833353064336232303335613333343439303565353665 +34376633663231373330633065316532626538353339363432393839666237303664643730623337 +62626663356432346161666637623930336265323764336137623131306237636233356437306165 +33653536376233643361633235663465663432656337366466663230633662643733366631313539 +37343834353165633138346330333334663765366638383764343265383665346238393061386464 +65613964653738373035356535323938323833316663353839383838353462376338303839393835 +36313635333463343364626366616362623834313937376463323932626266356365333036383733 +61613666396263393764326231663862303736373633366333313839356535303065393139653765 +36636163346435366365643930373336393837363930643239363834373733636532346635623464 +37393563323835376532626531623266376238306332643066323737623335613163653636323561 +65663730663532366562663533363237626333626564316633323265633362376461366165623465 +30326461373038616637616637326264386464336133333936383836613630633834316163643830 +66326338326539373932383333346532616132396539653430323035316138663266646637626261 +33376361326430663232656531393430646533313432343239333134626566303733306338336365 +66333262396131343732346139663432663533383431653430613261376264393836386466303762 +39646563333163393834636164626461356239376561393765656338666337356633653033626666 +65373366366165313833626632646530656634646234633334303731383261633332616430306666 +65383463656165613062356566613136393164303566313232393030636264643332643165333964 +35353864663934353435623032643964653539373765626330616230346334326361633338376334 +37653165623334366331323064633136346663313039663966383162373164383064666366653035 +31666638333462653161363338373033326566633136393836363262393666353539636335313064 +30346365336438336637613163376239343665633532623333343465316463313737353563626539 +31643938303037666331633161626664383930343637613537636536663066383061623535356336 +34666362373131616162316430646535626138323639646234643363373463663739396264666335 +61666536393230633763326137393935323930616136313933306266616634666636636338326239 +39396164313235343063376137616634343965653166643737366163333766363564323237396432 +30646262376230643061346438653235613265396430333464353863363633376664356665383331 +63383434376666303565336237613537396366346161356334396538666333396530633136663562 +36633738373838376361636330323462353433393236616130653336396337643466646531316566 +64303363353863363439666362383332643565633962373637343633666233666232333731353430 +66353761303736623439353361343633353265343139366132666563633331393732353730646462 +63353138376431346237356635393131643632666639306435343338653561656661626131383935 +63323664306336653461633033323633353839323532356236346363353439316132353964373631 +64613338363833383365666466643239333133373133313366393766626238303339393135616439 +63326531646634353263363632383735343434313130383138313534366532333265643964363863 +64333538366337326138663264323834623362313638343465663336656432323863643561616164 +32363431343237633539663838383130336537666538663936386131353434343731346134633931 +64343932393130376239643336396337393766353132346532623865323533613832666235336639 +32323330653466303230363065326335373636366637383363343334383437313562626335346339 +34343362323833376333393238313766376236376562346238356262373266663035333937373661 +62323665643036663763313237363061363132326633323461663133376532326164366533626136 +31393336353563373862323632306363666161356263383136353933633735663131666334633433 +64343536633332616232326330333130383534633232663534643332353435643036613963366437 +39313764666237363466633835353334633031386130383631386561346666346436623333313339 +31343963343662666135383336323031613265323864303534353734393437303363386366363935 +33326130393865643265633536346361383235666431393964316166633165633966663862346230 +39373164393333316465343565303635353765313930666665633264356566613033386261393464 +32393139316538663232366566353037383762336430316437636433653530666466666438376236 +64653161623638303765613066396433383437303430393062613364333062303336346631363964 +34613533303862366265383361366566376136616565623861376437303464363131393664336164 +30333137323734376261303834663965616365303464393661636139363863343835386365396536 +39333939613264613437303931353461343734653662313864373762316265316135303862323461 +63643233636466313965613438633230373131326465613733343338363863643764626631613664 +30353639376162306437373961333966643037643031353239396135663565613933333265393237 +33646531653037373337666334323832616236343936653366343762366639616234383064636365 +61303235383433613639613133316534623732306564306230333539633732653736326338343638 +33376139353135663738386638366334663237346435383164393732333433646535383437363335 +32353439343831386361343738646332616166346331623561343336316139313132613566363664 +64353966643461383237653333663639663464646663363263653461336639643430376631326138 +39656664643238653061376434323835643865396262643066666361633462396230386635356339 +36303461333434653662623061623637356163313439303434333961626162633531343766643365 +31393766626238626331643061366630363830393665323734363437336266643138353537626237 +39343935373630396635616166343436366564386230626435666566356636643936353735363233 +35306561306632333835613936313132393230323631396263373864626266626431643262323163 +66653031396433643430376635313439373163396462376261623962653365313634613135383161 +31623935323630303831303363633765313337646664383837396261666533386134363537366564 +65353361613130316634366365303033623331626231383636666563353539306635646339363837 +36396361666537313938653662353438393565366130386363643661323030313735633166623635 +62306132643566373264303839313635623265613465373538346533363964643464663264343164 +65323361616563663432653237653831336339356330643662316365646633333966643738663132 +32626230663661643761343563353134643734316131376631663864343438373432613635366535 +63643630343634613136343636346435633161366635626237386365323964356664663262393636 +35353561613037386632646535363866326166626136393433626461313131323432383938313735 +31666535316533316666313035653734613039626362393838353864363864313732643461366665 +64303266346630626434643264653961663031633965663931663663333635653334343566633563 +64316663326635393965306463643234323732633436303635646431383934656132363964663331 +34653238313730623232393830616332366436653035623839323966356633393130336533656433 +38643263323835333438613937333039346165386130396439656134323337373030383262633934 +31616263353830373038336136666663303339336566303636393339653632393931396338383430 +32343435633565626530343436333438636530373234393239336236346332663964646532343630 +66326334326633376564323531633237623938643434323664663935616163333366393865323539 +64376331653064353438303631396361306461343333626237373866396632306335373961306435 +39313632386235623762633435313265333761313537653463356564663730666339613037303732 +37353062666238666162633138346135326533323263346332393666353332653933393230346433 +37613332666632363534396666323035643161646164373864613434636465333464383261633439 +66343330303337663466386435653939326333333031343637386461333661376261346532323131 +39653537373330633064666334316136663935383533633464633132653163313038313764656231 +31333163323833366536313164303566393262613037306230313439353336346238643832653034 +30353561636631303838343161363236323430313537623233336130613934653261613233316162 +30316230366437313163623330366139636661313434373831613937383565636232613739383535 +32353262626330356163313738393534366531356264643261343930373666363161356334653038 +61323433643637323466616662356565393031356535643431623536386532326432303162653532 +64613533373734393332303162623038633634343033323135303132663531303361633265356338 +35343564366565653737323132356166393533396362373337633566386533323638346536656136 +62366136666632343438613632363765663764653462656530623139316465653632393030386463 +65663333376165313863653538663730343033383230343261386532613437363230613662306532 +64303464656366643761313065633032636336343165623536306566666538663061663038336232 +61333565313366356638316639653330616539313731323533303839636231633361376436316462 +65396430616637663265623966636638643036396264363637336239343332626434326438363163 +33623530373735623435656463306332653761623534373639316164616533356530663265386536 +34636663353734363265376432363933346639613266643039643733396637663132333964393237 +30613537643937343634333864636134323235646535306539393932346338626534373063393839 +62323933646561316161336235396133396233666138313230613532353338623633313438323737 +36386661663934383537623532386461356361323732363261663533616566383539643564623639 +61663065336634363862656262356431393361313164626433656265363532663039343664333966 +30373736313136666435363633356434303539313035363464663663623134653534386231303732 +30623362313262343936336536353939343232373134323734643935313564393431323939353962 +39653762626532363634323533663362336464626561633261616133303966663365303465356238 +35356532616430353134376136623364646635343362353334333138623864396166373035343135 +61333263366432376365353765663638356231623836363939353333613736373962383465353331 +39363336333837326463386563626134303332333162666434653830383964646635333739313439 +61626235336136623538353736306531323638303333336361623237333461303532303535636137 +39396564383363666461643463353161643837353065353835663538303264373235623563613262 +38623134643038323665346630313835383732653633636135613530363563386438376232623661 +35616133383763636366626430346161326362306133393162336337663937653838613562613335 +33396332323130636631646332653263336632383262623331653139663966346436343463393932 +31383939373630303463326630363836386638643638396164373364336638653533646362346461 +36386164313865633763333738363035353237623232333932663862663539303761656137653061 +61663762323961633766313665306137303932653131363066366433363138366465623236343537 +39616263383833643835633039343035313730666534646530346131653633376466346566326136 +37626238393831303131336130646234663539643563343064663766633737333361323138353835 +32323261633130636532663234363137623265646264336337613061363061363734646334303862 +64356161303565623437333363326537373731363832343839666264373364313735306535366161 +32646436383938623238313164626365613435363637366463656133363734343637613565646534 +37323637616465653537393935323131373166316435636437313332306237646631326564326132 +61666536303463353030306434363939643836656331326430376264323639353661313465346132 +39303265393538383966363162363661353133323837383230643365336366636561616361353931 +39316235313931323035646435646466396634383561386631306438303465333132393362363166 +39323736616132633330303162353534653062646666626462613839356263363864313830303265 +65356237663336373835363463643334386138393866306334313763383838346130616336353231 +39306233333438396537626531303165306634626439333230653933323166653238363566653935 +36613136386631653263363739653162316339366535626564333562306235336662363636366239 +63316636316138636536646431313133316431653439306666383864313130346635373636343238 +65353736623735343161303635386462303361323566613537393563653761666133616335303435 +34386630636239623830653332326131326566326163363333663434373038313833663539393163 +38386436383534663532316236396664393830343137663464336165373638323063666464376263 +38623632343265363335363433333338343034626666383232393438373430323961393666396335 +36393335636561653661323835333366303837363334663235313066303332383735346265623538 +39643133653939376362356663346162653963346135323031386535646338396662373762353065 +64383264353338313761353865366466646337323166646435323235633137343139323537363965 +31396537353236383430653266366233376630366165303662376665623132356463666330646237 +31643338383431356332646363333466613033663737326335663766636133353562326365336664 +62373637376666383764616130343038666165623264363939336131656136343035346262636333 +63333764353866613662343534303764663637613938373265633634346163636136663734326530 +33656334663631626432353539326231386337326365336165383361633233613033613064623836 +31336464313262323264663561623065613836666663376235356430663632313835323433323563 +31383561343737336434633833366432376239356134666231626536386232613932663832353061 +63646237376665663965366133636430313235383532366138643162353134633363343432316565 +30323065323633363233613633323331366638333765653035316334613062666332343833656634 +32373466626666383538663562396232373639373433386565613665623066373431376439393833 +65356263663637636434303863653465386535313461316464323365383766386136666361353330 +39663664663231393336633839616232626665666161323362383864333461643437383735653463 +33363636383863363035663635303962383234323266333863343262353234646365613462626131 +33323630366638643631323463653961666663656435336339613330393630376130383936366338 +33646565353536306565346432373932666339313734316330613361333665316561313561646436 +36333234663564373036636566356261373066666130353233353433383634386265643363663432 +61623530373961333035633139306336663266333461363065656331333066383134393538393831 +61343031356362373333336163366461323836373962663333393834393933383339623962383936 +63613530623836396365356163663634383562326165393233336464373166653335623065626339 +33353239313939323537353931356562313766633138343631353830373239383439666566643439 +62323038346633386536643564656138623837396236643939386531353336353638653664633730 +36633062346136393730326338363535383838333439313232303031656534363934376234313239 +30616535343563353464633735333363656634636236313437376235613032356632326166313937 +37663363376633356130356665643665663933333836653461386533393336613239386535666331 +36393166343837663336616264326263616536373930303962323164663961373533353361323335 +31383230363932386630633639376137336434323634646465653539346662393466323634373161 +36666231396664623864613432623463366133363061666463356233306635666339653331313466 +36316464386130663363643966356632616634303630323430313137376632373335633436623463 +65613836323961636236366233366237323336333838663638306233356536633635313730646536 +37633164333034633731313435386666313533613931643136326634353761643335323731663535 +39356137383135383237323566633538663665383661383836343332616138326463616436326534 +63666232303332653366636563623063383061643135333237363231373166303062343362333635 +62616532623433396135333338343031653261616131303937363531623762623761326262356164 +31613431366230633033383335303436363034323532393737343635633232343263343761383631 +32376135356436643131626136363737333137363032316165643662353336636663616436636134 +35626638623337626636366237663633386362616333653535623664333238656434613665373736 +66316262393637663739656661316461316539636238306135643439373061373733353632393439 +32656132393765656634366439663732616339366231333032306265396132306461346366383339 +66666438643265393133363235316661616536353865373162613765613666376137626638363361 +66316231653064616364613834343034356164333136366364303532303039373866346565303661 +34666138343762653031323635666539303866353432613962663435373061616338653131623435 +64633934383832396133666134653364356531363435626532306232623430643365373233626336 +39626563653632393236636533316537363435343735333062666331616130343534393336353338 +64383539346236626339316632636366366130623265373430333732386563653531333265303234 +61383165663837383837623637383931346433656635626537626236326333633266306630336631 +36656539613938303534623939356238393466626265313533376661306336323164633835303231 +33363637366131303030363564383138336238353865373636303564613965613263623837643434 +63666231326638336232623462643139656365613131313235636339666633383439306330363030 +39323236383835393561393534653036666133343033373735353664636565306438663862386233 +65623961343462666465303063326263666235353331333039373337616637356661643939366131 +38323535313532373663666338343164356337303135393234376365633962383931633830396537 +61356461326336623637363262306533386130326661386565363337363663356361333263303339 +32383037623066616530653838623134653735333635346139353062663030306461646332636531 +30373162306530336337313832393261666466316333363933626534386666333566626237376438 +65353036663039643164653330643562363335366434313035353264353732393463333737616531 +65383864653763643762303435613937316565313634626334613838623065386431313961633530 +35396466323232376165346636643831643264653930616530383433313162663162653834333464 +64306465323638356232366638376364613832353037613663663737323638343933616130613862 +35376437303634613438306262386162306430653339393933653037373366343837306366623161 +65373366636239333634303662663733653436643962656161626437623137616261303234303732 +34366630313162623666633737656237333638363533376235336161336537663138663664333163 +31353361623235626130306463656239316538313637336432336638616339646439646131353233 +62326137306363373862383164666635383032616633306163313234396136613663633465303034 +61633765646364383238343363303763353731393539393037393732653132393065626636303231 +37653039616337323436346435356663653738383964623730333264323464613639326163323333 +39396433383262636563376466373064376234363632373464393061633336343564396438353963 +66393365376166363637336330323536353064353564333639303934303163656235386130313562 +64303663323838376134393530666339343038343766343533653436323439323830316234633534 +61306263336561376337303364623964343931633130373664346664346231373434386136656531 +61653130346265326363356634376563336337613866333834343237353266323636353565386366 +32626261353134313531373334356463653865613236323763643833363066643430633832393763 +30343236663435323336366532306433376533666532656163643735323163393536393765326266 +37373562353736366333313366303464323663313138633364656235363163396566343331373735 +39616366393731613437336332653934633463326231656239303033366431666633383130396337 +30613565306262646231303234663461303130366665303338323539396537343137326638363564 +39366230626231323233643065393531333237393334363833343230653435626663396136343765 +36356564643133626263353537353861313130373661373537366133306462616431646639373965 +30333538313261656432316665333634643138653430656234333361636434353834323633396463 +66636333383564383765343762303236316461353134643237363361343566303965326532373738 +31363634363535343064363835356338353461656262636438633134636234376637383639373464 +37393935663037393434663936653330653634653436363666656163623738313963316162313337 +34613235653337343966666537353838633231623936623037346436386366646333336232393135 +39376465333964633661363830356463613036363962363431316534383033653039383136373935 +66356361346561386166396532353066376433303534353865343762626234353637303364316163 +32303536616632303037633365376439393166616536666331656433373035343365633237656231 +65643031373064626435636530636332666536313637653432376439633563303636633033643139 +61303034383862323431313535353133373831636331343636353565616162383633393838323530 +61383030336232383465646239376563313561343561373338376162313335613435323534373262 +38643637343133366266306433626232333434333536313839393230333764663465373162663935 +64326235356130383332356434313831353131643165363132393766626632626635663861613139 +38396231636466663263643763323434626166663863613533373265653833616564346437343237 +30643764666162373162363766653465376137353639396363613736643938383836333961323533 +38663163646532656636353037363732656338326565306535613334333361306234343564383130 +32666465626132353431643963363036623164353236336334373166616333643839613736643135 +33643631656363326437303364323164633761313861313931666633653436356465346431633133 +65333336643365383337646461316531646665643033333466373033336534376661613331393062 +38343531613639303735323434633039333633663262393264373932656438353430306634363262 +64346230366438623338353231376630623136616239656231643165663533623935646631326137 +37613464363836346233656536306132363934333139656137343165346433633461313762373833 +66336462656631313766303036636532306663353332353836383763313837613964323138363433 +66303837666232393030643765663431373332333962393564336530316634316631356536656262 +33663932343332323830313735353039336539666266303434396430623934386261333934303234 +34613838303235643938633336343433336266666661313463383530666330376633323164363238 +32613436646536366433313330303563373734643735323063356136363362643161313437626665 +64363463636432643163663065316134393139663238633836383066653562666336666339313765 +32313261353466396633643962366361353362656239313339616435616538383662393431376266 +31623537623864333230663363393364333332363461653961663461383032336238656238613339 +66303038623562326336633966613433316537636538353261333031353934613534653431333263 +31396533373033613630383032653866633464363632643465653435326462333066316131633732 +65346138613936323239326361336132346231376563666362383964626561393166643063623764 +66336261386166303330383633623633626332613963343438346334326666633031623466663536 +33393835666535636265623132363530323661396639616232333735613732303434396630336530 +62326430396539313533663063633931366239616663643037353439623939393866623262313861 +34373165343030363531623538303339643766303730653339623131623335353939306139386237 +61373837326464396264353864616335326133316536656166326430353266623337663563646533 +30386266613233333035383838363563363832346231643831386333653333383435396638333561 +66396336663535336266663036656432616661653132323035646130646666383165386532343339 +33616537653237613130633432646532613761336665373134303839646139616432373431613731 +30343630383766653635643539386463626661376333653734663332666464396566653036336539 +66386436393537383237306136653337386565306665363232323437623366373362643662353635 +61356264376631326565313662623262333465363439666461316335346236353663373130323439 +38333263366464663733373333303938393639336264653162333338306339653238623232383237 +39653239313361663263633064613833626238326439653030633562643862343865376163373535 +64303738636531396135303039376561336261646434623133366339663863626531396561666462 +31343066393237383931376634376235373162343962636636303337666463643262323261323932 +62343738613862616337313237313664306636323662363133376437383362663437616334313764 +63613266336338663235633933633962313537343337363861636439363637643466633763306333 +31336230623662636130343663666639383337363566653564323533656165313736616337636639 +31373330643030623138333333633535326364316265353062303565303936356166343439666331 +39343664323866346633383339653664363930373466303735623338353733323133663961313438 +38373037323538376530343865383439306435626434373066366635636336316632353163366436 +34616332366634626662356338613266633761383033356664383562666365346231666339356231 +37393063633636663362376663646265383834653230386333636263636361333938663030636435 +66623865313832623636353664643934313963336632323036646236343363616465613161626365 +30343863663363626232336335613030376135306236363063383761353164396539343335396566 +61646231373735663965343636616238613739646436316461306662653666633331376431363166 +32626536353933356332383236346166363662303133653039303661373262343365313034626366 +34666466633231376564666337316464616137626639326431613832643465306462643535366165 +35376631333436383262313564653437666263383961306137396634373331656334646238323665 +65386166346636303034653633383530393461623534366162356661666134303736633631396130 +64343232636536623234333363326134353432343639373537323364633262656438373566613161 +62333532326438376639373730383163653366666265636532383533656564326663666363333530 +37393636633866306437613862393739326138343832306165633434616164316239346134663635 +61663230643039626233633465623031326361343263383138366636396366613431306530386333 +37363834663666663239653636363531363865383866616332386139383830373666633139613131 +39393139343133616166313830306566306530636361333666346432613539303163383537396364 +33313562343361393663386239633431373935353235393338646361376639636463373534356632 +64363137623831366461376461646131356539613761363461326464316635396236333137333864 +30386135306236636262333331633536363930303063663165356537336661613037646139353133 +65343830346133613736363266326530633732346632303933346637656538653530346661326664 +34616234626232336663373161373638646363346431353736396534333730643461656262353065 +63626131353466303261306237653936646236643937326231326636646635373366393330336561 +35383861333139316164663865386361326661666631633762303438333035656534326535366161 +61386436623233306464353034663835313231633566613961613830373762346166306236653035 +35363765626564373238646331643032303539653731353831623665646165306130316230626362 +32356534323134363034643963363261383535313066373338303934313163633932373962343861 +32633334633530323931643235386536383739633836366262636663613166366635633631633964 +32636162366230636530333061656632356130656137373335376133636266633539643764636461 +35303636383133323630396133663632626466343030623230386262623637313638613737663633 +63366461386338346634326261323731376232313438346539303539356363613237393133323265 +63386236623465376135656365383362386638326530306533326161396636346565383536303336 +37363363353661336332383731633536366135653837666165323130613064303633616635313666 +63303731326638313937353736336536383261633266643930373036646530353361323361376635 +31313465373565633332326230323231333362623064393934393236626338333837363439343763 +65383735633261623636623465396534616630386233646663363531653830366632316337313766 +33323133353330323431623030323164616663303330393038643136313838646664366263346136 +63346461383536363536613166306531636338333431363834393733656332303661386233323533 +63356637643435316535353533623637623465373534616231656566306438366432376666323432 +31353136643864653133623037663436613134633038336566363563343037316338623236313933 +65333036333163313765356666373064623362356164653837383664316162616137333466306632 +36303862376161613536633039653238653439626638356238613931313437376339343466623135 +35396231343161653132626435316237323632666438633035353364383431396463373933643437 +37653263346238396234656366373832386366636339666136643865396539623533613736353664 +62396163353963356364316136333335316332393238376338356366323234666463633530613232 +63383939336663323361356437616532383931343538646436303563373534323632386633383766 +37656137373039613634376235306137313532613734323130626535623030613635666136363964 +39363838346664663862333964396136363432626261306530356337643531643737326364613631 +38646331313638613938363138393439383366323337643135396231663462643239343630316336 +37643739353965326432323862303966373135343762306134643163346261343832343532376264 +38363731383637663265366364373961616330343661393231626266376265366661313837303434 +35366539633834303237326334633761363830303136643235333536306538386463303766383238 +38633635643661343465323130633766663464323334373564336133356532323266636462663266 +39393930313562323363386562303064386164636538323934653231333466376134663632323731 +37373865353139353838303861343137316437383739393261333933333736363732626361663830 +63393763616666393839303364643962646238663838303633663833633038343661346461636166 +64356332346466383339623765636435616537393462396435323337306465383265636361393633 +32663234393562393330356536636164343536386464643732333231333264376438623439373337 +33313266363137353064313161343137653264376331636438656266643462396266616236353561 +33613632613266663966306463316163373263626565633566626139313664663135363665396637 +37613363333864663064313535663437333835646335333531633332336661376230396438613165 +32643439316636633962646537326466373239313130656665356534386231633464306463303134 +63646265333737383232346437356565326265616163656365653137343034303465376639303361 +61383233323563386134643333656438633136346432613062663331326664653138323637653331 +35343830366435323034356634323931313130316538373366663134353131366664313132653337 +39393636643966343862643738393832306461303234346236646634653037326437373837333138 +30303038323262323438616262313663323535666134383431366235643634333163336534383964 +61646230343834323730346266393736346635656666616231336530653037643161343636343636 +34643662643331343836613563363532636264643561363164643932386339313735343032366562 +37653762383266633136383136383935353539333730366436353138623636616330646631653565 +39303933396335663435613938626262643164336233626562613164626238366130353236636534 +65646239303833616161646230373864376364353063353434373561396165653963346266663339 +32373564643766313763333731633062613936306663376461373061333864636162303036646162 +30316433623838316633313532346235316532303232636434336636356162373631633634383232 +63336564666532643761663236346438366664356662616631666362616264396436336564323533 +34373333393133356633376232363434343536383866663663613866666563323633643734333637 +33336239346334386365363464393062333639656264376664343835306639663231623633646533 +61643339303864393635666633323764373434333036373064633365313961383164663364313034 +34393135393466383764343836303533386164643033353965343733386161333837346238666163 +30303738633863313934316138303736376538386134636464653563386664366364623439653263 +36383438336463363765396662363438333837633831383537333365316163383530306165303161 +31326339636161626332633238616533663762666337353065663436373430373666666536623731 +34633465333864383338643435383165623638653333653838366365366435613532663563373632 +32633739626162643634636233636530316562663062356534313764343233313537623063346330 +37383037366232663231366537636333343265313936653232303066663965613134303166343332 +62666137333566353536366333326266653561373831653264323538303563663364353164353335 +64313137356635383430653038366536313434653030623266356334613164363336626264346364 +31643665663065653164636432623439656633343131626632663236393433333532313563383865 +66643261383936613537616266366234663963386436643837646363623165666530396337396364 +35346466393833323466383934633539363434323232323466303063613731643466363838343539 +31633530623337393462353462376139356362323737303465366537613461343430303866326666 +62326536303235623533393164353333376238376330653565333164313838633764303032333064 +37623838376432393865316465333134336636656438663165616462356565626363633432663533 +31373735376538383265666136353966386132626538323530323132313562383636633135303166 +39353065326232633735376633646466613533623433613263616331343337616637623561643138 +38326465363031646238353335363964663737653631313037383562643464626636633564613139 +66643762396437393431643039356635643232636133383933626631663165653039366266346363 +32376564636363363939316562396461623339376661623433643232366663396636373163643330 +61313431613963356432323162386536663165353535623538633763616631323264326130333131 +63393434373039616463653363636531383533303362616534366338363332363464653136626438 +62633039356363353238646238633834613061316536626133313264316435626637343431303462 +39373932343135633633336361383933663039653934333337393463303632333864393562626462 +36663763336364366338346534336132663538343861653339663765623535323332316466343364 +63643933353037383936336532346237613837323239396233663163393337356264643865636636 +65393732333561323264333536333532633733356466356330633337646330366330333534336630 +37336164356364376664363538646165326563623136353566323637366666633065383062633138 +62636235636536333638623638636134643961366466633661326530646563613333646235626661 +63336661306561303633353031666564323731383739636338356139333237643438616633656231 +63663063616239363366313030396130383137396262383632376133616339623734376334346232 +34363731303130616337613032626161646663636536613238633564633761376530663964303361 +32663263356630333633376530636639306637356534666237323238346639636265643039616634 +38656564336339393839366137616262663534666364613238373262653637643430393565323962 +63646462613964373364643235633535643663656661333330306535613736393236396634656233 +37343266343332326534666162336433643666643334323661653465323762353138323063643632 +35663063626462303939373836373030303034333765653130313937333430626562666532363266 +66333733653434386438346364393866656162376362323634656635663535326432666663316531 +64656663653866656135383461303263306336633337356364623264333661633831346630346161 +66343733643437323537333833313438326136386362376331393434373561313635643061346137 +31663438666464646465396539633331636637303339613135303966363965346138653761383263 +38323933643636336635356233306530353664323432646331656562316264366664386133303965 +62383534633362333064623761346434366466393737326136663439633237383764333661353937 +61326438316238396163346635623030653630623038656338303163333036333264663539653131 +36363961373434623537383730643936653737393166643838643234613833313533316361663130 +35646165373830303334333339636436323363353930623739353539323936663761336435323632 +34393466313132656531313462343539373533373562646665396332613166343339373366393639 +62643631633031343962653836373762623631633565383232366439626531626337636464646464 +35366136393263383666306139636162313166393031383161366434313062663064663064336436 +66623538646431343739626535343636626633663131376465376234316638343239613539383736 +66346434363337306230613063353962303365383562623566346161313737303562356436643566 +34336436306361313738396161656230633865623931386363323531663666666363366661303739 +37666132353562383537303663643461343539613165393738653663323031356562396432633061 +37313032333563356439313336393736643638653066646631326461313239633637663161383031 +35633163663263616139343738333333363539623533666161623633333762653765623966363337 +34663733663739356663306365313330333337356132323464373131653031656361353562353938 +61353065366163316330643263613938373061643862373630373537363336653664356431363931 +64353637646334376132383961633366633838306538646665613263383663346631363239313738 +62376166353634643533633537613533303038616636396134396133343761393435353263343235 +64386338633737623032663165636432653761663863623436363534353039316364343663643030 +62373265613966303762666261306537626438636439376634363562383763336132663265653437 +39323464303230363132376261616434646632316264616334623036336466356439313565323932 +36646566386566306163653137383065643737363633383436363565366464616535396161326433 +66313030396336346633313330646565396435313839656464343538323937653332613236613766 +65366464333434373134343933303234343237386636306130616530656366316666623036343430 +31376236393431316162653763646461356263393861353861393533616461343561326664613564 +61376431336330666166303738656465636435656139333835346261643235643062393063626334 +66356263333965653865346431353731646432383262303739643432623138663131636132303934 +39303361346162353266363735646435363530393664346233343966363832383135346662376433 +65633530356430313738336664633066303166636134653436393661343830633834653136616133 +33376436623534613735666436373330386339313032303733383462616436363761666137306463 +62396365386166663466326165626463626233616135333939363536396134343331616434396432 +66386265623535393666643964633830623938636265663964373762373434303165376136333938 +31336631333832376137643439356564323161653536663332393834343462323734396333313235 +38393734646364323365646331303364336463303533313939356333633637366633336231343762 +30333032376366643535633863643134356635356335643832333436333035336235383739356437 +37636438373532646665373935366135386564363566366631303966613664306265336566656337 +39666561386631626334366637366366353161663762343332333030396435646532373436613037 +39663531356463343031383139663834313763626164643031323534616330663861653131366433 +34633739623765366661653835646266396434363931363033666430316633386265343465396632 +34613036633336663239643564366165376537393562616639396661383461306465653638356136 +66663766653765633730646530376134373837666163656362646631363633353766646530346339 +61356637633164376561636366383531336564356637363036333864366539373739363530663864 +36393330643366353433666264373062326164663532373434656239666663633362316138656466 +37313431633132636631333038313836623332313531643130316330333735613830616432663330 +61343631383933333762336330373735306262343561313137663632316633383838633236383535 +32616565663562663136346530626665636664396135366535303634316334336164623238363930 +31613631306134356432663339653761646330323462643136353265316437333632636131633665 +37303665653439323339336334633963646431643663626136333433623736373766323966663833 +36366638383562666261313937646266643831636639353539386361376165343037343830626438 +61633265633433636262663433383265386661643331616366623634346161363935663430353636 +33666162626431623139666565643331393735366262626330373235393832666535323734326132 +36643562316461363330626335623439656336303932393366646634653261626535323964383230 +39373633333534396565326238353133313366383030666434643636336532666534393738646537 +39613733663438616230306436666364666561633835373639663332323636613261343235653131 +64363734633335333032646434616663646262613538613739376663616533323265363735366239 +62356163646366306463343737393139333031346166623564643535366438626338356435376266 +33303039353333663830613436623331663539346161623463363337333264343736386530393331 +34653335346161666231366633313933383162626431396365333931366464613266643732303737 +66656366343664356337326537323937656231376231613939393862653736616336643932376537 +64633737336331656466373635623538356332356239376139353334626534646162613834626434 +30663532613165306564646533636365336534623064393039633538333663333630303034383638 +38353634613761336233643031653932643261626431653532626232623532663163643735363761 +66663137353464663537383736376636346364346632643638353332393037363536383739613136 +66303832636539346439343730656466306332653634393166363138623630373038316639316530 +66303664366136656530396564633139336635616338336233333239316539343938613762326263 +34333631303935333736663339343231653163376131353337333037666463303464663034376236 +62663065646661313432393837656136323939353964366463636433363633313862396337633561 +65366361396366316333636333623934353931363266636664343436663637363236373839613062 +65393635336337333365633235303237363535346132646532656439653531626561333962376139 +33326530323663346538653236303232383931643531383439323164623338646564386430613262 +30623332306562333337303233346534373161323235663930323234363661626561386662356234 +32356335653537643962336465663434363431356138373539613165363363643363316135363766 +36303739633464613735323238323532373532356263313134393435356530646264383761393436 +33663564656331633863653966646361623235336232373165636362303832363536666638636564 +38316463633738373262666365303537616131313139663538303837343762636330363136643866 +36366331336239346438626534373336616234336664393337386238623661393165666438636231 +61623266646665626439633235343633333961373661333236646134333631616164666663393638 +30373962393132366533383761323831353638326539613963303964316238666163376432316239 +62366634326637383039663839376363386337356134313964663838616337336132343765643966 +34326638636331326235323061623335666232613034653166386466386435666633333536316332 +62383338666235386432626639326637316264356131303133366663653465323039623965356664 +62643530363462366631633133303736366537656263313634623231396665373662383664643130 +63663334666365393436613939336464613836646233633432306163663839373530653033663864 +63343764613966333166346634343431643864643034633564306138373661656430396131386138 +32316530383932616434663934396631353464663663393834653233396263633339333430656162 +61303935333964653838316466356339626564633566643564643763376635343232393731343230 +32613433363364646435663030623261383561363334386633346638323136653236316665633265 +65303332346238393463363261396539313736356339653363386432616435346239643532363437 +32346436623431643831333932616462643765623530633333353732336565643334356534616364 +37343365343136346131636362353662646333623830353532373764323863393832336335303437 +31333338613737373363353461336438386163633833373330376236356336323730323362346339 +39633430646638353335343965303434303937306137393563383463373465653733363561396162 +63386330396365313332376666383834343030393738306135363238396630323865636637653962 +35383063356461383932366362393437396236623834333034643734643833393961396132636639 +66393362363763303132323835653130333833383337663964613136346135633632663930633539 +63613665626334393666363830306166643164353335393735343166626637613835383832353336 +31323835326535636131366339653766633061626636383866613038313437326564336135363537 +35656461343434333833633839376137653761343161383365356236366366376136646566643135 +63323830333331623839656262306565656461343365313937366265396265643732356462313831 +31353237613663343334343332666365613938306439613262656662383264383733366532636565 +63336662656237346632383964373832663539613565363062316431303061316163383134613935 +34316334313366616634363431333537313662393564653766363539353163656234393433383065 +38353231363137653564363263316538653639333135613836396465643261313934313131623364 +63626630376163613739616263623139353137643732626238353965336563393430363562353634 +34303963626238653236643262383366653766333561323866633735316564643539313138313139 +37373930383937633163313536646536663161393738363131383962356162646338353934613238 +62643431323039396139343364333833363732383536336632646235393633333339666663306131 +39376264363136346438323364626465393463303639323330666336646635653663613962653261 +61326236616633323033313437306631643937343139353066346336353338633263383963383764 +33303165646463356562366238623334613432306238653838303032376466373465653834636535 +34336565326432323339383563626464346336663530336133633866356664626165386566643133 +61643665653530633863653361653033393832626332323964623365363431343338363936306664 +37373739656361613239373937616533666264343633316630343437653861333532363938616630 +62373130333163386566613563626133393334633537323862663534363464303433306161336439 +30643937653263646330653765303132343231373239303131396636376461653835313662343233 +35326562323165636332666437633733303233333835623630386138363435303161316463613235 +34656539346362316435333166313335313434326539323261313166336161306533376266393033 +37616262353835373332336138323732323831373262663234636561383136333535376332343733 +32343063343936653639373162653337643164363461386236656334366333373736326362646434 +32376631343665333932326365623465613531663239656162326264366536353335633161623631 +31623662623238323361323730373239626563346535623761626139363930636636333033306661 +61666261626162646130376439366332353437313137313438643762353131663734323836653332 +64333336656261333565656562656135636638323130363138646432633939393336313731333164 +30386466303333323233636334663265623161616132666335633863636366636235666562316533 +39396435633864383032356134613731316364393063393031646231313139386236663538633763 +65303538346538323135313935623032663462323831346161336464623462396339363735663264 +65383066343361313365656538353839333936376164333734376662616334363433613863646631 +36646432323161393538656262643237343762613731323162666237623730643535336562643536 +65383634306438653762333136316664303439363730396333323530643535616237386333626636 +36326239303733613262623539376330363431623133383330343130363464356163616236653432 +34386638323066623637353531333861643935383132333864383164663432636530653439363334 +35643431313462333066613164663262303836626139303865313265653839393738383361313461 +30653031613538376364303238393237396136633631313231313166663765613631303239326130 +38623532343865623636623237356564613638393436326533633634366437333361616439623666 +63643137616162313864633234336562393866323734663031343533363666316561336338353035 +62613734383332613935336339323164383061323665646661356639323236663161316466656231 +64326432333732613232336432636566343933356561656332666466323861313064303236353765 +66383533373831623136653639613637373931383235363032313532646439383038373764326266 +30316662653664633930333030363635666636323865323838623065343435343263366134306631 +62386163363039393830366538383032656337326430323062643033656564666437666238306166 +39646333666539616531346234373363356162396662303733663966353536373465376164353761 +34643564313733656162656165393939666238393530396463323938653336653966373636386661 +65363664313834613263626638343234663663393866663834323661653364373535333836613537 +62313432643436303137336133356561643466306331626363306435353732666134306430366334 +35313462323534313662346139633131653034643830653534343863363736396232333835306631 +38323831646461316336333961613137333333363661323133323933633335646264393762333535 +62303165366631663830303134643134303133613862393635356463303966353337303931626564 +65343661373835343038633737313535656366346438336638306665643662663930613530363839 +35313933363862396237363066316262623834636465393036653364643630326565313035386139 +62313862316236626435366266333638653965623534313933616563626633653234326466363762 +64623739326138343964333234316563333961313538373638343463356232373163336633333338 +34323763396465666536386237396534383837633838623162313064316639613264643833623336 +35636235643530303166343834313362303464393635376531653165383566376138633233646232 +65656665623334393965616262643532633731626434356331363966306435656339616464353330 +64636636383161303866333530373333303835663131346366636332663635316235333965653962 +32396665646261376563633233343933663238346164376336396637323864326463326338333763 +66653332373062303738623930386665336435353735376461356665386665396630636234643466 +39343235386662383036333538613432653238663864303065366437306266623863366264633431 +38653061363237373130353335356632383131353334376133666339376165363637613731383839 +39643763613332396337666139613261323838363334366364366335316466646237666439643566 +31336664326531613430356134653665353662666166623561653761663261663438346166626262 +34643537633536623865393630616233353637626638303063366362663931373533383261363738 +35356337363938323466663266373330383066656265353766383264346534386363373735396631 +31626537376631366630323034646332313130636364393631363630616131333665323562373965 +61326161366337333464623639653465353138323837373761623334666131316363666632306265 +39313461643338333163303536623838336165313236306139633664353861643562616130616538 +35373961356334393538653332323561373038623661326232616566656565326134623563376565 +61313536353232636330636239323234333231393433326539623664646165333963326366666463 +64373463656664393739323636626364326631336533633233653838306566633438356331306435 +34363437303163346164383561356532373161633366306264623036393163313634646561613136 +37336566653939376634656532623063363966336430303739373039363564366565363539363165 +38316333316565623434373664386365626535663465373932373561313436653861376430306431 +62383034363139613036383066363765316264393834373465396463383835393264343139346366 +38333838636638343765313761656266343734376565326432653466666130663334636463643262 +38303435356163663631313365623238343033326661653334643937326166326266323265633736 +62653665656635336439353663376661333034663435636637396134353863343835623934393961 +33386666646330613031666532376639373064366332613730386664326638366430393865363432 +38343630373962313931326134396561636462343936363734623762356361663037666532353864 +37633631616466643335643063633839306331323237313335623461643930653735366563346566 +37323561643561663237623231616537323035383662373033346566356665323034646134373661 +62303039643932316439643833663465383032383366623030633936653730613939656133623835 +34613936313565633830616436313731643662353065633236666437316639646263666134663766 +39646138383438653265633163306432396238636232613833343965383732653236346339326333 +63363562613662643538366337396332333431303637323633356435326239643435613130303261 +64333635643762646561623062386362623831316635363839306663633066303437306639363734 +35366230626561363337613937616637383631616361626231316536343734393965633765306635 +33623766313664663832323437393333653563626466396665333530356162383431346535373665 +34336565356465626661646438653531353832613034353238646237646330333937613235313465 +63623930633734303165643166373134333236653838353733613539353365326138353465363133 +30323730656532663232343761376265653735623937303266383936303734613337623339353933 +37623438356561346132636366343661613832373066386662366361336462623262353936613665 +63313733323535363035623934396131643035623236396163343834356364346135643830653534 +63646539626431626431333735346230636463666338333364386363653036343465336332363539 +64663030353833643531313732646238613538616161303734396633326638623534336635323863 +65313031663630666265353761353039313562323530383061613865633139383662623265653634 +62613435633539383661653736343966343036366337656537386361323765646137363036343562 +65343635343034616462353234656339626432323437386464396266653064613631356363643730 +34303136343163353336376562343063343034363931653937383734396261376339316661656337 +33666334626466386234383966373730396264393235346363663730623431633939363938383337 +65333065623264656330656238363836303533336164613137343533633038626264303966373264 +33666439393264363936313937373831383932393763376638663734363233633436376234666463 +65653163393637383036653137393363333261363463373233633938363032376336613766383534 +64653330613861376632383161663963613163326539316363636538383535656238363635616135 +33323661313466373234393566383132333130303834373462613665306361313537346138343265 +38363736343638353233356336303132326238633930643138396235326563633732666236306635 +63323665333562663664343363336532633139656666613839613937633334313361303639333363 +64393832333939643836346233343731663936333536343139616634353162386432393561613537 +64656632353735323734323231343134383632653633313061303039323666313566633066323532 +31616639623738326264343032366639623261626337626165626439363565373138393439356134 +65323064323330333635616637613764323632393431313131656231373562313533643432386638 +66333330646438633438623161343636626162643436386433376564643638633432616264633435 +37333230393631666130343337323337636233373362363435643835366665323262373830313366 +34393233333862303334633133353837336166366536333365393131353066643762656136373332 +31633465653634333337366264323863623931393531623637333033643333306564663334383337 +38366337383037353733326430633165306638343837663439313839656666643162343139626436 +61333838623832323839346562653533343939616237643636346661333462323230623263386365 +61636165353464626533633935633265303965613639346231636638366430393562353836393262 +63313833373237616535333435646234383839323265623139633333396562653133623035316633 +61353762306461663638643634373565646134326334393937623139353435393164376263303538 +34323666373438633330303130383963626261663237653037646134356131386334656237666233 +65383565653164373062346635383434623663663239313635373136666131353765326264663037 +32356566656535326239386531353635333339333338376166313132663139616138383437376164 +65356437643038653630666161326332656239656363396630623434663562633865323435313037 +38336435663531616334313265613532653563613138643563613037303564383737383262336132 +32613962346664356163653431646266656564396131363338653539303966323364366266316664 +62656661343832626164663430623432646564306130633963613138653364633536396462313935 +36366361643635356464313637646362323939306162306661373762663562666432623837376638 +31646436386231353337633965376231336638366231643561336136366132313837393962653061 +65336139353564356637646664653836303934356132366634626663336138316365653937646630 +65396333636366333837346165633762373761633566363065313362336436366164643634393562 +66313438363030616239623731396466343962363930353030303137333663316661393162643634 +63666362333934386530376166393034626138333763373435376166396633333762393362636162 +32653763376162633539363230356637623464316463383230663964623636366231663932393835 +62623433663838313039663665643063623631303262663664333766623933386132376231616237 +33343338623765343034663362633566376539663862656230366432363061643663663566376566 +65343331363863343335643035353763643033336138366238303562653635626135656334633035 +62306463383238656639653937336132363234333331613965663932393065333964386337363932 +38656562386266636234633739643933333362656362666464356337393031396135643666313331 +62616530366631376363326365346430643064393164353533383065386264623139666136643634 +62303438346237653863623661643832313730643263343030333437393732336662393264316137 +66396337323139666136373530313562653363303537333238396537383563353365646265643030 +38373330306538363035343337303639326633663931633238316634346239336162666564633636 +62613464646330393466366631323639646432323331363631316336366237653332356637653337 +32386530656138356664333532356465623137363061336132623864633265356138643235343937 +61366430353236616436616137313436393332613835386139666661353239353564343438346238 +37346362616536643039643164396139623739663764303266333165366364363038666637656436 +33383063333834666136303437313562656464376638663665396462306636643565363464343534 +62616634643833353231613962363961363932633264616534353866613232363633666638613736 +35396565653264316336303136356335313638386333343634326133333266633739646334323163 +31306237663566313039626366386333636262636632353065316330616166396362353664356465 +65663434616362663665383665653362356637373635353964376361633035653566623664333935 +36386635303963636333363039663433356333396365306261613764346133333062623234306236 +33623931306264396433306132393137646337323139363836643161653636336430616337313131 +37386234363366653161343966626462353635323538636162356466656365343936396135613338 +35386335393762666331363037663834616233633132346332616630323264373361333839373936 +63376533633739666361353865343866333631316465303237336466316365393636653039346231 +39646634376531616661656138646535616662643934326436373834366531356135393439653731 +63393830623065343435613931643566356433376466626561333533633335343539383338326666 +61363265356538383263346661393133303863386636653563323635626363343830353464633334 +36386366646630623264343234356137393330326238336130373136643738383637356239353261 +61353064323864343339386462316361356534323165353363633262633235623639343331336462 +61343064366361353230326535333864333638633561616535303938323764383533333338356562 +31346437306166333430653866343732613637306435336561333739333164346632356533626438 +37616431393862613939396237616432666235343963623330306536613631323430626364643833 +38373832626431396633333163343733646437383931353838386433356466653537633535353533 +32383965653562396633343766313638316535636538666634346636383063613133656362613863 +34663566343164616565643665643736323436373337373036393939396135633038616330633539 +30346662633030316662336334623134353933393732303236383263343330383862356131386139 +63353638336566386438633030613433663935663534376130303334613862373963356166353635 +64626564333630376139643534396332633532613734353466303235333838376665353039363562 +36366364303066396564356133306232323433323463616138663163393066343862376461316633 +65383062666335386132353836613239363736343561326630346236323564663839653638383635 +36356433636534383462303035306335313236336661616263626264336235653033613362393232 +37613564343436363265396135393130343439306337656633356462313532336661633439336439 +65363831303236643139323531646437653934313731626662633635333039643532353961366135 +36336564333233396266626433306565663732313163613735323362643134346634333734613161 +66346162303166613739336565663136363833623064323834616437623530303761313764666535 +37373663306632313661626234336161363139616239373663356464613431643831356662396134 +32336465316461366164316662623731646133613866363737396230663130623834346661333132 +33616436376238326264633134363866376131613637646439666566323536336635653935323065 +33376334626366396135303135336533656663633136373836356135663333663135613134626566 +64333530346161623531326233623262653162353564303562393664376333333333343062633635 +66346163386637613331613734663266666639643034316163336266323265313839653936613964 +62376361383730623132326539386431313537653536663533643038313831663266623730313138 +35363033373462646637366562653166316430316236326137323437393261333063643765633364 +35353766613138643738316634326366323537373434363934303664316136613034326636646539 +34363264636636333830346562313131633765306136643764613038383161613035366261643630 +36313066356334656330383936396566616331316435663630353939363064393361366563636632 +61303164326362623736393463336166376462393137316330356436643963356333396165336533 +34643164663330666561656434366662386338626636656264343733323331663933373535653364 +37386363393862323563353737613532366563356334333233353766396334363639393765666337 +61623837396136633638623933336364323233386165346364633133376334656431633362613436 +30343532653362646162363965616666366464336566313266626165636536633535323362343030 +65313237613764633064303336653665653339386266333938373634656563343564336466326637 +32303438386336383837663234383233363836386236383830343436646363383230623934363633 +36613239653239623039386338323137653536396438376130633165613938633364306364633931 +37656234366637373337643765346438663133653637373835646364396536636435613866363163 +64303032356438333162656538376661336234383839353839633035386639616638656439633365 +66656230623030316263626235343363366434663139316635616432346633333063616430376536 +35616266633039353836643635323839353034333038353337333535633737376436383330343635 +36636665306131306164623135353437326136303333363161326432663265623437376163666439 +63633632326139623932633439343861656130306635306638356439663533636435376164393336 +64303832643863356665643137323433653066653036346462306633306164653136303766356366 +33646238636330616537353961323732336661313332303266363466363832376439373433386433 +34363362343831343763643064653631663063323461633165613034386131396266343035313438 +36633733613734346235653432313034393635643634623134646263656631383534313339653738 +34343966306361363963623337346661653537633964623834623030363732616336316535626461 +62303964333866326138353465663031366261303135326332623439653435373261613938663837 +38616339633164643463336431373839383165366636626635373034373163343962366362663934 +61366664316637356162353133323030386662366232663438336435623761393538643565353530 +65666465303737663238356634396139366635656239366130346534336631363964323431636336 +39643734303335383965383561633032313935343363616639333730376464643264326465346662 +62353762366533633064613461353333613462646637333264373766346235323637313032363363 +64303266376261646631393238393030306639316663396136393932333231333539663531396164 +39366637313133383836303638653431616163303135656337623932353965333965313735396463 +31613230633662393637363534383634616230656233616231343961663334353666303765643537 +65376639323530306336653965393136636338336665393037313836386534373161393732363930 +65303334306432366130626536306538316136333337613064313261656332376234376264666237 +61653431633964396436613337356438663637303934393030646438323734313964386631313439 +38343966353938376362366463386532346139663833636164373534633239663635393139613632 +62336266346430626634613337626537623564306462363561633933363437356634303364653039 +62346637326130643430326536336430653464653334396330666330656162613237353932373439 +36653038616264636230666361353837373537626636666165306365323566396634613831623230 +32366636313761313436616462653937616333303865303861303937323631633337306238393032 +37613232363961636663316464643566666239303862323866613865363232666164313561333665 +39303065356636343936313639663835633937363763653462623263346534323236616362393736 +61326430353866323563656365643234376235646563663330633138616237663433626434643531 +39616162326331333636646265303966353131646161316463326438656432353737616130353034 +66363666383064353139383966643430636435313162343335646533343162353862653363366661 +66333630633238343633326432663530373633386433646331643938346564313261313637366533 +34653033333831343736633932373230353236343635333735373662323433356465303735313830 +34366666386364613239646538643332376665313161383662646231343936376166643136323465 +39656466386364663938393363643734356132653066613738313837356661346634383063356631 +61626664663638636664653735663964396263623530356665326637353963303165663365363230 +64306337326262326137323932316164353435663731646538366532613133396530366163643739 +36333839343139396436393963366165623466306136663263376331366366653535653966343962 +37363637623863346263643962363438663865653632343239643364626435663432366566333130 +36643162326437363661633465343531613635656139653664623935366133383464323466383164 +37386462326562663637643737346639626130323962333661623335346338333763643638636263 +63646238316239623934333832333662653961396235393861336663306439626434656361366535 +64336163363563643561633663646539396135613635333561336430653765613963666532303236 +39303464613762363533316564383531653730366261333833613165643464393432653835663965 +38386164376338616232646231323237373631333637303333326663396430356436633738663031 +39326235653666323239613966323563343532616237623738306438363537363537623263613133 +37653066386438333739313839613661366266383335353361313365613237373137373633613234 +33313034343263336631386435336331363238333130396661656634656265636230353039616266 +36366233653434353261303663666164336466616261333061323930626661376439353135363339 +65643631373261323234396632353433376264303661316462366536663862653965633464336133 +34623036653236656661663937386232356564356633643063626234313162346334343938613964 +31666331366466656462333131316264343932393662396439393266666130383363383062626464 +61666339303232663761363863333034316133633962653366616262633239346563356263623964 +65633662613766373261346339616437326339313564633439303439386563386239316561366230 +65353838356566623536616463616564363734376336306161373832663638343138613966303939 +32343538633234363136393762303734386130386533663932613032323339303732653137323231 +36333164376137393065643533353439616331366338373165346231666164303538636135363638 +31633734663734346435343465623531303536636263393430396231316564663931303134383264 +34363162343437306164646538343562366131363165636263363036343165366266616433383835 +61323730663836346264643332306263306237336633316565613335363562386566613661316139 +64343832666362366539323861353062356564363062343031623164643161366665646132353332 +33333166326636383239346636373330393863313035313163623131313537333432653730646466 +64383064366330656532616637373539656162636238663661343964393566376230313761373133 +35333633616330626537366563316530303231376262313638373437336531393065306334383134 +65653330316231393638663839373731363832343730316630393138646434393933636564356536 +32663862363132353361313166393931303337373864313030346563613933643137396163393166 +30346363336565373138323961613461643332623839376637383237666537633561323336353239 +37393962623666306230303931623863356531333338363161376636623134393037326364356333 +35633663656433343530643863646430643461623564316134343365303962343531373433643365 +65363064613361383062643038326337663037646566353334383361393435333761313763643835 +37346662656136353537356664353032613863376438396638363731316664343531316461303364 +65616133666465373766616137366564343839623936386665646666366261363230616165626532 +33323865666263396166373261393231626632646434643239393637323862663032666663313365 +61383138626434303466623065333135353731396131623138623231343039363835303663356335 +65653465316431336265396138626461656366383065656437393462346163616133326663646639 +32376465323262363562316566313935316433363631613334643330666662356530663139366666 +66373230613333666163353763623464373563623833343230623761306632656466383736313166 +32356330663334666364316638633433346561643830616133393165373161303963386263636337 +35663061363337643338616530613262336332333734313764666633643765303962623839323432 +35646162613264356236393030653461616138313931353335306566306261643861383164353461 +33353662366130373262313630643531383435363934323235663037366531343139613633663731 +33643830613461613431373565306636393635356164636234616330366234313433306432323932 +62363238313762326664666363643735313131323630353463313365313632363130316561623736 +64383035386133316338313630643036333765366131303031353239623037356234343065346232 +30653430393161633633386565653832306366663534393966376666353733653638666234373638 +34643664396339333735363766623964613331356238363631646265346533313031333866313863 +64636261623462666339383635363536383037363863663332353435663666643731383264636531 +30666562326339376361353137396334383762356564323835646438656432363866333138326134 +64613031376137366537343030656263623566636564633931666332653535326664613332333031 +30653466343964363139393838366337613564333932653862633931633735653933366266303330 +65366438393162613834353462626135303839303332373337386230343562656133306531636463 +36366136616164376637653064613961323635343535303031353161376338346362663763303039 +30653266393031303364643435623933666266383136393766656536343134656435366334363738 +61613365663532646339613364663335646165333632613731613562316436613532623562316539 +65313163616236663431306363633166323033623464363037643239323239613665643766336362 +61353233623338653234306163333533623662373033396233336165353537636530663335623261 +35346538373834356139346563613664663734333634386433326663613039303930616164323562 +61613139643832393430376638393035373064633962326166396435353234623561643563346434 +30323966313462376236373465303539653239663831663538323732623030303739653938383235 +64613634363935343530363030626661326466383364623465336332643739393266303366663138 +31613939333764663264343939303765646539646538346430653035343534323664393839306430 +61616535613963373663656533346536626363633930353338623464623334346535393839313362 +37623966633636393037373933323334386663636335623533613365636335313130316637383032 +39306230636430653631623436653436653039356264383338656432396437626464373737346165 +66323038396431363935653633613731646465643463393061306265636633643666386235613331 +33616234343536643137626166663634396238643234346463306365386130663766313662393166 +34636139386136343432326531333535333033366263326637616535363664643631636566383631 +65636461376639646562373965323566643733313230666463636338643430636463393261323365 +39346266636537336335366138666265643132663532663965646531373239336466366336356432 +65613336373863666366643765383638653162656462393466393132623365316434636265666231 +34646539363138633833323566623835643937366437646462333064616635313863363237313539 +32353363396530643763363530666136316135373534653230623463333065653264363466393336 +64346165343061346565613635656630626566353366376165373034663263656334663138623430 +39383938663238373736656562303464323530666665643534656230383736353839646539343630 +35613633666137316536313338653133623131323238303939313238393733636130313631653164 +62643332336365373936663739393633393961346665616131623232323466623638663530623162 +32656661646366393639663737613731383335623731643436323431396563623036313032636239 +64316662643463653237643266353639306639663037616564333536343962396164613935663332 +39383766623632333333356338343632663930646134363864343932303161643036343438313463 +64633531366132623136626164323866306636316439353361663931653461336463373166313262 +39373438323730376334316638383538336436656163303761623333663035373963633038613762 +30646136653063343361616233303836363936326266646662396561666139353930616235316666 +62306135326262393736613939353064303039396363636237383735626366666133373662626634 +65373138663832393165366462323332313936636134353130363034373439643536383362303865 +66313561613162626561623534363639363161353830376137373735346131373462353033366431 +38343739623433633931393562343265346635316266653534646335343333383834313634386664 +32373333386132363932303830383230633333373433373331396662613363663135326164393633 +66326132373030383661396665636637656137396463616462313837396465326164646262333531 +66363233613837343832373666396131643837326134303934613366383731386331393030313137 +63643062393033346536353539306165656433626637643764323136313730356239393361646138 +62326266313463646136666335666563343434373961643264333033336135313734356332626165 +30373737373333386162636534653138393531326437386136616332326630323530626566626365 +37373135336465656539383232333663343635626231363262653030626663346265616535383266 +66306666343035353133386630313465306132633231396436666661623663386566613731633934 +33343063643965353530393661613966383933383562633832626366373763366237333331646136 +30323437313538323366353035656133306465656630636435393232343862353938663434313836 +34313235623735393736346239636364663262346532353132376236373761376461313066343561 +63353664306566396462616430373832333761343433323830363330646536633931616164646433 +33316364623866613730373466633565343830376638323535376265626266666437646261613065 +66646636396363303436343861313037356236303238313330306139346431636362636336656365 +36623433653333343431643466613866336431356136383735393732663261363565336663393937 +33626636633238326436316262393339343265613266306466343231386165616235663238316437 +37373265393337366266323766376236643632313930306430343336316365333166373738376237 +65303834666636633132386666363263356637383462383261666433666638313766353236376331 +61646564663566626639396231333738333134633534653166653964333530346230663165643164 +63633363323963353264633339383431663733663739613263336233373561386531623862646231 +35646431303139653939643139366636623562643461666439393036343133656337353237626230 +31663734313131376236333238366566653962336562666438653832653462663638323031366666 +65323462393365386238313639306161656263353134666434376236343465383066306237353933 +62373863636362353937383836343734303166306336333363316338316430363666393361323637 +63316666666637363838626263373936303031346438653562356263613937366638356138626461 +38343239353238633766633234323637643763323732613639323962326362636264373335623565 +39613035656231653837636433316262646265616166663666633731666430643435366364303863 +62356237373738646338623637393038323332313332656632613634636437633637306131313537 +32646438623562636465383937346163653466633634363834363134356336613338623966663636 +38376565666662396436346566363963303134653236623966313966636665316238383639373335 +32333133653231343635653932623438643334633432313364326230323562613039383931393834 +38653065376661343965663333653234373634653936613233643463313236313963663362623538 +66303239653861616335613662663036313566386264353330313934633739366235326665623962 +37646536633637333862303462643337383731343931653730363366383064663639303832633534 +61343934636563306635633733366633386664336666346331346433383964313661633832343737 +36656165663562326430646434343766303933336135316239623735656139653931633663343535 +37343163343739346666376334316361653864383832396564663231373263333538636463333434 +38343764373235376162326462613532343333376235663330343061366632653134646331613561 +35313630333465333630303766373863613366623866623433663763376666613236633631626666 +65633539666634396130363432613830316664383132343331333762636163376130643164396537 +39333537333061313362383836336466343436653534643433653831343762646536663533306364 +38663037653133356334613039663862656231343438326333656562626635623031373561316361 +39323131323336626132373739303061303733633466323866316661303033363535646233636333 +33363531336565386563396136353635336664333434383761376333363061326430313961353866 +62643738346334343465653533633462343836663663313562663935303665343265343361303433 +35376263383164646637323835373336386534343135653663663761363466386638323232363339 +31383737363131363138316462313664303562396434363531383330343139383965383136623861 +66336266633538353965313238383734303939653335326432636639303761383864313263313930 +61336562346663323636323534663962373766313933366437356435666635613865656334363933 +62373438356666316330396331616431653033363135663764333235333666303662333461353334 +39616431636165343564613338663439346161393065633861323430623062383462633466636433 +33356133306365636636356164653533656434373362346337343961333462623661363666643031 +36653639666536613030356230346239623363646235613666333261316365303037316262643431 +30316133653136363732666166323036373461663438623832353032376165303761613239343031 +62333964613361323930303330653036393239366437383962313130346663336164653462326265 +36323931663932636461623530383235633635343563303530303534616665616361613964396566 +36343762316433333630636239356331323665343765393338373038623065326335343866326263 +32356432663537373265663732383164646364373338316539313638666431373066636566366438 +37616335323239623139663765356564343039333731303361353138363766316437636635363335 +39393964626338396532363337636464663162646336343438626532383263363562396537363630 +37306634336239363736306239313765343739383839346237326339333763653534663139653733 +64623963373537376634393364636434336439326138343266623663623531363434383236353961 +37303864346363343135346237646534636433393961653636373332326131393236313830356135 +61643239346138633762346538353739393830656263343266356661346230643865333539613731 +37353033373363643165613661386132656338653731653533633837646533656535633938643263 +35636137363236326330626536316231646633333039313635663838653733636232616261653933 +34623833653530323763353337313637653731393835636162666161623762356630326439616563 +64363165336430666239333665386232373436386162633764323266636233333038333238626432 +32393230383661653063633830346163313331626339373030323136316538353537363631376462 +39383635393637666132626539656337333264313732623465303861393430313034333236346564 +63616633643834356331373963613138663239353136623333333465386461333934363530306163 +65323937643363393635656535613161306331353161336435326536323330383136626162333030 +37626361323864633437643233386164643463636438653030366663303932656234306338346332 +36383065656663373465356362346465343665613131663939393464353634383131616634396463 +31343531356666363339396638383130343632386537333265343539313231303562363663666565 +33343232666331383531653335303161626564653061666237343263373631643632336364313665 +38363261323632356232373236613461303961613561303436333838363737633431343330666534 +31303262623061656663343135343439646161376633333339326163636262353564393261333130 +36653539333836623562363530613166616430373430303065663330343433353261663938316165 +35636639653732356666346631636431326132306237623264383437386635326261323364343737 +64633265343238653431376262643332323733316331656433346635313839633134386466343334 +65633936306462363663326461353936343736386230636564353633316637633232366437373938 +32383064653262383934623364626230343233396534336630346566386632316433303965323230 +38646661353264366664326533353965343061326462346536383262343339313162343061656161 +63616136643664373130303237613833373238316339346561363531663532633332393061346430 +38623062376166326661656635383939313738663731376439616262643532313035633666316335 +33636338383962316364343162343434363938316633393935373236333164346538346630616530 +63646536353638393537383265316237613063316533306462353961366263303865303564663938 +35626262396662646636353837356537616535333138613430633430666539636166333562353732 +32633666643964343266363862303134383835363430313533633736303133393634313365383437 +34623363666333656462633862653633303733666437346638323866333632616130636236336264 +36396562663636343733343131366362323130653439303065356533386465366230333636316631 +38346263316339316338633930343263653739663135383334616338623263626634393065393161 +32316263643339396562616430376162646636373662663631393634316136356465646239386538 +64333837373435316132343234626237363138336637323834353638366334366162663564353363 +31393033373665633466373539353239303436653034376137333863363930393962343161306561 +34396539303932323830643635623737333434666437326463363236636236626666653632613734 +31366363383834383665376361303633666637303332366537663134646536343863333461393663 +30633534323336363335636262356531363138316434666536393465333238383566393531623565 +37336435306666346263383938366666316465646239333561336463353237383039376431393536 +38323430353962623866323265346261333461313237636333643234343935656634393165376333 +35663634336635346363303761326262323831373065643939666438633065653431663665383661 +63633336616366386534613930626466656639383533633363313264326238303435656530313533 +61333433326161333162356433653435633837376332393438666131333733346536383863323434 +61353864393736373934626663313332646466383435346134626439656437306133316365366332 +31303135316364626163393035393236313235316364323066316539366166333862356261333464 +65346366333664316231626435363339353063396131343239386136333062303264303534373738 +32373636376666663237346337646166313832623538656237373536613962643862643436336634 +62633362323362373161613762666230316661353635323965383362383639613262643366653266 +38366133333136663831313939646465383166613064643264656230663432663463393133353330 +33633330656463636161663765653038373931663437356139353231626238643237343066623134 +37623035626466383136376233333632383563373461633762626134323136306139636239396366 +38663131623538356630363863636439643630373466653535393464353261336331343666343562 +32353364643165396433316134646438623131613237363735623439333839396230613735303034 +64626262346262643537656136326435643462346133343130343066643932313866353437396534 +35616137323964656361623835316431643430383834653534393832376530366462373366613036 +34626263383038666365383934613963306662343066346334393866363761323163396438383866 +35346536623265633963323632393834653765616137393764653234323233303237393230346239 +37633437353931306536326233383462333938306639346333396338633437633235663833363334 +38353563663764623066306662303234633737666535653536633366613730396336353063616339 +32613361393438353138393061626562656561383863376531356233613565333338326661323035 +62383062613034626235343331346461393562666365643438653963646435396436376633653666 +37666639633162303132613334626636373736386235346139396331366136363731346663323436 +61666264376339356364343237373631383333313539393933633661333339396539623531323966 +37323163316130366361643765363530386139316536613939626131323333333536306438653664 +38356533643865396130336563663635313830393835376337653963323064326530313531613433 +37373136646530393162326639323530653431636661353836343762663161383664613965383461 +35633663343963656566633239323036633232623964653334623936333965366364386639653638 +36636364663363376330393434376131323733623334646536313934373163316363386362663935 +33363436616435643837323632613532316237626164313937653063356635356135343965623133 +61616438383837653539643532663938343634363064353331613838613433353834313261383331 +61326331323836316531633434316362326238643662653764613766656166623564383337633766 +61376464613237393731346333313465306466373965363036633335623236303463623234333934 +32346332636166316231363136656236623034623231303261396533376138633939343835383133 +62373965653461373264343565306464633865653231356461393432393430303630346466383435 +36396434656232623935336535316533326366386664663233333533336331343563336531346134 +66386630313264303061373738613934373665623663363934356361343339366463336361346561 +36363163386263656461376563636530386333636537636233616564346239383638326264363031 +62633562643332323761393639326664653164653136373466336164343761373861353639653836 +34343362616631303864653865666666333631396434643337666164326438393238383234353230 +38643937396634326666616334666336616330303438643638396339613361656133303732656539 +62356131343635656234333134306132643330373934626633643165313138303262623531333237 +63616138653537373335346533663135626137333938623335613965303735316332356635343837 +62323632633830653166646631343039343166366661383861633866636261623664323134653133 +66623963633930346334383630303262376431313830663432356133623565653535373365653034 +32303834353831303737623332323063623966373338333233633231633961373031636666316432 +65333737353732313830613466613631343866373834333330343339653264393734633235626633 +36666633353065306235336538383866366164383466643838636234343035363662303438383536 +32643063636162396630316661623662326462666466393065363934333733326563346130656336 +65336436383265336336313532613931363564393965666239393063346364353431656130303661 +37306562303239633666396563323165306637626532363030633939383335633036626233613032 +37623163633863343665633462363535353961656362646333666537643564353063303136353632 +37643362646334376434353134326432376436613437653734303066633063343534356365626233 +62623431356165633736363237633538346539373163633330393038363932343731383633343033 +30363438613030346631376630636132643630623535353336626530636534303165323937313264 +63333865633832373233393462326332646334343662616334356236636130313561616538643537 +64316166363262393263616532323831376261336233616630356637306365613336613463356333 +65623366383535356465316261303335343265663734643131643261613735343939363566613738 +38663962303162663066383134326436313231613931313730373139333636636139383533393963 +30343231626263306161666330366463306439353638306535643138663261346265306131636466 +64366161623439623464396235386664643330646435336637323032633832653039623731626230 +65386439353930653762623466366132363061623966363365353131613866376632646332656330 +33636461623831386435303265383565653036613166383865613332643863386539373732366361 +36626138346364366439653436353133353732663562303337633664326339333465653162356531 +37323132323562653933643064323031376362366165666464356334306661613362336135316362 +61313266366233306361316235343166326461393731613636393166613531613438383631313032 +39626337353635316266313133616130623930633231386537613236303835666464326661646138 +30343930376536383134653035646133376437333837316331343832323736616361636635306265 +31636231353365633761653139346137376139623532343362313661306437316238376563316665 +63643537653832366632303763663639643836616631373264363462333964663234653564383139 +66663161383733353533363766336266313631616637343337306132386531653339316633363635 +32393561633332316565643532336439303239396631386665383638313065613961626438346536 +65636334383862306465626131653234306134306466336165663935346335663862363234386232 +36363736626366633937316137323434303634373865383363353638663764366338636633363936 +61663832343663643964386331386662666131383934643264636636656466663539653534653932 +36323632333234393066653861643665313365376664626161333939343536656562656564393565 +38333261643232366630303035623837336536666661323930393230366432653333396461366235 +65336331313331633139643033303863373234646235313838626532303562376561393038663264 +36303634363236633038626432353939636237353834636361613233663339363538643237636333 +30346633643235633537393430336535323931303038333832346337633732396230336238666665 +61306230636435346463633138323339663733396261626566346163343639633431343035663130 +34633864613837636337653439303930346366333666643436376263666161326166656536333033 +30616638663962336132386566623962633130613630313935376131326433656431613530653866 +61303066663738323164383031303732326333663865313662366531666633373264623734343934 +30356166623664313336623065653463613965643937653330626435353133346132313965666339 +31366536393136626665653832343930336462396165343332376234363531353337376565393532 +63356163356432313731323366353639303933656533343430356337373832376261396665376532 +63643134623338383364376139323163373236343961626433343131396530396432393331346262 +38393430333538333238383931663464666266613662653964393533653539353338316361316631 +31323137633137646337386632396638373531303438663965656364316132616666653037373861 +32666139623730303834313835636664653437623336633332633733616335383530336666633033 +32636336636437343062313963316533666461353031613836663665656431323934343261383836 +33613031386331366361373935353936363061643262303233666665623632366161633163343163 +65626431383132626564643163346537333466303536326465383934366335643664666631643831 +38623064386436376430323732316538666462656266313937636665343463313561633239653836 +62646565326230323934373337666166306663323166393962316536326230666363393536613837 +33356236333162393866306232383931646532326235396632303033663935356430623561653635 +63363663316431656231633566616662663432663334316464373030323137376238623736656164 +66363031323533616136303765343662343330383762373230303537363933393666313566363066 +65653834306531653066303066323232393530313136646163663638646464326638656430303539 +31333163666530613564663464313662386135386539663530663538313337383761343663303031 +61643865323936343833643838646165653166383664393532623465386464373463633166323566 +36396137376439386463333130316234363936663735353037383434373964353236313232313330 +31646530393435383636346166663838393762353133303339386233366234643131313932663632 +63313064666430613036633566653339656338666630366363376165613364333465383538633435 +39383237373431356536373037333662383833613030396264663537313131343037376266626133 +37373066353036393239343233333763313337653861346262356337326463313765326639303237 +61646434363435353933353035376662646264376266613433623032386437626339663436363962 +63646364323335643433643137376464626234393032626463646162643265663663346630623336 +61326132393439623839313735653833646364386134663836346631383130666663373266343331 +63376131666663643265303165366162313162376664376164353136343935656631633064356334 +64656234643737343631626562653563366431386338653732343731373632633339366433386534 +36623164646166646336663062336237366130316532313939313939386462353138316635346537 +66313732623638346532303864363138303737376465653931316662373863373632333164356139 +34333965326533623534616561653264663562623539653661376366376232353433643134353264 +34643062613037373837626232636139643832386366326134376634366631366232356331356438 +39343561613134346637393430313530313239356266643635613033376537663936646563626337 +39383737393336336161306665303437383534323566623835333737663539663834653331303835 +33356532306432316634666534336165343261663736626630656364656533366239373864373334 +62356531396165636266323465626230366534633532353332613639303035623533646562636437 +32396232613135336139373066376164383939643137653030346636386237303163656134306536 +36366438316137376333613939666664666662363833386131346237383065303932643438666434 +64633131643434326466373764343265646461666330313031623635616135313836326438373565 +32373537356364666665326464343863386237323938326436333461346632306265303739316161 +38656436333562373037373139633234666664666234356164643530323235646462306365633431 +30643462343538333864373834336165306636343334353830376566393438303463323664646565 +36636239636437616364306336623435663737353036396330303563366663613833663038303936 +33366261663562303335386436366139653562613933353265626431343036633262326436303361 +32316263303832313037356531353231383439333664613138326430396133323465323132333136 +38663732366265636133353936396330653531376132333730356537323339346532356534666535 +36333632303832363562663362663136313033313232306536343630316231636564653462623237 +65346331653235613436333236356661656162333433366336646238363338373766616165633136 +66383865626632373239343334623537393732643532396538356561326463633964353836353766 +36623534623739663934623730653331313737343236373938396266643936323232633237396339 +65303033356630643237383463313364653238343537613935646437316461306264333062386533 +30343539613162306633363335613330316462666635356434626433303938663965353862313066 +34616137626363313561396232346436653232396130656562313761643634356332373732626362 +63353439626633333630643833663036636261393431353338343963356464313631356338343263 +33356630303837316165303535366234303534646462303931383362613763383762666134343338 +64373766626361343365626464633561646337663763323366643132353163313236386333353132 +64383766323137373061363964616331383232616163336434626535653634623339343839386661 +30343633363764376132633238343433373265303065623062373335346430643266306534666164 +61643461303164623764643433356166323432363337623165363463383666313238383638663263 +63323365303730356561396363343137386162633866376263393566343861383232306163316136 +31353437323330333834633332653534393964613865376263373963373936646434346365323662 +35333539393635663764353763363538623061383337323031656461373538373431616364303961 +37633832623939346538373338666131633332393966646339656461353236333764306563323035 +30623736303134336565626166396131363637323233363032666635326330343261343165343538 +31656438616638373133323361623433653835303037656462356432373830366439383938616530 +62646461343834333930383333623163633531653936633061356563353365373765623030323365 +64666439663261653037386165373466353365653731303731656166343732336664346137653330 +32623164623435653261653237323739313066393732663837383435393866633939316634346137 +33396336353630396234316532636563373838313733333938316539353636383561356339643035 +34396439356463323439663065663030323065313432646563616262633939613562616535633362 +61323437356165363064356537343432306365343763303635303632336138316336353463623561 +30343361633631343563323335666430386136653230646166373830663963653931313138653633 +34383839313436623136343562653338343733653533326364363831316535646137323034343631 +65303764366565386165313065373865396635346134633833633537653032636435623739343961 +61653265313433636264343631353265396231653437633336336133636434663762383263646635 +32613632363561306437313463326331316662333061343462353734646364303937643137303763 +65323834306532343663346338356234376562376535613661336463646334653065303166373161 +30643566326363343939666334636664363632373232393661646632343237613131326333373062 +34666632373431663539613935646663373735333633346134393631636334626463323539623366 +39626361366536326563303865646339396437373337323734623339323234326165643834666662 +38366238343932333263626338303066346364623934623137313233373631356534303939313734 +33613564633138356131633239643239366338366334343162353062313461623061663464363464 +65393831316339613161306663333731376636326463373161373939323937643238626130383935 +32313531666139356162323931663433356434646530366461363164666339373730343961643733 +34383939623861383366616266326262656131326335656164666239316363613263383432636266 +39653664386564366666663031383364666536633538623164646564386430643366363065633066 +39353533313836313636656261316231326163666337626362393062323738346636313735633761 +65633565666361333435646331303837323037313966393132323737656166623933316561303033 +66313761663262393163376639316161643262346630373564323366373261613939666363313232 +34356638613133333439633835613065303536386330373535663633343539383966386236393836 +65643963646164666363616338323030336433633130333230633665383938643532333233363562 +39376165666465313861623836303337333562366430306132323436333534333635356537643037 +30373132623561306337326530653965396665303930363239323833646230643535303064376337 +61316432373534663934363334323764623832303934633666656463636439653532313062386134 +66376430653336363233366635626534383530353034643839393739633230383938313339373335 +38363736323163346630613265643436316635343539666137383232303033396562643463636466 +33346262666431336630656138316165346339366636386431343637363837396132613136626438 +63396636373266646232313637306536363234343230313938616364336566653263326565663031 +63646264363864396233386130666430663366386437333238643138316632323064313131653937 +38386366386363346236613164636265636666373732383065623030353161346364373933626532 +32653064356131383334396232636632633031646331656633366237323131633335373931613464 +31613730353564633462353536656535316564393566633065373135383439313439313263303034 +63643034336563623337396530626366666233356530646335653730383435353064363539333235 +33323732376365373765363562663839643661653261333562366636646464646133373363316561 +39323763376665356662656232333234333739643761343438653731343537626636363237303664 +32363630643366323866353436666366326630643635663261343236363164343034303461353336 +33356638376532633334656262303563313665663961653866653261666361326264326433626535 +39333138353161323439626537313538643163666539613239343265353433383334643039376439 +63396366346166386164313765393762363964326164613564653936666262323766316465643035 +33636130653263623439623039373938376165313165343033373532393932663364613434323536 +62376263313463326132396234376330343935663165353230613566323462616236616361643737 +30656666363037316239393638353238663931373765363039623238326361383366666437353536 +65366235383033636462626666636138306230653330663938303262326333613265653732313437 +34666636626135353737653036636331666538353364643631613864643439303739633531363335 +31616637653663363261306234313265663332313337316135636162613761643939653762613261 +32393364613166313437303436326634333138623134303736353466633730353435303131613733 +64326238623064316163343066313330653237313034316638656134316637373338396562666535 +65623564623163306239373933356233323166663462346161353934313864303262613866383831 +62346133626533626133653237636264643331333565336665353662646261663261656564353666 +61616236363765376137656334363866643436383961613238336261323138343234356531363432 +35303766666234333532616565623839663733343739393132313635643965663865363630303637 +61653237376663623666306537306435633838363430373531326664393235353539656164343064 +62356638363630303235376563363761383432633339616462303136303738393334323561343664 +30363961316365613135346466333863613966353263313664343035666232633338303638643930 +38396564326265316166653436353066323730386230303237653137333465623831653739313632 +39666531633938363039343332656262336231396263303835333032393539363033646562343535 +38323663356637366136663336663862323730303839323534613532616438633362353834373930 +65613938626435323633353235316165396437343464326633393337636163346263303637383065 +34366139383339636638353537653034323633666166333335373866396631623938346333393661 +37643536666130663332373262613064356335363039303462666466343665346533643462623066 +38366432623835623964626539616536623661333430626434366537653036313338623539613862 +37396261386138316333656362633966396337333465343562303966333731363933323730396563 +39623534366264333737313430636462366366636532663037353161373364636438623331343037 +32386238333935333231333161393665633139373063323539363761633032353533663939656230 +66336533376237323239366239623632336635636263343232393363643633396435383231346266 +32613133353066656562383464353130363637396538393365366333366238396635636134393364 +32383937396531383236666564656461373663636236663730383362336337316336323662376665 +39336437323239623937306664643636333465376433666361376663376661376138656333343732 +32646664306637373533633934326439613666663935316235633633613662333837613933366465 +64383461373834353766396530636335323063663239646539323538373535616534373464353863 +35623439356466623539393938326465393064343961666337646165336638303936373664303339 +35313066383666656665636539663264666136666235303238333162336331376531333430613335 +33376133336637313362393135366634306233383166383532643938346661363163383137386464 +61393832316163366537666132643131653464336637313662373662633564656462303830633033 +39653534646539373064303033373933306462363630356530373536653834343265633039316562 +34613064626237633937633164616530313132303234653733313863366630393633323639663530 +62366231633961663931393764663437336431336338333338613733396463316466633564626439 +34346465636330326536363139613337626135663531663662323735346138613437343766366664 +32363931613632353365656163336266383139376461656435656239643638636636633630636437 +34633939353363373561363938366162383931396636313530343338616331393935313738393933 +66653831323561623434336536343934643531383663336632376233633366633539316138613161 +36323438336335643637373162666663623339663330626434343832623937363532646433633933 +30326333643566616366326532313962653961333364326333383163656332373837623964616461 +33396435373038323431663665303732623162663233303937383262303365656564346633393830 +31343139393331356235623838333838633735353066636435383838316565643164356139323935 +30626130363931323864343134363437313437303961373965393763303361396433393231363930 +61633835376162323865373332363866316239616230366163316434626639623764633139346234 +65313335383434653264643232626133363766363633616565356462363565346334613735333237 +62313432306264313762326161333337313430323737663431663136326435363432356332346462 +62656238306131356538626439376235623462346462393735313131313162316334656338383462 +65383961653563336438613132643266346633343766366265336535373533376232356261373634 +30666562313237333236396339316163626636316131303136336636333830373939363764633432 +62373231623734306531633832353930386462386662373438633165346133366334323837393666 +38616231323131333137383864633964353334643633303466393661383537626466656333636264 +34323065323431306334346461353436636635373734353537316139663930656262323537333764 +30663634326530366536306434343034636562303433646364323839393364383238643561393237 +35356330363563393265373637646364366437396137373332656338636431383863333333313264 +64323635643539303961376262643962633138396231343433353330303637326533316366663362 +37646430376564636332323965656264376466343965623130353666386263636662666338633534 +66333161393061613337316666633466383139373362623463336165666637663539363862333834 +36663330616530316630393035336533316335326337323535353831633736663736326433353961 +39376531646664343564653931373364653332343530343632663739366530363737353661386530 +35623439396362313138613732653034396137396464326334356237656162313666643364636664 +37303236646566626534613335636535353764383131343763353064303137633133316333373738 +35623632393166623864373433663439356134633761356130383864613063363363656461616137 +37643238343939363930633936383632373035663936363636313639333339643962336362356366 +36666262383039633165326335366230303861326239393933343763626537646163383130303532 +31303364646264303663623633363966313961646462323063303465396365656334376163323537 +61363664373065636537323665343165643064306539656439303836626631633430336631643262 +62616461663331346535323231656530303465386439656337636164363730616662323838656237 +62653565646562383362663634363031366131326638383535626435333538306132313035313637 +64653264623234303834643633646634333935313236356431363362343762343730653833363031 +65343030316237613965396139633535643231353063613865353736303438353066363432306263 +34386435303536356365643738376535616435656361396333396162653433313331636633613638 +31633335633632306638396366323131393734616132663531666262626636623236366236333731 +36616235373939333730633738393739633063393865663832323836373239373963323162316630 +38323438393336386565623464316366303165653137623632643533383938613264356437613635 +35313432353538393234356263363366356565643164373763313866623239633637646166333530 +61306664373764376631616331336662383833356235333362383039616332386236356363333563 +63376161353833623936313839363037653533343331626239656365623562363632306636376561 +36323034613766626230306637393661623063323061383564353435373162646366643933643562 +65373436363539393733353132393932643739303063623532323862396633353462383261623230 +61353637376532323566303031356230623632663630306161626334356532366132343531663534 +66323263633134643732623737666263346538366565343863356463633464393432326138353931 +38333964366230643334663835616465613466643038343361396134663063373063363738383037 +61656437393934376130316539386536653737356130356335356634323361333937383833363836 +34653662373461383463336336613336313865366134343337383065623266323265636539386537 +63323661646239326663636437313333343236326438303361326532313332646432373535653363 +36383466323236613335323365363039313934613762383366326665636335613237353139633834 +35376165613137393937303165643863353833343565396432636133373130656266376131353937 +35643362613862396461356233616433326363633834643234393261393362653039643164653964 +63343565616266373461376366613761393862663430643665616236396535343934616562623761 +64653639373739343831363033363363373932303133346431613030333631623935356163393964 +61326563666632303838366361613966393465366666376366646330623837343132376439306437 +35323866613138646364666634616536646630303338656361653936613933633438356263306464 +34313935636263336638383262396634383433333661653963663331636239303266366661386438 +63656236623563316266333463376430643333326133356333636631303832656333353939646164 +39663866663435336630303237316566393566346237623432306364353964303135616638346332 +35383930653635373133656361636564396161366166623435656233643162656565626566663936 +35623539363633373236623332333831313062383932376261643262643234363734656166363436 +61623434316238303036636330653436373661373230663865653765396235633161376238353365 +61633365343030373934323137313430316130616538333330316563653034656235343039316231 +35653630363330633833653336653139323361353764643335393132663162343336616532666164 +61343563383763336234336336666362336366363330653762313263663337393832623235643831 +31653463663433386632326363623365323438663431383335373433326430313165613339366566 +37323837333134346137333637396136353138356230333235633238373566643764383262346330 +63363138373233636133616665653761353638363162663236366534353435306462303661666536 +39326232663736303466623131653961366465316338326635316232636337346536306431303238 +63613233646461613537386430313630333566643536613037633335333134353431633833363835 +66646364343230366530633563363634623137313832386634653937653431643031616165633365 +37383933346362383330633339636464356339373365666135343534316439326536343438646432 +35346132336139326465393232646230663232363930343037363864636534396632343335393838 +64633236343661313438343261306462623035386333383261353537333235343439346134633163 +38616161396336643137666433333438303036616165323237353338386339663163336465383039 +34386661643064303332666362613833303562616565663465356261643939303765313037336331 +61663735623432336466613334333362346138363234346664376266396337333465336531336661 +36333162666436396337396539333039343966636433363730383331393231326534633537633337 +61313863643565363064396634326561366366326532373436633166326461363735353435393465 +35623234653732363761656464353364306335306632343764626239353231663430656339386631 +62326430313037383433343761643936363539623736383662313665633330376139363533383464 +30623938346230376630636535343733613937343564353732356331313135613061663834643236 +65396530356565343336393463646363346466653463313836623762663466363863653031663739 +39323232393261346265326331666130366263343130373734666366663939353336393035343335 +62666139626665626230396463383064363531353039626262616435363661376238326236646135 +31306362393730326234646132613835383963626430656262323062363439336364343864666534 +34303235643166326130623437623435623164333462616635363564343230326237346562393031 +32343966373331383539346161653865643766613164316332653239643635376531326238353830 +66333334316232633239323536616332363463356633383932333937656637666261393734316264 +64616566666631393461613738393635383830626162643339303335653635343534326264333163 +63653731653931656335383236633866353837343139343636393062623363633565316464613032 +38303939626433383637323538393933333035616161303137303165346365343734663965633137 +39396430336437326430396164316638393664633162396537373164623639396534303865396162 +37626662346539633766366264366166366539626632326239386631323066373739623338626131 +32656638633734396662623765626665346164643734363865656539376363313861633430353565 +65303933356637303366656563613335633462363834636333313836616435333961626337626563 +61386433643232326361336131336330373337343732663735346263633561633839663731326663 +33643837326363663961336535376631333438623035323937616339626263303665653539383435 +64306264313461313965643966333838393531626466663664313537323737646161303735626264 +63346563666437383166373763383262623366623062326636383537626132666230373233393932 +34316433353330623863396531656334656237333466623566636439626662666138303561316239 +37626333396337643539353538653763333265646237663464326333643162333835313365373936 +39326436663037336337393762653338363765663634393035343633663161373863643133376339 +30643137656338356662353433643362323335326435633663363439636634313666663631356638 +63313436623631633035316636393966316564326531643264363364353233386231336161666531 +39633864343135646561323634616366646437616238383433353230366131333933323734653264 +62313361623262646334303963363931373562343230353139663838616534616263373637336238 +38643936353166646439626133646264313934376431306430383232303331353231323031376134 +36353162643335373734623031653432343865383564656236663662656563393163336261613864 +32353562356464633731396136636530636164666566363939633230376435346561643534643136 +39333165643036366335356665613236393961336435383333373631653265393433626238653639 +62643738616536616234656135346364623539343466303263663130306461363764613039663566 +38653236646235666166633638306439363964353734623932626433626264393032303861663233 +62623532636632393362643961333935616533383737656234326539663237353566643665386261 +36343462376635623363633866356133333637633835333930363735666661656661666339653233 +35313430353265343232623436323462396561393134663934636433613431613764616266396563 +61306535343031666437323962333262353639613236353463666635313931373839663035323239 +36653531613631303939616231316436656164383339373636643231656539646431663531323030 +38616166616334346130336131373261656533656334613032303433643764323332633639303338 +38376263366433616364313336376365316361366132313931363032353938613366663163313031 +31363863626334313939633035373633386263653137613337623264363865663433303434353932 +38353735623034656333623332343233376264663335663430626233373632313530343066623837 +32623237373363666361316533313563313365623666336266633664343633316437393131636334 +66316664303263316366393830663232616530393263663265323730303732626436396337616536 +66323666336333313031623538653331343132643237663331373936336334336533393163323630 +38343035346631356138663733353363656436633331343762306139666335323266306263333831 +64653863316536313630616339396461396239366161326432626638643537363139623462663062 +39376565343234343235626364616135653830353262656461353838303836653839353236646437 +64393931346562373461306134346161333036376635633538643464373935663338633761326335 +34656239396163366639343733336537383830343963373430353832626536326361326537653162 +31643636366563343933303237666637383663316261313632396138396232386335396337306435 +64626635636535616137633266616162633634613464643034656139333263376363346464366264 +39663165373735333037336264306131663137333864313561623330393831616561386266643937 +34626363396336613962623165313134333732373365333732623361623132383864616263323433 +39393538613034613266613832323433663131356235613233323363633362636364353766656366 +32633931616333633830343539333431633861343231616162343339636431356432623939343532 +38623066663634613031653135663734303766653734393232303236333836313664633339353132 +30346166623333616365316438653539613833613235663833363436316265663433386435373861 +61646362626231373535303761393163656562393634323036386239353337643564376434343934 +63656232373636366361343933366635326134386635636431383830663865313234323564633664 +36666538343266313166396632306632653165356639633732666530626636663437353738356135 +34393265626533656563313331333139623532396561316563303263646464383066663332396139 +37336465376162396266323063636238353537363062316632393432633030336661316165393064 +31323934613334316363346135316231306639393935313635626266303138623735303064303036 +33623836663461346233376530633363386163366637623265613034353762386435636235316334 +66343663333532393631316136316336653431626537393636633939363466303566666566336565 +66656535333736393366303666373734656566333136613039333038643462363230356366373039 +38366438643636353133303434643966323531346561643637313037623734343532636134346633 +38653735656634343739626365643234323832653633366163303436633261343636656538326537 +38663465313366313666376639373533643836353330626534363039336333316630616166343762 +61306332363963343065623765623738633663613136316530636336623539373237373030616134 +62393835396237346365343137656138393739346436646533336333656265383266333432653862 +36626238613263323765626664666664663931373661396430373961356462373832373536363532 +35383433623038646164646439613966653939303234653435393939353465643434376238666139 +64363632303365346538383361323239396535313465376232303639326133643063366263623363 +39393136633461316430643930353436393837333932653438336434646364343838646639393936 +38353138386130326139653564386466303238363538336637626566373031633963316239316435 +35656432653031393734633039313165656165333463386139363436646235396132326664333232 +63343436316339656461333436376332376134636436623464336235613164366334363732636662 +38653261313463306234663066666639666238393338313135323838613030663334333838326362 +64616636393439653133626461663235363466393565316163353565383832666166306632613564 +36336338353737336235656134633237633838633330656264303934386261356534616161646464 +31306431303364393765636461313035323237623065346436383937376533313666666634636461 +36653366343066643631303862623031363561396330383066363830313336653835376364313239 +38626135336534326134326664356432356264656437313263653233653364363234303835653433 +34333932356132646338663734313733326266666538353661656365393330393235613633623863 +64343931376534336531623831653439373236383634366265376165343331353839633034343561 +34346330633562363938326363346539666433316261323463666638643736376336623231323331 +64636232613266376664346364353739313633323036643864333734333266633637383030343431 +61323539343161623464323237323832346231643739623161346433623961343533656665663731 +32343135663834373937646639646333656130373837333636303031343064626337376231626265 +39313232326232313161366333373731313261393166653136643066316438326364636265303262 +63326664656262393830636633656138343238666463383663386262316535643331343131666435 +32363031326464303163376530323763373961396463356235366231383363616663336166306231 +37326262623563333638643165373161343132623330396636613061643262346639373563626365 +36323062623763663930313965323062386538383634336134333937396234353233626233663530 +32396564366162643631306332623630313533663465663633623162386464626235363231316263 +62666533336561383133353861633130396534323331343962383039626631373432623737653233 +33363262316436393633623537303466366630393131373633376433666165633139646565633963 +66663130336263303362613161666635373763373239653363393230373161383638613031326538 +30376131643938636362653866393435656663353332376439376662326439633538643964333264 +33376366613563353064613030303632333765663061316536343061306563616364303134323361 +32306161363934386331333537306663613865636239396533316535663634646661643762316131 +36346537323039313438646531356535633337613037353964346565653064323432646633373134 +35626664616132616135373062343664613534626366393638643338613737623132336539366132 +39363466316436326463326337383165653333336462326166643563303439366330333065376634 +30353535626164623839633930316363646138363439333132303066366632336164366562643133 +64666564663963306538656465386566393837613533393932373064313930653336663961363061 +33356536323836613132626530366465646530383661396137666662663562313862616130653137 +38636661656432326163303165393837366531356630346464383534326130336266333165666337 +33636432313132336366306532393361626566333762646637363163383766656430386136313732 +65613237653536376135646134376262643662313261376162666434346232643331646139393562 +62646638623330623866346231383463383935393233636361636264613432303130393761383637 +31353361663665393539393439353739663132633435643831623432363438306133316133363632 +31343939396531343431633662393231633938303833653031653864666330313238376364643164 +30653734363338373339633564633862623162346237376532653961316364613431396263363134 +64346364646134666465333130306461376362643838336533653333633362656235343333366431 +32396161373134323764376566626162316635346561386638386133613663376634363035356439 +62326336643230653733326431633333353037366536656236363166643039663638396139343561 +35346537643866396665373331323162643134313033313737396139363764396462383034333835 +38643837343237376333653166663064396461396434613830383061323066396538333134376165 +30363065353433353463346530626162376630363063396565393730666634653533633339613364 +62353964656632383935363632336466356363393638366133663463306538303230386663383663 +34663532383135326462636132643631343163366531366438393239656531343362346666653432 +34346330656466396161343661636638373864636365393362646231386166616464346537353432 +37613936636438316335656263303861373465613438663239316161313638633736363265373961 +35666163646637636663396161373564636566626138666464386666323836323336636435613139 +35616230616436663739393636643738353237306663623766333537323038303966373731363431 +35613538356461383036343763626463353530633930303266343331343335666165613739323365 +65653030333432636539396333393264323062613665613935356637643834386263393930323932 +35343837633431653964393231623331313261356536616462343537343830336532303564333066 +36303832323864316439363737666532636563383662323665616637316665653735363735386433 +62623033626662323936376333376234353938313035353263616136623033396566663937633462 +63366536663732346439326566303836396564626363646265616636663333643162326433346631 +61356363323737386334323430643738383665376336393163346234396361653830323431326661 +61613733373964613734343761326466313339653234396334653162303631613637363164613337 +35336564663462353165613734663635363866376237616163353065633539316433306238646633 +66636462313166323661616134656638366437323939313464616130396261386433376130316462 +62393030663664343362346135653261333533623935333765393264336339633066363736363765 +61666462653931383537376562353261393137643134353837643834333466393665653435333736 +65623231343966383139376438323336363131346263393438323334336637316537303662353633 +30663731336530393231316464653161623035346531346134643164656462643537336139366263 +34356566646533326130333136363931663162386164373935353865306131663335303332333132 +66393239646332333761313737306433613731633466396236613366326463313130623962653033 +37393737316262626662376330613266623764633133656666323633663730323133303462656531 +38656533623539353262326531396239346630313661396636613639363264393263383365386433 +39663939373734613363346362373737363237326565626132616165323732316635323935393930 +31356539663830643530663730623761376665373563623066636436613939356539363237366666 +35386437633931663663346238306330383232356537313435623563366537393635316361336161 +36333233366130303036663135636433386465323139636137316161303837353830393930643438 +33313534313733346436653766383833336461306265306336356264613761323335623765303064 +31313831613162316232663764373861313664346334326530386134393935333664316332353563 +66623833646462623936666238323830653534666230303537643661333336633434303063393063 +64616432613439383065303066613937616164626630616531633261306462623165383163636238 +65386662306661653365313630643838303961313538393538393339323238626238353936373331 +38323962303330373930636332396561633630636162653965656335323339326564613731336266 +37353862383732633033376537396262336637623137303662633237646633653465356666663663 +31346463383539613534336336356131666333373835646630656235633730313062643464313037 +37623661396233376264393364306435306661316266626666316361343438333732613764626562 +61623235636662383332366262653033646261396639613032656331363636626366366135323839 +38643431623532306164333765666638613665643238323335346536316636646239623133353339 +31653731306535346636316637373863623234636439326635306631363065386534653435336665 +37356263313564343732626535623531653833333834613437663739653235383065373630636539 +66383361373564653136616438343436373962623336633939343837326434613134613530363833 +38333065333537383230306334396530633063343864383934396634666336353530666132316532 +39646563346261653763646434366339356333383666316265346533393636626664323865363039 +35666663656363353632353438613461343130306131336165393766356131633561323039303561 +61383031663834306437353732393832303263356462303231623366663466626262366631663761 +65656266373862386462336133366561633164643634373136646461303833306335393461663562 +62616238333139316166326639333064616634373663303239326130393035333763326263386333 +35393230336637363739333432343062653130616465353231393936643032353965373130356330 +30313261653235393533613136313838393138383166363830633062646231653936353933376330 +62653465633261336430333732623033343466383138336563366639313763323863333832306133 +32336632646638343730313931353531623461663333623834313335653764373865653438373133 +39336335376530353563633130353832373961626561343335646166353264633634656161306331 +65613437643135376439363836353363363932303936623231343632306262386530616637386365 +66303933383562613537373133323866623437383034353936386666653763643132626662353732 +35336632396365393434653564303733396362626335653730613962346338383066633062323766 +65383564653336313436343163346638353934386439666565313730333538646436303466616331 +63326634343332616637613563336530363130303832613664376333353539656262373939316537 +32313531393765643366336536303462623237343337646261653732313834303138373964643162 +38383461336532616464363935643966336364366231393163393931663936613239383734383830 +37323534393837303732343564363937646634313532643039313739333335313166626165643935 +30303663346261633762323962373434623762353935356666396633616237356433386139343830 +31326564316232396566663931306533373064613364306634303063313261326136366263643437 +63363062393237396366386166653434336232616635663539333233656439303462343934393437 +63326564323062363166613238303030346130373262393061656236623732316430306266363038 +31303239613533613662366263376637323737653963313764366162393065363665393031396534 +30633764323665346462626639363531343033666533313066633632316532343531326561306132 +33313134383735363339383765313336643866313031383661303030336536653332623563316230 +39633230633934316265363235353038653431613530333666326132373366376234646161346136 +31663439393830383162306136326139383264313936646230333834353463356138666635306631 +35333462613631303532663137643737316232373834346636353362356662663336633030613365 +38396237363165653531646263623333373731356531383262353632313363396338383333663038 +61353635373663633131343037333566373234366639366630663966346161663734373261306161 +32663237333064363734613134313862616538636533303838343732343038666430336438623239 +36393333633536336235383765353237323835323130636236626335326236643234343465383439 +61376663363331366465346137653131356463336536616236363037343130623466633937303439 +31326331353938313366383037323134363230666637616166646537643431333434376161383061 +35653639383063336561316538313663656436343336313335363133623330643330306632656338 +38643261363762333432386232356232646662333164303838393830626666346230373839303166 +34666635343665663233636664666263643138646661306236313937336263373866613933343137 +35666136333432363637306132636264383862393237663762316633393766383530663866376131 +33643335396566353036393633303135366638313064303462313834663566373138353731363434 +39636334386462613934383263303862613166653538313263653362653236306135333231383065 +64663663383235346361326234623632363630626634363265333338623961353038333163663734 +39316565663033376439343135356138653765303666656236326534323632336665346364653232 +34653464616537336235623565646561643538626364623939363935336436633939363663613139 +35653666376662303862346339643962663065613866396561346634336662653938376434663038 +33663763653665663236363736656635343661386131323636656564376532373862373638643034 +33343465373436393437353138323763353332623633656630663562343830323034333266323238 +35383064323738613835623430623432393435353966626332653665346461323237643734663834 +30386439393034376564666237646366313763346666376336643737636165333736326264333139 +38313035323961613866393136643831353839643930353438363866303436626333363639386232 +63616137333434383030643338613837616261313139346530343065613035626331663930326263 +66636639373163333430616232633564333730306537393837353737656165366465343234316430 +65613834656162643734366163356337396163376139346130373031623134653233616333376534 +61653264346539396461646462363835393663393932303033626131396233376532356664303866 +33353262656633383265393638366138346161383562366435363336313165313562646430363433 +39373361666538353939383264386630353937323966383265333966383232346538373737323339 +62313636636537356465633761613731393631396662346665353962633235323065336538613863 +62633438343064663462623432373762323634663138346333353466356536396162323966653366 +33306335323532633636376161613035623738316132616339646437383036633639313063323063 +39623566336164366634613232356139613335363536313437623033663961316236343363373866 +61383366313538323331363665396431656264343639363762643763323465353739353962326666 +30323736623532636261623335316636316461666366363861323565623738386431303439393263 +64656631623331626338353837643230376136313066373264323732363835626661303865633163 +36633961643132346232396230313237633737393639663264613037653535386630636439386530 +38613633346166343466646234323461393031333962303039356334633265353063623863363133 +32313163303936663765613935336239303835353162343862376463363763376535376531303038 +63363937353630653439373664353063633261366265636634623332653961356335383534346334 +37623131313064373438366333343564373962366138393735396364646638613034653934313135 +31363135303363316531386632363062363165333130646636303839646466373932636666363835 +39353130626564653936386438333734363239346463393537303962616231376433633264643366 +35643133646539643739386635333331393434373336663865626138393530323132386237333431 +34396536636366313934353930323637356434646466653761373336343164626264303435636632 +64623864323162383164663166386234616531336465356561653438663035366631626631373762 +61383965633866653336303563383266643164333261373039643865353161373536376161373265 +34326231396438636439396466643565613832313235656136363739346262393039663430363663 +35326633396662393638656237363237653938626537396265343337393831393133663030336432 +65333139393330383536336665613032643439313566383030636334376466656665303164653036 +65383662356130376433666432343966363739373836633664653063326439333164653036383630 +66633461653136333730633734326463656263303537666334643932313362336234653464323735 +30656666353033333538326166656266623465373030323934643965666131336335633135396636 +61373834316633366463396633313737303965303835643536303066626133303639323334643139 +63353834643138393563623161616463656338333431363165666264383661366637623035356636 +30303337373362653137656537633565393065616639346361343264663737656265316262393332 +34303637656262633166393966346663643837393434663335333131646130623865356162393364 +66316534616465376232633134303062663066383835636361613065383962663038333162383439 +65613732393366383935396563623631613934353638613763616332626232643738653639323838 +38356362633134396331316632646436326161666362353835343734613766393565326266323565 +32373435393537626132316464316266373064306266313639353334626666646139366166346438 +31346666663432653163363336353830303766626432646161633436313735313238343438336630 +61306132373334316138303565356435613338323537363432633039623330663566376162366139 +62356331663632623161306463386561643330666630323861393864653861393936323362336132 +37633539333063626332666335343835386535346239356566613633346535653664323234356432 +32306666646363623835633130393063663865326231343732326335326363336666626536326438 +66373933323033666236343939353136376163386335636138393734653832646438636636313733 +64323830636235663162306232373062626632303362333838616566616366666532666337653738 +32316363393565303637346665646632356437356135326632366337666535643034383962366565 +61656666633231383664323537373134396435636562666237396633326637623837636234666538 +34633331656435643137343834353462383663343430356462363964313332626239663264663733 +64363637636363643136633262323731333233373564613030393636316364346230633834616537 +63633231353835303561333134383038373535376263393763306539306562636138356266343064 +61666161306236346239656465636537626138366536353331353864313164353337373162386162 +65306535646233306639343432616432383135323438323362393533303437343630363133393233 +39626331323961373030653165353032616466646135636165656363663133316436313237626531 +62653762323336613733313038353232336433653537373961323031383966633834313631333532 +62353631363430326234343864333562363030383964643237646330326161663866653537333861 +35613832613239643262353134373630633034396435303562333937393739653233333532373039 +35373634316263636363383563363534323439623663303132633036343437396165383965666365 +31656266396462383862373065653364336166303665623662363566356232376236613839626365 +63653932316536323366666466653963663862636434316166366661336530383434623938376134 +32353338366336653638313630663530623639633766323430326563636561333533616236336364 +31393130636566316466663662316233623639623766636437633462333864323137386630633364 +31626539333339616163636633343066383461353566346630663861393739626433613432383039 +66386664313032383465303866643364313335333834633266316263386561643238353166306466 +38643335313134633937376463633265303261633365643930376666653836623132376132613961 +34633736363332623339376632336631626136613732646137306365376635643839376231643037 +31663730363934303438346561303135306532656639353430386261666662373962616164663431 +63363436616636376561306239633262363234333633353633353535346130343536643863343736 +37333464323031333931306261393637633135333364646634323839323837316431393962623832 +39333365653830383734376133323264373262393264303434323230386564393132303938663763 +33366166376232313162316536316430303732626137613936383035383365343538313134346130 +34393734623330333538343833323766626333366334326464656261653234373261313835353638 +65653230313532303062333262393636663633316635386161616663346664643363626130373239 +64653131306535633939323466643337333933636336623534373235313133343565643839656339 +37353330643839376637653934313035366533343031626232633065663631323636366362323738 +38353565333431653032303131626132373136613039653366636661353565343336383162646166 +33663138656330376137666335323862386630363138376361613931666636346561303434393834 +31643031643433646139616131613236656435643234356435616231373065363136653735386264 +32653732313666303639616137306465653035343563343463646438313833366161613437636431 +33313431623132663232353136353963366566376563353539353664306338646232646639393766 +62663366323832656239616265353032663063643338663737373666336234323032636531383165 +65363936393164396535636363616136323665316236313165663936663661613964356563646266 +61656630636634366664653064333334393863626435333366383030353564343039316564366533 +38373832633562626463336239303061653837666338313732643631373139663263323839323061 +37336134633939373738346536653233613963393834333937393932653935386533363862333765 +34373636353733363363613666663631303764386437343163623633353539663535313638633238 +38356631326634303837373633323633353362303939316162386535623432316535643434623461 +39386262616435303538346631613866356133343433353639346431633839386233356531393639 +66326561623333356164623031366431316135376161626531303730333161643965396630366633 +66663338376538363765666661393032356264313833373065663636353431616234636566653332 +66373939623164653666663863633762373264633062616531363338636330363237653733353331 +30613762393463353336326263313639633839353332386463366534323135313433326265633630 +30396531393765626536326435376539396535643337643461356365636266623239346330656137 +63636633623265306632653834646534653437626264626562366231316634343966313532356236 +66613961656631343266653139353830323730376232353334326339646131343435636664626462 +66613037396339316234343766393436343133356530316334343733633631343034393166633736 +62363035333333313565333138356631326331373061633561666666336564646166333462616434 +30376166393336323431303437326135366664333530626630393265303933633834656632363831 +62383164653034363132346335316238333336613263323131313132306539316533336439383032 +39333863356565323263323837383934613937393437626661363232373039376162646161396330 +34646565613432393236393237323261623535303734313731356262363337373135366436653837 +37313030663566323838343962386433636432303630303564303538373732393266316137353663 +62333062316231383966623938666362663335613764653638303064366565343165636464616463 +36616638366333613530393565346366386266303736613466616637353232346238386137363561 +30616137636335643239333739363234306566363865653236323532643264336562386637643064 +34386663353365613735663330373633653031346637343536366433653735613030653334383331 +61386235306339313837393538313239386162346666373364306238363834313363363430613139 +34306239316139623136653562336233636465653566313236383432393632613130373636333538 +61306636393433396466613930333566616236616538626661353733396239626634303561643561 +37346164353837393839313766316639363438336662386538646332376335363031363332353831 +31633564323839376531323831643962303835363762313636376536626166663137393961333565 +63643935313261393861373433633362333164326535313961373832653932633135646135656538 +64386531356335623862313632313566393465626366656135663530383662656462336263356135 +62326664356361663565666565353533383037383531663530323237646135393165393566343661 +39376266653537396230313430303837333937316639316362383063633733386334353566303964 +37366161633265366132313665626337343661313730653535643730323964646430323733353664 +62383237653262356337363436633662356233343932363434656230353632363730363333643739 +63616230326139333031363232616466333265623733633363303930373231643433393839613935 +61356530333137306364643036363339393665663133336136393765653031343930353539323962 +39613763373862353535363335306263623235346366346438356263633863393661666464633038 +35653537643261666165343535306638346535303165653037366133363564646561616531366436 +33326330393232313131336238353332333365663366326537663966633064666531393533656236 +64663434313963313766373533303963396330353933356332336264366438346336636564616432 +35633536363065613961616432386264396339396534316263636139323334393332313139386233 +31373462323036633133316532393339393931353335653565653363626433303234643432313136 +31616562636431373164353635613763613738633364646531363337323862373930343762376337 +66306234616261376530313963626465383866393165366130343337383434323265393036656530 +30373162353032663033666565313963663734643738326133376231376166653933633862356366 +65376264613863343237626239306563316133306239613938366561333131376436613866343564 +30636664323866313430306662616536323966336238303937363963653739656662646334386665 +62623766663530386463643432393463666439643165363863366166646466336535376535316230 +39393131653638646235646433666437356162303237373062643232333737633066636563393830 +38653964646566386232383033633335633462333535646431383062663232323161393030363161 +38326435316335343664643836363039396465323861343166616266376539656335373166613135 +39303266363935363037666165663130653331613334653764353431653232356431336532396163 +64623162643062636332646465313266373838313136626537343061383236646533616364663463 +66316462383362626135393962643464643935396134633639613965623761643837383036316363 +36316266643462633733386464363436313234333665643831303431356463303834383261303265 +34633966323133666463363963306465363963306635613537656532623236356439656331626238 +62393530626430646534623562343338353136366139626431393536303037616161366662376562 +37646534396666613465613639396537663064333636663662656536336438303462313838623766 +64646235633033666166626634333935313632363632353237353234313761643038366230646636 +62613763343334393065383566346233656238383935663862316464393239613830656535323630 +39383835323431653361393964633065626366613137353738626638633033646365636234306632 +31613735656531323239663931363062646631663264663737383130663730353131346339343833 +36653630336430393566366466383861353739376638303830313737333861393230303236366630 +63633134633133353263343330633837616636373638303737303233323035636333313935663133 +34653461396131306533323463326561613130326664316235363161383839313734616566373730 +63653832353462633561366139333666346164326139656163393861393139326531613962376139 +66303436663665653236393962616236396531353635383465343334633336363436666335313339 +34306532303332323034343365613636383330363463373337343661356230636163356666373835 +32393764336466643663613763356236383139326465613338363039323731633365653764656266 +34613337386462393832393365313235643430323938316234373736623430626661393838663563 +61663136346339333236616536356633376266326266663939653839643735336566316233363337 +64303332393434656239323164336631313062653465303739303266646564313963386339306633 +34373965653061333063386239366362366333306539323938636362636539313431366132376165 +65363131353734656534633266336561346566353864643431353464336464346432303631346464 +63306437613561323431643637663162346635313963373730616165643565353261356330626133 +61346366376162656663326436646638393936363634613239353735626464633633623032366236 +65336264366636343430356131663235343764376634653065326462323564333132323262663965 +31663165383938646637656462643633356331363461323261633462313163343761626437616230 +66636566313130663538366534393530613163663337333035363831616333666437633863306339 +31646238356533333161653835613361303661613831333735633664383830666130336531333439 +63323530633031326534306337636132373431616131656433666530653030356233626235353834 +34326238356239333833356666633435623366383338303666633739313461633035313364623163 +38666336656464326531373434376338333733613638343536626433333863353436383432333435 +61633065623138306239386639666362623464376665643330656630303832313535346266303366 +36336664636162353839313032373537303239376562623833343263643937633062666137313137 +36366665373038313162653037643933393738373637356530663463366231646561323832343561 +33626663666432346266326436653936613038653361383966313536613363336166303537353932 +36633937376166383465626366303031303361656562643262663065653334666433376433326536 +32643862363136643264393336373634646632353730313466633137333430373532366338636639 +63363630633562326562663032356631366363313465643336323531666434613862366134316637 +65653461363665376361646533303065626332616430626235313136656234643531333664653636 +32343939616663343837343931396365363538613965636164616533393139656230366137386430 +63643035336633643131633230643730663033653433383734313630336362333035633562363731 +36373932376431343462366364643665383161323432336339373632333164386262323435626263 +64363866643063306132656662316366366531363939363465646132373737303538626664356165 +33613237316666313533633963333835363737346638336262353031306164316264333431646561 +32613965336565646564373839323633646434616566663061323639613061393465386663633935 +39356161383363323238383037666362613433326666336439613130393761623731633934663363 +35353166613634353961633965393365383234396639623834376161626632613532643862326164 +32333438343136633937666533353133643033643436336362343739353262336661356662373162 +38303231623931336335393766633363613435376633306630646338663764306430306661366130 +61396338623865326538383639346334316264373536643231653837303262376364383561396235 +63623365343365616334356464643934303936643431646236303464346430646635363066353331 +63386332333938393961396162613838376465363664636230383365343061316662396364303435 +66363635396638393038336230623137643935303362306430366134366634366564666262316634 +36323830346564363261373366373465373162393638663735613938656361373466626362623833 +64323734376266376330306530663538366434646561373634386630356563386163306334623638 +66343861326461626561353166623962346264386165336166333037363763666461393833323434 +30313366326238363632626238613965326331303234643261653833313234626237396236333666 +65313266623664643664353964333336376666613332326666303064336130333930656532393832 +61663162613332323966613736316431353963633836323337646536653237373839363734313264 +35353031386365323632356135396334363564633832363662643265626466663534356362343636 +38366132646137363463386464613736346538646363386636353739646430666439623235616566 +61373064306537323738613136333333373963313963343232373035323966343564346563643937 +32353964336333383566633935623431313666643135303537333034356130646365323631306136 +38373661353434656331383462303838613133333461633833366632623132343930393366663239 +30363465636537613565643935613630656662656366313866373964623265396130316233396465 +39616235376539323865666465343965333366636330316630613535663663316661653037363564 +61643835666163623461373134663762393237633861306333633863633766316637653038343934 +34393365363433396465373066626565623136393363633365313266303165343830663030326461 +34323638366665643539396365393735373162306464336134396634346539656330363564383636 +61366237653136353662373332356437633334633037633730373435396531353732636131353963 +62373334663564303631396463363764353961326138316562383663393766363930386539333966 +31646333376137363065613434643339623034326139353338326131333434356463393035336665 +30626630323732306463356466303163353136653165353532346662306461313939623838383464 +37383435646162386436386630613334363838366465636130346165393530656438316665386261 +66656563663366653230616162396337383666316162633465393931663732373935356339626465 +35383663313739386435616231663438613931373739633037633165313431613931363838386235 +30366137346539363036613931623265643531346564333338663134336265396237663430363735 +65336438613533626562356135336133323265633561393838303235633636343763316233643134 +39316338613065663037616232373265313466376334626135373231313936656436653030363839 +37343466346134333839643633373635623963316333386631376638386532643334343266386133 +35386633383434383538353833653565303732333238323537353534666239333861333438616637 +64613036663035353765613263316639346638633666386531653233316333313363303265393735 +62653461386132656662356262613266336230613162653033396165633564633836383532303432 +35383561353031383166643063656431313433333536663033633039313530666362643336366133 +38643033633333343736363233656234636630363662316131643861366534396237643662316338 +62313235656262396632333538306332626437343033653062636236386664313435666332326538 +37346661343462336665653338303730316162626532366130363263313562326162613930633636 +34653365623963303930653831636333356463366462373330653264313135383934353862386133 +39366431343132363136353163316537373635626664663961353330626664653331393132333064 +30656530383034623933376565333438356334343963643733636163653761333439613562643939 +64353964373837663936653838633765313237336666323535656234633338396465386261613861 +65633138653731326438613165663036386439646630333463313463343538363330343435306330 +31353362613362396134343336353333373264333764666563326139303733313038373631663338 +39333332353766656430316631383632376466316531373039303238663933626162623331323431 +66666130353732306661376133316434343934653338396437373538373062663361633134623963 +32333963303463303130346563623433346130326365306231383932383264373036343562373130 +63393239646565373138666362373064323161653766363463313965376562393832303562366335 +62303162386166663961366437373264663132316665346366663335396162366637353236663038 +62613066663862343762623236396539386137343932303232343638613738613164643637333739 +61613064633961396566663239346164386362613037333132303932643333303333396139353965 +66386234396437613433396539316163616430663365613763323261346533346634376666373663 +35653363376561353935633636393435653431323439636564366536376134356263353133313231 +30323733303538653935323566393731373837636463323233343438303239303963346365346231 +31633636663532333863363164643032383530396533616632366661383631613234343631396138 +64326362383137333161646237633437396233626330633564366232353337616136336436303961 +34623030366230303134353864646464623066373635626437383035346130653763643734353431 +33363163393930623737316139313435666336653333643831646564306534383135626661626236 +36656639343164373136663163366264623038633239366537316632646635613738393739656537 +32353736643361643633616663343638346233363066663162303931316161393537326162646161 +61643532336163626366633632393835646562323433366139316535313432633735616464373439 +65396338373062626433616636353835373261393063363336336265663033643534366436666562 +35626432666535653834396335303862643063396336363138653239653737663830323537373930 +39663030343736356464373838373336343731643963313833336330643634663039623538623461 +34306134396637353336663631643263393038613661313834666264613764626262626435663237 +31636434346663373831623663616334373735373137346632303630376134613237343537373630 +35653866306361303564623330393735343661323438633164363035366566646165356335343439 +30393465343533333834613066613937663263383666306337353439346431386637336337393135 +37623861666366363133393065326139663662653134386562326332373439303030366532306630 +37306463626137396462666233643337653666663233623266396133356533393165383039353139 +31626335353265376333646530666362306565613932626361303630633632393964666635353832 +61653166333635666262323436633734363461306663343732666436613536396562646134633931 +30326137386339343164613266383533373534356337633631366665353033333738336331356164 +34396132383334366364666461333939616434356662663532356666303832363939623062373030 +35623535366130303338333933353335666166373961363638383032616633336130313431643163 +66303837363539636535353939326231343962373330653737653633393234643336323435386661 +37363262623363626439356266663661346635396234643562323161373538633262636464626239 +36306131623337343863303435626634306630643963353439666437383134306364613466653233 +37396566313138343261396464376265633139316233336137326562386465313432393633633063 +36343337313438336666633734333231306364616335343933346533383563383632653832366664 +61303634316137383632643965373064336233323633333736363262346364633733663336303332 +66633765353937303836626662623665653564643835663032643136396131656566633061333038 +62393261653133613832643164336639323530373731326162623033656364316235343034396139 +33636265343032343233313466303062366334333237303263636334306235303636393935393036 +32613238636239396565303164316638646337623466656233333132383566643963616436653834 +38343034366165643036666537306461303131333830653139366236346465623833393330326461 +63623933366635313331316339393038353036376564623565623836346439383037613062663334 +39613937636139636537626535316233353333326235333136313665653430333834363631323032 +33343632633137616239376333346236346235613865646633663936366234396433316461343333 +64353937343732336365333964323261343862643532333332373136353162363164303136316561 +62343665373364633966323561306130313731636462356333383637656238333566313933326362 +37316565336135363735346366303138623761623032316333326238653663663639366231353538 +65323439313133333838376636663761393561316437633264643166366138313263366532646339 +62656662303832646665646661393766356435646534616637383037343632616632333935333536 +65383561663130393463323631323461653665313836316234393361626266376435663166343766 +30336266313161643332386135626434326337336537616634326663373861346566613137303237 +65613762633664643033366334323834653730643239343737633039363961306666663264333239 +39356433666436643861336265616138363836643164646232356165336534353332343934653161 +64333139303134643630653465386562376164386132333731616631343564373661363362396436 +63393034663131363838323131376537353533353863613134643833396661363564366331636532 +35393434326436306137353463383138373533363038306234356434363030313433616561393866 +35646534613838373931353437386639663066623261336362313233623461376134613961323464 +30653666396666396430386439393737376435386166303766316635633731643064383833613132 +63303138663735366562326665363630643362313630376263616533306162643962613664363961 +65616332306534346562363331613736313234623531646131613263356531316635376530313463 +35353332373538626332343231363033396130303166633564303763353336653363663965333233 +36343332363437646631656337336366393061363963656330376334363266626336383238613262 +30323137343561336363373966363931663030613561653836613131643432373338656163303763 +37656535323230636632626233313633656565333533626466316239306435333135363338316533 +30613236323664663038323433323765666561363432636235353233343435343031373639306632 +64633738643962636433636137376537653761323239636561316164343134363364303965343864 +33336139663530333762333834623035613039666363376566643531313962303135326666363964 +34626131396136363064333538316565396235653861613135346433336339663231353865663835 +62666235373438343937396634366530363433653333313563333465323262666637353238623134 +65653032613965653532306264623262393335373434643362376434373032343135343933633262 +31646565633865633832323833613361386334336166393431656239623132363663326432643261 +64653536373935306137353035646436343535613331313234656632353862663665363933623764 +31383762653736373339313830663931373337616335386438663166343439653336343666373565 +36343233363434313566343565326437643831383362353965636364616137396263303539643565 +39663838376562666266626166643631383931326461666437643861316261323132383032323430 +31393337633430383461623439646339663766626161636531306161616132333238313163373462 +63343931376564656534666661336464653034316264326566633937313031393030646265643636 +33346562393039346435363032613533646438616366313832663939303939376637633736306566 +35636433346363333838396166333131366566363039643061353861316162666664386333356261 +63363564303532636262373937636461303964663762336162363933306238386361323332383839 +36313464653662623138336336326561316339353364306234356536353434393834343634316631 +62633261353761636632666639663863343662303331313738656138336365323330636230626235 +31646632663663323066363336306465633539633930653664653864633464326337333864343530 +30633539633337663832386132313261653562626139323666666461303261646439656339303334 +36373637613162343363383562663638393637383738613263353861616537386130336662373635 +62303930363763303532353639383561633833303034656432356365343233393961323265363734 +63663936303964366337353462656437613139633561323834613966323034313638653834633965 +65663933376533636665626362393237376137636265653135353935613132356234383162646638 +38303065386262623738323230646634366432336366636637623931346561326264333531326166 +30323932636637623633396530356130373836663066346163633530666330646463313761373138 +66623635633437376634623062643231316435633535383733343264383235343138616266663338 +66616438623761633061636162386463623133613731613035313934323435626461343761613133 +61306539346465346339313163313766326339336637666262323932326561373438613437333139 +31313930323465343339333738633662646263356633643738343132376534356635616361636536 +39663336653463666166653039656339353062353861303834353866393066656233396335346565 +38316231353065646236636465393762623130326664393634303164303239366330366366363962 +33376130363539323638666363316366376239393465623331323633346261336237376563343638 +61386439663762346265363439356637333235343464666663633666383532623763306462316266 +61333432353036316465386533353939373231383566343431346334356262626239326336623736 +33386435633834613264623138613637646366366435383131623965656332633864343530656164 +64313336616438343765636433636265323734653738303264656465393635663863373438363463 +37313831363633346564646432336466626534333136626131636634353436383664646338626432 +61303033343038356664633437313462316666353837343930316539343830373933383833343034 +63323839356461353665343037346139653134353938333765623737356437623333356663356436 +36386336333133353234396634656434323766353162313830643061343962363134636132353264 +63376561653065363938383166396634646336636632656465626431643065646230623363376631 +34616461663762396136653337353235616137356263303237313366616363643166656534643539 +38363932336535386665343263303763646132303365616161386533613839376235356431363633 +30323937316532303336633330303562663262383730623231363062366466326234613338323238 +30653564303638346537626132393466623061333266396330623231363961313131306537396630 +66393532633166656432373863346565346433666230386662333937306164326630653630636132 +66646233363937643134396638613362643062623032336266343462366237663464393737323662 +35316162656665373030396434306130373261303039626432636132373532376463363135616630 +63396630666664393635646334633063663139643439623339643231653264653836303439366438 +36313635653134303461306330333762363839303266626431323235343333623162626432613837 +65306638616661383166653933316264393731346635663164666365366237653366383532383432 +37303034366235616266396563366132383866643239356666383139623562386461386433383566 +65393534353866333034646562636237643735343036633531313636323733356235383962613963 +32343133643764363233663135343064396336386662626435353966326331303663353834386139 +64663739336333396265613864613265383165373932356431666333623961643963336137613561 +62336637653865353534303831636333333664343064373639323365626434643662356535383335 +39366366383762613362613331623132303063643131383137383935663535303237373836306464 +66326134363633323066316465343733353430656438356136666437616336633865626537386333 +64363931363961356262356462396363626431303335653761366434363462336536626333303632 +39333137303132616135306634313262623966383963613732363834646131386263653335613232 +64326638373835623034383966386538376336373333343566356239383637656332666631653032 +39313064363430373265353239356530656361373365643430646630316562316135323062343561 +31333163366135313866356366613361613736306366633936386437313334363136343735353862 +34396233356339323766306166353235336565376431393036373030333339613862343762643435 +33303734336638376531396639663537643931353636623366383732633834663033646564303964 +66633330393939656430353431346165646165363836623332333464343766353065383435396331 +35316134616533316134323636366437323763623635626639613634646263356636386165336337 +38623637373435623432613061656134623861303738393566633165383138323763396466346464 +37636233396335303762353637323935303732376161316563353861356136656665336363623237 +32346665383138326238383634623832653563623034333134346131623732306333643839303735 +34393833396631306430353631303830386262613733653435326130303933383564633135383162 +33613539653032396235346536646538376637396636396436326264333437386337343837303331 +37633339376661623131613363353032636135303337613364666665353138646137363030316134 +32393137316635636633656235326564626665333936643465386538316239623864616664633237 +36376630376534373637386232353565656534353830643162376262393432333039663131646239 +38393664323730393336373130396639346636646665623132393832646463303833303638623432 +32633262356631666231623230623866373731313262633831346365623933346266613739663739 +62633732303766313132383162616663386630366135343764623165663366366262336338613430 +66323566333664333439303435386634383137326464623230616262646233346634656536363661 +62313364643133323133613237343163646461616164333263313063353561613630616666386334 +62303536396434373237353439623733353062363138326663616236343264316537323038626233 +30306366626232313265383866303138656335313232386166346436616230643832633835366434 +65653530366239363665363438623330626665306663633837393230626230636132343431363464 +66383930323935323930663930393361393036303036643361346235373637633336616534323464 +37393537656662623930383434326331666132656637633632376233386533613535373532636333 +33353463353932303333373037363632303063393066656463376438333739643932303731386134 +35356235346633306438653766333032633632663331323761626136636532373364626539643733 +38313461643564646566363139303661326261336538366630613132316231363535623730396537 +33653261373930383661326163613834373561326331623065343439383164656433356562643935 +36626435633037343766653332363731623362366164313034326462316465383961373138623835 +31613036666635636233353531616264383765623832623463316438343833633661303465316233 +64303932626438643639306634373738373764343865346630303535343536613735636564333235 +30653663613834646366653737326332646437376137633137303036303566646137303836386230 +34303738613437353330306164643832363239346330656664653133393134353234303462653339 +30656332353561323831316230376461616335323136356134626533616236373762653538383762 +31316638613036613263643832316162393561633337326433626532363635663964373362666231 +66356332653133373136376336306165313664666232323535666538353435613238343433653331 +63666333316331336533646163366230393534386637663361623232663738616535653665333233 +65636663633065623838383062613235396639633163326333616361613462616430366238333463 +31613361383066376263623861633635363535663262366632393930316232613438306338666631 +30326461373535313537316234643161393434643335343031653762303838303163653165643932 +30393730373365336638343133363466306537613561373333346230376538656538353932353466 +63643435613034656463396165323031643431373261623839613036373264643762653730623566 +63323637353364376264646662313436666565343939353935366433653462623330336563646537 +35313138653131363861663365383739346230623265393433663131303238623830356361353933 +32386633333637646232363132303161383835653966316539666335373832393537353535636239 +31663738396535663439306162376464653937623065636336656339316166376339653830393835 +34343434633732333236626239343762663563643463613735353438633461623732356434623564 +65396236303465386632323334333463656132373631343336613233353365373633383561363163 +65363762336130316334663565376439666665653635333339326366313739346639363530636565 +63613734343564666236356630386463306662643938306366653031616132613737663132333832 +37656234623036313033613334366232643235313161653137653939636234306265666136333064 +30343265393061326134383762363361626265393066316439663332343031663762396161333066 +33306332663535313266643631323433316533303537613130323262376638613335326230623261 +30353939626665353565373665353462636663353534393066336337393834343162366331663031 +65646433323233366237646435346334356335393635383036616661353265343664366337333761 +66643566656337333763393237316661333861656361656433373461636364323337386362336535 +38623238636433616363313662316535623035666139313835373461663636343865376666326638 +31613964636435323439636634336632333862656537346266633436326664323065326566656633 +66313238303734643630396137643631356230323436633639356363343166323664653132616462 +30616165306266396538393230613566336562633934653337386366393839313837373736393864 +33383536306362383536313738383033646636616237623831613237633431643536643364336639 +33343135643130333630356262626334383362663566393837386263303236613838643933366237 +62323862653061323061363833393264636536363538303835646665323737353839626663343530 +39393866313331663239316261326464323730316237363066316161353265343632393433633039 +33313665343463363837643565346565383063393762386534383730313061333938646432663561 +30653138653565323061313332383331653835306535653762353365636165663632366135326132 +66613134623534356330656634393535323639663530653334373064663632633431356135646639 +62326236393165663334636439356663626534666633653437313038323761623965313632623036 +35663431303661333064363539626462363564656364633663323364303863353737333336313439 +62643232333339613061313664663430313831643339323163643261363132383965306363656664 +36326638613234646562383835393833353533633563623131303231376136323432636336643965 +62386132643630393530353333323565336631346438663134623562353366383638313162326638 +32366166306138656337616536623266323831363336376131313762616130656365633931616631 +35316331356334343964373463336361623736663033373264653431396434353536363839323630 +38323964306339616662386236666266663764323663613531336365666537343930623239663735 +31326265376465626665323661646531366339306238333232626236656435333261333136346163 +34613538303031353730393431633130613433646436336232623565363634623034656664366232 +37336636666431656438653833626438393365623330626234393564363531306462393135383764 +31636331396139666464643337636661636464353963333030313861343637336162316633376633 +35336363643738333063616235613536653938653533396333396537623436396661666563366134 +37396162653962306436643531626363653466346565636161383730396565343337373237663239 +39313330666437653833656635366536623736643362626538353062353137353932656538316461 +31643733383832326366623963376562373232396365353637303266396239306365646436623635 +39663663333736656263353163613734346666326561666465383438313666303236613264623132 +39316665393234353735383962363534613536303731343666636136393533666563616433613830 +35626439346631376634343534393936386161336638633837316533613664313030633766316166 +39633538666334613665373737363732316533323232383961643331303362616163363332633662 +37626638616530396635363362386133636131306534356233393338666331646632393036333237 +64636262653561316461613733643437366462333533353830366532643661333166643439383163 +63373363303736643234323436653362633837643831623339393162323937613862396635353261 +32646163386165373932353939396539323930343634363966326438346531663961653762336332 +36386233336631323561666330643939393235356563306533356333383831643061643361373836 +63366636333265616636656437343633306162373064636538396337343731656333313332666431 +61636230376331363533333362643164643666393264303337363362643164396434396665333233 +65613261666435313666363737666335336364356661333235636361336364383330653164336665 +34303035613465666134636232326332616538653535613564366432333364383636383333323333 +31623132633030396434346262373666363861326261303137636661653335376135363162666562 +38633138313731376163653330613165366232333564643335653562383836353234613733623039 +30346634656266643530333437343536356438346335363035636635326266623137663030636263 +37353563626130366231616433373965663435653161343266366231643264623739643330623463 +38346431333262656264326130336234666566323562396566616430313439333765656639363963 +32383066343261616631613733393638613139653234353461643735613135323264643936333765 +32333966643436303039623139656132323761326338633634653362636332366162373334313938 +30383637636130616638376363623061363264653863623834643963653539326437356338313133 +37303935656431356262326331633134316464653837356238393564363237613139323031643663 +32326132333662366530346533643933326230343165393132666265316661393064626466666232 +34623338383165386333633063356630653363353766383139656161666638323931353934303763 +34643434613839303631343963353830363561353038636132356630363430363964306335376565 +63633462373938353538626634393136373136353933623335653539383239396436326462616333 +31666632396434336166633562633461383261656637356130313430393333643531643834313536 +62616139343664366666353236633365323032333130366432343430383932643632383434323637 +30613736393861313063343038613566386630653439396262346433663731353731626130343034 +61663135303639373439373032633366653238366338363666656238633365666532393135363365 +64636166623332313461383765643866633062636337613835373165646135306338396337623364 +61366330333463386366373131626361396462323262623935613037636633353962623338366635 +39616565306161343664323761393138643361316530616639303834313664613136316164326136 +66353662396539336639373833336234306434633339646462316164363666646462396235626264 +30363330326139373336373338396334353338303930636631303165393031373238633863323236 +39346239353935336261633663393439396666333963366563666138653664383662386663353864 +36353163626539373130303530376163393333313762353766646461666361663264303535343635 +62343437633733626232666534663262646230666363616336396363663138376236626162656231 +38323138303330323434373339356434343738316262363139666362613033343439343436613663 +65353066363738633730613939333564393062303430643830643966656266643932366637373832 +34353138343837646537303434616163666230313833356335336636383537613865333364623062 +38346565643932643233303635663765356133336237646463666563393737616638663065633266 +39306536666230343435646132363062306535346330313932333537303061376133346363333734 +66646437666636646562326232663134366262383336613063326665376437646231303035663931 +31636534313231386233396365643635356361663866633932353463393535383933346332303332 +33313034623939336636313739666137306433323466343739383166353438623639633365303966 +39316437346264326266633932663434373439636430666134313664333938353730643961323365 +33386136373464393765346432323235303363646636363331663464336235623436353763316135 +30373938633837356566613832383233643364343632316530613632363161653336363530323332 +64303834643931666364373835616335373262616130323461396462663938666665646261376638 +36383637633236313733353761353866373330636434386331643935396332616135326263313832 +65336235303030643739336333353036356338623764386162626634313439393165666234666663 +39346339356162633465393364353336646539336431303434356133356238383261636439393262 +64393334323964653133336337386363663833623465613533333639653065306336366137663835 +37393639393336333538396535333536616533613938343131353131393138323036653931353830 +62326138643431613865333663613531336236623464333933356363323031656234613164643263 +36646134336635623530373061636233323739313036656231383764303766336664366239653637 +65383536663362363133623539643164343765663737316636346332636437616636633933343733 +39363065336336323739666533663332616134643734343039363963646461396434326466343535 +61616532366135623234356638383539376261376336316137643632373261396230643364333131 +61653534343830663561366336643835343336623337663538383861353136323235306339303064 +37663636663265663263306430393732633035643430363637326130666338356465633764363063 +62356135643832323636333839353861666137653962313936666665666462303764623133613763 +62326261646132633436336538373235343130663131616666316363343863646637633566656262 +63363565396335613565663134303039666239616239306635626630356561383666626364323735 +39346637366533323635343532303438656232343133313439363665663664316330656634303235 +66366130303562616534336138636262313339633234653736656432643339643930663732306130 +64396435383137343932303933383064353662643837373665636336303761396638326163663664 +35646331663232663233303664323132313364653535373161393830633731316461303432316234 +65646261386365363531623330343963623034363134363635373961386537393166333037303661 +32356532636130623962356139613032313534383132386134356137643565636137663233346165 +31646332656630626334393833383266323630653435363566633937356139313563373964373464 +37393730383361323738326162626134643032333864393332343265346230646635393032643363 +63306434666231343135343432666237633461353563373838656265656332303762626566326164 +34626464396366356638323137303039633536396530366332323831323330323763316533643538 +31363530393631663330343231626337666439363162373863396262633833663737313632643862 +30646661653232643135656337306561303539323365313938656338643736343063363066303838 +30313731323934656466626536653832396336333732373031646332386666346638313066653135 +65393966616636316565636131346234663931663139356535336363336437323132353431623165 +39393866303139313132363139626233373133366636383764633861376636663063303932623263 +61333637383934633865373534336538326530656531336335663164333734353161653164303861 +31643966626536313231383532373565613635656337303561346532303532303334336435386664 +35333835353237656533653763666531663762303437373665353632383035336631653164666231 +37613234343330313162356338643038366432666430643436326334306265333962383738666266 +65353962353533353862653263343138383264376137666135356662366434653762353366646566 +38646132316666663937346466303535323835616561333233633266313262303161623366343235 +62303565613238623136393337353935373861353033356339613465333835666563303636313961 +32306338396561373830313663383639393038383132306535613736323138643364343861663239 +35616262643530363035333137653631353565653134636331386362643533646636393431356630 +33636131643533636234653331323331363033383433336137303339633638313939383561626431 +34643562393230383262353639343662383539626361633039366166353662376134393638646630 +66626538393066393164646533623164333631653533666164333134313165653264313639653437 +63633035633738613764353863396466313766336239313736343064363763353531303730626238 +39376261656336333331393063363431303130396662656365636532333036626235313934346661 +39653034356132353137353466613533353537316536313764653863353665666237353239313263 +65356639656130633630633137633830353332363631356133333432376134303761313938373631 +38393663653564376533356662313864303665323462346435653834306137326165613861636361 +36383961373030613837333262336633343234303264356261626437666539306634386163343938 +39626365376439613532613761356533613461393865373737366164366135346132393035633831 +30663132366662336337363031623932343266373065636339376437316635666137666338666238 +61663735353330323537656438613062656636653063323034336138643633636533616166646534 +38626431616630666661656636623733633236343030663566313266316665336638393765653730 +66393330356365333135336361636366623636396364373934663038663065646130313563386661 +66303639373962333230316363343465663633613230636230303833643139633934663332306436 +34383835313965653063656461313733366631303231376330316430663833316335313333666561 +31646337333531386630636537343132346239313531656464636437336165376361396536336138 +65303035313730626563343238333038356162656431353831633466313339343536396332363332 +36633863383139386566303036653935396539663638303931333938393164646631643036356636 +66323633313030626561653036653731336362666336613464363065333162653166383161393661 +65396234363538306639396535626233386639646165623939663133626134356661633439646633 +64626337643033376663373239313061393938653834363933616262383833343364663663363039 +61663338623233306536366133396466613438316439376538356639303366646235333233356662 +64643036376435656137333232303461393134633533653265396666376265373864333761353637 +39383337616136343461353036303666343735633966303833616433313963316333653630343136 +65666562656432393832396633373464313336313937663263376339643462643732323831303262 +61346131623961353965363066643363653938393364633164326461343830343536306130613361 +30303565346433623031326535323635333566303936356631653530636231336265343765356533 +30613637323864366566373736616430623466663532316431663036613235623363613135313834 +63613263383166663232666462363165333339353162343636626635373966643431613031616437 +65343337303331333264373466383137613636636130616531666563323834373637396562623433 +62336138363833363462353162316530313630636237653465333161643939643261623333613532 +64633032346161643761636563656531373663313731396239643233643764653365363461666438 +63343165636538643337366135636631623133373435353835366537333138663432643631643062 +62626337383133383031663239653233376263396563616565346561386138393365663633613865 +32633730303838356330336239303537656165396262316161313937623739326236656639336331 +30343966633565663330366462363565363061623832343239323832633135383736663135313035 +66623137313061386161653931353966366164666137623037613863346132623938613835356134 +31333433633538316534386464306463353461383137636366333630326165386335363735633265 +37396133643834343835623134386564316661623131333933323838353865306535376566663831 +63663033313566336361313039316239333535366130613433303663373165613961646165656662 +61346362626639376632336631356461326364616264616539343831313435393336353036323763 +62373236633734646239343663646532633863303466656234643261323165303135373039393832 +38623865383566623935326464303665666134353732643031386239643333356235636531396166 +63336234323633323137383634616131666232633733646661613930393439306235663938313132 +36633630336264366161393934623262663966303337393133343237386134373762323364363366 +36313566333331343339323935633164656231346532623464633435643966346262636531396363 +31336136343230346539386163333131613736353939636263626533373734633361393065313232 +39353336303633326535343637363362613164316663336633396466613666636331316436623765 +34383865396438343133613461633165363939616161646136386263393435616431613335383337 +33336339393236396434323639663263366137323635326339303434313962376133323939616239 +38356561333439373532616462366333646166623636323936313133383834633363646230393232 +36363064336236343939653635303564613132326236323362613065376635643838393339636265 +32643836333137643862346164666136313131363566393165323830323932323235386135623138 +62643461633433343031373638616338653830393266333730353835383634633431383239613561 +34376231303934383038343162623238653663653463646338643835306663646565303937343266 +37663032623264353863363839306466653734306464356364333865303433306264313732346139 +34363464383637663338626361653738653435336137383833323039383165626237383464373730 +37613036653465636134356231616633376535366162633436633435383461343763396363363163 +66316361653363633632396266336339356463353662393031323831653534613337316134356437 +31326430303235663131313262356366663139343962353162333535363133623330626636396564 +33646539316236353138363530396166313863386538653066373438613964636463306165333138 +39623365333363383066626635306461376463383639623534666437316331643065393630333032 +66373637343436633763333030393731333130313935336631323265353633373434616237613866 +32383932646435313437373966653861616564613563613335336134616637343634303630373935 +64323538363165313061663630633138303932356666623636306138653030623530353437376239 +62653265363961333531396661346337636530663061353165323032643337623334396563656131 +32613131666434643265356637363835383130653664353039373437336433376538323739643364 +30643838346131613062393534376436633362376636303034326663623839313162386436376430 +61643237373731376338373564346231633131366361633232336561373634373064323131333836 +33353030666664323034366531333733356261646338333361616161326563643162313137353331 +39323931626435396337623233626337383763346535646663373736343161333636346435383862 +38373365323564366562666234326263353961656563383633343435353462343866396630366138 +64626638376466666265313362306630306333383738333635343866393238626362663836646434 +37646637663834326533396332623533613764656334643435383662383465643962323833323765 +39326162313331636438653932633137653135626536303435363131326532373631336432646262 +61623231383732383532313332653833613662396536383564316163363265353333653530656666 +32303936643865636635656261666132323162623434633535323061666135363337353364373930 +65306566363839626139646130323734636262306532623334376632623536396632343633623535 +61386337613332663637376434633037343137633735656665653264343365373535343465636237 +31633164383139636665656331613462383662316139613362326637393763316232643164316532 +62396163663831653066646132393839393766363231656162386238363863343438353138313265 +66343266623335663138666537306563303866383337386431623761346231326530643831633733 +66386231313261343863373236373266323134376434323438376561383430643934376161313834 +33636339656331663266333537663739633731653830343161353838323237633437323334333664 +65646362306662333637373537316533383832663733613239383332653861633635383930663532 +32383539323862633365616561616233373531633132383139383938336432393539306533636238 +31393938353437613861383665393462363835353134623564373461326462323931333835636137 +34323462613033633563383033643031343337646265633362656363333333303364653430326663 +61376634386539383139633764396462303261643261633466633866363233353935383164306637 +61366637333665333538633862386365646364363764623634656361353536653464303036626366 +33643164653964653331613262646363356533666365313964633339616261363664633630333464 +34383861343831343361653563646132306434643832343433353539366638383834326133653233 +61346266613761386132356435626337393563333736366638383266383138313333333232303731 +36626562363161346432353439323134616435633238663338356538613064633834306363303931 +31316562633161646265323261393266623132636563656339323963376433343634653835376435 +65316138346234353133336438353734656162326161343162383265643434363462353464346539 +62613033323132373833636136393634363063623738373531353561313037663932303831363832 +66326439376137363765353432373539643961386437656336663562373165633365633835343137 +32616165343466323961353436353265306133643065636436343762323830393565306563333862 +32643239323163656563366634346664376131316633336230363366633362326265386566346661 +66333233303736383434353765366564303330353164323339663363303034393432653431346634 +39366366306166323233396535623764633130363465643538313739393636306236353639656434 +66373537666637653064626564633631653164643938366565326431663639326234643236393564 +62353966303435363130313264666166666366663461376135343139346331663761306638353966 +61656264636566326565656133316366623636653735303731613734653739376564646462303934 +31623239326634303031336433616237396463303738646666626361346333356335663331363137 +65613633653064333332326536313037303131393739383832333234623337356466653336666363 +33343730393663666131343431343135663063653637623562316332396162396233396133643031 +64323535353166373531653434393866346431613663363230393531323162623666646561313462 +36393339326331303633613535383263383266393065663462326565336462353339396262323932 +33653831376361636361633931313866633130656530323332646364333662396633393331653930 +63663861326362623337323263663631323539313430633461323832343766386335393030376262 +38613739376139626161396231653532663564333533306431373731363035383466663361333564 +30666637313731666137616434663763653364396533326437383135383439363036363532653063 +32623830366537623930356662393736343532643339303363386531376164643564616464326131 +34373663656335613162636239346264643639383333333137663337326231656461376335323133 +66303764326531363563306362623736393134623832336664303134333636336563343032333131 +38383165626637613861666334363736343866336630346562666464666366353331623632623834 +30306164343038346131626439343233313265623836343564373436663235643338336665343937 +64353739363931363937623836663332393638623834316564323135343430376364363230616161 +62386133633338343936373135313133313834383137373131363836666436356630353039666130 +34636135396534393837313734343537306335643138366239363833633533373739313662336162 +63313564376432623737656331303062356461376538313061313931316535376562663065393833 +63343933356232353034363163373537336135383837366338353263613364313235613233393337 +65373738613530326135363438343135343938343265616462653230376166396332323232356234 +62353864346338663064353361323364616564303931366361343831633663313038343934363362 +34393432343638323663383136613862643431303434393165623735623632633837393361366636 +63616130316634366137643064326238316362353734646334633831376336303734386266363739 +33623533313139346232313631343934626165623633363364333161613933316531653065366634 +35636630393733653330386435613034313037646238646232323831303065653037653264656664 +65323165393938636164333763646130616235356134346430383137323565666536623561336162 +62333063303236646532653361393931366565396163343566616464306331383662363535343065 +64353236396166626436316233366663653731663863386430336263633933623262383437393266 +37313034393333393638353763366331353832363238336662323265636535663765663162383662 +66393934633939653230313538356261346235383233363735396663356530333862326637383938 +64376534336430316564313436363534623665393139373838323136663037313031393437373461 +35623033356633633232303264633266363237643632623335653439366465396634343161653638 +37373139383737633130623664343962363338396635646562306131646133386662373161653033 +32636562303330323962363761313166366264633639356635313434306361663036303637613335 +63393030323239623439353237616333326366366463323637346366376531373434623931336532 +64356166633332333563636532316562303165313863653530653431376562313639343161616638 +64646339336638663165316231313237643465373634303266373934623262646230306534353830 +36353362316365626231356631386439386239303861393339363736666336353632613762356536 +36373636356630643663333033616161653435616134353635313739363734336232663231633536 +31326532653634653134363233643761333936666561343638613166373239656235393632646230 +66353666636264663061623432653464636363643837616262303865626635313733363132383134 +35623237353533323539663439636631663934373230636238326533396133643366646565663530 +31663532376534353365323536323461623339363634303063353765336361633361656665346165 +35656262386539343862653765653132393066323935353235636265616563303863666163383661 +32333138383966343164383664613133383730343339313939613638393235356237346435363136 +34616233303932656263366566376239666463343039643030393664666364623931323532323565 +38613836613933363633366539306631623638393965666139646639663239666263343364396532 +33393436653263363334656637306133353961303162303865633364646366386535656135356565 +34343461366234363435396639346431663638333664303166653461653061356631393966633033 +36653830363564643061653830323863323433646232326136373561623965343161376534376135 +30663936383138393666366462633136633930386661653062333139386332663566336632333165 +38663337353765373562393835656633376134313939376630663163353834623863656432613630 +36623162393238323031333464663336616661346366666565383564303535323435386561646365 +38303138653462643238363562396463653033336662366564343133333733643630356130626566 +62356235343163333564363364303635323535326436653561643439623931616136363463656630 +34336532323439613336353433383061323039333335653133663564303262616433353462663761 +32363334343737396564343066653233623165386161353461343666643663663563373937616132 +32303931383130623466373333376434346463636335616437616232326632373863636164343566 +61383161666365326265306436313065346231653633313530323433363566373135633739383532 +66346537653938363262333136356638333161373962393939323064343034373966303139623534 +38643066353266363939393662316563366164613261333065613131346134326537393166326632 +34656465323465353838336536393363303661376364376334643639306631613961373462373239 +35356434333030653965643234373064646335316231383565663631356362383362376433646432 +65363939336266343863353162386335343933373663346466326361336630653233396164663133 +37396138653638656664383466303163303938656332313930363735373734363733646261333539 +65656638333437623233613033623365323537326337366230626333613266333137343765336235 +39646635633138643835333562656533303564326430626465646662346639613035383562366431 +64623861323961346134373634646563643865303263333039316638343437313037363532623364 +33376364373431663735666465316339346539323063663935333036396436326437383239616434 +63353039663431626436343466653136656131663938633831386436656435613632643365356163 +65373937616161396238396164333130336435343339323231653637393636303030306235313537 +38643634336461393464353461376662613933623962346265633532393030343339396365363533 +30653361623435356462316635643563646237353565316361623634373732313631636338366232 +62616439623033666436633436643935396662326131633437313331616162363332343764396162 +61663461343237396361346165303165346164633063636465393663303265343336316132323235 +38353133326163626334633961303065336131303234636339363734633739396666616231396538 +66336137626463616166333738306430663430373930313831663766386430373735346139356631 +65306632303537636561396236656438333039663339313261363937346539393732386631343330 +37343935626130636230643562376663663630376133393763336134633566653136396134623439 +34653762313532346132376132346361656235353930386461303533326437366632366566643935 +38393466363736393262613933333466333033656463303634323432323039666534366139393064 +62326333363839313134353566343230396538396464393137663163353865643838666633396265 +30383739376465656130326136643664363135363864326438303031333232373364346663646537 +33383437663463656563326264663334363763333336666138623962353663393338333165313766 +33613232343031333432336639616632383135386364376530646534313861316465313435653063 +38623664613465383533623561643234666264666534383537653436356261623034666465376135 +34396632393932626166303632363033323063623663356535616434303133333438353264393930 +34656437396666636565303330363564356637643064336230633233356263336166353766663261 +32393431646363353563333234356437313965336661323630386432666534666432633839353433 +37323466346265313465376437353938303037396130613365336238353965353066303434623361 +36643337393730636339303731616636643238646137333036643735323030616437393166343130 +34383831623766643736643132316631626437386238623630626132613162303430303837323334 +31303634386166663632396533343534303237303761383362326435393530373633643365393461 +64666532656261613237303736616232333736306661653930633432303961643833313937633661 +66363435336432363937323335663434313363643931633861353666353366613033366232303837 +32303764383961343562623165396665376366636237383236343231656433386364306564646432 +61613931396466353930376536393934323434623033393732653438376463623535623931656138 +30393839643030353066623564333263383534663134366439323431363366386135663961613738 +65613739663666323031373730373563306336336135373366666166626434346232313266373133 +31623038313137353762366538383930373835323138303230613733666532366538646635333036 +62626663393337336234343965346431323233353165376335323966333364623936373262623130 +65643666623164623930623437313238383866643036373236313739646664646263613264363462 +64316134303364383865663061383566633534373863613330643835626365313630336331363363 +38313737663166663163353034353035303037383939386165356563303361326535313564663062 +61653239623765313665613334316630333964666433303732653663363330363239666530393563 +39663232323866366332386436346332373961356538323333653038643665653730623031626364 +65626335616361643038363232393732313736323430356534613164376531333435373238373638 +61633931633963313633336332363937326234333465363837323830356566613439376531393936 +63386130613964613832656338363439653761393035336162316162376363373264643861346465 +30653133653736326665353835623065643438376632653264383732653065616561373162313534 +37666638333461353565343163383537383164353931326335643239613939323938643737383662 +34333630643963333534666363613565653634396632393566353235346238306639643564616130 +37306263636234366462653232373336396133616230376264363262383838616261663863643866 +32373764633739646462373533323230333366356664616532383036663731333863656139643764 +35316630656536353331653433653931346562653861353232616332613034373266613766643763 +63306636326635366430386431633933396161326433643361653562313338656232623631326666 +38333439353230626232363534313337353137653938663864376336616235316166646564613961 +39353566343937313264313238313063303561376435666433346430633036343762386465663532 +65343663393336363733333536356165636166393230316632373562366238643365653166396237 +31623565643366663333336164303737333662366463393430313164383964636130663663313033 +66666232383165303765303834363733333630663164626534633863353135386465333363356265 +63613539303766383439323737643262356133336137623463646264643134316430343365656631 +31303538346465396264363430643161613831336263316262363331626161356536326265333661 +62363161656534323632626162343935303164303136666564633366386638343562666132643865 +64313366666635396163663130626335646662383362663563386136376536666132663536656534 +32633730393866313761373839613866643161326463616162373166326337656464313463623061 +30646433663562326633306136386661303063303732386564653462633966306665356662303938 +35323933323635636633306564333362343562383330323236653837306663636264633434333831 +35313934626562656565626331313238326335366662366264333837316330616361356565333532 +61376230613863626364663836613532336435346262353431373961343364313037326332623661 +3963 diff --git a/vars/keycloak.yml b/vars/keycloak.yml deleted file mode 100644 index 8e7a054d..00000000 --- a/vars/keycloak.yml +++ /dev/null @@ -1,2 +0,0 @@ -keycloak: "{{ vault_keycloak }}" -keycloak_freeipa_realm: "{{ vault_keycloak_freeipa_realm }}" \ No newline at end of file diff --git a/vars/keycloak_freeipa_realm.yml b/vars/keycloak_freeipa_realm.yml deleted file mode 100644 index ac8a8bbb..00000000 --- a/vars/keycloak_freeipa_realm.yml +++ /dev/null @@ -1,3536 +0,0 @@ -$ANSIBLE_VAULT;1.1;AES256 -30666437623132366237613535336433656365336432613831386632383465333436343139396435 -6339303464353739373039643734303639666164303464360a343266646564643638373463656432 -63633838663665333138333730666565336161396338386530623734373537666637343436393030 -3866623831393336640a353837646230356365313636343735356237313436396164326135663863 -36383664646634653236623862613266663937613661653962386665393761623438376536336434 -35303938353561353734333562316636663239633632636530653235346564323933323566323864 -37616636326639386539306331623234323035643738616365386434333231396438323230313961 -35353130316433373566336435386138396530376366353733616663356364653064383138643532 -65363637373561633633663061383434386130656130393661363133663866356637393038353261 -31373036373038653966616661643166636436656236613363366339633335633435613632336461 -31343038636162373839333062333137363466323837613434626663623934353330353966393461 -35333865333563306262363862333666633438643137333736316439633639326535383163623961 -39336337663861323130613362653830663464666164353562396163373566643566313464656538 -65353833623263356432383861323665633535613937666334656363656261623164613066663537 -64623638633831336434306430303538383961646237316535613338373134366631313961386538 -38366639666535343537653261333239616237356338393630373762643762626631313362643439 -62313831373433306261373864623831646633653931373265636463303536623034346234633431 -35373833303936323131346566313432623834373538636637306434306330646639383237643966 -66333632613039323964386135376361386532643562323434653734313432393163623732363637 -32613732353939616664633532336330643162373035306432643339616265326366363437336265 -63316531333436643730323936653838353431613339373131363739353165626465636535646535 -63656634303462653139356462326230323964613936663335643236633435643131653137616665 -65623061346337363537613635336533303862396533386630376436393566363832386461386233 -38616430356137393733323562633637333365663530636130336265393032613732636235613636 -30613932323935653036663135313832313734306431653561333361303033363530613763376433 -36646232303932393231333531306238373162666562663936643365643462643565626432346433 -32343962323633386433636330623436616238396232386335306164303030393533643937373631 -65623662353135313733633530343339396333663239316632613338366165653535613536303262 -30396363616463313461623439613738653937626165633831373366613232303061666237613463 -36643766613565386666333035633831626463396539633461313038323666313863663832373132 -33663364373639336366383764343161383136383964666262313131613235336530623363356438 -38343337363761663032363166343363626533313733376236376639383430623332343439643732 -65626237313232656365396534303636643865303765303535623238366232616235393038356230 -35656337333761356464333539313465643565636638626231353930346631333032613335333338 -33323763326534373366633135353865613361646331373238303264356533643434333431633634 -31623862356531343135313864626565626437656532373034326662313636663161613139313062 -65666239663761333961313830636539653961343166313965326330356631663966336563303463 -32326634383764616335613364316339363932616562323263373338313736383433393037306534 -30343663343833396335356435343334313332353536636530666236633836666335623937353863 -39313530353766306261373031336565633530653936626232323435313639353631333531303261 -64343339666566616362633434303137396464633130633031663535316562393461653863616366 -66656436396632323438643765386537316562313737323839366637316165613330326331633633 -64656336613663393733386238383535636433613161323232383865393166356331383131333865 -36633138306661313731616135393232336532353462653832313739383939373137326162633231 -61306537306363653839666539636138353261333864613263656536613039396632363830363364 -34633034356533323838343933316634343961376633663165656637656536333433646338303135 -32623663383230666164326633303630643761363433623534326534636664636635633436333436 -34306538386531323565613036353135663138636364643638623361393063636261333964386664 -34386639636363663737636435396439646233393732376432623831653466623736643034336462 -64613837356331343538623231393164353634613639333761663638633363396635366635363538 -36303066613861383563396462363739396263326437393937396233363963313334626331613264 -38663565646663303963393132343462396263333664336364383839316533656562626534366161 -30666661376563646235326464653761613337633135393063396638336334336665393961626630 -66303961663234623335326632356636383636663433313732336464383765663861343537323063 -62393462306439623539633862616164663831313538623032346563343064386265656662643863 -30323363303736356464313362633538633937653661313063316238343734383336336331373366 -62636330663162353138306364313561346564306663363735336264393937616165393363303736 -34663738626235393034373566326337303936316630313839623137623634393430333265386339 -65316263396231353630346531386233386532653230643665656339383134303630623430316135 -61313165363962396462646134303465316139396237363135653739643664346535666662333030 -39303361316137366136643538613831393663666364366566616438633765636261313634363233 -38343061333264363064333865616433666338343833646334663366393565356562303863633964 -30363864663932373038373630613637323065646464626536303632656464333230393461353061 -32633336613939303762303834623837643161383238653535613238653134303731653037386635 -30383534636363313438656165626335333331613361643536383536656133346462346230336261 -62303436616265373537386337363661326561363437636262656639363330663739653965633362 -64666666326264313035363230653764373366666465313537396161646262363637303531393635 -66613063346134623230613232386531336363396438303366393966353462343634306464353032 -36633834376634646364323534613733353462386533356237616632656466303337663363316362 -38316638353937643035343432373633343265346530353761623730323334366439643430393163 -30633533323139646234313962323434323730613632363064613664653462313264626433353036 -64306331356635656562323331356632383362306331323632623434383964636565623334363630 -39366466363062323637376237613439666362613966613530656564613432623230663534333939 -32353133626665366165353731363663386662653935343433333263326235333134306266303866 -33653639363837613839396336376462396265346438363165353061646432316262666635616431 -30353235313038613466353435623265363233346465393339626331326139383064633564323634 -35633434353535343338363633353939306662633836353838373136623337343437326533376437 -38636662653530323031616663346264623566373039633866633863613536643335393534643733 -66346136383461383637333265343964663831393964636237343430663662316339613063306633 -33393265366431323539646432306639333766663565316433323335646365313332666130633561 -63633566626332663130656362656264633038326465393633613037636363386431306531336533 -65383431356334396663653062373630323238633238343061376530383836363261333231353234 -35373630326132306363353263666330383062643265356664373933323537623564343938373037 -62376135643434353731623733303062356438346163343035633430383830623238373662636264 -38373031633762373031313930613933333732393630633035383533636635393361326130396366 -37643633393633356630366236303361313863316266623464613261336663663964393930346464 -31393761353534343863653730383062353937613464333635623462643238343330363266346633 -63326261376131333963623036326136623136653031383434653331323830643636326261333339 -62306337373031323961653633613635316137333161613132306330643665626230363361663634 -33653035356439383764616436653238333361396635663935663937616337306531643339613936 -35663063623761663362383137376134646564636131633266653766396463343332393164396633 -64303536346137336537383164663161646539613365346566643533396334663831316130336134 -38363063616263646130623635356438313533623362616463616335383364616439383233386131 -65326363373630313062613161633463653134643035396436636464343664633162666265346335 -31306566316535383039623833353465346465656566316536656365363964343436363363346465 -31653333646430333637623434663530323461666630313635623139613238396361393436393630 -33346336313962323165313039333966393165613464653865383835323031616563306663343539 -30343537333038626136316533306134616637393261393335356230653065333533626461636562 -61626337636230623862303136646235383534376438356333616466323434633731376337633531 -37316161363566346664636631356564336634353634306537323764633632323034633961366161 -35366638363065663865303439313836636536303938613664663462626438383733343239623938 -66353564366566643861306131393261313932363836626262306330666236393133373762636532 -35336230663738316361343262326137313537386665623332383761333132663635393138303931 -39626263636535373332393935356232393334656363613766386262373665613438373261326266 -30663063653431636531386461393962643931306633353362333231396665623364373766373533 -35366431653866363765313939366137383933623063363364623338383364323366386630616634 -38346235323038633063356661323465666338396139366530333339386335386665666631643534 -34316564396231643939376539323765616264383030613239393830363431663030633930386637 -63393035373765343339373731666632316564353961656533323831363932613863353230386637 -33336662326262663332333264313737306565313966333063633963316437636236333038326332 -31303238643764323633366235313931653037643433656430633061633466363965366365373662 -63343961613933616130343166306463373639313531333830633662366630373635316632333764 -35346363623334323263333031356261393961616432396631366233636664643763343163313438 -35666264653066613334636131363232653338313161336334626565643531633138363738613064 -65316231646430396562663133356633363263323830343430376666383932633639663135373665 -65343866663631343262623964633036646134386161343731343066643334633239373531343330 -37653762633738376161613062393831626638393037383730316162613136623139343737366131 -63326664333437313931613330333138636362633235396536363131383664643638373265393064 -37346130393466656437366161396261313332636332346337366238356666323635346664376537 -65623861353839393664643835333166393861386538666232363332656162383164333735373338 -32383537623464623837643533613230613337663033303830353233336337373939323566343866 -39343564663562356636343664343136636461366565373761613764343638633533393632313638 -33323034663936393239613962623237663964633831386430316230303761656638613832343033 -36386135326532623161626238616133386538656363356434363636366130303836376363343435 -61656335653037303039376131333037336336363461666562356134316338373033666264613566 -63303136623532316361386233346666623936303465376630376530343935323937393362623939 -36303937366637346664663233353233653932626133663737353034363236396566323430396638 -35383261353766393466316366636434316630303766613236303061376130303961636639303462 -34333562313731373035626633316130396166613438313061643464313766393033383133383739 -37366630373338633564663861303536623138653765303461376636363434323633383038333032 -35626364396166343430636335386530383563323830376239643633353439303433396233663934 -65356337303435376461326462396435613234666439643335306133393661396266343862336630 -62653532636236366232373964353534616337663334356137663563346137666332646630346138 -36313434613232323532373433663930313862653566393835616531333234333564376539633231 -64336161643231636331663033313363316439336463326232303664623464316535346134626539 -31326439376432663832386530643435396232663733653930636138326530386130656364616537 -63373530303033333931303264633435366435306235336465323061376265613364663533646362 -38323933343431353834313262623230333637316662646237346133346235366165373763363662 -63303132336365376339623137316639656533306335623136326630613236386334623961636431 -39616162396539383164653634633363643962313966313337633432633733383930303061643037 -66396462653433633638376133313838383630646239363134613238663731646165356337396165 -61383333666636653537326637306231616664643039616332623562616366656432373433656430 -66333832663034326234313965633636626162303665306333383664636135623266663164333733 -62626564366539383437373061646430613863633461656634323435636337666335633339333162 -33323465346563646636376238616138353762313832306635343530383935643237353932396466 -36616635623233396664396537336634386366333835636332306334313666353738333137626232 -61376633626130653730383131313037613439363662383066326564663463666366323335346130 -61333035386161396130376361346161376462376631353764346164393563626637393463316636 -31643161666130623731313362356265633765363465653938386531646166343061626666373863 -66306461316566383664653335343438366638373835313733363962653737313933393065373932 -38386438643065333033353835386538393931326464313835353630346330333132356139363266 -38626337303965303965396433333636656366626232646364316138663032656363336565643866 -32386532656131323636663265343434653563333966303033383562653861363761393832393131 -37363264383961663162313233353965633866323331356539303238616438666530663764656635 -34363731313065306431366432646364376239646230343235616438343663396538326635313236 -37656231353639333139363230656434633864636137626361613534343365653333666637303335 -61373138316664386432306537663966643639313834343566373264363434333034303730376633 -33626664346235616366646365393266383831653635383735393932623162653630393638643835 -64386237636432616265373265316366373536333864616231616233373033653436366434636666 -65373837313936383130313766333061366363653935356533376532363463653532306266313931 -63313130366234666262646432663634376361323963313034346362353238383461616338393435 -65616238386132373134386166643264356330313061363263666163386531323563336234656563 -63313036653938363963666665626364313032383838353562626438313731346561373737373961 -39383265323737643831636461663161393631616335356636383266363837306430353561616131 -34306438343361333763303031656238303933663534396339656235343164653334666639313835 -65383530363438656563306362626232316439396535633635333062336438663636346663316363 -34356361316230373935623539633537626538376466303230626438323837356237336266633365 -61316636323462326236656130343132346337383933663837386234386538343237326163326665 -66316336306463326234373261326338323031663436633366306537656332316465353831383631 -65613933303361343834323262623331393939306638613533383635383765653263386363333738 -64356531393861353164303730383037383466313866333032643763393439393831643161653961 -64653932346562386633663566353536633661383338363430313963376565633936316539653964 -66306132336635313932323961393566393437356534373366366638306234333765613662613563 -32376363333662643436396263313764346334343065383865306437333035663238323135656663 -38323264376162633365383838303631336562333062613431356335306337316262653565623065 -37386264656263343836316534653735646365653732306464306665393931613232303836393730 -64393838306434376335336438646362383266376664356565353236366534333434373837663232 -37343231306161346637393963306433643930306233383462346633646561333865623339313534 -66643132626636646136333062643166356130613434643832633331363263663933656338323431 -62366135313461313461353536646634353463613537663963316433613765363662666235663063 -63313066623930613566346439373564393930323133316536643934653562636433323930393738 -30366361343335663734646332343461623564363037396161613533316132356538643230303566 -31346663623565363132623465613063626563323838633030356637356233343632386130633133 -63616362336238626130353561333133323533373732623365616234383864393765643833316339 -30383665616336346463646532353536626366373135633062633033333563336663303265346263 -38396163643038613935313637643735326232396661396231313436333132313264356239386533 -33343965356233353263366434343633346262333764333438356436383430333238386665626264 -31626161663732396331393865336262613964343639373630303636623635383663303266636265 -66653861306265323839633662363361653566376335333530613739616563323264623666386365 -31616533396634666633626631363233623337623736396436333130306639343139623438363966 -64366164666263356361333433656636306466333834383466353262333862613237666130383339 -66633637396663363331306530326235386238626666333434616137313766376663366135376466 -66363133333437656239393932623137646638613737653135303438663537653330623737326635 -66633564383164666336663261643161383762636435616131613664396434323432366165373564 -63616230626564636530633936373032643366323562306464613263646161386131613534303433 -32623763326435616635633231346131393437653830636535323133363432333264393634653139 -38663762656461663162623836613666383238313666656433636439306335333866373262306532 -63643864623033383335653864316264313363633837663930383236656561666265373437343463 -65343237323439613862343738323365356535316433313361646365333864633939386633353461 -37613462353238396566316334313830303731623534373439636638613764386232396338363431 -38383138373939626236653536656238353239333337313263643333303334343738656139366539 -37613530336530376332616131353265636463633033343666636136613034633666353563376432 -32623266303065333638366539323238626430656566373730363337623063373363643430336363 -61333739366536313937373130363534653431663933383765663633353561653934306263336635 -32326237633664353565323933666265336537666635306339393332386436356466366666616665 -34343865343566353535623933326239623266613666633663353261663437383536393263313238 -65333366656539636139316633376236303264343637386236376566343730346666376239316430 -33336331363436623363333139623537633937376631663665623962313133663434316633343131 -66636636383064313433633563356539363763633539313036346338326137363262333438613931 -64643735353333366536323162303563626530626536303630373166323835316466333366626261 -35353139316332323234366261646664636531633835343832326561643537383561326465323631 -61663630306433383036316635306436656637376362656337343630313165626534376466363238 -64393835313237663163646163613661363430366631346232663632616463613864643365313832 -37356636663534313062316565336262323337663464396639373636643765626664616134663631 -64633230653166306366666431393437303761326431323932653535363463326535393530353862 -36396235373036383332363661303534383963343432316335333761616663663134643836363738 -31353133613865376333383064333465336162306665643131383733326165663539316434373836 -37383666663733626331306632396664353238306439383033343332326662373763643566323336 -62383464663561336136343663346364363464626530326564326232383039363735353566613630 -38626537346265316230363233616638613938646235646136353065353965373238393438616232 -35353436346434313835333030613436373334613539663161356162353234343937646136663136 -66303033353537663064623231306239653637356266386137366136356466393932383761346534 -36306365623839313136303935643562666565633931663463656366356635356162386134383662 -61353061316566373564313163336638613533306432333162633336376437613234633263626362 -32613136626634303661346364306532333764613336396630333838643731316364653066643039 -65313464383763313564353464373061303938313365663433343231643663343939393134336162 -36373661356664613235643538626535666331353363653963663830356165663736646538316363 -33346436633230303965633132633337356534646630633334353632316666626636613665386431 -37656332643435303339646432666137336432666636636139383333343036656233383532343431 -35353963386465313537393038653436376237303638326137343865346232333239313465656363 -34666462393363613266316665366437356162346630313837666333613235313264663431313038 -65326138396563353835303339653662623961346566643066346330373566383832336637346530 -63663335623039343732373336306336623437353562356430303866616638323139346535613532 -62396538666636363834653163313761616261333165646161623033336533343237336532636430 -37383465313537313338633865643739393334383666366165363563353634666561383331643132 -31623366356635646131663638623438653334393537316137306433306262643763633032666361 -65383961366639383063623135353337666136616339376664656430383061383435626662373133 -39316333653631333932643437616536386331316531383938303962373866323663656135383563 -39363433636437343934636231646632663064383436656162343833383262646639343163396363 -38306433633634313531633534396264663537613738343032366138323339386535363836636364 -33313162623164663237316366346136663161373966636132613938636463613830353465653838 -39303035653530303437633564656337343861386664323734386130346234383737383634633933 -62653362303737623832633034383239333062346639656461613362313432303739396262353738 -34663635343438613738346237393161333864316138333166653434386336643235313463376661 -64616334306664643338633238373932633561633834643662303730306138386331646437323363 -31616261633234626633656666303031663836363937623839363131656437363134636239356365 -63653734393430656430626234393236653237653438336232383665643334383236616262356664 -33333238313463663430363431636133393731386635303565343731626335353531663738613134 -39633062383836616633363332376330393366383363336562326534666239616664653831643436 -65613765613535643734303761336265343365636235363961663464383466383536346364363562 -63313964373762393465306533656635326330363738616637363861383530313466393534366264 -33386530633331353236343435636432323561313639663165643532316533353035386430646265 -33383162393465653834663166386134383231333638663834386333666461636562383337613932 -65613933626330386331346638653535343636626464373762666237383965653265303964366131 -37363533393233653637333966633631383063393938353139613761663237393837343563326665 -62306361626331323434663336316365313830396638343863313839313330363239373235336435 -61646437643064646436353230376533306564356339366530343536376363616662613162383239 -66383538663132643032363365323462333262326230303430303539623936356564366235636366 -32393436316332643433346332643066373135663766643263313261353036383932363032333236 -35323561353238393939616436303636663064333237373838636464333966363635383764363232 -38626638326466653334636439633465373134363931363031366263653266323434613664396437 -30323736306233386330326434306537393837316366326539343632626630343532353338316134 -62653136326239623731353638363436343539626363303439376534353830303338613636336536 -65323730633664393765646465353163373766663933663066346662393662373565333865356233 -38643234353664333366323464376437383662343565346337623364613835633735336639653565 -36653363643265346531373561643630616339333037623837303136373037636361663334343035 -33313935613664353936646266616534366139323166363431646139613765323761323832653436 -62623036666134623432623830333133623766326338363533636338626535353731643336393832 -37636435373061313632636639366666323132646361633238653339306139646161346538323836 -35306133353564323937343466326439323438366464653834306433303862356464356331623631 -64363536306262343233356537323435353232306133663564663561313563393432653961373235 -66373861643630613639393262376265343737316631626233366534616461613736376361666335 -62313966333635396137616630336563393533646233646536373034653634323766386636616536 -65333364376437646236656533633138353266393136343035316635333333373963316139616662 -64383639623430653234396162313338316439666133636666323131373764363430626663373361 -33386632356339323235353633353264343337623839376464323530383131356439333662343261 -34336537663936363530633632323939333236316162373236373362616236386535376431363761 -66613838343763363361633566376266306164323631653863653332656436623734336237323165 -36663963663039616437383961313638363732346463386631633631313330393134626536373531 -66656261613739666561386561366163376137383931306637346239613130643836616330363034 -63376531636337333336653238356561333233656162646564666465323364663965613932316361 -31376230393334353562313964383831323637383638386563356331643338326531303162336432 -37386438383035383065316136316262666465643234613165663634643832333531316133623939 -38383534646439383564326530336234386664653564663537323666303133363063316266373632 -31303264316561613163323732333437333532626261353437653632613539616237656562356133 -34303537373961376464353336616138386165323837323163663030653461343538326239363036 -65656536653937386433333362633034336530613065343039366565633838636364393833346465 -39336566333637393636353263333435656538363334646266666635333533366631333535336339 -61326337383866336162643731343336336339363962646261353435636630656538393266613430 -65373566353961353165356238663562656464663262303937383733383564653961333433393963 -61363762306231353361383663613965663735333735316636333135303530343762636433326661 -32663834386339306130613962353030626337346537393830636462646431346265323833643132 -39386662656366386330326136393462376361616534646338623133333238363338623831386238 -35353734613462343338353430306365373739623561343366613430613466623833666232353039 -33343362353236363465623563373135303366663236653630646632373030306436393535393632 -38623032613736616239373265393163663865333331666339343133663864356361643735343766 -35663236666664623335393432316237623237633933333061326635643738643633616131353262 -33643838633362656561313733663562366265643861346131643233313137663164303763663166 -38353263366366353334363630333235306437643533353939616264646334373663643139393361 -30353466333362616132303132396638373737306365623939363035376135393338313731373365 -62643162303837386564623063393435373832646232323934643334383865653632373563663962 -65366665366130363661626364643539323736316533633363393462373737383133643433303737 -65303239633039636134666566666537313331393336626539343836303163393464393565353361 -33333637393439643761626463643330383865306131633163303263643633393437393032336534 -35356637653964373165383038636332373665373139303763626164653262363833303361653534 -38633535653464393737306631633132333165636234373839633939326131636566303261663737 -38353832656265646136666336343531393034613535663563623330313037613161633464336364 -32623663616436316262633566623433643038383165326635333938306135613037353562626632 -36373864636236613433303235366137353362383533626339303139363338633464666461333830 -37343265363932653239623361613231646636613231323939303137663663343139323465313863 -62383439323964646631346133373135353761356231323430373031303832306330626534313363 -30623431326231623033343039353866323966643739623537383036646265316564353461656364 -32646465363666306336663233363763316436383831323065353935303831386464666231356265 -37353865393065303037383339373033393166316335373736333533313563333062386331346631 -63633164376637636163323134383935356639653431336364333230666263643031333933373961 -37653164363236653336383635643636643565386664666533343064343832326361346463613663 -35326165346134316632663537353036333966666166646336303638663536383533633065353261 -64643034353830346137323763376536666438376263396561643565353934623539396635323635 -65613532613261636464326237393363323861616532386530633931333962363637303830663633 -31336261343030636538323265613430633233366533653563386631616331646438326638666631 -61346631353632343132656161656432666163633963323062666239333965326138643035373735 -32356330356461626534393433323561376132366131373633323932396364373235613261363935 -34316237366434653039353639613538356166643534343361366561626665306633663138666565 -31323065613530666366363865663432386236386239353337393331666137323462353430633663 -65393163313766316235353439393866303465613635653766316636323334386136623964393630 -62643161636330666662663039316535663634396331396233376134666362333032613438333134 -64373938336465313864656462613436663264336338373163313533356531623838386339326135 -64343661393432616335336464663663623962333564383264303533663962656236353036336230 -63613134616533623431346361373936393663306333363134656265663463646434346566663663 -64323233373234613839393839393962656539393661356130326234386636626539366166333065 -66393639376266353036656531633964613335633063316532383264343935643939323832373938 -34646565306631386531653266393965633566396630323233623831393666633233386661633630 -36323062643264626363653032323734346136336461363066643865363265393338656638396231 -30396263303636393434643135353364366132623565333737353039383565613238643434343731 -38663739343834653364636662623231343839373361386438343031306161363534393365306130 -66396136346335343834316534393736616365376134666237663137393164653237333732343732 -39643932656361343533626136646266353964326261343537626436393838386433643236643361 -36633139353062613033343236306166316238373431323837333134356164313538353632346561 -33386566373731383437633438653731353363396565643032316330343230643638613236626530 -62376164366262316261663133386366646464333637663134633962653163363233356265333430 -38326538373030393764366439326331353234343263326231633031343063646362646363636435 -65306531313434313637383562353764343538626639306539646561363339333630396232623838 -30323936323461336138333630366161343431396536663930623066333861363234363936653736 -36316263336166343732663766636336666133313436396137643137626131646663626232363438 -64666235336531633864663238666462353032633733613836303331623934393766313765323839 -33306161316435326165316361323737353934653035333733393466373036336534633865663262 -36643038333934326565383565373139643139313930313163666261326333363536643866336130 -63653435653230623765353637643736623337643863636631316564313433653863343838373837 -64636134363063363538366166313565616234333532333739633864396234613161656633633634 -38613632663637356161393532333938336565623634666438613132623163373366363930313932 -65373964363635383963613335356532663230643738373433363039393865386539383162303535 -35366563353230323432626131376164656134643138653665623464336366636661383531646264 -33316539646665626364623333303566663163633638376562363939346236303832333662373835 -31393537373766323066373235323532353439636562373634396166346135643061656635633564 -64373836313662356437363535343565373932373436613330623239666336353735373461333862 -61303930316530653161366666633135646534646230633831366566343030616433303134326165 -33633665646531323535396664356436386462366563333165643265356566373739343861313761 -34356665313065653236616638356565636639343133323865626138666632356264303837653964 -34313865343965323137376535393030636335323063633665313237346661663939626562363238 -61366536656665636532643263623333343737396365303536623234346637646330653134346663 -39613762366263326464333534373363316464336534626565656562623538373362633834373163 -31623133376534626536353666303839646261343336616433616665373937623938343239353437 -62343863633761666166383361663733363264333761306630626539336137303263303764383233 -61633763653637316634303338306538326364383465346635356434326364326137373662303839 -32343235626562386436336530306336303436396331333164663365383063656136343732623765 -37656263396434613064393564383033326235376138633437656661643733346439623736616530 -32633466333335663961383335333131623839323438393830353734653733353732396464303461 -36333330306436356138633330346333333336613266363963313832373763663563336366346131 -35376636636466363838346639386331363561633962393035353638386161363433616133333862 -62633736633739306161383238646234616163666336333566363535316137353661633766373061 -38376431663133343631353332306565643631663138643961343061306632303563663531663835 -34623739323330376331353665376133613830376134333939323862333561353830663666386363 -35653232613464366666333932356130366661366666353039363235646539643038643063663761 -36346339326162373338656531623239656336316565343938313038656364343039376234303362 -66393664386563656365663963366335363633626462616563656262396562366330313334613566 -39363532333462663164303133353262626364373532613462333663346362303839333038656137 -63633637646463346433666236393961383663376566663433613366303462346635636238663638 -38633163383438343635376532623933653638316364626535386235613732363839353638633962 -63356434666538373263396237333935613734303261303532613537346631636463363665313165 -61353139646631643164633737336463666365363432356337613631643838306433333831653632 -66323739653231376462333839613334623662363266346131336565303562396633333837336631 -61613332353566633131613930363830333465356431363035643736333737303631666530383661 -65373065613331633363333265656235363938353665646266363535386239373934616436393762 -61346234663739366136316564393230636136653439356637313638633730323665633264393338 -30613939623261326162653266663637616630333438636233363733653234343137616334343839 -31323762333632343961653032353839616533313961613234653861623939626463616566376539 -31616239336563623366303066656362313061333935393661633733303535376536336361623931 -39633462356139636330363838663334613562643866386333626337653837363264626465313865 -30383430303337373931376462613365313033366239336664643231316437643366336631383334 -34393533656434363532356336373332646565653534623432623036303635326664383238346465 -65623231386363336232303665613432656366346161383434383038336661353637316562353865 -39313865626266623337383235393962313834616138343831636464343330353364346433356562 -63396232663335316337363332616234396562353732313164626531396463313134656638383266 -33343966313866386664666361323566346266643334346231643638623335643238623534663632 -38656461343362313862373137363037346265396432326534333533306531643339313734326132 -32303832373632386263376431633134636230333463366436666532376364336461356662623066 -36613532653563663237393832343763323165646330303732653561623435613563616239626365 -66643066643430646230623830356464323166326362366263626338343237323563393338333563 -31656632313335616662336639656664363838633630363463366461343132643035323063396632 -63333035393530303435376137613338336136316534613735383936333261376166343130313038 -63656133613636303030396636643636643266623231613863346262643162646637316435323936 -38623335393436353866363837366432373939613464396139343635316266333834306136323466 -38316337393864663230316132323962313063616133356336613064386133616337303366653563 -35653561393836366461393238653734613134333765313530396533646438326133333665386563 -35616636663237303464303531636636393663303766373733326232326631376239303164396339 -36396665363638346236373461636235316166346434653938303963376561653138363034356162 -61666230363830393366396565663531313637633835396135636365366565653762633332343266 -36326333653936363339303634613236373433343031633935626561373662666137636536323063 -64366538626637343366363162333065646166313032336361666561323764666339393865336430 -35346432343535653030306437623631663932613137643039366639323965656332613136616431 -34646138303738376462396165376432333165663836383566383338383962346136663566373666 -65353336613734643331633664346231653734363630306633363037306234656336643837653266 -62343236663532343230653239636330343739653332393164643736666238643539396138643934 -39376636663834313439643264333937353933313465303130653564613331376430636130363433 -64373461356536363430346365393965336365383238646366656364363334626163326466366134 -32366537343634363064353765333031623261663064356430316638386639666166346165646664 -64393063383132356637333735373039373839313338383066623862386134623037616464376232 -32633038313135643164623566646266336632323731633461396138373836393038363364376666 -33343365323364336130353261363666383437636432363461333863633563623866326163633866 -39366265376362313739613035636133376665366138376266323162326333353232396139383730 -32613161363732303465663235653263323134643237396263363038373163656335613038656632 -36333731373766313563306234313838353863373835656638306537396136666663353364646635 -66333936386334653166663661376664666632306236383163653435303363303632343439633463 -34666562663962656138643637376364383364383765363563383639643064356161346233363763 -65653330656339653138623530303164666663393131653035386435346432653532346239366461 -64326463323131626462336239633636333336343738616134653938396663346238383932333234 -65336234376637616164616332306430663535376137323930626633326238633231363733353365 -62306565333565643339366464626164356366653437643030326566613632323763353538376533 -64623830363763666135663131643063383630363739366636393134353161653064323638666661 -65316462643636313135303737623965386465386532313464613038613561316261396638333039 -38373663363030633264363761306335376431316162373063333961653135353663343536633639 -36653866396666343930383839343861653639373565383134393439613163393739303561333065 -65646166346431616537333363386433396663393035653062396636353564306264663131383761 -31383739326130323564633461393337653031643765366133386536303561393662643236393132 -61643837323330353634643461656134353934383365656135396337303432393761353636383136 -66303232656138623339616438623933343362666239623263316135306531323334396230663837 -62316465376536313739373066363833346536653639656332626430303231666264636538383361 -65303334306237353631656233363135373732333261353032326266633839366366303430313034 -35393961333063666365303563643932326261306232336134613139316561303836356533336636 -31633261306566326637613862343237326334663239353030626663323665326532353632666433 -31313934656531346632316539353831353633333665386666356238633966363861383763643037 -62623666333361306337336266343861353764666337393736366234656165396136313962366263 -63616230613138326538346464323561643361636237626634373762393334333032613966343538 -30633831396638303036343437616235653734636332326334346637353335326635313430663165 -33333831326132623766666266653430363165663730353532656361336234663634363364393033 -34383630356163393532613861326365653337353234326134343631636432663438333434643333 -37313763643962366533353463333466303735666435343539666130386463616332613466333734 -65656464353363633665353338656130323239393830326566666231316137626633396262316666 -63363166633736663033313965633337393161306433356461336261313565313939303130333630 -36383838656237303866343939386266653365636535653738663161613032306333643236313563 -66613333363865663566653265346431613166366366633735643766656139323361323038366333 -31356534356361646634663464393238363833623263663061643039373030343638623433633034 -33613463373865646532623737353131343534353664323138653338323965323738346262323831 -64333037336466383830663664326134373536363439373161373837663365313565636233386330 -65653230343438633636626138376564313637326138626361383362623062373361363762396531 -30643130343964636438393433393834633238613030333865623339646238336234613938653961 -33326662643635663435346234643836643936636233666338363737303236373762383337656435 -62373334636233393263383738666335383064653930393537613136323763663761356664663035 -64353031646633346164316165663730616639313936383039633335366135343636633133656665 -34616439323064663037636230356139333734326432643231666166616534383331323363363232 -61353830373862356433373831313662393232306237396631303064613134633262313338636565 -39316564333331636535633264663137663338616263623266376463653961363661653566643330 -38366531353261313031306137663262623036363964636336613162323664623335353132616434 -63356565323163616539356435656662616636656235636365323735396636343065343432326234 -37306632643965646664353230653962643764336531353235623737393739646564323131373261 -36313264366163326236316532333832666466306335356139303933363033363363383463336631 -30313731633530313165616665376336383531396661653233353063316335646530613530656264 -30316335633230363233383030386431306230613365303662653831643263616136346361313334 -36306333336433663338663131343532393266653961643835626664323832386137386530363461 -35356562633334666136353165343963353731636536376662303763396130616665396539346536 -33643732363064313430653933303335363565613038646266643163383338346532326636313465 -64343333383039353830333665303439396362386234623131306331366638323864346365366266 -32643130333838666236623662653465313930343763393831626366336662323263323438333738 -36333838663664333239666137363761666465376534353964366263633835643038373766383139 -66356565386637613562303934616239323939663132333732303461356532653030323331613636 -65303063653133323537663136643836663464376164383863353065313661393038623362393363 -32353031333138383765393834353762663435303637333966663639656536343261393136323536 -36353936393165353239363532656238386562613330343736633862633131386632616132646338 -61313639623562343361643365623030636433623930656538373963386161653237663530626434 -66376131653162323930373261366431633435383763643138343564366466303663363138303261 -35326232353636613631663262656538653632376533343465663034613337336339633038346437 -65323236316237666632613733656532646565643333363133376464373866646530373432316435 -36313339623261313863636632396237643431393139653936323262336331303434383639343737 -31363634336362383265393831616466643831346236663835653933343535393763653766373739 -65306662383031366635623733386139323636323434626266356335633634303137613163636435 -66396539653437663464616137393738636133323362656533636564323966613765333362663266 -30373930303934303933393436363934383733316436373562633335653137623961356562336162 -36393361383734346634366266343164623038373638633934663662346563363765353433333163 -32396263316630613966323533343531363362366533326231376638656535316463353632323837 -62393263653465613436336438363165613336316132626664323634643733386162623565366430 -64653330326634613835363463336130373064666664313039333934646338386436613139303832 -63366637636339363530663534353036636132336164623062346362643364346236633066303731 -33316166666437376533353636656337323036656466383161313136346535333166643238393535 -39376131396566363165353934313761343464316231643736633462353461613530373563633264 -32623039393439613963663938343937316630356465383234663733386138663364643261323066 -37363431636562383133366162626238383731366162653038353165363730303939653136383930 -66343163313433313039663863653532313163306338643338326462613532313338656264343534 -31343265323834613032343232656131323466646662663663386331663539616438653663633634 -31353635336236373834353731323733663833643034383039666637306334306461306564393532 -35303934653536396366323939373839386665373433393932346437323833636231336366363132 -63383362393534666262383262663865313666303431323639633863373138353231326565336564 -35303637633532633865323561313934613933326637396633636335386539643765663262336530 -65316530613638616363353865643533653037393931383939633735323731346235643165326164 -66363131646262643230323238383339356430616266666237303530663361343961313836326131 -38343666383835346231383764333361663961323733616365303064303631316636653166313736 -38396630383665643765356638613139326139326234306665373761383436626166343138636161 -30366165633131336238626235363836313938383964316361663961643230343138643033656236 -65393133663865396162663938393130326131333864393566386533383866633733646366346566 -34313939613863356439316261363736616432316166363431366665633766323036373263303835 -38333064396564333233653039636332326633626636646538383464623638303833343731643036 -31343038636664343462666461643063313761643937393064353163313462326162366137633332 -33623836396230343433336631333434363339633662373166636431336130633166393161356132 -36323037613535303465343233346235663866366438353734383662333365353565346130623231 -39383830366537386164313832386138613836363139363364666231366330326633626134643238 -38383763613437396635353064613434633635643966643763333832366534643733636138396131 -31646266636637356338313435636363656135663639656531303735646564316336313662643539 -35366330383735313064663234303739393532393263643363666663666239393533363331313461 -35383865633565653361633137303931386432353638386361396135376362323239383239313134 -65646636633061396566663535316664323361353337653130626636666231306266353566396163 -35316239353833383365343366316430313632356166366239383033383366653533633639363265 -33336538393964343831383235396135376332616539623138373162646261623662633366616437 -32396432373130646663306162666230343866323432613161346162626665396162383430663037 -35663234386264313762316333376637383166316430336631666337303466303262333335306535 -36643763353463383338336364353338613334373862633530633038613962376335363061623130 -65623262656434623532353730333364353561393832353230316336646237616136643239373435 -61666538616364353064306431633733616632663734323339363532626533366430626138636534 -31663562343862616236663262313564386365393965343861366338643261623136633830366665 -62356363336233353330313132306136633634363538323337643836656435633338633933303164 -65633238633134613533386235333263363064636230363530613861343163643334333730333062 -35366533623032616638663164323034656266326161346336333038363765623566383165383936 -30626635613934373637343436653033306636323230323237333431613366666565313630633339 -37393066366238613932656535646566663261656531386434396531393833343436613336356334 -62653833383265393463343638336464316266666634353066353037376333633966356163326338 -66666232323966613337373736346333323537643038636635666430323436353434323134656330 -34383638656165623733363663653938653039393432666235353436316432343464623564336232 -36343637323934343036643437383939636131633863346634666230363539303337653638363737 -39663637643330623334393066396363623134623936626163636561363735663064313030393631 -66316539623465363433396563643565653033333065363965356632613931323865396530313330 -65336166386236313761643531383436343335626333383237666566663531613264646561316133 -66313539633932333465316334346666616361376534663136313962383735613131386631333164 -32323464316561343065316535646566303331396461353836666237653635303862343732666532 -38316638643762353663343965383830333536393666376565376236366166366466306236336666 -30383234336666666262373066343833343839373738353532373961373461633438346334316634 -39356337633135336566633433383539653562383139626366616332393662653164636236353263 -33323736643637376664366563366130313534306635623534303936316637326565323732383964 -37336335346565633061366135373431373638346232393562326161306531626364633661313930 -34396536303237386236636262653365343261613466343439306235336665333430666634636137 -31393632376462396334396430396632326633313235656635336233306466623632396336326262 -36303438613063316634386331356530663664653965343232663333376563396366613132333334 -64363566353466306431383765303031653938323038323665636132386562316231663136313766 -31323036663737323061393533656438333566626265666331343038386465636130326334363363 -64386665333063303665656363623836346632316135316536343435303338633137353066666661 -32666662616162303137303466336137383236616234393765386439363339616430643531306132 -36666361636139393737306133623436303566363137663935373637366437336434376665346666 -37353733333235376637636434633761393639363637613936623438303662663932353636383061 -32616139303031653534333932643761623961333362323963386439373536313536656532633730 -36653231633239633762393431636231356135333864356538343362633338633266613735303033 -39333337613637666562326130626338626266356333303463376238313535646430633137363265 -33306334363334376335383835303366356138633836376132656532353831393731623763636161 -38393933323861356531303235343461316462316630646466313733623631656461343761326538 -66636231636564333963383738623332333564383933353662326138366636303138386536616162 -65623865356165366636663630336662376634346431333431623663666335306162376136393461 -61643333613964316461363335393835313337616630343636343665376134336235396331373965 -39616336303062316434633631353937383031313666396437613138643863326130303638366265 -65353336303338326434333464393031306338396464373231343966613738373731396337663464 -36393439373935636339333166653935666632313862323962393930323338363635636565316366 -34303662343335353738613437323135343661613064386632633134383639346333373835343263 -65663764353833643464653737613863373739626231356166373335343262633130623138396461 -62623032343861343732633364323537633134313061396636313739326239646363323332336162 -66306434316265623436346661643738376636653931306564653838323763373865393737363764 -36383132646262393466376534313061353465346533626430383638626361663362363864356432 -33663235643862303137623530613066623037656366336665666165646430366663313237623565 -64396664306564666533623035643365313935393763343231346465323032333764623266333633 -65323365616639353438656466636333353336333335616639623964636430393061303838366132 -64626634386538613838343761353138653535633636666565336436663963653663363261656437 -65373332663334663061343033626335313335636237333166343930333465393232373765633762 -66333931303231646437393732376134396664373663366562386663663534326531373232643732 -32626434333434623436313466383938653934663238373363626430363031396131313366323663 -39313436383530616637653133383334656431643232316565316364303866386631626161623534 -39333139326465386466656531663339633230633438323365373962393138393333386639623237 -65303634303461336664656163646539663233343030626339353765373138353239323931333364 -62303761323634383139363738336131626166666664643535323831333666653336396539306136 -39326665316439663061333961623331313230646462333336653233653063383565643835306534 -63613834333862386466333034613230326662626234326438353738633861336432643738393038 -35636463653330393730336166366235323064356364333961366666613237323434396333616536 -65393930663462653433623433636136333938313865616566333434313333353664626265396165 -39636665333464333166343933376432373733663032383962643564373038653635353666616238 -65366336303533383539383065323131363735663336623637343234353238623132336637336465 -38383834316438313938373763383837306461393533363835343639386461353963373835636532 -33386233353464356234363334353465393832666132326165363137306339636464396662343130 -34663362396236386234613961363633383635653632313336616330626631363636336139656538 -37373436303636323933636634333936383231343937363930663833653238393165636439633237 -31323930306631663438623761393261653036643964313432306234333063313033383732323365 -32376439396538306130646235366436356234323466323035323536323662666238613466303634 -37616339333639396337313633383463653964636266396161636362653130626538303335613665 -33646461666336653864336162623637663439396364613130363839656337666465353861383966 -61373066323734626633653035663861393332373131303731343365653939666162303965376131 -34663963363238376633313739623832326531636134316366323033636164653639303330646431 -61663365353266373830656231633130353066343836633463356538393561343237633732623639 -34323733326537376530326632386237323063336239333137636436653461373530646430366230 -61336639613362316530396439623766313966633964306563326464633264323235343234633035 -39653665313462366332626232616537376162383535323466363364633464306633326431313362 -64663231313933633134646662656364336439656561356239353533363962653563616334343935 -31363164633439326236313166353465633332636537303561636465316165383436363866356535 -62383530313836646263323139313263643035616337656464343237303464373662343635316565 -37386332386435383433303065313166653065393035616635396161626262376534663034383761 -34626433343232386430623639646633653165626361316664636634346163666231643935633530 -30333439663433633631663539356533306534356230643332326666383431613936643237343732 -34333332373735346137323138373633653663306636383065303736643438373463376661326630 -65666133643932366130396534636536373361383731643663396530393835616533356634353136 -31376366363964373961376634313735333131303065356130626539363630316261363362343831 -37363563363635663637396138306437323431393736653732646138616239386135376461326162 -63643564386434356539663535373330383233326564626238653832333538396262663166633366 -32373837626131356363323732343462633866633038373635383130363030363639333332653736 -32313264303537633862383736333663383433313532653266323630616463363934663837616638 -34386165616662613361616139616234363664333061363934613034356565333436393863666534 -37613863633639613361326130383537316137306466396265313339396364363131626663633831 -62613439326565396336326234376533303337663331626630313363306134616261646335346264 -37666464653532653638656533316134353830343132643666303961613937356262623936353639 -63353132633137343163666536343363343238356362323261393637353533303062323837663666 -38646666353432386361626631333331626264376364343462363539313563313761663438393366 -39393732303431316163383932616635636437343636353734636465646362303865373563646266 -39306535323063326335303032353634313138653033663561303631613635346137356166623337 -36663933326538323835343038646633643738366637616165663434373065313663376536373963 -32363335363435366661353135646463643931633464636563626437326366363466373132303163 -65376264386338346664646134376538343464353331313566303762323832643439363765663138 -66316235323237366332663739333761356233363665396562373033643033353635393130316234 -31383336373333363631323032613164643237626235383735383930653463383263323866623739 -39346266366462376133386261396339613639383163306130633262653930616530663464303065 -64376337626264393861656161663664353437636262386330346631646132623034373761373331 -66323935623962376334323930323938623137393765316564333833623966326631353931643162 -35663531386334633862663638613932613431363139373065343239366262306239616237383663 -65333330363132343766313536653064643830336565366461363331313530633532303539666533 -39353236343363656138616438393833623263373363356262616534396363653830633436646164 -38356132373833643963613866336662393032396236386330346238373430306664306163363131 -35343232396233383636363362356639666162373839323266343037633431323131663431646535 -39393938623666383963343161623037623662633862356161643166373037636236333937656532 -64663539323262383365353665366134626135663864396531333831396235613833346433313762 -61373361323031663163396636633937376531373364393864613663626666313131626234613834 -64663336376366396562633165333764616562353533666230353337663765323962646231626135 -30646362626632313366393363366335373633336238636132663834653934386362663939353538 -61356633663662346266656562303339643731346631306563303965376165626139626537636633 -34383562663138653262323438353639306534383835623438616433323663623863313463373436 -36663263386663303433373534343031666361636135323333643833643266623531633434653065 -38373733343337373330633938666235653163616536626439303732383634316337363762306331 -31373632383233353936636131303663373433373163656639666565323361353136653265303135 -30376662303766343735643963303437306333366135323561666238353331346366366331323237 -64653832613138626531663361303764363336396162373534616333653536623730316263346632 -66316531653935663663366230376663363431393134613465376438366334663261383331323238 -62316661376632333934666230613835366661376430643463303766366664376236626463343165 -62323266633231663933666238383639396330663064343531663631663531373865323962633738 -32613866373566376533373963363833623731663766316435333435623439356164633034366430 -66353962313639313832366339636130653965646634313037633961613235393731313435336464 -31343463343338303637353865323063363832636330326463333336393533663234663632613633 -35653363643133336535633864643733333939366439303935303962393832626238373362303534 -39626639383633633665623930306563626362336338393633636231613736333262656530363530 -63383336386130613835326237366530346265623231333234346139326133663136363230383464 -31616465353433623165643138333330356539346435663166613364633162316339313331653565 -33656231326435616163333966653436656430616561326361393063633562656433333463343636 -39633734313535303961303066313931373233643831373162323465386361613334393039396465 -34306462373763656535376235356632303530616238363232323866386463346464663838353064 -31383837366562363538353566656535623039383861636362623939313765663136626532333062 -36643862396332656234636564303239386334346531393033613364633937636665333236663366 -66623431613336653761313061323532626130616665393765666131666533373462383238633739 -63646563393563613335623736646562323732346434303732663630366238363335303262303864 -66353161353061333561623535376564303336653039343137353338373731623666633366653032 -34363432316361333732663635633563633865393062633232343337303663353636353635393330 -33393665323362333939336163306531313536623264646330373135666539396533623536643063 -38633563373861613938303863333363366430323833333436623431636566356162626664323037 -33623737633834333233623866353934653531653963623830613738383435356639343332386538 -61343061613931653339363562356565616235303235356633343331643632633931323362363932 -65393835643666643261623435633761316363336339663265656162343065336530336537643333 -64636462353138633463356564643463666464663035353862653666366336663464643937303464 -65376338363334663466633630623263363662356337363937336633366335303532643831343361 -66306235303064356431666437356164323338396430303761363730393236663963333966663564 -30323331653563396463343930653861363361626535306438393733363233316430353737653732 -62396265376262313037623436383539386436306437323536666561353035386338396664616539 -33343966343039613939306563386338326130656538663033376237636566303632653535383437 -38313931366462376265306566613065326532646431386337363031616465356539633437306536 -63656462633331623537383736643135313034306538623636343530313263366330396238356563 -34326631386136363230303532393965663365353562393762353532326536633163656230323763 -37613334643866663762656362373365353535613839333962623062653261656636623831613735 -33383464616363376139323462333061333939336137646231323765653334373134663465616264 -38383330383166316230376539306261383837336165613738663762366364346162653938623830 -39653637663837326231313837373461326331653433303938306232626666343761353731653135 -66343266356564306363653836643363336663373064343934313930326638353333396364663136 -66613934326664666462613934353930376564633439363265326639303638656631636639653439 -33323135306563303530383435376563356231343739616438383334333066313836353335373934 -34646134633539303364643166633936663066393137393563656536326664326335343139623136 -62666535323533383834323134346164633531633162343438303634333930636436663730346161 -61383431613036633266373838393635663263306539383765306463653462646137643162616466 -32383161653838313762396133633864663962333664623162383461303037643262663733666462 -31663233386139333630313630306338643766666232623532303431626237363439663231313335 -37386263623936333639613231643561636234343339663166333163333338656637623937613136 -62376561643233633839363466306162653261633632313863623165306239333664623962373739 -64663562313062343361336665373862393061626462633163633534396232346638316538653037 -65633136626233356339393564303139633230633163303064386630353861393037393938313436 -66613036656337303636636338626134633038306265663430366363336635653031353136666234 -66323233636530633139386632643637653330343138336531343864646434656164623866303965 -38303431343563373564363031616561313663633861656363363962656464356565343235333163 -65346433393161353862313634366330376564366563646461353131646266626336653633363631 -33663030323434663937376561373338623164346532323735373265633831356431333039373636 -34386139613864356565343463616236666438343931663636343836613865613733393231376533 -38303763306265383062393735383662643138326262626330663930633661386365346462356631 -64613231336435643739623032373536326336383734643933343539306266303532313339363530 -64656237393361653632613461323133636333333137623962353663303364643839303664386436 -32613233343865666532663561393336333835633862386162396164393030623237613834363433 -34396337343566343862303266383761366266313338613032613936326261386365656363303461 -66643337376332373862613133656633323063316563633863353332306563323363356233376466 -37376366663938653238626562303037633830613039663736306465363339336565363665396232 -63366331646138396166316431306463323266313131383136333239326530626633613562333038 -65373865613432326534646362376164613862653335343837663134363737323630616337653763 -33613865313662336130353930376234346234373931643664346265323032363661323631613464 -65386536343432373965313137313032386563623963323363633366363962623839653139636638 -34366263633461643063366464383035326163353532336464646633386439666364613339373161 -35313230323934393632386332313865343330336134313432303463623237303039623661663233 -66633332653763313438653431643430653738333730353931306139336435323734383761326235 -34613564656364333832366337323961623133316333306237323435356331633065663034636662 -36316233373333353834366265323965316564373361613864373764316165306262363465633232 -30333232386262663035303432323938663263333939353566353031663534636133316230366432 -35336332386166333063633866363835343930613236636334613232386337666339373333326533 -32323966363631633536643334383465356530633434363361643135653266313837396531343533 -66343537643935363161643161346134616430383731623066313161643161366666383939616534 -32313734646335316438393563396435336336353730373639363962666332373263663363393864 -64623638343339663566326564353466653636666337313063393466356363646432633861363063 -63303336323332303666616335353638363233666463373066613833326535356639623438613562 -37396235393265633262363363393930376230333832626233323739663866363735343966366430 -32313838663131333738316162623033313338636436376466343431623932326534353835613564 -34643435323762636532333937626533666230303832333230303136623938653964303865346338 -35376531393562373666616137656561663334323361643130313038656534323736613665653463 -38663535643462643639336166633866643461386432636431633731363237363637383335633164 -61353031373135613663616538306262343838653062643961653335616632643166376231626237 -30313634363933326338643935633437393036393932383366326161643461626530623231616266 -38633665333134346564353033376233663361323761316538633866303336623138623862353239 -37653965396433646536623630316164656235643061623263366565633862366362363531316638 -33643262303461633639386663346265643235626435653739376539376363343036653632363766 -62313638313030623737396361636338616132653636666532633865613865643330613961396333 -31623461383536396366366166303033623437353261323763643165303531363135613237393961 -34386665323163613066633731333535323737313139346431343034343235653535356665373361 -66646461333631656665333162623763653132356632396263313936356463633332356164656231 -66316631623738313736383039633737333537646165353233373833333733323563393431643261 -32336166353532653737633436373232313830636132653039653831313031646633656665656365 -65336134646362306630366363613831353938363161316333636363613463333065356130323237 -61393433663234373461346232653739653430313539313131646662316536333732653437623263 -37343937613266356162323864636463383234633933313837313765613236636532373139383631 -30646230336664616365353935326164303961383637316466323533386635386363306132333966 -32633331613132376262343231333866653862333936663163323335633336356165313432336535 -61323637386462323137303234353561616263326466313665383131616365323135376531623638 -35366638353062323036303638313661636434646239346637616338616264663433396231343335 -39333132303261303436376433303533383932336234633565623061393164356364373262613761 -36306433373764663336316666653765306661363033613132663038646231303432383839626234 -38633166366366393535656535396537633634353135353164663764623839363462613765663733 -62383966383064636335646537393666663234643765643764636534623337343064636462623537 -34633031383837613762633363343439316164343336316436616335626138333731666165613162 -39373439316136313637303362363636353133666436313965346262353330663535666538613236 -30623238353135646130323364303966383865366337653035333538646433366232653131376237 -66303730643833316130663436383433396334643862333634346439373331653532373362313262 -61396535643131323364636362303438616530626561633734623963313337646536383963663038 -32316333343930643933663232303565666634663732656566616432633439333235333630383766 -30333835333936633332623632643938366161366233386163323932383664323663326531363139 -35306437316332356561636336346237316338353264373931356339643433643965343938353738 -64663066373034343939336532363665623662313665343335323866633065396439396330643237 -39626637376433326532633034303338316536346464623762663031646430656165353666356135 -38653464626139366133613438333666393230373831613831353761356566623163396332313137 -38326532646337373831323830306263346434646564393232303164393166343332323230353534 -34343134643264323933393135653763366361343934396436613561393235623466626463346431 -64346436343238643965623133313235656638613232393337313733656462653034383933616466 -66333864613133646561303666653265653764343631303430396631393633653231613438663865 -64376161626135646636313239613862316264313834396165306339353736613030613531613633 -38303535633339356239356332323665326632326337363130376536393339306365323062373436 -64343939393331373536333861613066616633643631323534353761333964303235383030333934 -64656231346461633930346331343766653862333561373166326636636135303432353036306634 -32393661363339323831343964323535313964653937326561396338323062303536373866646530 -63336436343061356639656162393638303236333134336330373533396231623630636632376265 -66636133333066613735323434326638653436363861356361383530383132303437393933653239 -35373635396131363730336263343136363732393032613439373536343730633236373364363932 -62393263336236626239373438616662643038313932383936616439663237393133333363383564 -30626631313566313365626337353135616530646635636233333766343663666231376463313831 -63613030653662336664326664383934346636643764653833376366313964363533623237616363 -36383761663935303563666265366432353765376462396161393734633137306236346332613436 -64306465376435313261336434306565616438313233333835626431623330633133376630353333 -36343063646565303138636335323030623162366561336461376634373931633061653634306231 -34303230343830633366353732383465373431316338393439656438616463616164333230626132 -36373430303130376361373761613933363534323731666465653637343366663431396530616330 -33313634386563643434393930656664393436386532386565353233643334393261343135323036 -61376261333935333238363766616662393565396236643962376565313330343936373263643162 -39636134356663373762383432623836666237613639636264663937313432323233656264373231 -35613665363161303731666335343330396335306261343232353235323830326331646434353230 -32613232636636383666613439643632343362356537346161653136343835333762666430363434 -35393638343761623632303631396161343230313639646434333866613837666565313466316139 -34323836623231643163613266373731363266646130373336333139643038633639346561343339 -31353462643565363330623832383066333166333436303663336536333831326161313966363938 -63333435393263383831333332346132393532613038353666633033363831646532383633383930 -36666339643031343931653334616339373435666433663032313163333933613462653865323361 -37363336613862323831656630393231383465313766316261363536376439393934356539653264 -31376463343332363465396265386662303936653861613963366638303935333032336266393334 -65653134363430393432323532666235386261386335313136343732333938323237383262363134 -30656639346663303165623762623037633532363766363739666136356332396465373433313863 -63336633316561613738623334616235656434386331653062366330396434636439313463346230 -63306263336366353932343239613832313464656266666339643532353031626535353064393530 -38623933666362336431326232613833336232353638383832386462666230373766636564366565 -65323061373132323465323462343666653465616130313038353433383464363034316661343763 -66323763373461616365313133316130656165353262613365373432666331323931323836633766 -35343061656661656130613463646237353662656263303935303738336338376137386135666537 -31393366366566633764376630356665336134366233363064633362626532636236356665663439 -63346536633234303636663433373530623436633833663564343230663730656335366131616637 -31366234366566656435386166323062383839666263343139616138323232313863333739313062 -37336361396332666332343861666533623139636163653339636433393134373031383261643165 -33656263376535643737386333666362623334643432353538393038376533306430323236616336 -36393937326139346265643531396533326339353963663162343034653163626665353965653136 -35653335353139346364653263313261306638386233633636393663653330316138373463653438 -38663063666137656264613662383737656562653565663566336161636533393238633437616163 -31363366393362636332613130373432366565346235393639356333336638653533363734633961 -31336537323865353861343761663065333766386336386362356330646534323664653638343366 -34356539356362613531343731376366626535353635336539303763633666376135373134313832 -38653231353134343835623933393863663066643234373836633439353461613838356562336138 -36303461616333383364613031343866303938313333396630643834306237316661613662363939 -35393139376631396237303539303963663032316261616637316236636339383438656338373939 -61346635313537373232303366336566373036616462626533653230346465316361383636306630 -39623132323135393531323132626535316334343836396237626562376364333839373065363465 -61633962373462326639653835656636323664333165333563383061646430316235383939393431 -62633065373465343831646337346439396632343166636537386664656139333165366465636339 -62313135623766343463633239356562363034373635396439656132646436653830363865626466 -33396632633933366162363935316334373732646136313736653862366465366632653730356563 -34643366653632366565383430376536353030633136306336323733303263336634313163396335 -65313938343064633562303463323938313338373830326438636335323635633663626664663261 -39663763633561353838643835373037376632663165346638373265353035363439323161363466 -61626537643335333436653331356232616531336235303330656133353834623335373832303266 -64656264636337336564623965363635353363303438616633373732303665363432316265393465 -30653235356166383463663432336630646162343264656430386433353863316530336131326436 -37373765656130326339306135373763633534316234316136373834323938303636303264396164 -38333166636666313962323862663565643538383565653365646238636331663938396563623730 -66386537323966613839643133316438323535303662333437616436313633383331326161383036 -36663266386339323363353236636161653765333066626433656639333232646162653166303334 -66346462396333653830393666316534353232353462383930353334643534356666666430643461 -62363739373436623364316536323631323465343162396366633563666337666630656131376536 -39643461353665303164643736386566633031353536623730623032666563333238393933343534 -37663937633737366330323535343731666436386336396531353234326235336564376666333662 -35623364313663663465363830366639353162306338366136383639336539383238663866616630 -64353666393564363239333766666330313530393237363235316363633437323733373930356330 -34656636363831396131353165376333393365646539666639346332613233343034383064303836 -35373733316462666532626138623732323065363334303864306265666131313265323737646666 -36386532346234376535663564313865366639323431653438306464653363333333306361666139 -66393261623832356463633063333363626231316430383339383636323739356436333132386438 -62346437653533353661336639373837343335396636393239353637313832666161666162326262 -35386535336465643938653532303931326632306462623831333261373233666465343464623935 -36353830363030323763633264393666396133376135653530613062376232613936343932626365 -35383139643533353032326335653230633036643231346136363930646465393965326663613936 -35326137333336663436333830333562306637653762633666363731356139363864613165373535 -35323061396462356164643662323164636630393637653832313931303934383566383965613265 -30366434393466333030346239373364613465386633623831643365356563636139653432336635 -62363865613163613432613239656135636134643331376232363630393835376531323065343032 -61356232646131326132356266326362323161643032646335326265356335343031303932626238 -33306237366137376566313365343734383463643739646566383431623166333731363434613364 -36616435663363376632393061626135343164653136343534346165616263396264623861326566 -64633436633764643863363363626436343962626439323033383661356137626264663435633566 -66653933326665343965643437346361303866386337633563316533343437376230613437646633 -36316465653964623863633230313432316332383132333132383265303464653632396662663538 -34633430303936373938646531353436363361643739336366396539656237376533646332383563 -32366338643138663639303537663666326436653666353936326337313437313139396361373762 -37313035396434313364326435633438636430353732393631653735393232343233633534386561 -62613138383732633630393061633335306131373430396335636236313439636163333335323630 -32353666313931393465316462313438653335333566396362316435383861326534323062326262 -61363733633664313635393532646339613132386663343366353730636634386662386431616135 -61623664343361373731643534313537353663383733373465656161323665336531373130346237 -64666238313836396561653732313233393361353031376266653636333762366134663237326262 -35356334646166386236393036353036353633623765396663353539663464326239306436306665 -66633438616261393032653866613132326232306532313962343533393833396531343761663864 -39386333636539646662653134313232653832356264656137653630636264383030656161386364 -38666530353535646238393538633731383466666362643538616237303436633063366532353130 -33633730373534623732316337633461333264623537343330633631396532343361633333613563 -39663565323430343638303266386631613038373833323965656332656664646336323061346636 -36393261626563323131323736316130303365336133336132656235316462393836613137336631 -62356364363766326331316666313634373934643333653865336163663566333038363566353530 -37623762393932613866663532303133323532313532306532616366623166623834623035393037 -37383531353835333332346633316332626435396335396565663333656439353964373430633431 -61313337663832623033633864626666316262623265323037666636366235313334656565396531 -36656261353436623438396266343765353936393861383065393838353434663934356131633566 -64396666616639303636653138666530393938323533306563663632306433636236633665323331 -66663630396234333932366236346232373631666134383537383063363866616261383431336531 -39303037656563626635396331623561646362343437383966363232356361313037613830356232 -36393864313362636231623431383539383666303632393664306538363061383561393332636233 -37623630396237336337363665303236333036356632636162623661643531383338633539366537 -36626630646163396239623364626639653065646362313439306233646165333863653438633063 -34316635666464616335356337366339663639626361373334623039356230303432663435613134 -61643964653438393039333539643462643861393336643934333364313465643464343761663831 -39386234323331373734343136643838373537633665373230306238326434336364363666363562 -64666364623638386266616236636232613633656130656565653462323833633364346135363431 -30363138663035353465616237383037313664666364383035343363666433366562343133336438 -39326139313665663864653863653531653937326633363832663533626533336336643136383035 -62626635393661613438623236386139343739376366653135333866643139356638623834386465 -35663838343566396238643866633763666238353063643735353665316432326266613764353138 -65393731346137303732623835353436386139623866366235646234656462666164633635616532 -32346163366336386538336364333562363332323534303564333232663638383137326466353232 -30373031333834383862356638363466616330646537383062656163373133363534633266363633 -39393335643564623238333835313839313661393731353832313562396666373135396332316438 -35356435363163306361383834303361663564323463316534343265333733306566613561646535 -37666331643939663164346630633564313666373131633765366364323433373537623832643936 -30643462666366306232393764643462373733303465653665396431363330663137653731313430 -66656663636534396363303063626536326533336639333862386266633863336163313365616130 -30646564393632653538336465326239323738333539393565323137653132376437353165633939 -62306265303265323438663662313435396333333131366533396530336439353863373636323133 -39343932303565306534626364336462393435386530323833633931373661613633376430663130 -63353361323639366264663636663433356432373538636237653933306434653839313430316562 -64623234363661326462396361613234616532346462663066656361643633663333376564643631 -31363665313433333736313262393033663261633939623332626332633462666231663966353964 -30633331653539303339653365306463353933643765393937366539383730343531613332316633 -31393631396638656239353566333165616565393935613638336663393864396339363634343061 -34316663663533363761393137343338653664336563363261643736393938663366306262623062 -32383963336431323636323765383836376564613931323765366337346431323430663033613237 -63343137646639663431663933613063636230633334393164373662333063653234326438646133 -38313430613432616561633635353139626539653961656265376435306462626637353662666663 -64633335393161653936623566376439333834383139626137626230636637353061663230356531 -38653838623635643831363965633930343663363864623666633236356330613434363036333365 -66336261323935366361313230306235633165636636336230653132333562303564306235373464 -63303633613335343139393065316336316632373039323230396537333164626136663038613933 -34633066666565656537353066656164633866643764313232613338346130316537613838646665 -36623730393631326536313636386239653561386163313631316662613761666361373437653363 -33616334303836343431346430656539643134336365653961303431316431386135623661363731 -61393661383466643162666437396233633330303062343161363630306639396261306237313562 -32366166366138313931323138663263353136303937393830386131643466393332656536343738 -62313063613838333837613865393134653931323635333631613062356262343435613837303065 -36313532316330623130646232623364303232386430653561623634343162366230373832393533 -64323238643235353165623735333730393533336131303366646338356237393834626461636638 -65376365313866363332613530643438326563636665363635656631393934356636373766373261 -39343439363961626262366234656531366361316132656533666661663531306530636236643735 -34353161633864633439383764343935323066363763653233383530646137613535353031363837 -62346333626261353436373766316636383230333264376633613238353830623963396262303462 -30373030343936666463643464643764623632363139333537343064653763616337326232646432 -62353539313337333939356461623435626338633732366563316435366663376664396339623931 -35316336346362393137333361383862663136303430393737396539366634323131616666666535 -38656266363765643263333136653433633134613838303530366435383137323533313336613136 -35616634646635316439663731653736333432393464363633363535316664656262633631303139 -62396138316333366532303936326365653436356264653363363965353964303662343236363533 -66343737623931333936316166316662336461313337636263363438326439616661373064336230 -64643364643266653062336264646632303934636436663134303262343332663662356239363166 -36616433663763663636353738326134653064656362336336623935626532343265393832373262 -30313736346234653464633936383464333264393730346263306439366138623131326136656438 -63666635643937653936313031653265396233653734386261636136616234383230633331396333 -66646431393166363539323538616430636432613636663839376332653739363162656332363837 -39666231336265386363386635323339313633633836646334373461623365623164303133343638 -38643032386637633432353762613466626261353166626439333861333536346663363131356634 -65633630613831346331653762333137336330396364366264303362616431666362303130386432 -66643861333664666163393137333964396264653931396432343236373862636433343539336561 -31316262303164343439376138393762323833383661343832386163313838653362646535306432 -61373366363236343362623133666166316564333032653735366439656162633632353736336163 -38393535623733373461346465326531306134636134386434666336663138653632316135613338 -66366533626461323863376463393737616130306363383931353134303465306436666364623333 -33623062663033646664636435383433396434613633326333336231613163313863396665616134 -34646135393631353162353561313437383238316538663061623562376466303532356466313932 -37343761363065313235333030363636623638363763353535313566613837343462643465313133 -65613033313235666333653530373632366238346231396136346631666338346131313964373561 -37363432616133303262613561663837353262353133333634613663633033363833386331663535 -36303333393634666465656266306237343731323636613630363330326539373031383632613133 -33623965396463656138383933396231663733376463353063613665646662626366623137313933 -30623263313430326531316132613430303938396464303165643438333466326137353066386361 -34343561303233366632313730373531333365626663316332393933353738346531383734613335 -36643936313934633663353461643735333463316462343132633034646538636639643766393063 -65383232666566313365393930646634663965646438643835326265643939653536393537393733 -63623265333439313030643632316364396234303530343762343432636331363163663465366131 -35613963396234333062353936316639373263623234633934333830666335383332336432343366 -39353734346230613631613565313166623062366431633464356137663837346639386663396166 -30643661653739333966613464333332316234653761633330326137316636613166623436393962 -30366661653538346536653363303864623063356166626261313230356436386564353933363165 -35633338626132366561656337373666616336316532326337363162303438343261316637626363 -31373534383463376338633866363930646531343762356439616666626664646163313635623035 -65366234636337613465356433336530313533393132666532366161303561656630393338636236 -36626233316232396439323337633333653761383261303137343939653131613064333830633064 -38643831386139303863343666643830656333336139323531613238343530393664393333613932 -36663836653333323838633565626132396138386436373039623533306163333731633336356462 -35373138616330643436653061633332353939666137303163333733656638373263323631666461 -62616236353761333431373736336532363937663666626332356538636437303239626232396236 -34383835643339363030366231323664343332353036323232386433623363346636383065383031 -61386132316464653235653736316163376563313465313039396435313361636239643830396338 -39353163303063643630636130643265376335356335656534366262663638313732383635373461 -35663935333634646232373937653461653236393437356437353965633632666235323634663330 -61343932663236376338353832336561326437616439353361646433663064323337323437626430 -62323434636137316565363133386437303435396238303730376461663633623031373562396463 -62626139663534396330386438326236613331366233313039366465313965353933306536313034 -32613665636235646462613030623161346430666162396337386137313130363736313864653266 -33616163326362343033653531303832323533346330626662333962323232303261653962303433 -61643335363265353162333237616337303464323161396235376639333236343238623331376630 -33383932346434323262313831303032393734653462656332353638303762313361303334326535 -37653033653933663836343030383366396632653135636663316265306236333762646162326234 -38353531653661396562653764366532306239653833616164386137383862323965613363326664 -61623434313237316439303734333738353333636236373066613134383863303664343663356564 -37363836633365633031633833343063393935636161616130333832313166326239653838626637 -32393365643838346534326439376337323336643630376464396662623135313736616238643439 -61616538383937313462323361653562306465663761636635663833366463323965353033666165 -32646535373531383330653230353230653437383664626439303163346163623838326361613630 -64633033633538323663333930306433653663346365363761313738353535613561653932306630 -65313136616163303566626561616637383633396462636636333236656461396666303366323630 -36643739373561323166616466666338396663616632323239333034623233376435333430383565 -31666236613439343238376434333139643436613438333565316432346565643464303033356563 -34316262653031383730346236343138656633623836356538663031626232313537643938303766 -61643038643237623235636462616434633432386364393835623961366461326131393462343930 -37326165313132613730323634383763373336656534366263373233396463373365353534316633 -33303130653666313665303561363133343462326133633466643864396339323232653334306636 -39323736366132366334366261313036353461613939363862393235633163623165656162646166 -31303030323435633065356638313563343064386365656633343261666139346536623836373636 -30316639396536623735316166646162336662323431306465623534363239343039663236363966 -62633334656462346639353362323431643633633864353561366162633431623039323931376234 -33353861343636653336346139313132326238323434343835343537623764323031366161373537 -37643364323366303863383532646136333464343762623166343134633236373566343066366163 -35386535343939396538643866363135376336333031636530626135613739643537306161376465 -36653536663632316333653038326236633737626161666636643335386336316666633562383461 -62613336626135316336643731326561633461646138333466373232623538613864633833656635 -39393838636237353863653066306162346530346530323861313137393235356438363765363939 -36663431616537356535623031393636363433666334626531623331653030336262386366363035 -62666266363563336139373564396330636564363037626239643533366532333733633461623235 -30363135323739313635376463343833653431613438633237303838393530626465356637373734 -39653339333133373537366561393330363264646135613465653431333463396439666266623832 -38326137316464336630326464613238636338373266333139636366616165646364666266313634 -33363631336431396431316531646533353534336439353138343736333035356430333735353139 -63313635323037643262643735336162336530626162333336396134366637333863366465396563 -38353761303434636433636266386632363666383239613838653234616164306363333133646135 -34326639306464353438383361386431663031356139613138303334373233336638616334613032 -61323735353639363136613036643237656431313737323531323133313935636262633332313331 -33373931353133616661363266393931653831643661663366346438363963323531346134376131 -37373235646264316339653532396263653463663066373632653635333331666564373665386134 -31623235323537313461323265633661376131383331616165356239643831333638666161386336 -61366330343638393162393665306235343438313462633834356135346164386266303165313930 -30613062653961333465633430636462353337303232373265386135393235636264313236313766 -61393337323530613835343030393332633364616339383135353365393230613835316138353334 -66373835386634366130343831633436633533653961303561643334336463316334663562616263 -37373835616263623036653239343433636239323466353862343130666435333539343839303162 -66653761613631316435666436623438653966653166376338646136326661333638313933303563 -34326230333238313737303265383230373536363064393738623037626235663231653834643432 -37623133646362623434363566643066633236363937643039643734356565353030646535663431 -30376336326131356139643539306637633833616435353665623565633064346663386439343739 -38663466303132363733316165666661303432326136353530666535366133333435626663366530 -66326531356339656131336234356136383465626466376466393237363036333539656534653638 -35623438613233313564626637363436613565656261306135663231306138643339613161323831 -35393131386130613663666466653336313962653461646535356132383261316131376237653435 -35353862383364353866346166396338376234656133666639626237633132316162333037366534 -32373464393637616634306135633061633332303734373366373834303664363632666234633838 -61663438306266303163623934323034663361343930326637366465343330613361653164323636 -65666639376137633936373230316135303862366130646566333065373431636263303639346539 -37633830613462626331313838616564313037313933633762386337653339613839313861366163 -37393035616365616363396133336638643438613138393731663363663230393937646230306262 -35363662663533326363373535306630366538656433356665373463303838663133353964643933 -30666633356234333562326663343030383739633035343466363735303833316361333437363762 -33633230393664326563346365326534373831633832373432313739613036313963663964383865 -38356462626561626436323362383139386530666237373439626262383565343534616535386336 -64393134653132623166623161323964336238376139323434343464356266643636323835353036 -33343262623038346231663938383237376366326266646334396562393336323937623438323930 -34343663653933303230613135323137636239323438343761653438656638626337396134313935 -30326233643066636365616562646231303137346462343632373639353466323336373564336666 -35363630626466306538343535633463616436363539633663333866343538356134666234353336 -62323239326333363763656537653666646662623564393935383563663463353131363766333861 -62666430636262623535373963623939643965343362663730313636643432323430666462633366 -36613337383633633766336534646632343339383531643834346433663534613237343564336462 -61316631343431386234663937336162626638666664333462636434666632333064653136643736 -32353464373538366666626437386332316232656233353235336536366231303033663836333537 -30623563383362303839666363663830626465366564303430323535653235623632323662666564 -64663030633737663532373638366366333334646230366363656564373138366666646363393362 -62313037393533653839636466396131646239313731313165353233393766323435366531383263 -31663135656534396338663563316230396433313636313963356164333931346633353465393632 -39356435393532363336393164343063363134353635633836653830383735646634306263316564 -63393261356138303361623039626264633134386632376436636534333938303531613433343138 -62353466323431313463313864656433303835346363653463376564613939626261623031343736 -37323566636232613632336663643563666630393235643065663436306330323436356534333230 -66373233383634643630613764343165316335343030343762303163666238376565336639396239 -35613233363661613664363632373262373063343037346561653264333263626365653461323662 -61623364613161353135313466376361636365653263363631396131373335333732636237343737 -37646135316166356531393365633064356262353535623762316636353737633466633936633763 -39613964623064353962343066663538373837343961383735653639613161666430373965633533 -65323764626637386633636331376161326230346634613862633131353163316236383533386436 -65366630393136646232383733663736353931306236343161393331326634346330333063346233 -31373637636437366464643666363462386638346664636331386231646263393465616134663134 -38373866636238373333633233643532656563396132333336663930383262346538333965666437 -61363432623733383231656362396639366236636266633763336633626665636366663936333634 -31363834396438303033656366346434333038346337646664383534663838313963376665386338 -33396531656165613233623864616463373462353330336561326364353533663832383463663433 -61376430646265383637633736303833383365353831633935313731373064646532353633333666 -33336661383638306137663139373336663761633030336235363262613861646262636566333033 -35386136646232313665306138626437333535373063323766643565646231396362663231613237 -64653364343366303033363734336566393436623532303338616632333263636661396536643164 -32336535376265306563656139316164656137343633643839636530303935663866353139646334 -65363736336330356464336538646532363434616132633364366432333730666637616530383731 -34633137306235363739336262373466613066626636366534373130636430303066653732653237 -66346337633862323936663862343134353239363131393964383932303963616233663638386164 -30663634653466313832373463383337633966613631363832666664396233353032363735666161 -30373061333730633935383630643436376461363563366166666532653263313564396430396631 -34636635386262633934313062346531303631323862623236343537313165643733666339623365 -64303063656433666137613937353333646461303564623862393961383964653365383937326132 -33373834613566646630316635633266343561303737656565393863336331316265323361626635 -66333663333034353062633834663335326431663465643935313861663833633866303730633330 -65636564666634363066363639313739333865363866636463373536316131626161393833623030 -34346231613565623931653265373765376531663530333235613064333565613837366164306465 -63363335623835383164393233626139316632363732663030303834646133653236613065336336 -61383534663563346330343164333033316432386365633534366664633537623234316133316137 -63623231346462353664386464383963653865636233616130346334396230363434646130663066 -34333837383930616139396665373636656333313832336536393230306165383861633635313030 -63383233396234316530666531653937386230393534343438663830663566616532356563383961 -61303238616431326335366635663565383131633936656464366639363730323234336539653936 -62366430346665643266353837666363316161623563636165383561393766363165363963323533 -30643562653238666237383564386362333832666433636138636234373766346661313634663438 -65313338613262303063393434316236653235313831653164316264653963343735623961616262 -30643031613238313033393736336138353366633234333338336639333037653731656138326639 -63363534643531633832613436373133313334343631333532313539643830613735623130376535 -61646138613263383461356564366233633130633861643663303263663238656236333762653830 -61343633616161366362666539373331323665663662383361393764636234373430333836333934 -61373437643834623532656630636466386465666563663738363532613633343930386164636638 -34663637393533623131373461653263656630333335623931613935366238643531653036623762 -39666164356561336361336434623238623730386436656234353833613836623233373035613038 -30306236393133353030356664346663386263356233393836666337656363363235313733336133 -32336265393935613039356534386237316433626566346438643233306335343939613335386166 -63636432373832366561363133666166633062353239393935313033386162613861363763303334 -39316133376665646431623965643863353232396238663664376130626137313139383134643264 -31623361396334646664366562343838333461646666363837633532643533373338313138633564 -37396239373234636264376563643162396532393638316161373061633662653966316435386135 -31623663636664656431366664393764363661616631353638386665383531326331383965646633 -32643365356165366165643037656639306663383061623437656235633562366635623832386538 -63653065643537343730333664373733386536633035383933306465303438353863333036366534 -61613539376566356533346333383038643265333762626365613964663265356162643362393966 -64623339326135376535363930383861386637343437356231633134346463616466313132653666 -35643039633266333531346166396661616563383435313662636163383239396562643366353233 -33313131643463366564323962633731366461323038333434313562623130313365613232326639 -31633330353237633737316462383861376232643730616464653064326363333663306631396333 -39393231613937363038326363393063366534323336376638383062366332366261303439346238 -39303636616435323537623939353431396632643461653238613336336464653965346431393238 -65363361303734626237316639646233393963666339653036376237313631353138363332323936 -38316538343739663238663133613362613135643234313530643033353639336664376639313038 -64366332623166656235383863353365316637356562373639653062343631643339353066353231 -66653866366661646630323362323363656666623761396365313131343334333431383865306139 -38656537393932656666333762326266626437346335303761616230323235653962363765656632 -64643433623339646236643132623135356331653636383564393266646363363466386534333334 -34336236653730376231376561336432303363343834623136366430333233313762623534393961 -33303561346635633862346538663364663962336537363331313435633336613461396265636332 -36383332376264613738393738363137313463343033633434363362346430623030366333303436 -66346431316639313334393131666463396230616237643930373034333565656139656662613065 -65323461396137313164633932363430663934653637363162643563666664656538396163666631 -63376166323962643062643461306530303863353866393336623933626462333434366531313765 -39383636376632393532626137623531666230656665363966393435383830653333356137663138 -35656235373338343138383938646637643563656239333833323438333439326531366135373833 -64323239653163366534313764613934613230653431643830366361653232356364626635373463 -36663434336138316663313462373935373235333539346231623137626334383162343463646266 -32653738626161373466373433656465386135653333666530653563393234306361373265346133 -31656265383166306137373035356165313033356435396636643761306331323963633233316662 -39356134333932366137366632656137373233363737333764653638343335346137666336616233 -65363138646434356533626162316661306534353661346637313531376561313838353162653865 -62383266396633343632306135373430616464646134333466643432613861643230353766353834 -39386466393933656461353461646264656230633139396361306436343366626632353630336362 -64396566643164623938343366626631353563303030633231643034353365386535366630623662 -38373663646532343235663039653866643334363665333535643262386535373838656261373463 -32623138353133393161313062633466343533653863306165656262306364306333343464626337 -32343062386365343636386265323638356330663537356164656437656362333538646538336563 -66373933386535363265383339346235393462313961376663366235343565323438326338643132 -34353731636662363762383231366235383737613464343537383935653634366262613632623539 -38633265643238353632363034613332613739653332636661616164613863343438383262326332 -38306361663530333663346666353661313138383838386135373539353462383831613437626364 -66613764626238663538383439626464326435313138383061376264313061343239366134633333 -34313065623332316362373962393732313661303535313432646430386532336636663161313266 -38366433323337646463323931306235646163626264353335373731613530316133346266613032 -64396534393930623034323263316233356564366365336461333062636535623037386234393531 -65316564633464333061323437646632376334626330373437373539323033386566623262646431 -31636663653337343135373763373235613238356633666436663733346531313033383365623661 -39373365326338326432373736336263373566396161343134386262653161343336623736653333 -61623438616637633735363664373935383239333639646331613332663037343630646139656431 -34633130323830656530313466386137623132363766353532633434386437613435366461656331 -32323430333636356165656137373238633633393438646363356265633163666163306133363034 -63373733323438633839366561633834333030313932623438363532313536623163656565663930 -33643938306437666435346238393566633935336133616363303434653235653039313333336635 -63616336616330393432366561653239306130646239363437333733393533356339643435643035 -34666133366562333131336633353263366235376631656238313534653332386535636662356538 -61303738383163636461626334383833363339336337666361313337363739383732333434666233 -34383366336339663564633739323366636638373836616464353532666361383137326164613365 -30626236623161393330336363616536303033643661303164356230623263623130313634323664 -66356664306535363264313934633637646433646665366636336336323665626634326139363763 -36383761646534626565623137383032363533663130613965363865623631383538326262323861 -61333838666334333338346364653263343761643539643839393663336433336335363632363336 -63616365343335373538346234636635383737343935316233653530633461353537656363303662 -63343735353861386235363935393562303564313034333866666161363665626366326333373164 -38633037366164383036613966333531323139336238653632663663643730326531396231376132 -63386430313762353265633765353734643535336436616635393432323464343363346361383664 -37303362373332323366373336366264333030646439616239666664323332306331613664616562 -36346332663361366133353032313739396538623535623435366665646466376562373331313435 -30323437383033656531316131646237363266336634353431333062336566643564666632323861 -35343565393566386131343539316337336133333438636339343033386135353865313839623938 -31336566353439366463373934646539333964383332303931373537653434333133363563613831 -39663933346662366232636561656363306166633838623639373262373333663465613334353462 -64393362623331663030306135646138333335383438373765613466633939383937636238366131 -62383635623430626539313566303530386461653263373338633339666330663863663635396330 -39333565383034636135646637633932323662663533396635336630396465393963313131616331 -37376132613331663365626433623735346464333630616234326264306635616662633935306138 -35396334656131353538623763663364376566626535643338386638626335363663643533343334 -63623437616139623331393066323738306138303263323138646135383566663730326333386661 -39653635613334613339366238386432343466333362306634336564363266666164373736393962 -62353933386163666266623331363565333966343833626661623163633235323335666666623835 -39643962343330623061623032363665393133623330323962343630356364316566663961333637 -32303562613531363263353035363866393164616532303539356266376661313164313637376332 -37323733386535336461323665636666313335333064373765653532363231366361646430393336 -38616432313065653330333033316438336631396564313761313739343266643461323830373332 -34646237376435356237656534313563646231333932656264353731326333333739343336323635 -36636264656539666632333733303038306534303839346165653033633631616438316435343332 -33336362323164636461313663343833373932613834663239353038633466643565663736636239 -39366637333030336539343065383230333232346437653637383861666430323334666562306634 -35386433336237343632663364363332326166666566653632386465313539333461353835303338 -64306434626335343965306539303339643162363164643833616134333434613438376339373233 -36616633333438303435613363363737343237323333636537336331633237656331336134316135 -63346138343033313163343064363836366265336331343964393130306466623462363235653335 -63656333616263326230623238643463336566336464633632653163633164333739363938353665 -66616339653532353663363466343137636434646431303565636136303962643932316633646263 -38663665326264386261663534376233666661613162373165653330616632656634336464323537 -63383334383532656139336461333132643865666136393538303137306661393932333066303562 -31376565333832343331333166623639653735333066333335353530303465356132396234353562 -62643638663539316632343235333638656561623739316332303039386433306437376533313533 -36663234376533323361666664393435383365356661346131666234613662373166313136623933 -38653639663662656664343831613635356434326534663938343933336131373566356438653165 -36363230613062396663636664386534636662626632316438363533383665306564353262303761 -65613538643535336663386262666265633731376563396363633864376463333932396230363164 -37316561376539396265616365386364323137366166316534386164363936396261316633623131 -33383636613238316132366232656161316233363963336465653033653864656630336434306334 -37633832623163663762646161623964643965303330326562333134353762366662666537393562 -34373063373636663333323439613165333430653738616665663764333762383163373262613463 -64313232616137313335376362313939623433383666313039373635623634333332346434343463 -33333664616536623764383334653630386638386331613562373061396130333135313734626663 -32366536323735636636393066353838313937643731333839393661613638323531666634633565 -37373364336138323761386235393439393731353635346662663735333332333935656666356130 -38313639613335303230613330303239343665396331623736393061303237633961326265366137 -31623136656162363464333830323130623836313965616138313661613139393939336435666635 -36303264376336346661656232643661313038346464376361366637646632633161363733663931 -63643338636238343239383032613838613630373763663835346537383166396332653930303961 -34336233323538616531346163366166623235633831613739373139383239316538326365353937 -33313837373239613433373961306337343663663535626666303832623639303366363737656639 -65323231623635326635663763653864616361333035306330333638303564376661346665326338 -35666631343235626637396132376166643462333830393438333439383731663836333134623039 -62656130636234633464316137643862373338653465346266653263383563343036643566303061 -64306538643266316563333931653165373137366432633533626235643133303236366262613632 -31373432653164633266326566333335363864353764663939303236326462363636366666663031 -30633966663535306530616664323039663662353338663162656138666337376134653265373933 -32366165633631626565386462396535323936326132633936333938353561363733303462643761 -64346361613230333537353735363336373138656538373537353766386632303861653738343062 -31336330303631666364646332383235656163663634313764366665633132613063613935316235 -31346533633763313262303364636162373061383736393530336464326230326335303739326638 -35343036613931346433626138633064613536313236623034656335363833303136663764613366 -38383965303331323734343431343764366134643532663630356262633032626336383038396338 -31313139643534353032353032636237646437333630393234626538373039353037626435303866 -39306264356637653637646536323065633434333032636362643963386262356238386237333161 -64323439636263303935653865363535663130636564376231356237373632336661313230633934 -37643333626163653234326630653966386135623963343730623366306562633436323633363633 -64373430343632363162663732323738316237626432633965323564313131626537663731323661 -36363332303461356534396136383032363239626361653537633864613037363231343633326164 -39613431353331303730333336343463663236336465316264386233353433663034613861623935 -33363466633832343336363761346563633365376430653132636235366264663862363733666638 -34346661306632326463663234383164633939626665623634333133333634356631386234646131 -64323233656532313066313033646431366465353264396138373134366133323939666364643533 -61333162663333366662333134633264326630313934623937313663386531633332383133346332 -35663030366333353731636465323965613236333738666237353634373438383138646633386536 -39383732623937616634383966396464616239373466626431633338613536323662363531376366 -64626631663838383539396466626333643733393262333431313761633239303463303331643364 -36343565333966313533303037636238633735313964616561663739626466613363653963353065 -33613830663139656431313837633734396437363430303634383639623465366236623433623164 -63363665363763333966336436383933623736353661646165623635396238333464353663326234 -30356365393438386131306132363663646130353732323232613263356238353932626661313563 -33653039643761326262366439626562396533663438373161356131646661363066396263336633 -38303838656134616138393833383431663563353037656130343931353665346336343961373462 -34316631653261333338396337343034333465636538393963343062383439646137353361653537 -66623138613830383636343638353466646265616366653961313536623337616430363937383436 -30666464396536643466313962636332613933663431363462356635366633643132383662623733 -61653463663136383861663037303135303761373234363831396162623531306430343231386537 -31316436613438663334626537363031623363396131386637626333653964306537376630623231 -34343737666338636563323038656638326665323262346239623236306361326632333366623534 -33663462646436643361313132356439623736373232386562663437636133316562323466643763 -61303031313534646633613936373135373561323162333138626465393233363137626534366136 -30613233626538333963643932653032313838643631656438646433656237356462626434363632 -30633762353435626262366533366636323433363038653437643631323336393730323831303332 -62343731643235363164336466353633626534383837383931303833636562636562313362663933 -63643930356338313662373763373463633435343362313630396236366661626235303064363330 -38343437313430396237373266613763366337396565666635623235336637366439303863386662 -34333262613438666263303435326565373432373130346235653830386364383436616162326639 -61326264663833616635313736386666623736633438346231386333333838393134666262616133 -33626532373830383832373533383931653638613665366664393439386161366162653666356465 -37613338333764373833646463303363383637316266333263323437306663623862363363383230 -36396461633633643435353862663565663238373366666338613432643430326461663064326230 -63376164643965393761383732396135623037613566636565353134376365336661343830653339 -38633834336239663133633938393537393361376135366563396133666136386564643630393739 -62383630653831653132643132376534663263333737366635373835653335333266326633323364 -37666334393438336661633031326663646232653064326339346336633839383131333061313337 -34343733643834343435363462373835326663373739646234303231373664313164373461646235 -35633266366532363436646539303634346337346432633965396364653865383839666131343935 -39636531313166366463353462306536613938303935316432613264626539613430323462323839 -31613235373061313761353137353832323830613964383362653862306231653535303939353666 -30363632346538643463326234396539653463316462336630323738343438653031363963363763 -32653131383238333061303831653331653731616565643631313031653437313965323761376562 -64363565653737336663306632616161393762393966333436366435383761623238646639306130 -32653466393036356333656333636234363561366332333333373636326131393736356161393564 -65333366633235626534393136326432366162303066663331343332613365323362306662336234 -30633664333031643761653736336439666562333836356331626430316363616437633836323538 -63636139653931646132633038386638633561613531653533323834366437623461356464303632 -61323266393837373562653838333362333436646636656433373464663437373263373235343336 -31656661386330346163366231626266653032343862313863356133356431616666393637353765 -62643535333765353236323432303235633161643464346438373266353631646262616162343965 -31633436373932616566306436366632303139666666353561383864636436656135643863316337 -65656135323937616530393830636633383333663639366662353738333566663165316364633666 -63353862323833616139376661666331373430653939366336663535633333613761323436643136 -65643063646437316332383933666435636237386263306361626338336239316261363762626330 -38616634306434393661366634653662626566643238663439353739383535386633613861653639 -65363635343535663765346537616230666131363639386239643631386464386634393231346262 -31373566613661313133646264383830636561643161353830383731386461633262663334303862 -35313433626439313339386434383538666138313138376561393665653132386533313561363565 -34306431353434653962316630343962313864353864386464646162613064633966383466353961 -34313336633539636235386131323261633434633066386339326466383931316335623363333630 -61326666326663306436326563623335313566396339623365653566633237363539393964303462 -38393765393032343439363066386332666535386461316337633534363766323866653164653662 -61636464303062613131646464373638343335353765336130623137303431326465643762326462 -34356533623337303331663663643436373865303833383132326536643537643237626462633434 -30326561613836306365653064376635336261653631663036373462643262323366326564643338 -66333334653864336434356639633332633765626264646335323532313435613462633638346634 -36386637626462396662333662636434383131366266376132653665373639633133383265346364 -38346363393064356234356331343338363834373864356134616236336666383538343435653037 -65306465363064316535356363333735343435393035386636313032376639653833353438383038 -66326336333465383964323337343433663134643636626132393961353935336133316130623230 -39313130636166313232376265666638356233333066633064646532633838386161613631623938 -63653866343765343837616535623766393031663234653164343036323637363338663466633530 -65303837343832373964343337653630663838346631303365663665363230616266303532393334 -37623161363032306464363163643331633131656362663531356161323533336263303435626364 -31643633373232653561616433323932346565326566343531616136666532363734613237323032 -35653665303838666535386234383634386365646334633164393161303233653736306164336130 -35376331653564303463346635616463366165343161363362396366353030393336653630653532 -37623135633965306430663432653530646338643930663663353839646232376439316437376666 -61616262363939363738633764393965323663363736363662376665613265633261363861323065 -64393234623065636332323233666230386563633363383237653134373938633061353231363339 -31643262633564373566643138626331336266376164653666616132613966303336643136613735 -39646162643431303630663532316333366239623537383330313363613834633232666334633065 -65363436396461383333363063646237383637366366613766613563346164353032346637646166 -35343262373935383566376338353932636561383061363632653761353363613365666362653737 -39623062393535356434333832663239663234313031313366616337303334306139323863373462 -65323939363363383633353331396238383938663537343039323538353231366237306634386562 -64376565643131316437663162326164306239303537383239356465653039633639373338613861 -31393330346335386566643264306331303734303934666666336239353333656563306434323666 -63323866316135363233663130666637613931346436393137383261653838343965623237666162 -35653262326265303266343763666364623563336139653734393264343264646637373333666235 -66366134323064396330613831636239653266663737656664386532663864303037376237643339 -34373337346338366433343962613836363831373734653134663536336236626164623330646534 -38303431633838366331303361623066396338316232393734383236633365343731646137356561 -63646631303931336231613865303135386232373430653938306366636535613636333466323562 -63316136656165663637363036353063633166613762333962333736656363363937306132383338 -63336230653766306135663563306432313536323731376230626132643135386631323435306138 -61386637383632663864383935393236393937636538623037646637373838336537646463323933 -32653937666631316539623366663731303363326639333266663066363762333439393737386136 -37306431623935323832373437326632393337333338346164326338316162653239633266373466 -33393339323863663061626536313261383063613936656562316162346236346563323730616666 -65333961613834353936386133666162656233336235313461373937626566396161626264653863 -66336536633466303135363632303839623736356436326663623838313335623665306636373432 -39316163376565643963336233346637386332336438343630353663393034303330653062333666 -64363364306261393738333661636632313663613365353639343836323235333364633763353363 -63623433366664313932633235353766383239623838356161626130653361306135616533353434 -31353933653636343866353430313061613063653063306330666638376236653330336139313362 -39326231633734376536356434303436313434616162393835663162366462326535373839386639 -36316536666264613965343536633266353935613265616466386432363530303037366333636531 -66643165323063366237373231643866653465373165346535623131656465363862623130326337 -31663334636531333936336239353265353663373734633936363039646334636430346437396539 -32323933353065663236356533336232613738333361336136656337383432383062643931373830 -33326633393639616563316265306433353734333864366361626634623639376265373934316332 -36636437363264376636363434353066353735396338666430306434326561303662656662383139 -36653134363863393137396366303539646666663866633033653963643465373838356339666563 -63336639313161303338653839616439613533653637353930633035323539613263306231333033 -35653837616663343235343065323366383465323436643536613562366261643938356239623031 -37343262666264346262376132356439646564346262376261613530626335363937313538653565 -62333239366438633962373838326236346230313738303433306166616563643431306165393965 -31326233393862393763336534346433323937323136326138313831616630663761653962663131 -63373138636334393432366635376231646463306330313665666231323837613732326233333231 -39303136353366343737643734626630303965353334333763373562653233373165646632333564 -37373839623635346639373666356532376163313839616630383439383864393066373966323533 -38376562376530353835326633623061386337353336653237343763303065393037336465393165 -33353835643431356262346235323230353130373764303133326533623463396239306334373638 -62643165343162353662306130386366346166356161666633393331383262303535373233303866 -35356561303863383135636338303766383665313935656336336137616539373663623438396462 -37643363353063626563313566323137613830633063316439313463356230626230343536616465 -66306232386632633565383461613965356139396264333366613038666161366239663931343536 -37323266306235613935663166336665343664663837616630346132666566626464633536363335 -30663233393232343134346563363335616430656261303336656338636162306234343362376266 -61616137626662363866623561623861333065323862346434613866393766623632623632663338 -66316238336561396630643832616236353131303666643437633631393961303230356463346633 -62343438656439653635633265396634393266356361366330393333613434656339656561343134 -30303066383662656637336665346136663733353765346266323539386265653635613265373737 -62336362666637396231376437363663643264613433376333383362353363353430343564306166 -66346134396235616461366432373132616139326632363635666132386232393361313138306530 -36653334383837373938396539386264353962336266623634306539646237356164653565336262 -36393233306536623231323738366366383931333863396137313639316231316637633638356531 -30313265396130393366666361653164653265653138376532323436303866643565663139343866 -37643865306163346436613730326466646531326466336538633365373239623631303465323030 -64363834326362346364383239613634656461326631666136616130656132313638363536366134 -65336261376163303261643232616162326138633133666332383765656233373665613362353763 -34656230666232376234336665633132353130633663363430663837383332336365643231383364 -35343936353235343961656230316663386564366333643434656266333737313130636462633731 -35376665333936616639663535393062623635313735303439663233353931303763386266616461 -64316265343832333236373932316234396666663761363131653035386532653737316165376534 -34663365663563313037333030646238363236303563313334333339663262306337383262306235 -61623631376132336136326235386438323839653933303766626438646336323063343634623239 -33663131396532663832656262333535633032383564616166666238323535356437366630356239 -35653136393561306339346436396265383762653030613033623766653762313239633733343462 -35666563373361643137643931613433353265386636623734346534636238386263333365323164 -38633437356538666130303731636335373837343430316530303763326333613263376630363930 -37336130326665383638393933643437633563323864303934643961393731386663623164353739 -64333839663438383838373563636437353864623063616139343836393232313030356366663262 -37313662633065633061613761653632626564616132303963633130303137336234613133666264 -35646338666231643864353734393137623834353633373737386131663434346363653065306437 -37633336373134383833303365386338656163656330336437643039633062396435656131663864 -31333539316336666332326530363135643163356163383939393932366366623938373633613136 -62366465363930656463633536336338373962306438666561666261383962633739373233613237 -62643630616162353761346539363465393336336665616561633737376561383330616439303530 -38323362616136366434336434386632373065323063373462393035666438343863326131326663 -31333134346433326365376330323135363430643631303365323164326133646435666637396664 -39366561663861396139316336653030316334393662343562666630623935656231313966386231 -61323861353036373066666338643965653134313235313035323063653537373564303436323064 -65663835363766653930333461333437343163316135303333313561313434353434383964333236 -32316230333366313365613833653933323065333439373031373235383261656235366531636362 -39653831326531376431303631333362316530643236326238633365333461303537643235356537 -35366236313933386333366162316161653135643535323461333464626466306134316338333662 -33636162393463623334383936653864353432313838656264303065306430623438343461623932 -35306236353963623237663235346637653638353131343463613933633030363233313231613839 -33326165386331306234323637336136356138383535366434343064373963626436623162336237 -30363863373738376231663135353266303839656365623832643631666466313533663365656466 -37653962326134356462393561353432656333366565656236663461363034396465316539306662 -36663333303139303039366466356635343337396263303031643233303364393466653332313662 -37366663636236623664306230303938363830323837663435386165313033343830323862386532 -31636666343739393931656232353266613837333630636134616430653935383365636661333333 -31666434616164363534353835336630653063626266626263366562353438626531646435646361 -63613864393635393861363164353234366637643535636665353532343666616432346231613832 -31393739333565373930646638643733666336373862356135633764633761333563336231346235 -31376239323366383938323762633937336139393830313036623030326363653036326633396130 -37666534663031373864653463386662613630633935383361626234353861363662323062336536 -62396332613235656338636330346164383661343664386564313163663066333937353133626264 -33333663313566303032626239336635666334383537656630653731383166383832653637366132 -30363033366132366664333535353434313335343637393933383837653839616539643432393465 -32376464613036323364353236623865613562656330383161313963656532613064333264643937 -37653661643262396233303738346536393039623064313462333232393135633635653365363236 -62313866636235643931653733343237623565366336656138636635663236656561366266386630 -65393036643739353162616438373363343732646563343262366165633836323766366661616666 -38383938613665613166303230373338643261363166633961383939316436643531396437356564 -32646139323963323231656232383930623036616432663630636331326261343631306539383733 -64373635333637376338363736393632656234383735383431353066363566353866353935663563 -65363438373963656634623430333930356135333232333038663831653837393630323933666666 -33663166616537356431333562393038323239353538623863653666363031333835633536343133 -65663037653565363062323935363938373633316337316633643639363638636431323964303833 -31393332393230663337303363626462376537353334646137656665353539323261353436373033 -34626630313564313632616165343836303938656661323638396436616139623866313362616564 -65613561643364323537376165653236323634393739386365666163353034316365363734643464 -63303034616365393834663834363862626534353262653035643463323938323861663039333036 -39633764313333303166366236386230356463343237613263363163356462353232373164376135 -35623033363132336632316138376266613464643033646339363964306362306563343632356630 -32376134306332323966663831346139373234343633623137653433666635336562383864663137 -63353334353461643161313531386364373863303361393762303935383233373465396166313437 -34656161346530326331636461333762653537383566633134336161353630376337336131363962 -66663535636438383938643735663731346536643466373739336337326339336364303832373735 -33323564366231353338393838393935393265336133323233303061353064343565393863383165 -35653466306463366530643231333465643464616661303539303832343366363334643230663834 -34656539343365613764666264613863343266626436386236303738303533613737366336353164 -62623964323632656464356463326563643863653135363636346633366263363663316265366338 -35386435333666303138633863396136396537343761326365633431623665616134396234613731 -37393330336234633630663164393935313034633566303532313366386131613338326164386564 -37356664323339383735373532643665306662653335646662383735363465393736633265623065 -33363230653730616161663062636163656265363338383934333366396130643637653636653030 -34656666336366636337346365303766313335343536623435666363363262366463303666306666 -62336364313563366137633864643535663337616638376163663131633462653962396666663134 -31316164366337333066306339626664646131363635363662373036623337383963316332386437 -66316261656130633566363632643133343134386430306366643335343665626461366361313061 -36653832393966363365616137666564313633353635613334393030643966376461656137336431 -65653639343039326533333530323336306236386463373464623736323537626265353865373239 -38363561643831386432323964383039353164306434343534306139333836363863626538333131 -61653862663234616162396439646438303566653766353539613637343661383564623037323530 -30643461333233323739643335343434373232323366386430393632666431636230303238303662 -37326634666465646138653561363931353163393035643734373661636565393264653139643637 -64663333393639343366653933323533373535363834336663353239663436646532323966346232 -33363764323138646563666336636436376161633431333634326638653533613164333138313639 -63383938366532393239653162383961393839613434616363623630333664336437393163646238 -37626532366564633165373138626630346234376262646632373635353865616132323664383733 -64383235643436653438656137346261333137313864643161323862346665663538393932636630 -39366439353233316365356633383666383263393263306462633832613161343562643034316664 -37393230613132386134363965633232393166623436323264623939386465396561623662356664 -65663766353232373763363062363336336431333965656562623332326539373630663066663431 -30663962396361323131643839316333666465633131623334623335393732333962353739613331 -39633535373234373230356336336361383730633037323931313962656265313439353930666665 -38373233323864613736343564656161323162346632393530336262643730393530396331623132 -33636332636666633661653137626165633934303635383363323463313332376162323364616266 -39653365613234633562343333613732646234396436336536386366326337396362646363303233 -63656561353237653735663364323565346366373733383237396363633437393239363531356436 -64613432366566346163373336313430383166396338366662316336373231323065633530303763 -33316161353536643836366663306631313961306336323939613666303538303035663763313235 -61333037366432353138663735363061326630663661343265393735613665663739373330356263 -65326233376264383566336364316163363438363230353162653062623665646364346263356337 -38636565613134306566656361396538633638646432643261303132313830373463646637633964 -39643736383364353662346235376531643266363366623038346631396534643965326332386661 -62646139313531353231643038633134373362393832336164356339313262333532336637313761 -30383234373465616335336232613865393831383635333335316135636131366630623866353564 -33306162303666633561303462303038323539356137363139376630353361373134383833333933 -30656466623236373764336639363835393439346362393530646264366239623662323932616665 -65343034353465386534643432656331626533306138383564326534656431613065336263393334 -30666539396263373264643733633764313363353038663231383839613737306437616534303961 -35633031616236383536303232373561393463306561663437346335333364313537313134353564 -36643937663462663438373133313837373063336333313037363135616563376563363562333133 -35333863643332383738646632323736626436666664616337316665353430633536343164373261 -30313735643633626133623237393863393235653039656436353836343736383031306166333731 -37636165363635613233306561613938326563313066356566313265383464666665633731386536 -32316161363464336266393064306538366665326566383437613266373032393738393338666132 -36303138633239653334656362653636393765383862353965623831646464666161316166306132 -32343433393332623737616138306333323365376539393730633636316365613161303262323864 -63336630383131663234373463313736383734633762323863366136333538656135386634353664 -35396662633666343136383234653534303435353764356339383638613839326430653634366166 -37663966646631656136313361366637663738353566626135633030373934343336646137643532 -63396636346566343437376362613534633035393361393764336538386334346539626565326665 -39346137313865663433626566646663373332353239356236373762653839336136383331363463 -38313337363663616662346261306131623231373762663736376434666637653037393362346234 -63633266313965316366653737333365643262313565353032353634383531393765306632336634 -61333330623038376437616133623663356538643464653136663830626566396164383631336334 -61353438313565656530653930616266376462643336643630313161363836343232363031323039 -62376430356363653033323538356533353964343737303461336638376132633232653930646632 -36386430643161303162613032313166613938353462373661663265383662653262393966613564 -63396261366365373966336664393037366233316264316638376130373031373031386330383333 -62646437363933663032343730356631303333363433386538303933613731623733383338343530 -64383336353431366666303061623863336662386565393162653339303766633264346137653965 -35663864303965346438623835313537343039396461306664313931323239643763663638336332 -37393031616265646238636532386232383234383762613335326263313739376335333064653939 -37306333623665376339313066336537633739323166396335656466316162373431636339323435 -34346539346538366332343365356438303530353865653332663164396437396336643865303763 -65313833363530653866313237333732353164306634393137316665393638363662343466366630 -34386565663335393037656262366461326161393766396530383964383034626430666638653439 -33363139343138663364373635613434313038323464393161363461313866656566363938363839 -30343165663961313661353432373166653433626634616337376330663566623735303338333838 -35356130646566633661316466323736316433616639613236323963376463646337643966663730 -34363830376563623335653938663962383539386665386562353233303262323766313433346562 -65396266306362343963393064313362366234316461383862393032353131336538393337663063 -30393437646336396162623934323739633963656337633239616632376636303934386230623631 -61326336616635393639636464666462373662383232383733366437323164666134353332323462 -36633036363136393763656565663636393636633539343039333963653562343136316536343030 -33353466316538396138316138333938366332323962616663616437373836336135643066656333 -35323262643830623035323637313433646236653432643736393064393139666233353932333739 -63623861633931323737306461333938646263666634346238346530623236623263396661343232 -61636164613262616363616465393066623034616666333639613561366433353663306664376436 -30376131633562313039623537313365363539303638626535613861366438303132636434393665 -36323439656330306430613865626365356234663136393363356231353064636339646335343234 -33663036666439323166613734303263356134356637373538343639633739343035326338363030 -37336535353237376465353731636263663934373365343434646231313464653335336663346630 -35653039313865656434623436393338313463343666333030303630343665633666613831313337 -32653132643531313565393765303037306438313531373336616134323261396630323438653864 -66653862633263623431376239653337323366363431616139333665653764643262363265376662 -35663461623562616439656234343639363833646266656435646262653231323366303135393633 -61336237363534323631623533373735336161376231393430313162643065313839363863626430 -36336166646165396365666535356664383761353432383937643533333332393466643634383335 -66636661643136613337633736343835646232373535356438333865626361336361626366613865 -39323535613461303964376632326439363163346234386661343261323364333432393330353366 -65373035326563373865626235646364636531353134373431363533656233356234316534623232 -64313764646533393332623232303031623935623362323735626337346634386133626265656664 -31653537313832343434396137633365656635643734653534613231653734623062313439636466 -34623535643665306636336361313238303030336439666639623031393939323930326365643466 -38306165626566393333363264373963656338333462323932366633343131363036363233393865 -35313666336266386434343837316363386637383330313963316532636262653265316164333738 -66366531396435366161343235336363303933336530323438313030353463343434383934356262 -66313938363765346538393732386566363431663766666331653764306665313437363965623661 -31643830663466663062306333666239343434646239373136636532376239383265386135376436 -62633136343265353466363364623464393732396662303133643333343661623235333432633564 -38326266393763303762353332303333303130623737666236636666623736346139666462323838 -62393361326135343238626437363366373639646630333837313462646632363232666430383539 -33623566646330646361616661353137356535636566346666316635366335633630663138383039 -66316336323261313238336638626438353638356432633934623530663963653330353935626538 -61326334333134643831646161613732383536326262643964393239636333376533623330326437 -64303130336566336633393132333230306130396536666461623335386536643939663933353865 -65623139633439616265643766653564636563353062646565656533373138653230393738343934 -35393761616231323536353566613764653837313165326661643338316134376165366635313935 -31633337363736313036333532656336313936633730383530353531363034366634373534333239 -62313363353365303330303738343432643939313464316234376661323861656232323166393761 -62386236343038356631636364643966633661616366653831346638613065386538653661643665 -36363531383430373636663866643038363765363135666239626261303465333536383462383930 -34316134663131636466643764303331663732333562343063346536613337353337333731366430 -36353031363964663331323936386462366531393639653363386232636132373537653361386531 -63613331383063663132393533636538656137656232356434356432626233343865363565646235 -39623066346131396366356365663532386333613335653134633762353064363665346162393435 -61346531643265643538303363666230646465633266363634656265373931346137333138643534 -61313361376566353733626564666236353063366339623164323866636532626439353937653463 -30373330316666366662363366343262333662333631326566316537616162373334316532303734 -62646335333734303765396164616534353930636130393064323766386666663061653865316135 -36343134616633346166336637393632646265376565393661383363383730663364363732396663 -36326438306236636334646465653731393430366462326533663037643166336233313564613237 -61303539373136316437383938346261326438373265306132346333383362383064363336613832 -38343237616161313231623838353434313930386137663032336638386363653636623337613736 -61646164346633313539643866303966376662656161376333336566303535373139393136636261 -32623130303738653365323166306531393733356566323132306265316235346431653136373862 -33333838376330636261386335636534323936666663346634306238373437363634316365646135 -35346134666535626631303539646538653864626466633332326439373866356463653566646637 -63353230623766306465393661346532636163353937336235373764393033383738303663663762 -39613534613137336430636639316261383465663131303030393533383264646332636365386435 -63313837353230333030636235636162393936613662386361653933646136376333376237656532 -37313130326136663262393762616636313130333931353462313364373764336133343361326531 -64363739663235333533616132326433313137363438373665633132323162306564626638363733 -39656235613365666636636338323161373933656163383735366465623236386535666537383733 -39303534643561623765613639373634613166326434666633633164643132656366393761633232 -34363163396464636233396235363665613664346333346261306463323864353365653838656639 -63313830373566343865616361663630343736373764646535366539326536663466616239616134 -32376261616166366339333837306631363234656163383233633535666231343131663563383235 -32663566656566373037663630363166666538316165386261346439623935626466303038636539 -36623866643431376237323262303937336637653030373664383939316237646161363463386234 -32643933646430633663356337383637346537316333636539393036363465383663656432386134 -32393963313838626462353130633265316630643633353038313564343039333066666335306238 -65363632663564393037346164633866376433306337373165303261386635376162663930346334 -37346362646338396664356566306362643531393663316538366531653365383565383631656239 -37303564306333653135343034616633623737663662356165353032643665613663666536346535 -35663735383734303033366566656132643738636438623761386530623434653164356238666464 -64306466666666313263623061323062306138386331616261646264666463356333623232653039 -35316438333566343937383431393235306431646266363930643838393937613632376561656465 -38323838393936373865303161616461353664346633313431316434313932383930613261633064 -35653964333133356265666535653231373565393630623134646462663036653433343837653732 -66653439356165356238633938643265653833383234346330313638383161333965383763323264 -62393333303935393262643438393634393034393163613761663066633062313462333333353731 -37663863306235343137313265393837623166363438336339393036323935613661653033303135 -38396562623062356435326237343163343263613535643137373233326266316535616434663162 -34633064383961363266383339316264646430613435356333623933316663643630343061623932 -30316364613562396530363164613432653166393031323339303038633738666138656136363562 -35626365373331626636386430393163383638613135396561653762373666623134396335663234 -34383135633963636563666536353063353433633366373664626462333736333965646430323162 -62623933356132383961323661316562616130633030316663366565623661616531613530356636 -38383935353561363565346566396261333739336464346433383236346539393666613537363132 -62303466326234373061643231346335653465386436333438663034336538636665633663393030 -37356365303634316135333335356535613463633833303361626337373631656162393434633565 -37376636366532363936666632366265376365343637336462633838303637653433343161366364 -34616366393438666662663438633439326537636163643736626239366136326335313362346537 -31326130326333636166373536313565303436646565636633643862393530616336306365303331 -33643736316361326466366339396433623737386435366166646162616661313931343865663235 -38336333626438343865356266613034343339363163653662393832636163303361613561616165 -64376432653563653637353939323435663364323237313530643836613430303335663431346536 -61353265396438633031336135363131626234393036316264663663326634383531633630666662 -36613764633065303931366461623861383964346666643362663834383465346635393739376436 -61393831356234383066333734343935616134666636303932323737643161643535663265613363 -63343838393632336566373932633763303636646438323535353833313464613639656362666439 -64383463343263663230373038366239633361346335306565663262663163663238653139336465 -34643631646663653436343931646562363163656666373466313732633131306436303932363230 -35663935643766646463653137346134336433383466326166343832313664623934613862366636 -37643862343439383064326262303739323065323636346261363832656437343336316335613435 -65353237653265356539353665643734623065373537653830373735656631396466306630363566 -36346237343332343062393133633433363334646564653865313561653962386562363936623631 -61356234663065363333666263653763326464666564656437306433663533343466313536653134 -65323931646634303637323464616364643031363562663263333839316135373764376538306336 -31393830323632336361653333376632366136666538363531636536653631646537333131353566 -36653236623933393164366666323134626165333331643839313234353232396332396562636533 -37376530643531643231373562346165353039306433353463326134343863316332343538346666 -30316464346231303937373738383334373865313237346161383538333635323237323232313532 -63396561623364613964356339366562653639366535623737323131313931636365663338633737 -66623938323462666661373761656139373463336566366661316431666462636539393663653763 -37393932663864366539343632336237616164373830366439386439346335626431323331343531 -62663535383361636132633461643931386339323730376539636665386434336438333363343066 -38396166386139633562623662636165323435306164336632363236353865316534643231313335 -31663266653730386535656665386266333031313665306565313030633739303138306365343038 -36353662373635366636353635373137353930323635383964383632316362646161663737636335 -65373238346332396166616631333833323239303731613761623837613138386230653332643331 -39346531336132366631343866366466653266323133323931313537376664306230343630333831 -39353534616666633830343839396230663365636665303239666332666363656630613630386338 -66626638316433323931306431613161393366613131626136346238626634623832636663666635 -38626338643138363431363339373031323936623331663533656462363163646433383738333637 -31306133646638616135386238353865636662373966306134343034653632616236333536623832 -30383938336362643765656264346430363762633665643963643766643263666539666162316262 -38333766386331613333313734303062653934626330663761366362303833636632626364373739 -39616465373134346431303765646635643465636235313735336339363934663161616230326332 -32313234663763323830636136346536303633663436336137623762323863383862653166623962 -37383265656530356663656533613437346433646233346431376133373636616236653731303133 -63313931373862663436376437626636356538383834376538353066646361623239343233386361 -64316566363435316261356361366537396636653864386635666464393239313564663261366666 -39306133626563336535366264663565383430653635303062626438396637616133616463306237 -65323335656532366434316135336333663436336263343235303834323639646637343132633731 -65623061303861633133626633616661306562353736356239393535306337306539343736356538 -39316464383036646436366666306538646565623561363832626633376336386565616166373465 -35376664346431346132333438633535323537613166343464383030663831343164653462383761 -35363035376131613666333062666235336330323163623534636566653339633830626532343263 -32633365306166633234646335666530386231633361343837666235303764363661343738386564 -32663163396232323838663931653432326235316534356662316537356339616537626565343830 -36666630366138393939393435346361383633363338636137323436616164643430636536316165 -31626664326238633536346131356634303131343062373932343437366563306537356334646133 -34633834366330336638623035373532383131333339356361636633336161313662306661336134 -65386465663061663963316562666364303063623266643135663565656664663633376461393664 -64626264373265356562323538656132386439363466306366376266356362613864646137393963 -30373330323565386332636639663335383164343930353364666563636537353139356333623634 -64613663326466393763353561343638333662313735383538616235383864363730626432376632 -63663962623137303761616139323664353365626630306661356133373962386661323132396263 -37343936363963643333343536666465393262646163343665313764623034363365663436663765 -66393564616535386464326334353332656662343736646465356662396236626439356134383732 -31303834646335336433313332643332326439646464666533643864646261343630366135333832 -66376164373137396466663162313636653430666666386434313635613261346235316163393564 -62326166656636333538373038303538363866313065326538363535363535356139336361616138 -38346265353137393064616537373536366366323938636366646664393537343236396361343638 -30316533303162666431313134656366333830373739376462313862386138636137623865363231 -39633665393937386261373931316535353138316666636463386466323763313562656239613635 -34636233316163346433363936366263356565376437306331363930323165666662646566336465 -63663932373465663765646133353934353661303966643537366131356339663638626464336232 -30643034363864376431356638366637303063313035303731613539643039623236393537666633 -63343832363561343264366239376538363636336332653665383832653765323631396438633462 -38656365613237643363326263323232363035663734343833323932323536373837656136366465 -32363265643134303964336330396432616338306133333233653461393866396364396134313362 -64643233333536366630363335653564643834393530616530346535666232623030626566353337 -33373766656332383665373034376132663165303263653665373166633763323263343565626338 -34386531363261323230313661643135393430323036353037303234386332333938343932373965 -37346364383338396434363734653235663339643036646636316136653264633637633338326138 -31346533333764653234343338663931643030386432646666333731383566636537356462393063 -66613566633430373165326266373566653032643462343130303936363330323837633961356231 -30303930643733643333383434653030356438623239306234303261333463356432656362313132 -36633338643264636630393038643436306165343436636462363564366339666637356134633030 -63363833346636386462336530633261343735653238343031346239383231353533373433623439 -62646165616237383231613339303163633636653139316439396131636463646566313036373635 -66313763353035393731643935653035646136343961323961383561373937323630393330333838 -37336230313134383363626339346130613837623333366233333262623862383430356666633938 -61343131333031346464313532313862373934306266346261373964396430356638343139303238 -37363136653366303263653531663862376639643935633937393066323432323439353437303035 -36313163366564633262663762636464363036333066356462343964336265396338366139336430 -35633164326265343961653365386530613365393739326563373938616334333161366630323535 -63393636663565323866623639333065363165383431346266396361636334346462626461316161 -65303530376664333937323737646161643064633231643038313636313765386631356130333661 -62646237633137623065396265656432346438666539653330316432353733646239356464343130 -34663537313036376437626334636465643935386266393662616461316465353665386535373166 -36666232613433373335373237643364386331306139376564306637633463663636303236643133 -33353232643834626134326336303361323438383736636236326362646561343266346636616335 -31653837323832656430393536376165393931306530373834376661393534376631313164353562 -31376265646237343062663533393063653235356132386663623934396564666133393530373838 -62353264623564626438333364663338613732663866656637376464663131396434616563393632 -34303737373738633234626132376433316138346261366630303465376238333761383636656161 -35313166333265366536623839386166383739613635653063303262316439636235666333336434 -31663435656637356533306432643661393639326264626362663436313062656662643462626331 -61346130356664336138306539313163383464363364383433346666356430373464363462376430 -63646334393736326535376365386632323132333730666235646437383437353035303662613238 -33663834633332626366356165613939306363313639366637346264656261303365313763633238 -36386566333239363732666638363233383230613336363036663130656566353031333762623635 -34663333313137343461343764643264373462336430663035336532306465303338336333366564 -39303365636131313366616435353961623439356333626637663836353332613236303163306332 -65623237663961613632313761333666346538616665363434363062393966386161353737343434 -30323132636165343232393062646432303137356261616461383739326132643435363762633962 -65323434613566303330663562666536366638356463613730396533663061313062323062366337 -63613832373335366366333936346261373537666462623962373632616638666538653632316430 -38326135333565386437306261383435383438343237383461373331343930306531376261666533 -33643934316531376366663164393737363266396530306231666162336163303732376235363635 -66353066613738343763363838613132383132313538373130313038323464376664303166316234 -33646330356137326234633033626331333061396330653634353239353737396333636531626332 -62343735616363326166333861656366646235313661643937303261333366396535643435356138 -63313236616563363335646566393637393732326139356162633131626433313732343632323330 -34643232313330646638316530346461663764386131653461353139633361396664613835613434 -39306664646331383234363738343732353538643362653233653661333362366536626531396366 -37386339366632303762646561323436613632333737336532333336646362306330636632393834 -61623638666336393666353366366131323332393032316631656332353735363966636463613437 -35366361653165373863376438666464353365666332316666393137616137333431613764343735 -66343333633961613832303530366531663434353431356233353531393363616162653162366236 -30656464656163346161306532316130643237343032326432646132376631616166633231396561 -66613838643066316532396461393466336163396633313239636431646365316431656365366339 -64653538313338303566303533643339353331323638343132323332303939653061353239353566 -39323065663034623430343635306465306335373462633337386139383964383461363338636430 -30343733343463656263306361386162313563386330643133643233313538333035313063613939 -38353133323736306566383265663035663731613065646364303765633732636661323534373463 -32336634353235336237643337393132623432336262616533356133663035343437353737373261 -64653939343432353134363032386161643561353539646337363437616164346666333434646537 -34343865323631363032363137343832316237346436333835363434666238383535613264656436 -61653137376462623866613530643931316330656539393337376237303238316264376664643133 -31316335646662666131333363636633336233323932346637363734636362653235303666343035 -32333262373339623439613339303931316432613130386636613533313563303964626166613030 -32376464383531623030636437663531653961363133386365623734393334303639313032613930 -34663832643766326438376264343136623931383931376130313038383238653435393463343066 -34663430376361336161613037363137643538336661643262313036373135633366323764373834 -39303637623430363830343763313534383138396431323339333464356631386231396362666161 -33303437363837626163306138346265383239656164643461643636376236373333306165373732 -31343435336562666330306232363863316137653936396261393065313736666664396363336164 -66356361376131323139326131383163363831313465636364366164333266336137373661346437 -38616634336536336333663330316630653935343035666266343064373531376334326433363833 -61613132316465646566323632636165333133383538316335336632383332643765663566363731 -35643463633965653731396166643833656366653935653161666635656163653866333032396238 -65363162613937343135376132333061313265353865393339366134363533373237633433356363 -39386236373931663861313236613662353762633435633036343338303839396561363831663333 -37386563353536363464626566353366323262303563653037393136313066303339646164316637 -63383536616534616531646437643836333831633464643633363465343733326638333138303935 -32643565646634336630383231386166633363376338343763663431653264323763353466336161 -35663335613635326463326337633666616432353735383239336266376337326431306161323437 -61323331633061653838323639626338613861666539663062353432353066643566616362326166 -34633139643732366465336439306535333531373465373566393335613763356365363639336361 -64313436636161613266333261663939653830376335633533303432303831386163613039393538 -37633331363630313134393761363637633766623063333238336333303963623539656533663937 -34386165373733656363376432386437343033666232656361326266366138346535646163656134 -62633465646636653331376363616138373065643762383463653532623764313366323332393562 -39633134373763326637363134336264366135393435373766303833373239643233653533386438 -36666265353362383234666238663037383933343431656461353830653833336533303466323230 -31626630323738653633313565376336383037653138653530373534653735326366643937653136 -33326530393131323235613663373934306264313265643264316462303265626135336537326634 -32326434653661653961353264383832323164303664363137663339333333313463313061343166 -33376330616465356438663666346263373038353861396363393661633962363465616563613638 -34663038366633616365386538323466623031366263633633313538396639363737326430366239 -37303633323962643436383964323630633164303531333162356166343962313836383665656264 -39333430613131363835666462383835353638383966613537316132633031636364323338643565 -65613365383237613062333766316339396431356430363838356463623530636162633532353134 -61363662383863646362306132383464383237313436663161656565393331303535303465336331 -38316533313633663536616363316163353864336532643363383162633337313364626465393837 -62653937376363666230306131636338616434613262653162343334323062633037306161646630 -30643062633335396639316633306661323535633566333230346666306365323034353030386139 -30326361363062663763343233356365346563663432623832653562373133623966653262613138 -63353536623039346561316263323662373062633735656131633435306464336133633530393064 -62323835626130646135646461323538353138303864343331633739636135303634633866313266 -36656563366338306562303737343331323630313761643133306263313563363032623635616130 -62386565386534666333626562663437326466656136653639666164333037303939316339376437 -66613565616462643739373539326338306332376638633630306636343631353634613364356262 -34303466373835353037653165336165383761616666363739653139396631663531666239613963 -35376230316161396431633264633030633362306366386430323161376137643565346532356134 -39313034383663626432313865346333333863366335343435666133303766326135366538646333 -36323066656535306230393831626666353864643430623966333961616434646234356539343038 -35373563643864323730343162346166313166356232356265376536353031313035313064653534 -34376535613737666631643465353962343262333030376432643635336232306562373238323365 -33343461303736366461336633646638363530643036353132636135336433643465643534663638 -35373435656330383265366261663031636533386365653163313136376361306134656362636333 -66376532373564663837643331353662333932303761666234613931663838333438303665383237 -61396234383063613235383037376134316365643734653263613335366362663963363732393730 -34623434333864636364343738626337643834323339376431333437316333353465666264386434 -30633162313864633164313666356364663032303335373133363733613031616432623630383361 -33386538646330376639623737336236653433353430383266356265393563623764313830373266 -35336634633130383232303131343062316165393633343338336533633463623366366538313163 -38663862343066333364316538386365386361323135643161633265643638616533616534616436 -66383037376439633835373464346235373132663538333365666132346261353936636233313034 -36373239376639383536356639626536343031633861313539623863323331303232326235663164 -63343561626233616239653435336362356635303063343065303632666566653838326636393337 -34306437343264633133646530346465346337303637396232663633386138366334383330303266 -35643236326533313664663065386363636566613732636131386262613536303032393966386265 -34636463383036636234306638643235316164333661363763376635626631393135653838636665 -65323836386265333139613662653564663635303462356133643965323465663261636263373532 -31613538326137316339653033616361656530326135613336363732316466343535383238626532 -36653938623265343930303564353032653062393161626338383536353933663963356139616565 -30626665363938633430323237316631643166353365646536643139656232623231346239306532 -66653761366662323132353464653766313163363764396337333637393236363962636431623636 -65323865393930333665353765353364353632393237656631633331373734366234613331646334 -66326635393831343730616535306161643433653635353866316134326135386530376463623339 -64346536346431373832306332353233626437316262643261383531313633623336643738323538 -62656665303339626563316666333263343864323661373262656535313838353639346231663235 -32656436323835316666633030363534336338336237663662623166343634646132393633326261 -37353066386238333661643031663832323437323764636531653364306365353432626566623238 -61343531303865623565613862623937633237396365666365613132303030336331346336326339 -33373062393464353032343964636133626538343330613936666539613039646462313834623862 -62663439333535656366386134366162306636623339393031623936326637396464653961643435 -38653737613637646234626134623164316534373936333236653266643330386639343062373865 -65623039653237303731346433333038323038656666303739316236646531343536626462353933 -38666439383236376331363263373539366638346465353838336564663834653436656562393639 -65323231333265383036353866306264366464363337386563366235356366373562303361666436 -66303163396133303632646263663336616139303532383939356361356663356231613439316432 -32313262343265656361343137653435393163366232376236663134643831623035343031353331 -31363366313963653039623931313165336163393435333866356432343065393230303439643765 -62346331626566323062353036393937313266613837663236346336326138666262333734616662 -32356264353264663837663663653630643030653531303032626663363232616531363866633163 -37663032323238623535653063653333383363356338656237663462653630313163393539626239 -34633161326132623834653265333665373736383731333836643039353531616631653861353366 -65343030306230623831653630623735663265383036303533343837303134643861633837366364 -34313632656438633766633065663364383338326534633430333038616437613839363532616233 -36386637653866343332373033343064386436363037623362363732303766373365613032373266 -39396136393265636232373863316533663535393435656236633032656638633436306364333731 -34633033373234613231613762653532303266393230383937636433376137623430653763303637 -35333539306434643161393434353233616366656233623261653938663464636462643766383830 -30316263323830633966633466323734306139356439323831306265343565356362633266633236 -61393635373363313435656665663938666661323131393934353438366366313262313733306133 -63383561366466626130346539633339336561303365336438313633323430336238666637653238 -39656434353931383335623561363532356635373164363331323963663561376163663961363562 -31333338393636643239383030623633383463666637326366636437333835616536623264373839 -38346538646534333965323865356433346365356539656362373961356235346337616432313162 -34666263353537376532363031646136363764643362663636386636346232363932653635383838 -66323530313832626661303162303537663464386163326361366139363935383832363038346239 -35366566376230323832356539306235616634653739316461313564303237343361643862363064 -33643838386430313166386663363162313331306635613231643736346336633766646131393364 -37373635306539303865653166383031363139323034366536336539313266373563366462636162 -33376362366461646162386663663366396439313933393163313831393463613261333938326562 -39383961323661656366393936366138366263393234666638623465663936313962363634353664 -62643534386236323530653235663737346161313132323962646338316334363234623939396137 -39303232323633333137646532313236623133323962373138653831393234336362356236346264 -63666439306432653339346462356136616265373461643662333666343938316265333361633839 -32356664633233333965613361376264303532636664306239653139393961643562373138383634 -33353837656637393137396631303430366431313064363463336431316130663635636330353038 -31383462376635393564666537313832653564383933343766656663633264313661646338383462 -65613538323530633734303633633762383536633530343834663339643132646531656663363633 -38376630313062626235623036316236373130363336623734643338363637633232653564383137 -62316161306139623237393637616562623730316330363865316165386637346339636235323031 -61646232663562396334646231623962333838633364393732383435396466636636346663343066 -34373563356430333932336361346566396439333964333663316365613334366537643537393038 -64383438363030373335316234323664633834383138363034663863623063663061393165643932 -38356531373936653964323362336663373131383739393532613037656662336439393563316139 -66666230356563633235613464306237613438336461383735646432653138323536366637306230 -63326539323737633266346438356133643136646438346162393266666335623162333038323662 -34316332343732613037636264346566393139646566313233373236383537643533383363613531 -63316638386662633931646133376139633136313563373232623233356330643134343762613135 -61376234646465646134323738633038633562346166653631373664633535313036313433373331 -66343337353661613432346239623766623533343533326233326338333937353432643661363831 -66303637613032356365666361323030326162396433343662323164316365393431646633616234 -64613134393835633562383438613433313234326662336262343765316437326531363833323739 -63306337666532373764353065356330653037336332376237333735616539306565393432303161 -30383439626363353839663238393163396231393961636333306133383862383565626337356664 -32366364663736373833653065616135333838613030323665336630393235313063316139356365 -36633031646161316331323161363233646135616534363232633966663138616337613466336630 -63323233356363646136653738653337343466373134626563363263383638646666666532636334 -64313735323063346331623464633338363961306138316632306235373236636233613030333664 -37383534313534353535643330353663386435353939386262333434373930303938336165616637 -33636334646564646464616634303332623033643534653233643261353937663031373033633536 -34313235326631373264353564333738363730336634326638303539616236636435356663363538 -61663733373264376466646434383738643937636632353631383062646166386266643430393039 -66316364383062653230383839366237313966396362373936623130623833396434373632666333 -33616635616561366632663062373435393636623862326638623934646565643839636265636264 -30336232303837303663313936616361373239333739633865633237313533333839376234316639 -30653036333661393936653834663736346534613864383534636632333531663064353638663439 -33373661313565663332363434313436623561343031626165616263363364636361623336346633 -32376163636334343562353065613536616466316365306265643339353866393234303963623538 -39343536326161326636356534333839616661613838323764343738353538646234323931326665 -34326235396464653738663735346635346632643730306437353664633531643038303935353238 -65396663613064646261633230373461636335633436336632613961666333336437306262613364 -32326238363538326137343931336336316365313736633136633830306363323833323936313833 -30313666643933666263663836306634626261393561616262313961616662346534623766346566 -63313734623864333736313634303238306431396134643230616235666332636363386637353438 -30323838323239353361623863386564303431633664366230656338326434666339633332303437 -66303939353037303161636131623964663333383465366237393637373134396237613438306364 -63343632313466323030376339366137303636306566383236313638353263353638666264396131 -64393436306135343635613731396437663332666332306533646137656532623837333336383863 -61306165616134313064353466383533373133323366396136613939383937613032623432653561 -64613936616631633064376537343832323464343235336365633331366637383236613631306637 -62393466663735653637643763383335353462663063383732383933333563363337386537333634 -30306633336132316665303431366435373835336537653638613638633464386562626533633831 -66653664356666346334613636356263323133376237656566636230333763623063346631393331 -36613261366466316338373166343036393137313130323933306466623966326239386562393961 -39336536373235383537316331313435613832353062323230313562633462656537306666323230 -30353032383935366666356262383238373531313938373863663339623037343736306166633565 -38333730616131353633643465343030366231623061646639643535653339356636316134363238 -32653631346436326434383430613238356434303630646562383434366433613464636162633433 -38376433623366306562626638616665396466626435336662636266306330633437303639346662 -66323461383232373331343664623335333664353861613332633133333338643065343161636531 -33336232303664636435656332303466393163613037653166363764316430643631366132336631 -37613531396366383061643636323831306139303362613961643361633231346366666134396465 -31666564653037333637623237656665663639326630353335306465363764663032343137313233 -31376439353364643935303436356638636635363564663535613930656437373636343138316138 -31636333643861633634333539386634393463363335623763393235353861623065613937346534 -35393137343662653731626133656463353261383433356164303862316466656532323566636139 -62636135613934383335383462623962396234646565303165363039646133363966653933646332 -65386463306365313038663236343163646438326136353761353130313937376233633363623933 -30323165326661613562333063383866363538666333363437313532346433323430353832666630 -35346564366638306230346365343331656536326466333763306631633133626261666233303134 -30653466326664656137646337373532656132386237613336356139313230643864376461653935 -62616234396438343366633332356334313362663264393961373731316336343065333161383130 -30646265326139643131666262313264353735643232666165386165366339313838323862316434 -32393932613031633466633838393464306539353761313734353766636337343538623264643037 -36363833396263303736633663353330643465666335326465633335396237636632393939306366 -66633334623439396332313131343131316138656665663138616535386363333463336661623030 -36313463303235363838656338646636333936366532623130383464346234353734356139616139 -33393631363433633663303230623663373532393030633330643930383536393634346465373837 -36303039353865393766313130633133663238356239623063353065643134323830383931353032 -31386538323632313739336333323339353633373866326462613138393362333934366337393064 -38386131373938303131393761643134623136666332656464356531313064616534633834663864 -63646366313537313364306636393131383236353338646164396234303738646137326135313636 -63356636336431376464383535373764353931303337313837343030653539626337303162376238 -65366361336134626335346136343564363732643561393061303761386365386636633963313661 -33623335623430316638613161663531633331316265323962666634326435396164666364663232 -66396633353465353330396437313662323832613363663936653762396636363534326333326437 -35326436373463343137646639623538396261663738373532613638393031313330643733366361 -34653331653438336336613839623266346538366430373231623136623665383735653665343636 -62656631343065383533643438633334616237313333373765356136643835333634626231613163 -62363264643961363736646539663034383237653861356365613936663830306632396638336535 -38343131653465313835316532303662313265373932356161613961656438353566626538633964 -30636431653039663165653664306362363933383231653033323437353066613933336566626163 -37623835613662626161333239626533303135623035383638663835383032656633363031393162 -37613734316233313166363131346661366237393164653761316461306366306239623866353862 -64663037346162356262643034353865323766626561306165616338643136613030656161346462 -32366663643066303332333733633535343035333230333738626338663565633534636565633163 -34386537616137623232383330343965363562373732393363373337613937393362343735323737 -38613661633132656538663632623537356237666563633464613636613933363732303635393465 -66376634316263393837303862333263333462386264623839626465643364636138326234356263 -36313932363431383564323833633035636635656636306562626263333339336439666563363538 -61366565633439383131343263613165376337386537653065666136663234366561326336373531 -35636334316162656465346534376139616235666361366231633838653064653738653738393730 -30663866323430613165613837353439343639396635623062613631376433386163626264643235 -30356133386166393636653963346230366533653039613134303764623337643762343264303365 -64363638643361376339346364333737316566656435653066636261376133653738616137323432 -35626234303966386634393137663465353033326261633737363263663237313766373061366230 -35353739343136656335636338616162373439343163373866396465303838373932346164636161 -30623261633733346135323330343264333437343933336363663266376564323931363734666532 -62323431373063346637326361303663356335636537316339616561613763323436393434313864 -65646230383266323766323334376630356464326462663937353664636632326437623838663335 -32616566633031613030383565323239303764633761383836366433373564653434363933613833 -38316335343963383239373665336465323163666333393766613732613938663330346461373237 -38636330656431306134613765383632376430653238393465353565326462393834623565613730 -61386137303435343734656233363231616162653036613836663039363333383732343738393766 -33366439333234383534646435386566333961616535636637613461346639356234373537356331 -33303766656137386164623938633763383364303034393231613166666537373435363439343034 -35323263353365366335643465616436383532623838303239393363646638613564616265383038 -63643230386332646330303266383735666566363365346539383139646536626661313331303831 -33623061656333663939626538663233663365323539323063333532613164623562376266643766 -33643038306132313430646236323133653531306462643566623035323434376539326533613632 -64653239643966303034313435363865303636343837346138393232333061356562656661373164 -63326661323663643266313233373431383330633239363530643032313534363765623731343966 -33616130646165623032633638343939323366313162363137393363313633353264663137383464 -65376138613639303264346362316634383835393630313930666166323836646664376637643262 -30666636383365386264333831303537323235646433373738396437383862633136646538356462 -65613037343763636239393432663832326665653264383932313033363533623833643662383832 -31363165663138643965626433373561633132666232643264623837333737313964313933393161 -62623561393033356464663032326133363832313432393266366563346139333530613034616338 -38373334656634313533666239326635393564373365303063653663643837626262663139633166 -33636438383862623764636138613565376666383935393933356438653436666632623534666530 -38656536346238343131363839306638346666336430383165396562626634643634613964356664 -32326165623466383630313931353638633831323533653233343936386666393136393038666432 -37616562353830303432336464333539656538336239663538333165316662383739333331613666 -65396433346135316438306265383065356563613634343765323331383839663761383464386162 -39383163316230663539313732306539623361626132333066666639386465343162643531363066 -34636666383439306238363664313435383739323734306635666433363664343065313064313464 -66373934376538383737313364613737616537323961323638333566356238306465343230333166 -32396162316261346438633438313135666434666139666130623364666434626331363566306235 -63613863343837333465663337653965313662663362363533343736383733636138393134346565 -63633332313238356434656465336161663562303635373239346462376239623361316337633035 -33333031346337336566383038383263393931666339386163306635646333393566336666333739 -35323630353162656366623762353936343564333634386536626536656133333931343134386365 -39656433356261393931326261383732363534333934313439373130373863393237663761653437 -66643432386165626331663064323362613635656332336138343238336366376535666530653136 -32633632663166663833653832393436666635643734313561323237643766646263633864383434 -35303936306234663164386636623062663034623930383834366434303832653238396162663166 -32666335346230616638353737393230356365623562336166323364363531303932363265636436 -30346634353666366432613262623664656565303564643163343431336363366661326530383961 -63363434396364663835396261316334356331613063616264633963323763306563646236626362 -65303734633862633361306162396361313031316332616134316339643439316334306236363135 -34653839303766353866386232396633356531366463666235663138623139626436386331313966 -33303637656366396131636333633431313365303665353232353437356232613337313830353032 -66336130343166356364343764313530366564353131386363666532303631316535303933393831 -64313262383665623837303938663834373736323134313438653939613862313965613035633939 -36616164376436306334346233363230306532613135363765626239336635356131333635633832 -35373336373165623637376230333730313636306236343132383536356638613863376139316364 -36363238363765386436633738376264363536623863306265316263663664666161393565306638 -30313733636637333766366331643331303135663430623132616136663466623139396131613962 -63646463346530313530636638643937623939396636333537323239366334353664383762663137 -38663033353265316630616163656235623563363861316365626430316632316532663938333834 -63396664623061636439656166346437373661343061633466346665626532643733666362353938 -30643866316462626261303533373864373963336634323032616361316338353431376561303436 -33343862373065383035363439633765393536356264356435336364313237613735396465396134 -32373234313562333561633632623435643338633130623831383166306139336166663339666634 -36373036663862633632623432333435356262313031663834616662343439336433356664373330 -37313362326539633162346361646366643539623838633661383933346561333533323932366539 -64323738323735656232373166343339653663393865623231353962343261353963643863396433 -39623732353836383131636363313464396438633032633764643830306562393939626136303130 -33393163653633353264383932646539353965663164633466393831396330323736613037646463 -36396161623966376231323639366161316633666634383135393537393231316639343062396432 -31663665376334666562623766346632663930613937643736626135393639333331636136346338 -34633237343761393661356338323931646131343338613036383162396262386366396130613536 -39333434343339636466383633336435356431333439333833633261323161393436356162653835 -33323439666431316332633239303138633364636136386431663831393765636136633739306536 -62353963326538396666303866313465323163653935353534646639616338623564346662643562 -30383263633531383836313332646362616634363963353836373736353232316130663865373431 -35316663393265356565336661663663623566313031326137393237356531376632643763363132 -64646162633031356666303837393039633662316131613437636664386162613436326364646664 -61393063353138366534346635616364613130356462653830383562366430336365653830613932 -37373132363933346138653634363032613430396663616236353837636334646134373362343736 -37313262663637316662636432333133313434656638336161303431646537383631396532646535 -61643636346132636164366464653761313464313065393138363738613434366330653739336436 -31623930383038356535333264373736376466313965306532633934643835396134653365346366 -35656231323134613236376538623661313231613061356635663865336366393732306635393066 -36333337386261306431323335656339313838383964316537343239623463343839396263363066 -61643431383433316537333666333466393636393735626535363132323535353339653062383533 -36653336393062353035313132343861313532353836316333353433663834633865616263306433 -38666336663031636634613463326334616430663162336532396363393366623363316637383539 -31333937366464643638323162373832333731633736633466666134613637356635373730356435 -65646239346335653737363232663832353838333065613333333237306631323937663432316131 -37323762656130396338313562663434343066393033396666353262663736373431636139393762 -61373533666136306162333831386463663431623961323563346566353365626133643062353835 -65393733333832326238333337316434323530613530353135363036393063386163653637656236 -35643032376335383332613937303762393230343662386237396661323831333865366433643931 -31356461316233633634333533656661643734396166396437613032623239633239303161326164 -65623561363536626630666661356663333833643738323034656465633939653733353431306565 -62643333653262343066366439333439613062353938353061626434353537356237663566383938 -30666339386536656334613836343137393736393230626635343239346165663063396232636435 -64626161643864373537376563383430336332343136656133323139653937363833346363633732 -30393133303264393662376166613465333138373132616565353332666635643936666439326466 -32386563653865373835346230613032386265333065373839626238613230653366316535653935 -34393862383030643233646538353531303730343963373937663034323766316361613065363534 -31613835666361356431383739353339653662323833623237336236326265656464346134613737 -31336436313236356565626538313463386662633332633032666334326364373338326636386239 -30613065386462303136386137626163373363303237386239643331376331303139363135363137 -66343539636536326338653561633665613665646130323332346263636163356432643331373634 -38373861343836363737316533336137623531343736666636663761313065333837363165393663 -36663533373864343862333237363962363566373861613339363930303039666637383837613266 -61623237613832376238323837303862373637303939346163343635343030633864333461383733 -64626438333333373932353735333861303066343539613135383961623736636161626633316366 -39396536636362323834373630336331363936633965623439636135383033376335666439393965 -38623533333833333832613065376434613630326338393939646138343936366130613666656266 -30613937366132663836623739626431623132646335303930656333316530663362333161333830 -66326562313630623533633466333036646261656262623364616635643562623533376466663165 -34366266383961373736386366316365336538343066316230636635656234396564316238336538 -62353438333539336161323836633536633132303532343439323061326237323231383530316466 -65303236303634343434666564343464333731313866376163303762326530666662356563323664 -61656536626161663839386430303336626437643763313232333237333839383561313365303830 -65303337353639313762356536346439346532376462653665303239333436653635303231646634 -65373037353861323761386130656165613234626134656236393436383639623966323131646466 -63306632626339366239613465326237373236643164656136396562623933623831633336316561 -30363930306630616431623630356133343961643931626633653463323035333265346461333136 -32376165666365633962393636313639356136343461613635326334656634363366376564313537 -36393663393838643434363539363061646233383130623661653261393036326663303336323238 -32373533646335653032306262373735383333333830316339653962343466616239636261356136 -65396234326531633631306238646261643238343137396631326261376264393937646130323834 -61353935366562373436343263336132373862613732376334353930653866353038383931396563 -62653833633839376366643530303734343331323034386263316639333964313665373061316538 -62373938363533656661363534636132663238343465363236653365663535336431353365613962 -31646564306439316637313336303238616662333135343038366232366339613863616235323931 -64633530326139613530383962643961326139393366333931646139346631666331626435313637 -63366539383133303034313233336533333030643539306634666337666635316635636238346137 -34613038323661393839326534656465336561373433393935343935343530623836366362303435 -37353366396631643832386366636531656531383734663463396439333938386130366662376664 -66616131646263646239663130626335353930373432383431363733316432633633633332373765 -63646139643765363332333030626166366563303839613765373862373237316663613061663066 -64663833386465343035353031366261363564326462653137306431363965353538663765353738 -61393333356539343735343063663231396164373531616261343532323337613561623030346131 -61663233386463303463326233396634323239336332666565303333306538643137636534396233 -35653034656364323862623233656466336366633565653465336466626362316233373261383061 -62633464643637366331633539343061623833613137383466653238623735326132626434393038 -31336363303263613965343631376131306131343562333038393931636631353932313461653335 -36363132613465653039623430393138626332623332316533633534643835383532666162323132 -38383665333262313034636438653738393461396565316466623761386633633732366138353434 -66343463383134633538663839396266316437386438393861653431643333333731643165636238 -39623063393633373333623430396336343761643565373539623739663738303164646330393961 -39366563333865316539616665323562613739666130336166633438653830303433633037623632 -30323564363636316438633432616636323461383230616166666335363462303139623337316334 -64356530356334333131616563353662383236373636333130626163303238393137613666353265 -31386532626464313164363036623538313635353133313963653265633466343536353338396464 -66333265363035383036323361343931376662386631663539396261326339353163323061643038 -39666633633134623162383161363566393962343165353930376339376237306236616636393731 -66303239323332323037376633386261653161353962636337666434376366353963333435666130 -66303138376434343764373936656437633064323436636366313132653432636430326538363239 -64353464316161613233363034623636313033316266353139323936356464633739656334393037 -62356531653739323237353231353730323430303332336436616232626364326437666138346636 -37333565343062373961303663626666326666363765383934626264616262626337376332616433 -62336466343361363337613934373539646263623966323762373962623237386432636636363938 -65386339646138616137363533373435656562613336326235346362333336623239303838396133 -63366536313932346630646636643062343533396239643234373133663132643834353863656564 -33623162326262643663343431373166383235373637613830633139313563306661396130353063 -37303233363836353231666332303262646532383163663762353265326134666136303465656463 -65323266326339376633656433333332653965366333383963353137353439633533333866623262 -34616363356164363064383733363833396461333866383363636437613363316366663038363531 -30653934653533383635326465643536323462643435323161373030383666303532353437303731 -31623762393735356261323139326532353330656432363538363265626532343761646563393863 -36303939396534623430653331633563626335313139393734303761643533656339386663353535 -63646265343761363532323437633630313933313662623761653133333962383637643334386264 -64636262656432356336643761303863633834333630633939653131386238363935373537623335 -33623339366361633462313864386661316361383936633139666462393965376462343932663963 -30623137633033383865353731333532616662363639613832653436313137316263646534623135 -66363565316237396137366335623036303463623135326563633231316131636264633837656236 -64613833653431303263363064343237356337333466643130303661666235636130366136653039 -65353933613964333137626136653763393933343964376563333533333036313035663737373331 -33613234663735353530663934646631613133386330663032313339613837393263346433306331 -62303965326664623936663330663730356364333335636439363033323165353635386364346330 -39623434623234623435323966653062363334656130303434346630626366366365313561366139 -33633434653566333365373135366662306632636339333732343231616130336235333361303262 -37366363363834623331373730386537386433636633383932653565366336626162386465336630 -61316437326234663865396565363862326434323633383532333539336631313038386566313931 -63303438373333383966636336663237636131303931376233346237656164636339643965396439 -34623838323334323632653166656535306563353165383261636339646134353435373133303834 -33343735626264336466396437316430316664373364623162386638346435643161363361376262 -36346663316166336464653735646436383634346530386433303365653162386133376561336437 -62643931356463653930396237613064366337326235386530333133383566646565323131633334 -65643333636231396235393132383161386161326434633139313939306163363233356130613863 -32363536616166333765623437363732636135623035643535316437376239336534616434353333 -35333433346339643637653163626262393431383138633237336239663933353138653963346538 -39316136373339636437643233313566316564363736633239616230333937636432616532643838 -66666566363862396166376539303364343566643762376238663737613164393230623764646336 -32646134383932653532336234366166643832356561353530623963613233626535333039376630 -36373566353338366131386638323235316336626130336235353338303664313965623066393165 -35383736646163613932383664363736313331636466636337346239313337356363353338393336 -32383134633764323961356261333233386536303465333734633661363231356235366366393033 -65366261386165353762303161373063643730303633363665346632336534663466393833336266 -33343330656332346130623861643161396461383639633037626366376234626433356566363639 -31383739626263623534303133663038376633623635646539633238623839373537313161356135 -37353634373834333037353236653438383735376565303063633633303334343435636438373261 -64666163303464323135653264636333333633373565366663326166666330303730613166326231 -36353531353532343365383833626265316437376165323063626362346162613866363735333863 -38643966313864363137633430323838353835623138356264316139623662356663626138393933 -33653039323163646461656234633666326439303630396465326132666566313136373830656437 -36643637373433306466633437623232386136383766633933636664383266333361373964323765 -61636439663961363639353562396163633239643930376465656364636438626238363265633239 -37316337323230633230323761666133306662363736633433633532653438633837393435613464 -61663037616233626561653666323636636563373764363461623930643733376666346239373565 -66376139666465393736616438646633333837353932356233613639313431643364316135333137 -65373462396130333761633930353664313837316566306465353566656437666165636636323135 -66633364363136373164313034333764333562363862653230306331636434623365346639646232 -64643734643061346433343635623965343534393232653933396632643033323836303833373630 -66333731383430666239306234356231346163653433316166343833626562393163373836346631 -35626133393731346665623665616633396232643935346561616231366561366337353135633663 -39323131366233376636383731616236653839356262343564373964393330363032383337663462 -36356336643438633064363262323063373461353730383564373130313034393637303666623436 -66333631313337336663646136653233636335343130616161643466306664343039636337353934 -30396630316630316663316637646232363638326533636565336633313764633033353364393363 -32383730313433363833343635386366653131623834383739343166313061386132383935336436 -35373363316665326537336361363961663264333135633166623035396365316461336134393837 -38353134626533626438393335633137383736646362656665316633323565393236306638383662 -65376532306437656634663139333834636530396664383363333930373866623338366166636130 -64663239393335633461326334663630396131313734666334383139333634623262636230663537 -38653431316534333733643064343134353164643233643138313838316332383837636130656533 -62666135626336623633663535616537373234303838616537623335333265666431623034363738 -65656639646132633537353435623831383432636235326264373162313263663438336133383138 -31343665643661363262396366616563363930373133373237383030633433383661306265363130 -63303134363836656632386538636537643462383532333133653365343630363434343536396164 -36613961613734633035643265373834336363333933336562623761343865663437306137373564 -64623834633565666538656663656339366536373563613938376635343363623533353937623962 -38316162636539636632353735356363633236633863393532623962633739353830626330363932 -39393263643563373834663663653339336165653564383233623532333336666461396531623235 -36356662653335646166333763626261386436643663333635343330333565643665623638646562 -31623534613231373062643265363364396561663530653461313932346639313436646662666366 -64316165323462653830316433303161623238636633353036353039666163323036303136636530 -30326437393336346637306165613864663334636237663535613135646134306434383033336233 -62613464633063303561306330353232643664303135346435323039396561636362663832386332 -35326635343238313939373036373433346537343438366432373234383064323836656661383263 -33393235373639333237366161363632643432613335336666393465396261383638613862633563 -34366662393332656463303930343033333765363964636365313331306439363361616264376531 -34313661633637393263376534653132353662656461386265643730316435303433383166663134 -33373236323131316638636361633432373939646261653433333761643431623962383036333834 -65616566373961326231333466346161386265643134633262313839306535363737386163333035 -62653737613536663639663833396337643035643839323861393736333339313938313335643839 -39623065313635353461386364356235646664373734356435393864623164633736363634653238 -34386366363761386537663135343563303838313936343331653163653363396161353834663130 -37663161656433306363643364663639356431313235393837316331623235653836373139633030 -39373132393436623064336230396135613063396130633138666636373936373762633035663339 -36306439363962653631636364366366393136663936363832376365373062353532373063656533 -63643262643338656633336566623238616139383761643033643338316532666630373937346338 -61373632623664313836316433323765363737383836353534363265343564653733313030613731 -35303836303135346361613263623934646234356531343262373162376463623035616537383363 -32636138333130316334356430653237633566633538313338633064353039613964383365383237 -38643062396437353336366337336561393265316536613339613937303035363034343134336132 -34613733613232326132303539363330363266656136373966303862663539306362663665376633 -31623366356234613033653363336166373334626134303737656565356130383536303365323937 -32396434366431343034613237373666643839623838653535363761613536333636313834373866 -39646663633432313434623431376532363239343637393834363163656261646637623464313465 -65636537346435376565393761633765353064323332313439643836646132396536646530653330 -30336637363033313465626664653666656334636365303835663232313630323535353164663933 -30396366656230336564323935373461636337393139383134613730646366366139303231383038 -61363930333236623966313265613965373463303633363734356636326665386634643264303661 -37666235303561633936386665376430643162383831316164343239626563363264646132656434 -39666261326239316530626134393762643062666264363732313666356632336536326666613765 -66373261313464613135303765613838363133316538396364376264363436386163393538616663 -62353632643361353739366635323162366164353334313035633433346461393566613835643031 -31373036323265653938646130343463326130363935626437626266363262623366356535333535 -32663136323865303430306130326537343130313534653662363631636434343663313661343037 -37663861383430653563373964633762386131383664303263343164333064663565373564653839 -32363232383139343433396435323065386565373233346238353637396564653838333465393436 -65353139326465666666303864613561376639623630656662333964363931656166316536663965 -38353961666130613034306234626630303035303130626262616631346530646131366430623630 -38306261663032333736396130323536636634636261616431336465336434646666333563363666 -65363134373236653430346434653739303337323232626639623935396465643764383237386338 -34643061396265643930393432383931323965666231363536616133656464333036646132303466 -62666535343032653331316338663933636139393964343130386566323764306132633965396438 -32313037376566373261363532303065333634646439616631303065303439336661393362396637 -36653563656666636462613830616434663432616234633564643231623365316161663937373736 -64373635346332323563323161626531663636363635663865316136363838396562656566666232 -39643532633535306563633837616539633935363839633438633730386163346231613139323062 -65633461613337323164373765386238396137333133383530313062663835316132313065626465 -30663866353631396666656637323137346162383838323932306564376531636264653932303164 -30366661613231303462313364313836353261333937366535643139396130663964623162336465 -64303665343464393237353031383436303162386365623061636138636334653764343638376533 -33383531613333626363626364656136306137616163306238633930383765386534303763353437 -63646137303130373564626437346363363732633166383133643364386463323863633434373136 -66623663393238383836643838633839306563653438363332336365303462663735313134666537 -30666264616462366431343866636633376235346566383438333362656632613965663563656163 -64363361636232306564616161303538663736323535353962373030323436643363396264613633 -30633131326362366635363262633535346562633365316530633839383937663238376133643736 -63356539303936333039663036383933313862333864306138346334326666383335386166653133 -39643937393864316464326339353465396265383439376166326162333631616364326231306566 -37373832366238623163356131366134356432343461383463366533393635363838623037323563 -36373064393335633565323037303536356635663764343465363732386136383038356462663461 -31306263633036616436343335633964626665343766616139323638386562343431613137386563 -31646464666465383964616533633565363738663363653463626239306333636332373339376432 -30366466633264393630643566313535663364313562616665656561623966613736643661386164 -36396564626230313762633761623031363930613234653139336538396330656562313830303866 -61633163653835623266633862356639343337323334303263623466626337626666353838636466 -32356363376563646464356361303337356531373832316335666264383634336433666238336538 -33653736643265356436653330336666366334373661333235636636373966306661666533323465 -66353765383663396532333436366536383531323861626632353362663862643935393938623332 -30333566663130373333396664346131383434626532323934636535363234366235393263353038 -36376433303862663564396432623066333164356439396166353864303461346432623737393436 -64343665636536626633316137633733343937366264643235613934363037366463343130396233 -38306164343738376261333364643064313636343962643937303662653033323066323163383465 -30333965303337363131333335306635353736393032316538663936376565633161376261656131 -37656366313565326665343931316366633232656663633763366539353731623534653835653862 -63343164383565633431613632613439396336643832643439353065303838303063613564636531 -63643764616266373532643863663335636434353431666366306631323438623464646534303266 -66306333313332336361353335623938353336386431393430613432356638653063346163653138 -39333136666637626661396332393934666431633232396464353932333439316633653163653137 -64356232303333343033353836323162336539656164303762633462363230656137383731656261 -62623265656236313433623234636263373663363537613635366534323136646531663439623736 -33666163323365306166626333336638303065316632343539353033663639373532356137363436 -64313134333539613664636666333734636234333733326438383566393062333134623036613130 -61383834343566393865373839303530636163316332366135636335616335396234323936313465 -37333366343736396630353432646466313164613432366233333538636331623634643238363633 -39663133376535306461646632336634623966323364366635636266393931646663393263653634 -37346166613361663961343932363563663834666131663066663262393630303136613962613366 -63356363336238343533633561353337323338366533373762306162386539323030666239346430 -31323536643838656536633064303965346135623565646463363638393137346262663139376463 -39633036656132353237643134376639346266383331303733643539323935323835343233653366 -30613138353637346636613837333138353463636231373737633031633264656239306365643262 -35386566376230393765383431363231393137326334353138666530333738653264333365323231 -62396264373065396232326561306430313036383562373865373366393632636164623838376166 -31326233343030376663373465316338326333666462613530626232343362343839383566303933 -39326233343664643939363339353365333763303566383033316635333037623236373564326564 -34643361643937303561656533363038653164316237656530363364383765626666366361326135 -33323162386439613938356235326464613437313435383231343663346332636535356530336538 -61326632373530326462623139363165376265633131393962336635656237636465393965393961 -66353161373962396639336430626235333232333137383237633139326163313764623163323331 -36393834663038316538323630646364663933643765353630633236326231656131303261633335 -65306535393035353232666332643130333431373634623230636639376431363837393130663361 -37656465636162616361353932396433303331313730316565666534613430313130623161353734 -38393862376261323734373763333833373232343763623035643137386139666364386465636166 -31336233633864323439343838336266356466643562373835613737326137303365353363383430 -30623135303937636332393139326233376631373366356631323038363364373837376432363039 -37323036326539313864663233643235336532356635366138663362363436646265613164613735 -37383730643761386566623132363031616262333366346133363136333931623162356237353765 -35663733323730643139313036353764636431313032326362663763346435306635376465643633 -30646263633434623034663532373737303538363263623233663632633162386362386237336538 -63356139663135343133333931636665383036353865613932633162393330303761326565353137 -39343633353263316365623962373066643036626337303166633335616661346631393839376530 -37353436323138393361363032346330343632323637393430323030373837303438623665616561 -36636134653031333234643035653364303466373362353732373938373734653638303430306136 -38663333346533353363613762336664313065333730666335633734396635396565353866323061 -61306637383862386237333231376534333963356336623636616262383865613962643730373330 -33653134316437616635633936616432333134613835386261666632363934613464613362313163 -32663761633066383433616263633830336666326662663435353061393565656364396637326565 -32616261613931633463313739333037343062653432356636303838363231346633363664316231 -64653837653764626332323036346166306661666466636433646462396438666533336663613563 -38643037326261666563623761343163323563326163306164313162303837346530383434306433 -33663463663137613833393233363336386431303233656265316237316233346464663534353830 -37376536343239323532363338303730353562363734643238396166653535346663313830366235 -33343530363234623262666434363865303432613832323136656134363137356261383737663634 -34393665316162363739363566623332373665363466343730376134376133666336333837666538 -36333561333639623134386664646138393461396435626535336131646233313130343564636236 -66303665626164313563323361663231336265346130343763663537316438373136386433356566 -37393339363964316139633138653930626534643031613630636265396639656233366466663530 -34353533643431393363343562633935323739316234323833363563316337653665356561316135 -35626537656635386330663938326333356664343363616537643838636662326432366464303363 -35326536383138653466343837326237336338383339386634613931343034336261646430646134 -65303462633463386361616265396237623865396530313438613233653664336131643939643135 -62356131303234346338663930646333353338353133363331663733303466613433623233373263 -38303830396534353461643334623562616366316563396466613265303438323737316637383361 -66653734633231663734353632306637383561313762363664363733643336303862646637333463 -36356237646562393038303861303731333061363666636331396236393766613035643831616131 -66336433383830356435626365343236626237383436333766653036663261343530643465616531 -32626132316139303264613834643036393063333835633164353961346137633130303834643662 -36623931656231303230303139333466323631373232663765633833376633313562373262633134 -35333733313938633439613130326466613635653738646531643833333439313332363734383837 -63616265316161313635386532373130323066656231653862643861343064303030383238363731 -31356563653834633930643062303332336566643239633031316164323564643835623736666133 -66333365623862366565373538396361376465336130383563666632646537376135393936616537 -38613630303630663965363565323437626539613034343331633564356162663431633665653436 -34353133393162626133336661363565363030393661306438316532653235323362633630386162 -34316636646466353633323762323537383235336230383565646563336561626636323464613331 -62353231316262646238653638323566313462353737353566353939353461653934383334373264 -61316363346561313062356466333335303132346362383661386162336462326366346666343365 -33366532333633306434346639373634363962313537323864613364356163666639336465636238 -30626263656236646164363733663639306336633435336564623565623262613166343732393136 -32326133313135316262303937366331643935626664393138396564656636323864616663666539 -65626565646535393033656134386362316335333134326139636261653632633161316537396538 -63333466393165396263396563316538646464323530333062333035393135373662623638353563 -39346566333634653264353865643930633662303162343365666430636562396235313536393962 -31353330633231643531363435373862316630303661356366646130333663363062353637363131 -36366137633230386365346235326234343562396465626263646537356266326536353066353563 -34643362633538613836613766353862393937373964376138643630323261613537613639333637 -35306266313534393338323763633033343037376536333962653162643661316162616362333565 -35613136666365323134313536636662376238323566616430643331363562323037373165643733 -63626235303764633238326432346661336237613638313738343130623034616564626438376239 -32393830663335386438633234343166666634626363366466626236373939653762363639303662 -34303538393364616534366665383465626331333966646266306430353065646331626131346234 -32373837363463303836383436363733613433646231343730336530393833333837336561623730 -62306563313430333861383431613234376332376131393431343262373734323235316432643036 -35303837666534653738623333306237396536356138303131353864353666383962623037333030 -31393238353662623366373639633535643537393830373661626336363238653661356663366330 -62323832353931353539313563306630663232343466666234393264383231363864633632633730 -61376333343339356565363336316136383430346361646532386632643233373931303766613137 -30623938653637333336386236653839656563633062663234626261323533326635396661336164 -37336439643433656165376261633738333764316266633835323465343539373331373432333139 -30626531313631356564376232353032333338303535366233353534323033646230326334393137 -62366332656534396166363635313531343037393737306139326631386163366337613138633736 -62656532656235633032623333656565663437616138613734316535616639303939393230616536 -62666432333332373833353062366462613364303434616564366539326238633561383965313437 -32393661316262616362333664646563356536336436316332386339653035303432656562366261 -33353465653734646263653530363436633138343439373937623964316639666461353961663831 -36343462633139333933366465366337396635323862656431643765363963386433343737323361 -33313632383439376361326665363835663536373034313138633265643462366236316437646234 -35316563313030336566353532346335333761656463376339333662613463326133303237333435 -38616138396432656438343630653239373637663834653232663065306363643534623561373061 -64336266653633656266623639316464386364373332396336616133613831336233396631363064 -32376564303230623261623563613933343832363365636334326366333763333739633132613239 -33353738393164346466323564356664333864613938656537333865626166616638663230663234 -37393735316661656435366435636137326336636438643230633937326432623266626630633066 -38633563643835376266323365383963396633386134653737663634306163643633323863353062 -33646135343631366234653437613036643133616230303337396433383064613730356265656263 -38633365613334313465383663383766396465633037393038613863306435343136326462663531 -39306439303230646165383639303665643633643365343566633861353432363463636161613264 -30383831623630343866376637333235343361666264616635333638353065656633333235326530 -61613336663430366537306661333034363533303834383961326261356563323733346139663735 -33333833383562303630303632633630613061376530633933376330333363303166653233626539 -61623765343439626134373439363434336362373832386565353236323565363533313631643865 -61383065313738613837356161393538626634653932313731653037643833313765663231336663 -33623731663761376636333263356464613835633362366163393136386163626633396661306330 -62333762663966616531336466336365626431373864373862663339363361613161363733623732 -64356336323139343139376262346438323163306332643335616438316431326536383132663130 -33346633363161323337303438393738646231643732663337656237306563613636313863373363 -32303931313666353438313465323039333033333633626234376266336264383836623738656330 -31326530363432346539356133623664613137393739646539353432623865333866373164666563 -61346231363235383664613661363561653062316263636461323861393062643839396235643533 -34663431313737653063363133393639393165653861653939323336386137626534616236643633 -37303837303138616434303864326432656330373030633435393839346233376535353361386531 -30343332626138336535373433646238306538656230396165316339323264373263303166353461 -34383664333333303931373536616230356134616135346139396136623234623136313464623634 -65306163613538653530376635336362646331326265643032653962373033346137616237363334 -64636363333031373937316462653536623436336261616262353431343238653862313836303631 -32633736636163613532666465643730306334643139663734663138323762363964333332393762 -35313636386262343539663862633565383239656439663562616135323831313430653663336535 -61636462383833626664623763303163666636363032346364376333386463353763336432636534 -32393935656461383836333334343638623464633734366232343563326130336330333761666462 -39666534623330643439653065306236393330386466363966306262643530653939313865356266 -63383265343037336232346532333065393866353437356230313039656139303266333835303939 -36323432623433336130616634343263303330616361616331636532366639346537396437636634 -39343533343631356137343365313762303639633665336530386462353536343666353134613833 -34653261616361393230316632346238633737626435343233643135376336373138323235626632 -65333038653761353032383734326663326532396134653036633762343031313661373661633731 -65356236376235373730666534353566336534643838613964343730373539636236343364326231 -30383731373162333439643163396235316134343132343638613463373038663765663833376665 -37363330313932656131613461373962356165653630393863613062663564363336316336346239 -33353563336462373161643939303033353630316437306236396664633238363137333862303566 -61373531656633643534663365366537306536623962326636626365666236366364633466333863 -63326465323064656665306131316135343965316630633537383831343031653937396565353662 -30396636366436306232626234393436333639646139363961326435653961383332313932396166 -35353830393162383539646466666635653038653038633632616238366664316439633138623534 -66376533633661663761343132393837653634323631373762343436633230313265373534343535 -64653734376161373131653837636265363237393365396338663235653264666331623839373666 -37333539396237616333366330643231636364313437623561386536613461323463343766613761 -38343062323837373933346562623764616630316134383535646135316436383761396637373431 -37373461666363313238633434323537333038306639383066633562626433333465663839666336 -31356534313930666635613466393931353539333532366339663238356635353063363037333530 -64386135383664306561663562353431326264373834373039616362306330333561356161633831 -65333561346532626239343632633066663334613763396636663534653065333737333737366465 -39326335303639373431333038636666333362656162356237616334343736623666646563343835 -39353161353765653163643462653862346365393465333462386461306461636235313434336237 -32366137626138316232633532343866313163353965313539633836336538343038366133363833 -30353837393734356437343737653435613334663735663237653532643639383334363664656133 -30643765663530373533616463396663643263616361643934373762373130613764633135343461 -35313036633934373965376338353261356163336363653838633233633162346262633463323737 -62613136313132376533393662363136373232636662373666653436356539663961373334633438 -35323937333831306536316563646664663831653365643838626564383430626661623465623765 -61306161393430653363363239363733386362643534333432656335636331366238653437393937 -61323065373236376234396239343936653938653362353862636134336230346265613866373036 -36626566646532363666393466323339643562343163663466306636636235356639333932366435 -35643366616536306163356538616338336664656664363438356539323737616264363838333734 -31393534343062623130626437333164353536393431326534306138393964393539366331373834 -39316131363738643635363934663832643935643065346538376532373761646366316534373463 -33393136636539653365313138653139393538653134383961663732333134633563666162343264 -37393164633363346433643661396562316632303466653534363362336633373237393362303765 -39626433386637666162316436356639383434663630343035373338346138333561313733373738 -65623763376432343762383161613833353961613936336539363233366564333030623766386562 -39363665633431363935396435626638306631653863306266653166616465303336356563613863 -31306363663930326136633663356563383932643333623465623761356166316233343865646137 -34366337363862303666643335616131393034623337313439396262336663343331383761373135 -36323435326337333634343164323736366235356230353035666337343438353431353630656166 -37646139313330376236373039613763323034653837343133313065633563306664666430613335 -66333332313231376536343836303036633935653562343261313737646131333462383237336438 -30316137656663646436646439656661643264346262376237356238343533613736396633376432 -63653561623731663235336164326163626363326161376331333434666262643932323936656439 -38613764363662613363633935393563396334356436646437636331343939313435356166633164 -66633336666134636464646331316637393437356538303131616233613961333638616566336662 -33336262616361306635356661643165303863656566346264366137666534336133643165373737 -65373363303262353662393663633965313266643065613765353434393433386633383033383765 -39623866316265613738633833323133663966373230323039636334313335366235383130626239 -64363230326565306337313339343236333937313336663465306438343536653365666166353333 -35636562636538323336656238313532633265306637653162306237316339656236653735613564 -61633838393939393539326566646139306265326263646634303033306137653366623331363361 -37353562663865613437656265383631326665613966373236623939333762396633376237663239 -34393633633334646564306436313766346538333237383363316331636232336261623039373439 -63383238393333303061333637393963373365653835633336353430613136336231373935383734 -33666338653863646134626233386630356537306164613062633563393036373234643634376138 -30343966353961633066356535613161376238656562393334356636643362356233646233393465 -33613035313339386336303639343161626134373533343830343066376261633364633333636134 -30376437343861363331666338326132666335393561623361383464333833326330363437646639 -64313666366262376265396130313963366462346162343839626564363731623165623731383037 -38323163636131636563356563393336343762616266663461636136363138313330623833386335 -38383366366235656239666461316534653662346631313930343163396135303938623939363936 -30323634643462643338393661396461666132316539326263656438306632663930376530663139 -65666135613361643233353338643835653134363366326335623464626239663335623932303165 -34663364366631326137646635363235613233353062333165396435386335316133633464623636 -63303935346630356333356330343136336530323836663161666531326330316666383330323764 -35303035373062656538343662626463633466396164313663356566653130336536623034623638 -38313235366238313465373535613535666439613138333963336639633331643265393734646466 -37393065313131663364616563356165306166313432613964346131393865613365373161613938 -33373664333764623733376665363365616238623936643337646237393338373361383461636133 -30356362373665343564366366303033353931323164303838386633623764633432396663363161 -30663236373439326238653938326138663166336161353363353236646531373061653130393636 -33323339353033393032383065373737656664356533643637633730333061663637303535663462 -33306662383430316432316330306262623938343430616136363166346166393362653364646533 -36393531323936633264653139333365303131343433633264323861633433343135313237326261 -33313435393134643661663637653832653332636164393932336537653538336238333438353665 -62623335386539363362396164366334383435313336623738313133303166353765646265383763 -66373630333731316435383639386430643536363965333036373639613163366635383863663533 -36633665656333376331643564633134633739613863373336666262333964346562306463373865 -36636636613432396130333965646132336631373732316166396264633833626561323861613963 -31343032383666623833376631333865633536663131633431663462646130366462366538353832 -66343265373633353166376662346234666532666164363933316262306437626166353764323435 -38663663303239643966663034626135386134396236353438393266383230376439336264663638 -32313966333565616466326161656437333462313136373966616564623964383237343161616163 -61623733353939623934633736393031643964366335316639373962353835306133613262376436 -66336134363837616561666232313532353331376235346361323363393538326330343066346438 -36363937393033633138353939393932346636306531663830653131616365356333666330323333 -61383765633137643930636333663362333933633362353861653363376563363037336234333733 -39363363303664376561633763646363616434323564306366613061666535343464386365633138 -34376266366137373864363439626562663463663735663861653731613965316431643232396163 -31316631336235613532373065303365336166323162393632376339353562653233356664303361 -38636436366662663130353934393665353230636463333033306433633339316233366262356437 -62636232376163333764383462393638363164313339326333643236306539346531663839376264 -36663532383234346532386331363739396462663163623835313832393462326333663935333031 -62363537363561356365383330326138663564393133363738383132346537326238323264326135 -35363737336435663738393832306638323533353338306238353039656666383961643730353031 -61386662343837623664333030356663396566626164373831383137313438613138613636306539 -35336237363566356433363132333035343139323663336131366631636132613434313635653365 -63393535326532613032643436313731306561353463333331393531313737323736336137643361 -66346233376439663066323231653261366235613664633337613932626264363034373266626137 -36623237623330633836386632333133343439616566623661663034393061373764656666346437 -30373339626237346263333837313337313336626333356335616264373332616665346437303031 -37333230643230373061356564323265663962333131333861306263666361343534653761636562 -35393535336564333766653263626439653838376365646635373366363638666663616239366261 -66313064366337336237383764363264353064376235643632356635363936356234643439376165 -36333839643263373365363933626234363539303963616230616637376638343931356331626261 -34366230346465353534316338303131316362373038336437323564343538336362383639663834 -38363765393931383539363237333064636233343932366331616234333364616131326232316264 -62353466386565386232663730383939633232323864663633636436343839323930656264353866 -39356366353330623062333036373962353163366364653633616539383434653133643536336433 -62306437663939663436326335396564323365373732663630646530376365303639653962333931 -61633537373835336439376331393331356132316365333036393863303435323839356436656238 -37656266323538313238366262663961323461633762363931303166643565303038393932613930 -64613030373663333133386261353534633763396434623664373465326633333231303064613230 -62623761393034356238356162666332323065393063333834313835386561353239383765323162 -30653633343764376436323037313762613364363835366330663965323731316637313335663333 -38653037616363313131623637626131356330326135373462636333653966366230623464613032 -37356634376566623235613935336638336163376663373039613962663936383336616366303232 -38643964626332346331323135303931346532333938613864383361356237333633666533326238 -64663132323333393534376138383262316131626464393661623439346566633936633638383431 -38356165316531346537386239373331396662333631366666353035616561343432333936336439 -62613738336163646336633533373237636631653838336636633362323962613533653565386238 -66633536336363623866343635623030323434343936623261303633636366353939313239653534 -33353137613662646139663831666562613134373964376230383430343239623161346238663862 -65666561396232303532306366363930663462386461626433616262333939396633666231373166 -39616234396639373638353333356661323132346434636138336438666337653436643535626533 -39656633306338643865376638343235336535646332363162353538303763646631616631643030 -35383138633038636334636134386561366435636665396466626431653463666631303733636238 -32386137326265623461393736343835623533336332326231343632343239346661343631353666 -34333565346532376237353364326361623839653164616639356665396166306663303363656562 -30636638356334343862626132626635646462653835333563343830613765623034663461363836 -64323061363233643537393534363136353731343630313138643131646430383039636166303534 -65393433366330366430373538396165633339393762326631663231636535623736643666303563 -34393032663566333639383632653965326264323361613366363030346563643333396561343436 -33373738316462326335646232316234653666386436303661393737306166386236393966643835 -35303533643634316263663961366561643636623563323236646333353233386532373263663164 -36633334316364663738343434623736323763343939626532353132643034313765353565306565 -36386338306533623038663762393632636465356362376438383236306662373336353764633365 -31666466343532643866393139333530383135333462393364653133643537633435626237666337 -33383838636163313862313537366263393461336239643637636564613366616363666166343338 -65356666633964386562653133346430663334323962653134386536356263336139303734356633 -36653336613961306535393237326337366630653235306165363532346631333135326133303530 -63633761613931333066373863626461643262353665346466316465343833363964383062376631 -30396434343334323761306365376638633338386662666339376233316534636265363431326365 -34346332623637656336343665626334363335616561376161393436333665316638646237613239 -36306462363138313463323930653838386266306332343836393633396663656538663764633462 -62386336353266313632646530633230626161396162366265383932653237313539326537626637 -35393362366363646238333261383837666534343634306461643935373333346335303939633031 -65383038643633636335343738326134326334643435366237623161663234373236333435363638 -65316266363736636566336161646635656630333035623362323164663462343434633061636661 -31633634353130316161616663326538636236343562373339633164633832643033663734313765 -31306130373866353735386639346533356364633861656138326136323765663764643466333433 -31653435323562353364313062303730653033363361613136323434623136613132653731646438 -61616531313435653239346331373137663065653037653834386230636336623337373062306364 -37643361633632333561313231633230386466303837333962363038663965363966646333343765 -30303166633535356232326534633532306639306164386339346666666235616231653865303963 -30636463613632336563626136643932303261656630343161653538303562333164636539646236 -62613835636137303931396163323262373936366331313531616634383764646666633963653539 -33633664363361663665346134363164663230393831393136393939633162363831353866633935 -33663132346132623233386463633563343132333538353134653663363065653362393739376638 -30376662343132323831666464336661633732636664313634633737333364303939316661386631 -65393233626566326564386237383566663139343434616464383535373438383835656634356662 -66613231613931386237646433383239376134336438663466363966323762323636336461666533 -63303132306637613064636236346433636336313062636534326131313334643435363330613432 -35306165646535623562373531346363363633393733653735306131353262373139363938333666 -31333663393363663333663433326433353564653638343335626362333366646138343266303334 -33396334643961626636636230653936393734623235316130323830356166613364366430626664 -61383262663131306161643939383363326461613065633364313130336231646330393538393537 -65656130393963333161613335663665396465316135333066363663316635306135386566643338 -62383765643837353064343262366266336463643063303831396535343565323666363563633062 -36386165363462343039353930623563353063366535326431376666643435613338333432303134 -33343330306363373263313837303033633962346337663739383534633830306334636566616434 -33323161623335333861396133393264636232313066646436373335623163363031383736653836 -63313265626639653561373339643165323663363437363833383063306237633137666635306431 -65356665353533343961656533633734653366633262346339333239363165666538303065613233 -37343339613163656235643432353934626162366530383964616131623264323562633538626262 -37373361303531343265336662636436346231363364323637393165646564633332323365333937 -65353733613630306165663832376666306562653035663733343166623435663937383432386364 -66333237393932396634653233653437336331346135356139613736663334616464343438363731 -62333931646633383636333266346166373030623437623337643665663662323665373731326561 -33336133383461613931663737656331613936616333346163636238643034636463353137353664 -38363732353437316465306662653237396538333536623165303438633634373662663833326635 -31633864313233333934306266666561313130623861653631616663663736303164323431393166 -62646632393861623564623733366635626139336231653661343731663434646235396239396466 -32623333376135343230623639643963656631663365313838366439346136616131633030323630 -64326334643033623562613263343166666236353639363334346330366539393534663965373435 -65373966376231326337656338303733396437323338656130613230306331653136343533383737 -36393339353838303334613636393838343333323132326531396365613537626565373138383361 -38623633353465383133636134323966323939376630346661396562313434303265666531363934 -65656361376666653138323234353237353161313934303236373038376236353532353361386436 -33613134323463623135636534333939623833346237333231306164396439376131323662653131 -35313131316433653131643835303238383033636638393130646431316239363864306333346164 -39326135366533646234663532306531343734313832396235613062376234306163613037353235 -35323937373536313065616661343931393037373563326435323266633362393831386461323836 -35666234386561343633663035366631383464303532363032353661333032333632366464336536 -34323231343661323930326330333934656533363031316631313130623032303630626531356463 -33613563353738326537613739373738383835653763313736346236383931653639396465386138 -30303666386331393730666561356232313335666435663239636666393164336331616338346335 -66376434396339313734383336363734323537313332393132633736326234316437373965623364 -63323931666536303130346136333966316130656531316232636331646461393061336634313438 -34323861396233643032616263663138356338376265653131613861363934623964663164346237 -63323636636561373437623836373937353163633832396436623735353765666535613864303736 -34653861666466313261303032666234356432353664366334623062303637313730636637356466 -66663766656136383337306137663930306636376363663465656332666131646537386264346135 -37656266663233383666626537656435396565653966373065376639383534333431333139353634 -61323361353666383137396237326334333732336338303431666434663563366431363966356262 -37313033643165666637646361313366343663666134346466636531383665353436343037613363 -66633530366532336131663533366563626662616334653935363133323966353738613866663466 -38646437623735393262303062623436663564303130613364386439363736353665623030636534 -30613632616231316532656536653933393039356332396532366165613033656439363934653737 -36363832323861373534373135633539363364653537613132363935636164306262633437333664 -65323639376234346234646165303037656462343161656461306635373162393733303762353561 -30613063643964333131613832663331363236393332373333333832613638316233626232376662 -39613734383364393666373239353634313765623733366235376434613935393331383730616136 -66346232343030303434393037643532326332306538646166663733316233643732353938336465 -65303239646539613036323036326137653837633033393130656662663836656636326136323764 -35383731396435623761303961323936383732643864303437353366366561333663633965383563 -62666533313935383063313231666636363039313632303265326462343232616366306163323934 -36656632323662343365316363303962326433373164303630346435363936623161363362343462 -61373234303435646436313232613739313061376430386163353938646130643732356239343338 -61666335313061343432393864373334326436366661316634653263313535643561346134643366 -33613430626465373939313034353638323766393839366132346438366362383437626335376630 -34383837343330393063663165366562336237633133366565363831323963323735346431626562 -39313539336565366337646234653966623731316461373237373137613761373539643534623332 -32656565663735363234663133643138353964363937313038643633356638663062626564363463 -65366630386465333863323038323066323061306630613138636562633864393633646132353361 -64326264653539626531366134373930323962666233313736633364336239633039383631393437 -35636532336664346232646138623166653637373966653536373237316636666435653065613034 -37666464356161313563363434613261366331373364613963663461306433393636306238653732 -64393730313031346534613865343063313638393365303039646164356639653966323465363535 -30346134313665386432633233613666316563363732353563633761663633333533653066303763 -31343633303633373136633430656336663164393936666338346230323063643333663365636331 -30333633376636356465653461353665623361343331346439393837363133346534343265313133 -30626262363138313839363738356139386538376631306461343132346332643334373239643032 -33653930653532616466336632386163396261366337366161386438323063353361303237346133 -34353434373436653034633537346434336262663136633737623931323065353733376162363139 -31356136316639323632613930646666633838343164373139653539326334383230333033356561 -34373130323134633366663366623739333862323030343637353333616130646663663864356236 -66663765323464643736373634353736313236653066326663383965623466626531376130633236 -30333932666261373138363731376136393366356431393466376431663133386337333432363130 -65623538666665383634643333363131396163373833346663323239653464616338336461333739 -31663432636637643432383331376366613132386565363531623233376339366565616464613362 -36653362623566373932626333316237613830643636343131313634316237393865373137306434 -37386463643638336237636536653363316132633432323964616532663735363335646162376561 -37333837656336356264363366626565616366646434353035616131623236613332613632373330 -64613839383538393736653435306631653665393062633534653631303762663736343639376636 -30313932323738373830336462303332643832613463393039336431366635636564663130396439 -62386534343632363561333637613538396538376332646534653930303037633063653162623232 -65366130383130356662656536323534613336666539616635613437613239306237326232376366 -32663032366433666532633764393630313739663066633530303332643262653431303638313665 -37356631346562303435383561636662303331333335393537366365323065326334646534643864 -65346464323366646638656664616430653761343735303230373432656663666437616564663365 -39383035646634313032313665323236613266616166646462613566343363386632666162636239 -33346136336231316539306431373766633234643330343531383539656130346162656663393638 -38656534323964616565333631303032396464353366623261663632643663656433336533306366 -38323361376230633263363035393334353131646235323836316136326664343837383634323930 -65303537386165353439353438323230306430353661353363366432376562636631396161653233 -65313233646462623865616338316632323539666162653865366337613830663162366634336232 -35353363386238386161306337666364623262323165613833386365623566303739356635313066 -33386531323437313963366638313662613433373139306466376562303136346264313431643532 -32346135636161373434663531373161613534353034306166653962376462386235373738663064 -61396633373939633330646133306439366662383031323537623233633032656131393337666536 -36663861303036333134633638336337643835386531336537663932613234323236323037366136 -32623033613832663464353266343338343861333337646533306337663662363930633739396238 -35323166363634303239386334653632653336373463326233326164383533373565336330353534 -33323430613964623336613839613466346439343837383365313366663961353839373831653061 -33636632636564363633326635383139386364323032393039306433333336376565306436633866 -38303536633031646261613335366437663032393935306163623566316361663235396332373839 -31303230313366316539666131643061306634643034633037666135643537623633616232393261 -38313337646438306638356135383963363537383561643733643036393733363331653634313536 -34383166663933306438333231653565646664616566653864323839663931356132306533356562 -36323366303930616562636661396337663838326337663636393631393239626265666465323533 -63633830653564363534363862356339666361333566643732633036666136653335393936313539 -33333264616134336366333532366165303661303936383261663832313738336633346666303561 -30666239653030313331633232653863393634633430373437346461383737343539356365303162 -66323631666430623034616639353539356466303439316664353866373531643334393030396666 -37613832373866633866323665636333666532656532303531326132666366643136646438396135 -61633135313137373562633237653762313437373838313561386137353236336434353962616562 -33326636653338636663623233656364343131626132376332643332353962326366316132303639 -63653665313261333963363133343233326130653434616537626630373364313537383931373162 -32306533373838326537326330306564646232613462623538323463316161363331396163646437 -61396462366462303030613536306563656566313264323064613932346337633439626161623263 -63353434306162303765643634333264636439636130633963336163386331373162343764383938 -38333136373630636531313939616532613866316239666138626663363231313064336666386131 -62316536306232313234346562313366663039636564386136643064346234353035373863366637 -36663033353065623836643364383832323436656266393135393733313361656135346532666436 -66666233316539306263383062663963343563633665383764336436663066646463346161616363 -31353363303061393530633764303162643230376462643038623862633064363736373437373763 -34373635366365373839636338333137356461383630626466356535656261623634366430613931 -65383335636132373262393635643564333761333433626333386534396533666163363435623666 -33646265623935323539333634353461396538383435613233653761663331343236306430663564 -38393362373333326566323639373065636562346434343437623137623934313365323038626437 -61383765396632356238646362396562386334656361323037323330633666326538623332623732 -31373434643737323464333337363737306362346331346439333066613963656338616139303938 -39323333636662396535393937316133356630396262333033333463613865636236643632653639 -33333037306132613166383031636566323235323733393832366538383233336263353763346430 -37356463356463336661383565643537663064333137313664316466356232663437663730326262 -64623535323265333133346265663431356638636263613863373639636366346365303639313937 -39356438636364376462376431366333353963656362623565326563333533333939643966353462 -35366534386232326634636166353965306362386165353733366165613963343032616265383630 -31386462653361386335633536376635623533333338333662643666343665353633333033343637 -66383537646633376133306162386364353663303239653239333636393866616436633037663162 -62623932653965613536643436656232383264666233663234643238333061333462663739633066 -63613939346534383062303764396334326133626235303331393861613035613839326330393435 -64663963396265393437356534313561313734313661303233363431646663366638663731316561 -36316431666235376636643132346336613838306638643935366464623534326133346536376531 -63316265353562663632653763383935646661633766346631343766323335366262326235393163 -30666330386463613835346531373136313039303264323938323139373061306461313662383633 -38653931306565666261373434363234343739366163306435663635386536336563333135346533 -31656239633835646136383365656534333166323661383833626135386432666465633236366566 -65366663326234303431386263366431623632326639626432366165623764353761663265616661 -31333163343961373966326563666132383964373531333036373233353634316236333633666134 -36303738356332646666386661383264626631396230336663393864346266643861646663323734 -61633761343664613364306131636334386538633062333130643134346637376561346532626431 -65616231343439653430633131386162613539383063313161353131373033613236316563366361 -39303664346231313335623261623631396535333530393238616161393330343239353030333439 -30646536373261366632653435643333666533386431656163326535363939303836386132366633 -34636531663232313837346239313132313037353164303661623237613739343137313162646239 -39373432303965663565613565313936343161396535393331363934613336643462306639666536 -36613866316436643635626630623533306162333737396535356638356237643461396435653733 -61633134303865356236643766396430303539646662343031363733613633613137386365363432 -37363632373265326238303761366465656137386263643361633866653631396235323066316165 -34323031306264356465636433323936633466393161376166336166363537636336383430303236 -35323737393866616139333866653238383963623339323265316235643666633234313961343264 -32373231626262336537633661336537353733623034363762633836363830303337623532336537 -35323964313837666335323033386164643736623835383935353836653830376265363438313864 -65303233303231326234393561633839303736393235633238326432363465316237626438333035 -61666331616666393366353433643731336137656162666162376161373765306262363537643537 -37643032623332356639646563313562633238313531316436303539306636393066323330613139 -65323432663830333536663134373732623361336461626432303033366232373563396133366434 -38343239313731383865353738626138376661303436323361376438316532396536613131376364 -65323361366162343236373165366531636662663432326665626363353434356131326339373635 -30666461353038326664366366656538623466643035373665323537666365386239623566653861 -35326635366231353938663066616535663930656265303338616465626564613031643666363366 -39323539313036663039326462656336626264376264356132353630633932613535366333646531 -36376364336431303135376665343862353031616430326432643932323937346166353064643332 -63653235303262383735613437633565656334653437306365383861653965373830323762353335 -61636235616536303663356565333735333631663437616334386666396364616664303530393232 -64393633393037663162626133303232646238663931383563613963616561656239393266666136 -62363261643363303235343439653731386135323731623766343464646261663939346132363464 -63663538643332326538386361326564303163306532303731383663313133343838323361343630 -31343362366566663532376238616562393934663966376438383632636632653763623536333732 -35626332633462633163393033333831336531376635303865346436306330643037383934646336 -39643865633432386636656363333262373431633738383435333830643361363464623638386563 -38336262376433333161353865303634356330613532646663313266316561326332383832646637 -65323833316338353164663233616138373933326635623863353036613932336537343237396231 -63613938386135666136396533643861383261643163616639393465396130313963343433653361 -64303132636439353933343662326633346164373239633739653662643730663034356164313439 -35613664333165306639323431386437366438633430326237613138336633653464336365666639 -35326633643231386336663835626463303864393934656564623537636138386536323235616533 -65316334616237643733613362306262623139323263633736613033313634393838386333303338 -64643539346435316165353263653964633365306232623864663365666535383762653635323837 -62663866383237333065616164333965326531306435333062353431623864633861386332396163 -38616533313130373233316634366161643334343632323934313164313266376661316330316532 -36653961633764333365343466303230626365613039303437336537366439323136613539633835 -33333438313464623331323332353835643734393261363366333939366137373939653532366337 -36613161376534623432396164373630353139396261663065306163653361666636613831613532 -32313335323632323963376332626639663132643632643237653531346531616532613839303932 -66633338396563636235393937373533383734373036356335343265326465343339373936663934 -34333064323839393964623031396638303039326666376630633833623933653736636234386462 -39346363633139663534653665653864303039343332343435326561306531313864623132353635 -65633366323463613936653964613130396433626166306463353533353464333065333930366137 -34653331636134313038643134353739353732343033306161616461616239316633633035373463 -37613133636265616462626437396332646635326632306535666137343765643433353262303037 -34363462306663386135613933353636396630313466616231666637363331346432393061393763 -66633535343632613566326139646466313831366334323631383739313739323737356565323936 -37376535633934323033386366316665663035306634333961393033333365376561663865376432 -37666231366139393139363534323137666133316336393862636262303136373830643835316136 -62386335633637616666633938353966353935373131613763393733643265333733663939346461 -65373333356161313831373139313330626264373933613531396364633065393538616133633664 -31333264636536663263656365316336303337303962336165366661346135613931616130653962 -61366665366438646565626535353638633538363535396135313038663839393363633539633539 -33383639366534346366656466633665306630633337646264323134613631653033623637383239 -34373937633230346234613336356339333935613963373633306265386661316435653864363166 -65303630373631373636303337643131373032366535666261353962316137346231633238623532 -36366631643431306539666639663865303330373066383836646664646562663639646162303165 -39613063353535326631303166316533623663663063326532633235363865313965343737306236 -39376531383266393062336538393132356337616434383061396532663965353833373566616537 -35393737336131396266343237663131313036326465353435653566343637353430393961326231 -30356365613263393266663430643534623034386235333335643062623866396434386565356330 -64353436353638643030396135633130306338616539313238376338636637353665363839303665 -34346534333865666339633130396436316338303462346161653062386533396338643461653462 -30613333396330303763613836323531633339313735383033386464643836376133636238393234 -63383630363437336331373661343064316266383637623964306364646465316166646162653464 -63666238346434616538626533346161383461313162366438346632383762353438653431366435 -37383965326436363961363837636236646131326464393634316164383466323630666435323331 -66393465363234386137333064633238656536386638666433376237356632653865356563626636 -33623835393539386438373237636136326166323433643233643630376436353639373365646632 -66306332343135303165663434653131346536663666643830643866356236323831336530316536 -36666238663033313162626436346438613866663432653631353462363364623839393935613430 -38633361353066336137343535356133353935336633393363616361363766366632623338616664 -62616364306666643861396139343439373130633732303265396364613562663831616166333661 -33323163363636313136353830316435376438303764356361613231663631623134383063633333 -38643235323236303263376438346465356636646432636134663462393035636330363065303336 -37653530366136333661316532316337346462643061313162643034353063656161623464333035 -35343566366363633839373864656535616337663163653533346233306532353162633434616233 -66623431393065653432313637623565646538313338666431663266643337323333616164366637 -66303262393037313564333231373831333965343663393638646639383531336131306532633639 -61613763666630353832663036623062376462663132643361656339333633656135666662616664 -31626638386363613037376638656566313238653137353163616537613233393134626231376237 -61303761643530313437333234646130316666666236396661353730366539633530646532386439 -37636437656561393837643364306130666134343435646663616631393332613864626362356437 -61303938373630333862643535386531336466633430346137666233633062343134323136626638 -62306534646637653435316663313361623563356533646464663166336663613130333466333461 -65383562373966616261303530303230346138373962326565336331653965383430353161383436 -62343462376161613233356631306463333938316634333562316638313562303938623461383331 -62313336633237613138376361623066356165343231656136316338346537323563633333623532 -63396339653663313666633539356633373664626165306237643031383639626239633338316537 -33633438353034623734316530643439343131333439613337666363663061366336656561313435 -33616532383835633561646639303364356133313839326534623664303562303638633964353964 -63613265616332346237616236353435666231356633376234633132326635353763636634373434 -33656165643435313535366230336466613839666333373832336431323433306566663932376161 -30393935346534326434613431626438656464643336346633653538666330303539303235383863 -32396564663538613362643561343833623138336666613333636337366330393935653865366330 -30646339393261633035363064666365656165663931323236643763376262386237323865313036 -31363630323832636635626633656237376130653563383137633364326166393835363961623933 -61646365623461613863653536656136623031633664383632313337393232346266643932636138 -32616363303432393461613335343337306133666563326237356566316561313338343662313435 -32643966633333353730303034656264626637303331373561353235326535343866646231373962 -32383138623561386438303663636139396130363330623433613763363165663939613031363837 -65376365373463383765323437346432663533613230636564663131316363663336373464653139 -39376230366137376132323665313332646437643364323833633036643133346661353465326332 -37626565316531393232623139653033376166333630336530393966366131313632653439336365 -66613739333132353036666333313537643438366639343333613933376139643235656337383562 -62336462366434343963613762623362633934366333353761343235633131633434376537313234 -64636234656161306433343233396362646630336535313631363938346539643366623732306164 -62653961313664396264376161656230356461333637303730643636366532626166333465613936 -37393132303863396235366563393837363038656536623665653737626639666233326164313664 -64393233623532366636316437663063613465636166663664376334323938643465323165666662 -31613734373464643366333664373433316662636337376331663565346638383835313739623964 -66393236666566636463666561393332663464373830653533643936653034366338313735393131 -39633765366633316562363561323863646230663838376363366462356533616232373833663930 -30643731343839613832326265623765363138643061656437386232383562333036646137616537 -64326131353239373433306265623734326266336261393864636436623639376638336131383431 -63626464343438646438396531393334383339633930393431313630376566326563306464366339 -65383433333236343031306163643036666231363832326466633361313136663830656331393661 -35616362336532383164383566343165313538396336373565643961616433316133616337313537 -31336363653739656439366136323034353438663261303338636261323164643166363464393164 -33633665343265663036376438363430316363383964643136623732613833313032356663353938 -36383564326465346338333136666164313965393838643663383536346363656338653462646336 -31656566316437333835336461663131653132386463323761326332333537393836396238643338 -66646632346462613035396239356131633764633036383338613130363964313336353331376130 -38663536313562633630396135393562363831633865623337343839356566353139663233336239 -65633133373130336530396265313632373562393366653534633839666465333936306234643962 -35313638393766396563356537373965346138316336623131613661343531343437653563393938 -30373736643038653436653134313039626161386338663763336463666234383236373137346464 -37626132373462353739636536313532353365326639313236316437626634373039333336613831 -39623061633334336565343764323139333433303132363636396365373661393533376264613164 -62353831333733643461613732333133366663633562343935623963636265343734366266306261 -65633664653431663632613861396237616664373131656333343366303039643336353131396261 -32316435373163393032646362616261646533643638326462333432346635366330663137646537 -38336234336463303465363065353433306532636466383561646634396665313638623032353832 -37613465373133386136306531373538643639366236393466626666643066653033633739373565 -61353635383164376165316462343631386533656436656265646632303138396563366631353962 -63626363626131343066366137666164373635396237383165653663363437623661336233306337 -34656161313065353766613635363732636463613339323633616233626531333334383435383561 -31663766366361376432366431363461633739626463353563366564313635343466323563656335 -32363563663065383932313037393831366565666461353631653132346334313031386162313962 -65626636636666356664373764323336636463663531366433343534323163343764383965333364 -36396130316263366561343263343763363732393232383462653664363965316435366465373639 -36633466393837366330633337636333363061386562666261623564356535306438353039313234 -35383463333835393561666563353161303132653865613061656135616633383961353062346661 -31333934373162656461663231663235666539313636653061323961636534386138616636663035 -31343961643634336635646536373331303438366231633561666335366634383039626238313731 -63666430656165666663363032663162383135353733316566306637356461633166623166363931 -34666632303233623435633433653430323831313965366431363432666561313139616561346536 -38343037303535363533666336396133396535626366383432366362393064633266363436623432 -38373430613231316438373034653865626336643736636538613866343366353163653834336133 -64376565306564386662396262323164663463313364663866656237343363653636363966376466 -64656634316433333862666665643138306361643430653436633232653631343439653266616231 -61313639353539616538303538313462333837653165636266643731316265356238643062373632 -30376661383132333630646663643064633939373639366232333137383364333734666562656438 -62616630386339653930303438393136366565386533313536656666313034353164663732313963 -38333832333263313135393238356264356538303138363866663764633538393432343338643963 -38646362656261656561366661343038343964643237656263643662363862396335376363636337 -65623563336163653461313664666364656465633636633334623530623335646266363961613930 -64653363646138396233653861353365646463343934336338366533353933393732353633343364 -63616231623463356466613063656561363261633165653462626663653566396335636366353039 -63336638333735333965643233306430313736316130363132643534313034646366316266656137 -61316365353236613635356237666339363663333863383735343631363534373766383339326165 -62316137343736393638373162613635393961653532666332336136663037663966643831636638 -36636634353038393462343361316465643139653761353663366663313134616566383266613332 -36373434303766663035663339336563626330383361663565613962666236366339376235313333 -63643038333338393037623839336533346133386334343232663566633334373937373761306238 -62663361336564653166303666383164643231336435363361303137316632336363343939373633 -63333162323565333932366365383265613733643136326164626163336435653561313161663536 -32343635643162653037323162383530653132653835313262363761343133613635333133333437 -62323635386137376266363061316562396661353931623165383230383763323739623265306330 -32353835363039343535303135613932663162393730366435613937613038643333313562343631 -32643361343663343739343062653231323865353933623930363461366235636466313964323065 -34646234666338623061666564333337613566316136316336353832623163663736336666326162 -34353464336533653664313764373334343164656566373038303532636362366130363831383430 -63353361653166663235326339366237363834356536323763623135363337356537313962663865 -31636135643535303563666232313963333230643632383437366337383738356330323564333365 -34336562386262646433396561326333663261373539383365653664373163373639353133643638 -36646638353937313032306363303062646666613763386565306536366365613032383337323338 -63643866363133623563333661373331623561356565656364656535323637346661363736333563 -36316461393063643062656166613734373263346162663134326230626362653537306230353335 -63316432306463393434666132326334643731393563363364656330333663653765323263333161 -64393630326631363238343039303566656238613932653866326361383039306436346234366662 -39613564643732393037396130353033346163313564643762393331306431363637383761396432 -37356263313837373163376339363566346665663231336432316364643638383739303162623436 -33383637323366626566663236303965363761646363356231306262313366306264663436373964 -34643839633037656638613563313638666633393439376364396336343863326239336330303065 -38643638346465636231666566326562393732613533356538343964386332353661306439336135 -33623562353037313739386539353065353037643035663632633765646235326532326133353166 -66303234636139363738366566613131623133316231633364393162373037316639343536653837 -33393763646464383764653333383837653066663362626532373763643661393962306330363765 -65653464393339313466633163316562633630336439393737626561613532316261643165633233 -34643335653735613666383630353066393666363733623633643636353639663937363165313166 -31616237333133386461326432653735653265396562376635363433616238313835326462363731 -33353962653366643664626637353136343330343233666236653661633465346661613735333333 -61343832613365306363656230356235303565623463386564663063326337663337396339346365 -66393838363961383035303562653130623636613139306465373933366337343834656632386464 -39393639623530633639343535646133356261653333626639383962316263663135613737613233 -33326462303865343965353238383561613666363566643431323764356563653935663332633634 -36343762666636323638623030343731386131653365353436343262373961653631666237633266 -61346632366637626136643931653464336236316164303638653063303137306362646565306637 -34316439646463333830613064353961626537306464656633646665663930646364346336623236 -37306564316430373165633562613834396435356266633239393336613665306432633061643064 -39363837653463383234666439653265346264343137323765313431386663613830373832356332 -63366430393162333632616636326631376134633034623439343661396332333064343133343639 -37343863663130366238353037653863656339326362336432366465383632616231323332303535 -32343361356138643262626662656230303763396564316136653030353136393535626662366264 -63646463613037343432366161393935656430303230663132663564376435303833653933656139 -64386165353566666565376635643437346365643564643161373332653063636131353465353139 -62636264626635373132313763333565306664376434333161613066306662353563393731633966 -38646435303261303263333766623638386134653433666235646563336237326431346137386563 -63356636363232333133353434306634376635313634616366376463373365366335373464343233 -30646164383736386432383830366132353938636364656232316261363464613031663965663536 -36333037376536336336643937623930326438336539386462663235356537653231343437373337 -34613733333731313637366266633462336633633833343035613333333232303263636437333532 -36613663656338616538396631613032333066653765363334313831636234623033613336346233 -38313062643362613666643231663839613539393932346433623262623462643663356530376161 -37613665353866306131323431306237376663303232396231626234366532383162356562613833 -36613665626631376539383664303430626630313536396132316438383335303166383930393961 -35343833316139623131646237656439653634393238333133333231333836333335636637653966 -32383932356365333537373162333236633631383536613330656534356437343036313639366131 -33623632313234353165326534356331323239613066323664383336633265333037363066353962 -66656539303663333363613266366662633763313130336264653030613364653637326633643065 -33666333363735656264363538643238643831393037333234303961346238323138656662666335 -30303230303065323363336266636265353433383234336133343766333838323430356235316335 -63643335653663313230653539303136323831653462333666646330616661343135616637303037 -66323563646436366162613030316237383032373762663133346436366431316664653131623637 -32363035633066343932333362313463666434356161656536636162663261643862666537633930 -34366433326534363933623732366332353366636164313639636335326633316466656164396265 -37373961363335636362313935666233613064626131643439656661343166613462346330636261 -64616566376436656431346338653132356638633034326265386162326336613230386337313437 -62666233356439633331383234613535323334333961366236373262626233363637666232363262 -65613365656437333439663232323066393030643939643663393337343134653039643361653663 -66373935666436666336336263643462616632643338653664373432363632346163396331346364 -30323136316165306536666439376138376130343132656661613865373236643833663438633062 -64616135353463326433653531333134613263626635636538376134373164376136663365643337 -65613835396136313236386661623266663133626136313135623138313732303334623464353735 -66623432636265333933386264663264666661646264356262346535623362643363613735653162 -61386361653664626337353039613263366439343636373666323663313738343939326565343665 -39386530376362386466343137333061643339356339303564356365356434343936396339613534 -36346462636461613363316665333034393332383533376230326361633765343138633061396134 -33333837356136346562653536373663336238346231303139366462333138326232613637313666 -34613661613561366536616365636138623734643132643034336561366337336435343532366234 -33643630363635626439343766656638396537623363313636316562633762616263353765383263 -32643838643636653361376261353033306136376332613438393265383263613061373063353637 -62653536643739663865633166656634663832613538643264343661376636643764626631393666 -31333330663563353634363161666361663835636132303730386533643861383665386231633931 -61313161613264373834653137316362373363623634373938306566626662653734393037316439 -64326631613461383337336561633030353365306164376439303266323537373663623732643965 -65343231633561633961633938643066623335653035356163356633326239343964666266623931 -65626234393164643732643439393261393565323765626233343532633339346237393735613638 -36336439656532666534326532376165643338663966376666366564636665656665646231303965 -61323066303730636337306133336638363666663632373463396535326162656364323365663134 -33316664323338336562346238626538383638363339316432386262623362393634303235346638 -64623633373632376461663737346332666365343263653435323039613230393363306431323931 -64376437333333313437323532613362313739396431373631383635316461323639623337393530 -32613233663161303264633330653438336332336237363737353538346235343137643261306261 -64623838383464663939346439393535343631373238353562646431653565653865616564316538 -38613630336531333663326134353438383437643530363365323863376236616337386430313263 -32303162393965643263343762323764663138353538666165396435343730313164323536653935 -38623132366332336365643566353631646434313730626462333934396362393439316235303431 -62396537396161643839343039636636616139363134613834333863666236633165623631386433 -66646435343834303732653239663037626238383665393363386161353035653631653033366134 -63376238383036346236396232626636643133613434333065383762343662636436383030356262 -37343364306237393030613034363730333639373439663133646439316237356335643032663634 -35373761306333393432633630383932313535326661373238336337373332386133303664663464 -65303539613137613466383435343066653434333132613161636330343363383538343531316233 -30383236393139326531353132376165396361346562636130353065616232626237643631646564 -63643863636163656437346332363461323930636463653261393262396665633331386536396266 -63633462326466626265643866393638643135636432333161316465313235346232323462633562 -65663563373137643165616261303434646536313132383138303763363561383133386635623566 -65316365343231636330346437303066656165353335363034353165633634356434313639333566 -66393433323364343232313030623938393639356333373530656633356134366137393436343832 -63363763633431626664386136613831326131373164313636373438656431613735656537646637 -65653262636339336664316133383665383764383863386662623830363731636235623565643363 -34623439323032326531626635333437656163326638346166376135666635393039303338313735 -63313161663261323839393462383138373532313932616631653933353635653932376462616539 -32313930663234643631343265373366303431336536653366666531313434623733373338373535 -66343032656339303334313163636137646633633761316633353131643533626239633663386135 -31356130326537373438613039616632353231383961666131316165616138323962363337336237 -31353065393537623066356363303461616238326566356164663833623263626262653031396131 -33626630336366373736383036316434386433656131626130623831636536636433343830626435 -62613639313062653531643864386462366238656330653435636636653935653437376339623138 -37373565343566386635383962356337643035333633653166313033666638643039303765616238 -31373137636263616531326437623838396164346538313462343137313933643534656638326633 -32393264663664303266636334646138613130663564383936396439383162623765306533643363 -37396438313730333530613539346566353030636438623237336564623962383766356165303433 -32303737323364623838366639333161343162303933396433333363663235643839623631646366 -31643766643932386661393430393335353537623739343039393730656662643964653339363632 -36333661306661303862653431373536326537646563346237636233616266353665396533346265 -30303439363261306433376663636137306332393765333936353938303938316262386466323862 -32633765356463623336396234383535626235393432633365373834323663386639643031326262 -39353236313762313038323638326235613732333732353239373633366636636236653231333335 -64333438383439303834313832313965363830306339333865363634636234363839653933636266 -32623933346632623135306138613062313263323666613137363032346165646361356463333766 -64366665626664333436656334663166306339396465353539626136393434663662396138643136 -36653936383461363138623636393530626662333063646366383461656263663033386339393238 -33386330663436643663346132303935373965646237383337363938336632623435633264383264 -64626638653663386561643366343731633630353532613532343162643862383165386263643663 -38376237353833356539646362303739646234623561616433653431306265346636653135366562 -35326165303837323964616135326234646530666263336334663730666637656337636233633234 -31653835666131636633343430653532613039373532633836363834346366353363386164373635 -37313635323337316363356637356435373664626430643830626130663562666539386561353562 -61323537383734356137356236323765663862386335613138303530346236623562303036306335 -37363661323531303661616261316563326136633534656339616438393531613265346165633039 -32363139316364343932653732393965396138613065356661666331333766663938666637353236 -38323934333463663334306134366432623731323432646538386237393031376164366238613933 -38346365303965373339663338663834623235663139643931626332346562636539303765356534 -33393839303430383838386466303036373136346133313930326331633233623931633264653162 -37613536653934646562313737356565646661356435383235366263636235393764663964313231 -62643832633865313232303266373632366437626634656337366631643338666635333838666565 -34613233386631306338376437373263313237643932623731386262643036616363643939336563 -33326536653834396133383239643666306263393662353637643566323435333134623438323362 -34356531326535633437656666636231346362313434636566646634366166373431643239653161 -32346263626166313134323063383739363137353233633265323533633535653636303431366236 -62356437343231363838386337313361373432316333303536383464623430663763613532616566 -65306266363465323632636163313762653939376239666134313766346538396562363866396365 -36626534613736316137343431643630666137383262343936333836373933666666613439333833 -31313361393234626538393730623230663962346432613066343838303135653562653762393733 -63653139366634366133613433623563616263653761333936393234383061633730306662633038 -38646531613032626662323064613066393731346661623866623637303036383739653830333264 -31663537303539613439636164383130326661353334333036646464333239313134623338643631 -65373132653934346363323832656634316439626231653563666330323930353030636262663635 -30363238396664663335356437396233333866653266356563363961343162656235393634613331 -63633863646632393230323233343636336364393131646362346537623539313965643565343930 -65306631353935326236303735323631396634653961306431663966383934343730353336633263 -38356634653464353061306134313437303239613237356139306535643133383362663161643662 -33663562393762353236353664643261613931613132323764613163353765376364613966333139 -32623832613135326163373733653030666261353262663033353264633037616234353166613639 -63643930306565346233653463643031626439633764373432313766356637366631613166626639 -31663439373932643935326365326533373365376330646661383464396237616232613236323364 -33653338336565343937323263363330333732366334653535323238353531616231316662346238 -65633264623565613731616431623535376431326265636537636337366162313664333437613732 -64613663636238383865366164623735666433616538316538646531323563356636343163346230 -35623939356564646264613561363438623630346461353361383131643165366165383138396666 -66356437643731616164663138646430626435373633336362303863353261663437666433363937 -65613533303134363331663439386632633762623930666337363862313632313235633463613932 -35353066303439393033386265643037623537643632663362633361386465653564636634323164 -63633236343936303666663665383238383432636435633161366566383633383464623537366235 -33376134633431613461386535376563646663666639303235346631623632313739333333333764 -64323231616262656266623761613636613638623532326631353633333937613862653565373531 -38336238303166353762353934656230333030613633633538663062396531336563353331353363 -37343133326163333437623730393039323933656362316466383130666261313536633362656438 -30313831396234653637303937313033316363623466393534336233396537613034386235356435 -66343832353538653033343933633461363961623038346238646536623039323530643165653734 -65653232366632353431656161616130303935633839353163306333643962653539663434306537 -35376364623664323136323238383364643666663962373264346661386266643239346164313264 -39626234663565343236663633303361666535363562623630393933313865663563653935326634 -36393162616366623539666535323635363130306561653163333730626261393735393232636436 -63373937626231663265366536323661643137653436333937656539313736626438623363376566 -65373438623737306331646531633065376235353532346239343764643035393864633563383866 -66396639633934393030303934353432613866396435383537396361333932663036356432633231 -64313034616535633236353632656561616134613266626137656634646262386331346230623764 -34376537356231326463313863633931306632323762386231613035353735653061643764366236 -38316334663764616461343363353837373861316131303362306238396631366331663064323934 -65643131613865653732393032623636623633343566323938613066323165313935613336383064 -32656663333765303461393338353938613632323138633066653039623430306162373162656364 -34616233303736646536353235313536383566333962303236656632653230376362663361336165 -64323537343031323364656466633234636261626431616532633935616664313433636466633330 -65646134633066373066663637323437653837383032393063663631373138613166326233653166 -36333938626137366430646338643637626237623332666265653232653864356364313234653335 -38393330656164323132323230653135643261626239303031323638666132343239336632616464 -39393232323962396638353138373033356133373537636162333138636637633636313766373336 -63383863353262336131663239663538643536663061646366316134623235346364663431323138 -34396538626635323738346439643065616539653437343734323562336430343734383639383435 -37306337366239316464343030316138336663373736636335663539373338313336333432613638 -30333565613934306461656232363838303431363239333366626663326233343330633138636364 -33366262633935343432653930363830643439313632316262616534643963396138643332363564 -63666137383736636262313835616238656131643263336435663333333062373832633330643839 -62626238323634346661363665333230316432313332623931616662383530393137323363363932 -31663162323430383438386165333934616362313532383236326565326333663634393737633737 -35643838636361316464626163316134336530623138636535396233626636346136653966653061 -31623938383736386434626362363631616236363063626233666232376262326634616263356465 -33313934336661383365336633383732306439653562333034396237366432376134343735616532 -65643338323437353539326239666163383365396263393336396133353530326136373061376339 -37646663313430333839666663666161633661653433663838373734623839646462383030643563 -61303764363161326331623066306462396363646333356437373463353630313761396262646465 -31316539393439643164396432333535336336643564653436356431373065653463336266323035 -64626165313465663032653338343065343630333834353635646530396438303236653563396632 -33316632323337376261383639366332313863383038386539373761633233376662303632666533 -38393164633565336566386637326434653233666234616163323064373164643938643065666338 -32313763383866376333333432326232383531306563356437333536646462323430326234373964 -33326134313965316532323138356235643436623533633337626166373864303038316132616439 -32656432626634343437646366616531626265663934636465313463386532336263376538623236 -34326532353331616366363232626565323034346635616462646137373330653038636362633238 -38663966313839653466326133353066393761326166306138636539363337616264623032343663 -36363637653863646261383731666664363165373732636534333562306466383965663031633965 -39643139636461303865613665656362353965346134373961393963623132336130336562643863 -32393061333233656564626634376537663062363064333435643134633637393731313733336539 -38366539323463643039363164343839336164633066613835366465316665383537313838656133 -61336161353032623439363936323638383732303334643131616336313936373036623361333635 -36366438666564613330626431386539356665623264666464353537336366613064366331656235 -65643034366130373736643861393763663633303463623735323737623538313265616437336566 -32396463383434363631343863353364616139363566633237613931656532613435376264313365 -34343337396132333637383839666162373966383533643564323837653336656431326566623063 -61313066653139376432636230373839366366373261386239663438313662346461643634346266 -61343034303139336337616136376237306564613131343333363938396438626135636138316131 -33373236396265616630653166613135363737646436306235653063633433363034386162316331 -39363466376263326664663337396366633665636536353266616633613738383461363536366130 -30353663316135313132653538366463373436336665356538316361356463393138353662333634 -38376237383833363237313037313538623733666435356266323563343862313633373234353965 -33396361386237666561343433386430343833373361376637323730376339303033376265643735 -35343838666536393530396661306561666238633261633663336232323866646166376366643039 -33643734333562646364346135626635653565613330636635343462356561643863633936343632 -36393764613839343632653966633662323265616436303832383434393937393536646534303238 -31666236663138613736303865646537363265326161643933633339386165663437366164643932 -37646438316330613834306639636438303735313362333637623238613163373139616466383135 -62646438366239373763313930616138633332366535343466363330373632323665376366633934 -65666661323133303838393261343431373565363339636437616132366163373765303630363431 -39636364306238306333623463373733396335653565653632323536343034333031386165366131 -37313335346530396161363432663662636361643033643731663235616164643364623961326338 -31306632393262633564643961376464633266353136383730616133326431336663616362646663 -66343537363238333536323839623764646263343833633830336636386664616631303133626430 -36663338376636653965353664633336646364343534306562393630653561333637323066643035 -37643061616338653164643636353466323134653731313430396637636630653863343063376331 -36356261386331303035616639386136616336356630373137393137643432656666626232353237 -63653838623530613034646233633866356563333332353064623463613938653362336130636462 -64386137626663356430626165333666613036333838636439663732353963303935666566393932 -32616330373233373833646332653764373236363938663561616265653561616633376233356435 -30336636326238393135323339363463336239376431336161613134353835646262323233626163 -37343036636533323361396134643936653136343535393962666237623131316363343038376437 -65376533303135616438386131613930323036366635313836363634626139316235376261353639 -62376265343161313637363036666336356338383866366561643631326261616231333766353831 -33376236373065376338376334303763643333343762373766326637636363623365393739346233 -64336563383233396139326436363861363663303062326335663537303134636138393635613031 -38353736636539363062633239376237323737373936626662626461383862383965313264386232 -33363930383938623833326566303462313333663161646164393430613262616363353265383033 -34623365653235363839356534653830646537363565366432623431306637326462326662363164 -34313164366266613366393566613839333839353438666536653038623233616665393831653661 -38386530376331323331663338353034343961383163336433643738653738663036313464383635 -37333137396365613236656135356539656237613436646430333562343166353231363535663735 -61636662343165333139353462663563376264373432383663313238396632313437386338363935 -64633236636631653966666434363361353937626337396366643739363434646162396461376265 -38386632643838313437306364646366336166376430393332613836373661383436633735313137 -61346161333662323738613632343234633939326638373437396465363334303862373261366666 -32373730313030653765363566613433336438313165646561373632366632303530616530366364 -36373331303830323963623632626232373631353438646437393765313331376462346535306333 -65373562333365666438373134646335336333663130373737623734386338393039306130383462 -62396561386163386361353034666161386662373637366566666231313934353334636434396665 -32353661356261373638633331393435313862346565666263313865623137373965326335383035 -39353137663564383332393734616266326666373734613634633364346132633932313064303030 -65653963393062323034343165316338326162623536613866356535386364316661636637353036 -36363933323831646461343533623331623064393537306261323639626265656561656664643236 -39316565353766363664616434323964353932646533383961326132326639666661643964613062 -62323332653461616131393564386334333239623639623237366139366138666439623362623235 -38383939663465376334613039613066653631666165353066373330616138393632363765636363 -65633831646334303838346630653463333264613030623438616339626330646134646431363465 -35373339316332643130363735376566313261613363363766356539373665393565363161643465 -34393931356339353338633032313432656636643839343862623863396165356265623437373530 -63343564356430373133343038346238656130343932356633393166633763393437336465313234 -33613236646238366339313532333664623236386139363136303932393963656561396563353138 -33303361663839666636333635313631393064343732613263393664626332653030626361656433 -62663632653966303031383937333361643732326539616165313061366238383864363364353538 -34653664313831353434396261386335333561613931626161623262323834386564666431646338 -30646363353039616436383637663432356361333561633665613631633161623138663730323433 -36383435393233353261636634333732316436316164316665346131623939653763666638613037 -34313436393530303232313462326133343635346164356331633862333236646335376362363437 -35366332363030353832313066336362386235376265366338643730393338303237393462633737 -39333932363565646337393437393062623661303364383166633461663630383933356539333566 -32356665623732313861343131333137653962613838323036353731333363616330333337333163 -63306664313437333264353033383531376565633830613963366165653262353935363139653735 -31613435666433303030616338623831366535383237646136353339666431386231646633633961 -62633234616263623233333839313539353662373432373331306338393633396530313935303638 -36626635376435353832306362633434333832316539653637356130336461623233633966316237 -39343664626632303334363338623864363134376331653531383539303835636166656163373139 -39356432343761633237346265356137353261383433663830383834336666396561313664643034 -66623863366662626564343630383061663932646438613830373931386635613039383266623764 -66643831383937656366623632646563323038653138653132336462363733616130376336396134 -65313933666462656633396436346231396532653063363430306436373364633465393636663165 -66346361616262646531646466313836336133613866323366333738653364613461643033656664 -35376332653938626631393933356262393739303136353537313061653262396363623061353361 -31363462636162313438333338333966373539356463383361646663333065336363333938663338 -30656161313766323663633937353964313731336636353437653263373432363331316433666365 -64353866376232663737666636363331303431636361316330306635646137396362316532626238 -65376134353161316165663339333536396430396231343533396234373532636330653438333734 -66316363623761643965373733626631653039646663343366653364356635653839343635616563 -33393739643938323264616436663336366230316134386564353131633535383061373562303566 -34663263346338636661643034393935663334366439313539643337313134393862663230373661 -30636665333366346130346631356461383535386236333130633838313361613937393031366362 -31356330393038636437326333326364313766663734333266653534663330633732656362653134 -62613537633232306233616337633036333662306339376263626439313864353737626163303331 -33636531616532353438386432636236616139666336306666316339666337623931323138343530 -64636538306134356362353033656336326230623462363131313933396262313539623433353362 -30333038396663383138636636616531656464393730303839356233383961393330306664343231 -63643731653632663461356265346230623762623163306661353932633230373536646466613532 -65316230646333306134383839623763626634333539366136383430623537643361343237353466 -62613436656563333061303062643038643537363066643237343765383737623136306363353037 -63633134306462666665353935373663343765363539373438643439393638333835393136333462 -36396665373333363766323264306164653364666235396565373666623363373231363532663664 -33326331646564326533393761313464323966663466363638393839656463323438383638396264 -64343939666436613836633037663336376332663766376463626430396261663839333536646638 -32643539663037323638346566343037396130343434306265333534383835366165383233393936 -37313838316166386666386438343838643731623866333164323931613365393062643233663230 -66666634363164353762633465313364333735386134356335333761383764613963396462396162 -61363831336338383630646634363830393766376333316364356438623530336363636333646630 -66643039346363326337376237653563383765666238336232616432346462666162336138396634 -30343532613265333431383861653933386235666132653431626566646566373330386565353565 -61336665313861383866643664366566613465353730343838363030386234383731303439396430 -39356662303133303235616339306563643834346633393037616337653238626335373166633238 -30663562383436613436386263633530656636383638623565366333633536633064323566616164 -63643737653831303666386138633235383862363361613262636632313033373636303939613430 -63393732303465323139353534323936663631663237376331343462643539323236383435356231 -38396266386361643333373461323631366465316364646531323065336161623530323032613034 -31326339356538363866636465343363366535353164663533303937303134613866373466386432 -33306130343134356130316466353765366163323135316337613837663665323037656264393836 -36303833666633353038666631613364396335653863626663626265393435323035316135616666 -32643338653637653831613434346664313432303035323230666134323662303562633631623036 -62646661336332663830636164363464316237303664313862643833336238393236643134383836 -63396134633661313136656465393864616265303335623031623266383566633962613737653239 -36613165303731323337373363346462313337633635376132326634376131363934636633383865 -31393766343133313335666263633338633331383231613532653533666632653534616134313436 -39643163303830626239346334636635323966376664333037366230653066393538306664613562 -65613835373935333663373533623938363139396161623732313032636234656534313362653335 -34383339353237363466333463326665613736336131386332643939353139666335663035613061 -32373833666466363063386539623864333065633166323562393633376636666564343434303036 -32313964373835323935383738326331343864613733373461663161626338646461303064626137 -61386534326530316466376639646130343931383636323461623564323330623162656435363430 -36336131313734653139313531343135313236326337373866393334346132393838366664626331 -62386632393263643765366237616533636535363061393834363633383833636132323236626437 -34323662396230303566396330623665383965613766346361616633653730643335633764666661 -35653864623335363030623933656632373332333136373565623537626166393165393062353339 -37313564633162666263363862383437616166623534326361613336363763393732636533653365 -38663138656162333531333330383164623334363130663961356664346135666336656631313735 -34323934356132326336346638333737653534633066636662636335353931643261656265363035 -30303035323430326138626364386339373966653966333130343465313134633531633439656263 -33646666363730316436383734626266623736663339333933636365616666623239393835396534 -33626236353561353563666532303161396464326266616530623237396234343837333863633930 -66336137383036366264323062656536666338613265613338353061323334623265313465313135 -38636463663561383262626364386461616237343563656462363332356536633136393661626663 -64653531393630313063343332323665346332666366626339356466653736303764333462303661 -33323032346433653538363162363438306566643232353162333937363731626261303366353466 -39343761396165633732653137396363353537653137303432636366346236643136623461316666 -37623635343636316562313364643435373733623961633666616337666631316436303736393661 -38383564383463393133633463333939323033373164353365373230323539623865346165393763 -38633831333639323936336261326534623032643938306163376330383036663763623930646166 -36633163346434363439383939636565613231373133336331343630323030323437623139376661 -32646239303963333634623264643638373234383864303336663563643638646663643634623533 -31623064386431623561646434633730356332356164316262323138376232613362323732383764 -61613538616366646166636462333131363135646364373932643930353038623337383064333639 -64636131393166613262663338643637313533313762636339663438313532386239313363616236 -35663833376365323438333664333061366365303730633137343438303239373965623135336531 -32343462353363333137646431633664643838313831346333656163666662376131616666616635 -38373862343061343939643864336439363537333664383564636463363639326666306165323363 -30663865353065303438323033356238383832646634346131366236623463643962616539313161 -30396637616464306531346537626233353035366262633664666665333334383262336164653366 -66323162633933373130393337306161313761616337336534643434636665303435363861383863 -37383338366162616431613461383063343037313639636236643036613134653266323761343839 -64633333373937643464616562663564613939653633323332366333353733613965383162386465 -32646461386363393961323061616162393935623633643664353235653936646263366464306338 -33636433653266616266363632663535396164326633643535373337613235316130356163346232 -62336636323066616361323039346333643661336431313862323062653033653235613865633931 -37633833303661366662326236336437633239666162643632303764633461323737313735643064 -37376134656665316364666132363666303838663739663036366661633931383265376436303165 -31613335333736656161333531383761353963343331653533353937643632626339646433646535 -38653363393934346534323662313963636465613864386538663931346566633930363963333165 -61343130393731636661383964373337323338623163646330636262343765353266303735326635 -65663438313264663366366130333562343066633332323038646139306663386138346636356236 -35323639396664373238303837633733393833383765333237323536303131313064383963393935 -63336264393335343465376635633339373839653237356137353734386636363230306265653761 -30373262643134313035663565313230383961653234323762333738636335343262393663626330 -30306264363234306562376163633433623633313436313038313137323730343938373465663136 -35353532373266393437313664306234366464626462386232313234613539376232396432643563 -37626136383265666634373139616634336439303430623765613734646162313839373333613732 -32346335326262303035353162323866663664666238643561366138386261303238643365356133 -64633862643162383264366362363362633863306239363937643335393531346334383031383035 -39633039356236663437663138623738383831336263663634636632626131373464363664623838 -34353763393530333961306635653663316164616266666137353561633331663939636165363535 -65356136393533633666303736636339353061356231383939396335636461366636313437393961 -30353964363831396263313937376663626461623062653733623336373832333133636239613933 -66653364313631393233636434396437633033306565343036616463653066333230656635643831 -63336437326435396262633430616363626132663630343638633035343439306631383064303335 -36383932656539313533616530383664346232623265373964353562303237646536383135626262 -38633863353863323661353537313064396238306436353563393465666663646363356333613332 -63626336303031363234366532303465303939613830303031323938306439303031616537663466 -61383131366130633738383136636630646439623361623764393033633364323761656634656566 -66363162313331323838613930393562313631353566373535383966303431636263646663316465 -33353566613635326538353764333031636465343133623033663763643335316362343234356165 -64383338383338663137636531373665396365636463336530316465666534393463393539353738 -35623464643633656261316638373536656135363862306439653130306133326262343863633766 -65313130386561643466333334326530386561306638393739613765663232623534383666643635 -37346430316136306138616664343861366333333431393863343732653463343537666335326233 -37363234663737373638323135363837396638393831336231343033636139386333633231626130 -37636639653831363737363839613561346331396263386262363035663564323530613065383665 -62626638333031616265366366303131333130646533316430313665383862373533396263616539 -64353631323030303663393362616566366665633233663333356164336561313264346439316133 -36396664316533376261663862313735613035366436666439626461613463626438333764626663 -62666135656238343763323039333833633734383131336563303365373434316333343830306635 -64396134613537633337373934383530306437616465313739303538323433356263306234353736 -35656364396133623138316365643035393638363736633635356264313130323562353935366262 -36613735633237396536353031316663316330636231353536396666643163663634343533633332 -36643764303631623636396537653037386332356465333462323938616133666432363963653064 -36643031323939306233626136386239643734333239323839383234326262363465646236383361 -65613836666236353032353664373465336266343133326437313130323537653965386666376537 -37613865366536613035383136333936656632373861613864646338396465376432396437646338 -61386334303637663736373062336264363630303537663839616564656539306266626239373062 -62366237626430613332656630336435336635346366333164366165373234353266393330326462 -36616238653762386439366663326236333462386562306562656437326131633533303639666336 -63653238303330376466353034353962323631646363663733353839623264383565373762363834 -61373462343839353437653637306561333964393439636661653264333866343961373839383065 -39616630353438643535323734333531323132643463333332393731613630326330333532316566 -37633036313338643564326139633438376231633639326663316666646165633637656130653233 -61386234336636346637623662393763363336663436643433306164376230326137663066343866 -32303031326439653539616437303966643236363233623734313636653162376138323332623331 -61343130333530663039613530353462356261366537366633396439343064336338613534303138 -35336532663332613036663766376139376264366161333961373861303531306337656235613138 -34363235333161363630666434313263626138386438306137303264373733663165643432346562 -36613362336639303961373635316231646537643936393334323530653764663539323132323933 -31643663313334656363343965313661373631333639613738366336306531393436663638613865 -30333462333039333962313433666465313232663734326339636633623933373631623635663765 -36643262383631383238313561326136376636346461306532633465326634633337326137343739 -31346634376361646135663131393238303239623132326666363433373865656230326437613166 -37616130323063363061633561383136376631636562396537373331393061353066363363653065 -62356361636163623566646564623861613934306534663730363663643038666133343666386661 -33376336386336363831323730316363633566663530663432326364663037633639366237633138 -36306261373565363635633362316534323430353235643865623232666563383962363831316636 -64333131393639313138363139666534326231386132323631353230376563383431343663656665 -63326637343333343065346238343030346432636238313438373430386334356232363333343666 -32306335653938346363633664616533316662393036376661353133376135393538663236633133 -62636530393864666138643530663663633238663333666265326331313464363637353562353962 -37303434336334333766396665386537636333363330366562356662316439366431613965303762 -65643733333933316234616136633737633031316435303864306132393362373839623834316531 -38373534356364653839336432376233336432656634643162343934373630666331366262323530 -66336538343062653237356536323961633931373838346534383630396430626363353936356663 -34636239333135643863303234323932383432323932353639303562613539633063383836636638 -33383333653466303263323165336633623337386634633037636331613862643061633438643730 -37313533333730373030323866323765373563623839313464363139616439376234353631653664 -33336462303130393961326238306333623062303230613233656432666337663662343639303231 -65376237613131656431623431613064313539623930316662666131626136336530303135343331 -38636232313839346432616633623466613863653366393065626462376466623233666435616263 -32393064636265633935313837306161306363346235613731626138343965653236643639633266 -39623135626664393133343136323664383163636130663037306334303434323962383339303438 -39323566363165313364326538636330376639323463366331636630363437643235366639333262 -64623030386137306230633537663031656131323262383565363566653735633163666537316231 -39333366316332303234376361303335623936343239306363393232363838356439303732666233 -33303462656561333735373931636131383066656264656236326166326266653132653166383462 -61663333393166326130396439643135323739313932353566376230363836396630386133356431 -64656431366430343730303933623161653866643961316230373332333330316539333564393430 -31663839313132636663616665626632646438326564323931326435303064313732346361353632 -61636237646464363739643136623661386534633338363739653431626535633131323462613930 -64366539356564666166616165303533393333303764373130343832623838303835393264383239 -62313331363965653864303262323565343934306362343330326539323037646237356632303230 -35363434613764643561326366643261633663623365653535306361323765393535663234313735 -31313065646566326138626465653365323766373434386537393239333661316234623564346432 -33613534356235393236393739666664353364623830393935313633623061333539616464666462 -66313534313662653532346662306464316339323834363236663965646338313333326266363363 -36353336316330356330366236376134656635623662656437653761656438343537653932333366 -35613862323138653039646134333662376661313032623138306665303838373636653364313364 -61346539386634376337333366373134613734643834396563373637383763326136636134313330 -30356662643962366263383365373933623636376331306137306662376231653166383664396534 -38383533613165366366383237666337623863383235663864323839303762646463616130666464 -61386532626662643330393338326665666130663864366463633562396232663432376363656236 -66373230356563643036333133373962303166303233323533323734333166396633646262306634 -63386534343137343033336466326165386566623530616333646330313361333835383337373031 -64633836643465303031316564396334623066646563306262633434313866633633313763343232 -30663062336534623633653732623432363832363933623139336130626430626437323537393765 -36383965353463636235633332383463376562643933653931393038383666623931616662333264 -65383365373963303030363366646132636261363664393561663463343566653766666137316561 -31623630363463376466613137306663616337663931363465613433336630346231393266363766 -61663836356330336261323861643438353831393465313133663763353639356566633332333737 -66376534633831316262663461313630363436626165653030366335636135323236646562343264 -30613732343663646432303063636361306236346537326238316336323537643432616631353564 -65633738666663303965623535653430383334386565366165343432386537623435316537646431 -39626363326530376661313565636562623036373134663836393463626639666464353037393238 -61353731643765656236386333353862326561333038346363396162373635306466613865376439 -34623263353065353934636266393336396535356661656335353137643663623439356565346462 -64343663663464313438346564316538343463343730376363316134636365653930356635366666 -61393636356163346662316338633633656232333034346435646337636636666131326361653634 -62646466343566656461376464626366633862386135313536643163653234316664643862626632 -34383333633231623236643239353438616165623362363163323065386563636337373238353461 -66633935636432653665346339626330373138303663316561616532363262633866343362343039 -37633164663430323239393561616434613164353535636339643961306465643465666563383435 -63353965373730666461336237613734333934316136356636313130393166613837336266316532 -39336533616632656233363239383563343037653336313437333430383633303961303734626234 -63383166356234656430333333353161393737313262313739623634626333646537663937363636 -32626265333031313462666163303364393230303631343664303365336465343964663831373935 -63373038613631633030333364643038336336373630653936613136633561363761643933626435 -36666237636335633736313533363064666131613031356665613238656538353063373563346333 -64323737663562323962616230313334316134613465313632656535313365643133396564396139 -39386664643463376365386339346165316334633138373766363731323264336262616539343630 -62346134323830633330613831663366383435323262616433376333356338323665383233396436 -63373937623439346532326138353462353263383462343830376164353632343361663935343435 -34623636383762333462306635663965353635626366343038633433346534306632393133303032 -62306530646531656666666435626131323132656531376230666639613563303265353265393566 -32353637633864626663633934323330376538373635393337346139303231353137393864343662 -65343564363839303636306466336135356637663563643534303465346665643631353338303363 -37626138633537366531343862633132396336666562646564626334633439323562316539376639 -65623632393063343633633563343664363335343963336233656138313931343038313266663332 -32366634366564306132336139633237326234316463306535313934643262613530393165373432 -64373662623335303338366634636132313466626237376534643132633863303637343236666163 -30353364643831346132303738313162383638396536366233373034616539323630373265656438 -61363331346462666635623533373639376636376130623931346462396366623166326331306632 -64396566613663653366623763666434303534303434636362306432333736323033383930646365 -34386562323836613063356134323735616562366131643939326638363037633033656233303666 -63393862613834656633353331393561373662613364363663613464333036373063373264653562 -39653333643237653864323161656237363561393736613630313664633562333365623861373261 -61323163316636366131666238386131343039613061383964303361363131316263623961663664 -64353866623039313063346461313664626534613731383062633866383662343862356165626163 -35376465666432653366383832393062656439393130613661393030356132356663396332313636 -37666239626662313635613264383434643437396663653230396534373230326463343662656336 -36323362373837613066643132313531316161313132626664613937326261353839303333613539 -33653938623135366432663131653662653461613263663332643736383830323665666331343939 -65386236326461393466626262376231383338666439666266396365656565386336306665316634 -37373633393062613765313465393936636638376330613931316238396634343334353562623039 -30383233333538366264653834616266616530383538386239333462316230353863316564613534 -37613236316532353431343534363632666234353261623963616135316566313538363330633433 -33333666323037663833316338616430353831343661633739386265383365386161363733356263 -36656365323465666133663339623131356664623361306263663163663231313739613664343031 -39393264313531373937613264653565346563303537346637356366643364663837663330353437 -33646364383732383664363661313765626335653063333663363164653936373866303938386662 -38383565373139316235613062373838396263383565653137366463393839316338333038303935 -61306139316465613537646137343338663533663737376164633830643734616337666466346632 -64383131336631313833653137306464623235626231373336343665326162336663353235636430 -63643937383836356631316337323235366439613934643531313533333835386432336632323131 -62333937623131646463333336303933343863313637656433373832313230363637633735353766 -33666234626639646436643566383537326638373537363737633235623339313635346338666232 -34336431663636383662323933306462623431333633613864373364373532353638323564633634 -33653165653531653666653934636331346536386162373635396164613337373635633739353033 -32646432366166356534393064313934623164313262386561386162323137623934366339663039 -61636134343031386234363065336432333039396534333764643365346365313666373134343437 -66303539356636396330613431353964666530326362386539353361313133643239396665333238 -61386161656630626339626239333631643266383463366239373938366631623565303339323765 -37326239373232323662613662343531653263613562636234303938353135653166613731343031 -37663634636530333365386661653237623838613630343434663837646432623236643831303966 -61386233653864323135383162396366336563636538353935643166633331393863383465323264 -30386663383766656435363730663734663864346233303430646335326563643635363762353338 -63663862376633363939343061653834643235353134626161343834353433653837343865656463 -61313636373731363662643231653662336136623830356638643135636135366134613736616631 -37663738363033353035303338313636646639373033353065303436333530363831303438376663 -36333230353930393930323335383735383138333364643364346461353539346133666661353634 -36646332393064366132383636643764343863396639336664343537626232396566643631383230 -34623561303131363662303938323066356366356535343331346530356535623239366434656136 -66653562653164666261363134376138316130663333336139356338633263623732616234356538 -62313664393439313431323830623231613135623738663934653036316337393862623130333738 -30363966653063623461353134336665306165363831643739646264656339646161623965623665 -33393663313937616234633136643336643966386532333535306461393865653930313564393066 -31336530646434326633656664353231346665643732373733326661613931656564333132326633 -65313038666134356632306631363966623237646334626536333130386335326563663766366632 -62383631666236393536306337313631613263383038643431326366613761623465346438333830 -62353537616462306238323263316133363561643763303634663430666565323837613131343262 -32393735316264646130363435613063363562396331366239326635333963353433633164343962 -34353132623136353565663537386362643537613965663632626134353433663765326137646133 -30376361366431373061333336333934626565316430623936383466633266323863366436316536 -32393936653066653662656537396137666234613534306664323163643033636162613136663964 -61376235326338623066366463363637636563663365663238663566323366653330663532346633 -39653632626632316530336165613737373030386433353639643361396661313036653664643332 -30303635323031383734633933306637326566316537343339376134313036343335366332393039 -33326335663437636237303631346232313433386536303564323933303631313765616638346364 -35633331633034656464393564376337623030383637393735613433643235323765376538386362 -35303464393765363632373731376135356633353036393065336631353633313662386562303038 -65623361623565356462663164363862386465646435326637373133363638343063353935316630 -61343934626566643837396235316237616136626539643837366636323761373262363664386334 -37323264633966643663626636353661386336356363303831376333353037626639613362313933 -63333339626436613966633333393630356565396166393935356230313636303536323638633930 -39656534356665363032356462666461373634366632303339653330633361343631393566613833 -64363032396636306364343030323564653431343036393866393966613236653663656262343739 -34313134356239333961393739323164366362373531313636306538346531383231393334313238 -64303333313263306131663831316433363961623563383866356663643666323830323635373733 -39326137343736366336663536333837306363326639343730323639376439613839663739633333 -39326334653864616531633536663836393063633834623639653630663463646233653331306639 -37613136376364613532303035306231643637373231613235616532376535656364303235636137 -65643066633466646365303738343061323766353839623036643931383635313731636237633937 -30343138353737356533643631653364346263373865626562346462316239363237623937643464 -35306533366131663734623963393364636433336437326533333335376533393438656133363236 -38636262333739306564303266346164396563383439303166353334313632346538316166613435 -37313636346637386665393562666530326462313065656365633239343739353466623033313136 -66343363303933666362343961383466373263656632653030396435646431326665656431396237 -36643262323831373237313162643830303835616163666664653661376362336565316663373037 -32313237323539663630616432353431643233613363633862656665333336333462306136383538 -37323230343232313331633961653539613938646535396362303732356263636561346436616466 -61373439323163633538356237623038326630316364316331656264303430336532303462316139 -62353138323431333564613763666264613731363138356339653532346139373737343063363761 -31316361613237623437643933633530336630316430343163646439353666663031616638313262 -65373166656536666131353666373861393234363532656466306439656632663030356233373562 -37353664663731346631326161343563346434653639393735663662633739616362613164616532 -64373237353436666131623163653838373766666463373334373332333163373461363532376366 -37626463656533393630643032306238623862633731333838333662326136363730323166336435 -34356236303034343632653065356234636139313263353230623135623532663066313365656161 -61373761393266623133306638346334626233663537353030346534613435333465373431346237 -32613165376531313034363166393163393639316262653933386530396236316566326337613335 -30373233633263356666393531363030396339616263373833323635613839656132623462633339 -30616238633164376162313837376563383533616539356538643465623739376232386261346566 -36356135663639313463663164333937343235326532303134653031646234343439303533313738 -66623335663563346236326337623562306232643564303935636232376532313636666531373563 -62376539633930633562623863386537396630326332636232356637383630646465303862643738 -30656332346133356337323239663835646262373837343263346630363266346537303962613438 -36373832333535623937313138376466656662333564343437613263623831353733626135356439 -32383133643732396663643266393338646539383666653166343761333565363330663935333139 -39336335333133363739353662303531623330383231336132323035333963363937313735613535 -31346363303763326464356337653166643233393338383839313766373638316562386365366536 -38393839613434626539303263386633616638313436353362363039326537613630386138366462 -30646663306533333831666336386531333639373861336166343762623136613039356464363063 -61356334353762363261643535626165653564333935313433326537623837653537336661306530 -62303133666565373033653564663961393866386431613361356363356335323133376339663436 -33623261613462613962356130383366663762623935633930343539356362386533343435663836 -65306332326265366232633430343731333735326165313430363232386663613530346337633061 -33643134613238653964643535323961313265363338353230306465356635623432373738653032 -61613566383734666136303763636165336330376566643537666364393237656434336233653962 -36663862323063613630633835653537346261343039333936316432656665306438356138633732 -65336336353663343163643235396631383230303666653862363432323236323738346233373732 -31643261653064366530366238356535623535613736383665653264656364383261326362313333 -63333466386566663938336661626365326663323566303537656134393639666663303537656462 -64633236633263316639346637653132653632353965303462383066383337656463663537336362 -62623430303663626466626231643736356433376639303362343862636336393835306336333566 -37636665646663383035383639633163323365323638653236366466396636643331643332613034 -61306238636537396564303833366661343237656438653430343038316362343531326235313936 -32323466613635343136633437363663363263366364383364323664653735636265323432366462 -38616535326133323536653934323564636135353262343666326536613034313863396166383633 -66346332343862316134643831633430623265353338363534363465653135333363346661356439 -36386564376231326261373263346239363634663461393330383361333265633737646166306437 -63346239626261396663326365653630353534616237323232636637653164646466346164616363 -62386332346335663135353762656262613030646130353535343563653663353637306431363935 -66363138383134626466303238356134346532353330313464326532643233616566353262303661 -30366163316532343435383338326462613439333664343233356437333530633133386661663330 -31373538383763383135353833316465323862353531363266313737313335363134346366333132 -35383334633762336333306166346135623836303234393161643433646166363134306262666330 -37636630663137306161343930626132306236323263353738363234613165396131326430643737 -31376130386162663634613933363837663335333066613535656337373161383466663266376230 -343964393137333362316638653661386561 diff --git a/vars/mysql.yml b/vars/mysql.yml deleted file mode 100644 index c81a018d..00000000 --- a/vars/mysql.yml +++ /dev/null @@ -1 +0,0 @@ -mysql: "{{ vault_mysql }}" \ No newline at end of file diff --git a/vars/mysql_server_legacy.yml b/vars/mysql_server_legacy.yml new file mode 100644 index 00000000..cf1a61e1 --- /dev/null +++ b/vars/mysql_server_legacy.yml @@ -0,0 +1,3 @@ +mysql_server: "{{ vault_mysql_server }}" +mysql_admin_username: "{{ vault_mysql_admin_username }}" +mysql_admin_password: "{{ vault_mysql_admin_password }}" \ No newline at end of file diff --git a/vars/netsoc_cloud_api_config.yml b/vars/netsoc_cloud_api_config.yml new file mode 100644 index 00000000..3e22c13f --- /dev/null +++ b/vars/netsoc_cloud_api_config.yml @@ -0,0 +1,244 @@ +$ANSIBLE_VAULT;1.1;AES256 +30613664363261623963623162396563343161303439373233643037333230643366663338303839 +3536343732653361333437373836626130303038333235660a323839626131616137323735326265 +31386134333565336637306437376634383337386364333766656464626133363263373161656638 +3563613864346531650a313366326633333537333262333638336364313665376635313932366264 +64663634343262306563303036333136643932323234316239393739353632363634383739623138 +35366337376265306566653838373130376566393937653936383232313039616163313239356666 +32323738616332326465386532353334613734623739353231366239383335356430393138626433 +34346163663563356333626562666439376439373039656533663239326339313735313030353037 +36336364326438663162343031646530313934613166353861346435313538396139663235323031 +31396566356235303038643135396631386638633665663164396531333037643533636536373136 +63663534363462343139356337303538383866396130383664393937313038646161313532363264 +33623763323931623130616531323065613536316632393133303538303865623337373539313439 +62336266363363376661626562336631313761643664326538633936646437356239613436386139 +31613339323564653738626332343939383166343261306432623063333331373437343564623365 +36363562626338613835616661343262336638303862656661623565616631343236376632653734 +33373539666531386261333338663438306435613733386463633438306433323964356634633266 +35383062623130336339616334333230326465336430626231326361626461616239303634343838 +61663739633234343362623733386332366565346166316131353861663539383638616336653338 +36653432643864343533396535366536306561303962623739663865643233636333653034636533 +63633632343964326561376663323163343461386263363465623064616132386636336364653333 +32313339643337353339613466383735626630626434316631393033666130336332376237323463 +37623031373937306233383738333462326164346130316531313938316561623732386433376633 +64613231376561353664643465356431643966663864666235343536623737653165653932653130 +39396363646136663330373065326433383663303530353134366434323162313239383937313832 +35653162306165633832616164383831333439366265636334623737636337626664353938313734 +33343036336462306535313036333338616231336466623863626234613138663131366134613136 +33336636306338666264393763313737353962663763313663323165323863643134663362663663 +62646661356366656337356532363966303265363065303163643538303062326266303039353265 +37613933613064373630343161376330383738333465653133316238333665623863373661306639 +65356439363835393432363039663963623130396263393736653931663863646162326362613864 +63643639386261616161356139356433363238343463656262633266616631316136313830393961 +39306433656364616362326537363736616133393466383137666463393538666635663937633162 +39363364636232386163316338363735326165303633636661636638373835613637333664396437 +36656266656331323762323531316633326565383265656266326133613839623061306264323066 +66306239366433356434306162393136326433666231326431356435306663343235343861353261 +66373335336533396464663962396232383762316530336334633362313233373762333030393964 +36393134383039636662386430376432313236633733313461663534643433656364323030323032 +35653264303038653866643037633334643165646461616263326135613762643339393832643364 +63323133666364316162366134643964376135623366383163666133656662613537306265306536 +38316563363935313761613531353532343237316533303130646266663537626231616239613936 +39646661363936306130366235316364626231343463353833353831306562396138373837646331 +37303631623939383335396132613231343062613631626263383139623035653435303463366533 +30366538306132326263383738626466666462343334366238633866363335373530363132393232 +34313765346437613065363838336461663766303666306337303464336363313064363337343838 +64343438383133656331393038303334653137623339613662363030616435363732323937373964 +64396165346534313665623936376539323834396534646239633461373332313532373062313031 +63333339356633623562636561303766636664393132373431623031366333343336376536643065 +30343166386131666136303334306634306265326437363762343166346561626666353463366566 +34613731626536633534313134623735336533386238653331326339376332346365373464383733 +38643836646261313637383330326130663861323531313731633035333232363337386336313238 +62306231333239643264353863343565386530613966623031383664666566373961313132323937 +31623266656362333839376135336337356630336434363336623934643738613338376133306337 +34613062666231373661353935376133343861653739343331356666313037316366636366626365 +64346362363932343630653962643434663633386333636165613932346434623764353339613766 +32363932303335656365393439386637613537666662343365653161396362633933383731633731 +64333963363465613964666166326263303235353261666337383237373663343235666233306238 +65313164373666633663303864336134323166386661613466616335326332313739613563343131 +66653861323432393664343739646332373534316566326434336138666433626238663134633665 +62306336393164663563336334326465366330623666353336666465613865316136393363306332 +31633939313938353436646335623634303666393430313432326265393366636233373062653862 +36643333333865616230646439646635373064663236323866613064353036353861306535353239 +66373338343765376364636135623963383932306239653230343730616632366462323765336563 +30653536383534363235346438663563313839366163623739316361616438653133666230353638 +61323362376134653037613736366536386439303466626134376561356436633332666666343463 +34623737353362656164623533653261326538356235343539346538343266396235383238343532 +35396633663261323031326661366461646364626339643665366264376663633833613763636231 +30363838333431383631643064336435316665626339653037623831663135323266313732643032 +30323636343465393061313732333237623733613435326266353735303265653466653563653062 +32326362313839363339303536363064616262666432656164623738316566376438343735386332 +34616361313365653334313231343065363662316664373135303465363433373965626235363035 +31316132613862646435333931623934326437353237383663336131363533326333366539356565 +61643134666635663037363462366332326630353333646363386139666365323263396435656266 +61626561306134336432633232663538626233373636343862323638363839303336346332353738 +36646361323639316462383736336239643533623366376233626636343834623561393136626135 +61353366346161353236313665386136373161666461623332396564343835623933343239613366 +65326235396536393632386537343430363837643463656635636230373433386333323638643762 +61613563343536616433323564636635663461383633373566343862623039303038376232613631 +38326462396337653462636161333163616462666561336537663339613463356165643661653939 +66646136623765616165633037666437343039303332376433336261366237663762333237383035 +63393837643838636364316637313464383263353663373032666537373638356563333662393032 +65373739336532356661353135636435616639643530663164326233333564326266373766393935 +36636337363765383862666161396339633666306166323566623535663361393235633039643037 +31316332623937363839636531306535636232393434653062663765346436303835643162396462 +36393231386232316232643264363766343639316630353565623736383163306561343064613361 +30383330396231336439356235303864323339366638396635633538646361323361313233646335 +63343063616537306664316631313736376162633332306333393162366137356138326662383362 +30636337323635626431313536383935386632333236306366363035343938373834646234643365 +32333433366261646330313164343039376131633739366163393034653836373831376235643432 +38393162326231353562333335353363653661336633613532303931616137323537633732336164 +39383361393761376338393938313266326431306564366237343135656537333233376239343866 +64366530373938373966313062316633313966313933303039346163343539616239333439356230 +36323931376130303830316566636637373364663961613634313865643763393436663133633365 +32386136346432663834643733326537656265363833363833653437356431303932646465383235 +33386634346134313838663764333931366632656661316438613162326438636163643066376236 +35386332346131653832653865633231326531386638393538336638623334353335623662346431 +63346530386438396365333466323936653062393464663661666236356362316235643130383739 +33643564653764666138363430363963393265663832333435323065383165386635613337653839 +33663033646462313066343936643865633238633939623236333538373665663062386530666561 +62356530393166663630363836643732616238316364373863356564313864363730616235383231 +64666462393966303733643732313065326130393135666632313938663962363961643632366233 +65323637646339363738373033353732616163396465306234393762383161663464633264383639 +35653535333238616234323937623731663863313931663766323863306139666131636364616166 +66643862356439666166306135636438663935333661316265316235366265623037656231346136 +34313764666633626134343534376535643866626535396662663063653035343336376236323339 +66366262343066343966343431393139396339353832336132333032613532396133366533383963 +31623663396261353262663533613664636138303934363862643866323462306462303964373233 +64366165366237363863313166313864373035373931333135326266646132643639343638373433 +37383264323665653534616132396663653038613231353032373238643136303065303133636164 +63396134653165323431353734316162653239643937663137336364383736356238643331343762 +37303430323935306236386132613533346536323739616639326361633937643665363436373638 +37666634323362623536303732373161633637333135386633666163386338353834303631626234 +33633464323236393734663836346566366238386432366434616139656136323538323335663839 +61316539653933633164343262316530643261666539316531303439646362373430303436643565 +63646630656135636637353136326162613236363632336339386261653831656532616636613635 +62353832373433663837663532393938393766666361623363663262306465363138356635306561 +30626134326465393764323932656361333264353731636664613364636130396635333439666365 +62613233643566376166653463316134353934393833363563636538656664343366343532353761 +31393064386139393637353336346362366631343333636466373966656233653931613935356238 +33306136636337353031666364633931336236363066616530316432303266323436303162356532 +39303338336538336232363334363737323966626235623861626334396533306532316262356434 +31313632663631643332636261373534333163336162653832313864333434646262393835346537 +34336362623831386437626137343562373432343936326339353439343139643833656631613164 +64623038326664366333653739646466613065373636653533373633323536613432656332303832 +63373665323139633732333035303063333633653936363832336138393731663335396533386535 +31643730363961303561336636623031323730663661663933663633623232323866366438346537 +35393465623831646439633462326131663664616263613137663131656436306133623835386332 +37326635383338666166373739363366646136366565366537363962343461353835353361353934 +65323963636431666234613531623633383064663062633238346662333637643830326330303661 +32313436366639323365383433393130646439393061336335306232333532363236613233313231 +30613265363636366138663630663365353530343533636365373031643630376566346265613235 +31616531623561653532303235386665333362623138316137306562333932356131303032663364 +31613430356637663130373736646533363866323430333962626438633731376165313965326164 +65356139656466646131373834616233353232623932623261356564383263613465323139383631 +36353933353438383866613331326136303835653064333139633631353239353939333333313666 +39343532643030366538353064383762636431396332373065356133656635303032343763623237 +38616566613434363466616365353363396463356431343435313332656135623465333730336337 +38636461303965653663643765626633623964613330636663623037323336316165383062343163 +65346539383135343562613139306436326365623537623266643435383336333633383038393438 +30373566393264626534656463373330646561316132323234663032356137623931633238306434 +34643732383138363363393935633830643932613461353832343265626661393566323034373232 +61336639326231333764313637626363653862386332346433353738666131393932323635653031 +64646366386362376563393434383437373562383530353233363432306137663334363938656338 +66303266346132666164393633373161663562653530396131393138316234666239336136363266 +37383035363630666637636635353938616234316665333435323231633231626566653233643639 +34323437343962333637396139646133643535393937643932616563323433626131336135316363 +31666264646562643561636335656231376638356634653761353861636264326336303062376363 +36313834316333346164323365613961616264323331613834393563633835333635306466333764 +30326338343735306466623133393264393632396133386364623938363235353435643566386637 +39393965663536323631386338333333333762653533353966336138626630613832336237303432 +32333362323937303833626539383033646432623334386439336262323936386330323232306662 +64383838326336333864333165346336646236663931326362656333633935366239363166303639 +31333061383139656164333161356466643337616166623138313130336665623836666565383466 +65623834343439313331653738313934353065616139356332623666623639653637343730316136 +64323232326330646261336133636336356238363138663534336339643937323261653039313033 +31393966356164346264623639623432386566353834323237643935323233316163313637376333 +62626236303834646434313766353236393266313238313737383361653161613536636633376264 +39643831643833373063313432653831353963366431663664633865653132363835616536373631 +38616663633936396131343435303737636438366636636365636531653731333233333336633638 +66366232313039613362313835376462633837343238383163303435663561323334666330376464 +66323934356630366262303638393333623163366463636161353036366136333930383334323866 +33373834386538303238643632373639393731363333396165383238336337623164373965663537 +61303437636236666639383937633735373464373231313237363362363336393963643666633334 +62376131643764333365623031336532353535323366366535323137363061633735353336303036 +64633031373163656365386335653730393232396264616364666333636235633234323930626532 +34303564333339653134626432353934616239653831633962396231663035363433303037643930 +35343962343137383937313336663335333235323639636138306438343333313564646461393734 +38353835386531613333653237666436303134323633633637626238663063303061326239376138 +63383865333463656565353031666232353665396436396134383937303234613634613130626631 +39306637646264323565663239343761393963333465613432313632383833616534633163346465 +31623166363933313131643163636164313036383864323863313165363838643434663438353230 +32393130393964633236663263316463656566373636646137626565376338636136303432623861 +33326632396531383335306533663464313639376434376166623339393835626636313837386637 +66303930343834386265376433623061646366346330356665643661373161636634323038626632 +39633936626537636130666363323266393636383732613966646463303364623231663561313936 +65653832636362303535653064316565373830616331383162366632633635663663313364616231 +37613532663936646330346431386533666631393264613131636239363939623864306666666463 +34623533373432636262386563646638656466643830636161626437396163343664386338323837 +37396461373233386536323263626235393661343565346239346633633739303933646339653537 +30336535306563376263306630323163353034333231656330383865306163363066646665633335 +61643964376363656638396464613862666136643934666633356535636262666636366530363265 +65666135326666626235353833613530616162336139363865363563303335613230653338313831 +32343330656463383039363964396332656132313030623865313637373065326638373730366338 +65373237393830653634333334613039383461646664376166643766376130623165376565346436 +33623161346235333636623361353335326365336564386537646331613139363630356566653436 +63346533376466656239633465393962346162303033666238393330656266643836373063613633 +64383263323339303561386631313933373662663538353266313431653632633430626431646134 +32396665616163343261346537653633333064646435336135363830663063656362383739306436 +38333337373830323336316437383731346366663933323038663261363939313539363235393733 +65386236643365643032633732386661653861363339326339646561613463636664363734613235 +62323566333364663137613035353236663263653063643033613233326665623261363636656234 +36616466383530636634343734323431363530363836373961366163323561343634396433633432 +33366265653961626664383638613933303961613232336466376233396433373734633765386432 +62666532336531346466356564313361356365323864353136336464323861323534313531626139 +63383162356262616538646533336639626632336334636635303566663232633435656661636534 +38613737666665303237356366326364356564656365373762613331623665306265323530636436 +31313064636238363339653565393836306663653932373134303465313535326565363661316238 +36643463656462346539383936366436353231613738313063356266386636633964373264623639 +30626234643633333735323735663237373763393333626332636631366261323236346461376331 +37306163656464393634366137393638643066316336303066376539363166323938356237643834 +35376338376163666663643263313632356338306134653633363932663038383763353766633039 +34326161373064653661653930636131393731343534613835623265326132313631646663363732 +37313561643038346438613363613033326232333636366332346134623434376430636666643537 +62353539633064623638313161616432346335646461353139363964383265336664333338343434 +33363931396531353538306166383337626132663766373566616334333763333764663633316530 +65343839666465323036623062376138666161646164643939343162363439353932383033616438 +33323262336531306565653065383064613735313334653331363361313764653530323439303861 +62663339303961333334663932623832626233346537663434323438633965326262353132313130 +62306163333931393963363238643534376535333363323936343236666231343032313731343736 +30316331336138643630383037323933636333613666396231343334356562333230336330343938 +30376561346433633063633263666465633139326533613631366536636366616436643638346366 +63656233396430623137333663353630616635336366623332613535663966353235333061653364 +61333134613137313539663864333366656663366138333661376337663265613665616466613062 +33626561646234326532393231346164646335653630613763366561326131623633376634363139 +39666666633038306335656637336633383264303365626339316264393138303639373539623636 +33303435313064626465353563323164643666623237333466353533616461626537376166393164 +31326132366137656562343664376563303762313862626631356230636333666333313665353661 +39363334653264626263333636353638383465373131653737306464326263646166353832613531 +32336232643635313139383531643662363764633562333031653864643362343539363234656233 +39383731323133646637363465663733386532663737633330633766303364323337306333356639 +38633236646230626432383335326334663064376137316337383861363332303465306464626231 +61333134613335323164336339396337316631643365316561633630323836393061323130356332 +31383035653233313466356162306163393832353235363063626637636231616539306165353636 +32393831366537363330663337323031616637653566393062636438353664333337316433626336 +33393537393966333263316337336132616336386163336233323566643235643361366638623563 +36316332656565613930316338386564393430643762666436633533646365633563383531336332 +31326536333333333638613230613566336561386533356262343738616135333133303532383634 +35376665663932623130386461653435666131643535653137353065363535613931373437363763 +65656364663836666634323132643238333463383934626138626638333666343466316537363665 +66616330623366373036363535643133363762323633613938383837613264303066373130643239 +64653666326433646537303335643165663739613431343866376132653137646366303562646335 +66313534323032643339326461656261666430353433656237313739633161353565636438366638 +61326463646563363837646430646330363064623038336366646632313330373331326362663534 +34363261633066346466326535643862626136306262383437636161363431383661373262636464 +30373537343339393863643963323263373431613730396265393834653330386438376436633835 +65343166363461336533303434306562623864333133636437396435323932363031383931633162 +34376662303131323033633234636465643033323363313736333836623035386162633931366537 +63303564333336656231653236626132306136623136626133636434383239353031373137316366 +38336435366561396563623062623238613862616133336161666266386530393632333638383432 +65663134623261636562613539323434326238616364306339373638313766656430646638326365 +32623835316662313763323065373435353765643364653034306561633938363630353737396365 +32656438353439323536656637663336356435373663636565336130613238643530623730323438 +63383834633966316537383864343532383333316635666132343937373437306662653666633138 +663239623563653961393339383330633964 diff --git a/vars/network.yml b/vars/network.yml index ddf83f71..26053141 100644 --- a/vars/network.yml +++ b/vars/network.yml @@ -1,109 +1,102 @@ -# subnets are isolated by their subnet number in a VLAN -external_ips: - - 84.39.234.50 - - 84.39.234.51 - - 84.39.234.52 - - 84.39.234.53 - - 84.39.234.54 +public_ips: + cix: + - "84.39.234.50/29" + - "84.39.234.51/29" + - "84.39.234.52/29" + - "84.39.234.53/29" + - "84.39.234.54/29" + + ucc: + - "143.239.87.40/32" + - "143.239.87.41/32" # vlan tags vlan: - wan: 10 # Uplink, connected directly to patch panel - vmhost: 20 # Used for management traffic and proxmox clustering, has NAT to WAN - infra: 30 # Used for infra VMs, can route to user and vmhost, has NAT to WAN - user: 40 # User VM traffic, includes the User ssh server and user databases - extern: 60 # VRRP stuff - router: 70 # Used for vyos clustering + failover - oob: 80 # OOB, connected to CIX OOBnet and OOB ports on machines - mgmt: 90 # - dhcp: 100 # DHCP Vlan, used to offer IP leases to building Packer templates + wan: 10 + proxmox: 20 + infra: 30 + cloud: 40 + extern: 60 # For future VRRP + router: 70 # For future vyos clustering + failover + oob: 80 # OOB, connected to CIX OOBnet and OOB ports on machines + mgmt: 90 # + dhcp: 255 -# 10.0.x.0/24 subnets: - wan: 10 # Uplink, connected directly to patch panel - vmhost: 20 # Used for management traffic and proxmox clustering, has NAT to WAN - infra: 30 # Used for infra VMs, can route to user and vmhost, has NAT to WAN - user: 40 # User VM traffic, includes the User ssh server and user databases - extern: 60 # VRRP stuff - router: 70 # Used for vyos clustering + failover - oob: 80 # OOB, connected to CIX OOBnet and OOB ports on machines - mgmt: 90 # - dhcp: 100 # DHCP Vlan, used to offer IP leases to building Packer templates + wan: "10.0.{{ vlan.wan }}.0/24" + proxmox: "10.0.{{ vlan.proxmox }}.0/24" + infra: "10.0.{{ vlan.infra }}.0/24" + cloud: "10.{{ vlan.cloud }}.0.0/16" + dhcp: "10.{{ vlan.dhcp }}.0.0/16" gateway4: - infra: "10.0.{{ subnets.infra }}.1" - user: "10.0.{{ subnets.user }}.1" - -nameservers: &nameservers - search: ["vm.netsoc.co"] - addresses: ["10.0.{{ subnets.infra }}.10"] + infra: "10.0.{{ vlan.infra }}.1" + cloud: "10.{{ vlan.cloud }}.0.1" + dhcp: "10.{{ vlan.dhcp }}.0.1" + +nameservers: + infra: + search: + - "infra.netsoc.co" + addresses: + - "{{ subnets.infra | ipmath(15) }}" + public: + search: [] + addresses: + - 1.1.1.1 +vmbr: "vmbr0" interfaces: - auth: - net0: - addresses: - - "10.0.{{ subnets.infra }}.10/24" - gateway4: "{{ gateway4.infra }}" - nameservers: *nameservers - optional: true # prevents waiting for network hang - link-local: [ ipv4 ] - databases: - net0: - addresses: - - "10.0.{{ subnets.infra }}.20/24" - gateway4: "{{ gateway4.infra }}" - nameservers: *nameservers - optional: true # prevents waiting for network hang - link-local: [ ipv4 ] - net1: - addresses: - - "10.0.{{ subnets.user }}.20/24" - gateway4: "{{ gateway4.user }}" - nameservers: *nameservers - optional: true # prevents waiting for network hang - link-local: [ ipv4 ] - nfs: - net0: - addresses: - - "10.0.{{ subnets.infra }}.30/24" - gateway4: "{{ gateway4.infra }}" - nameservers: *nameservers - optional: true # prevents waiting for network hang - link-local: [ ipv4 ] - portal: - net0: - addresses: - - "10.0.{{ subnets.infra }}.69/24" - gateway4: "{{ gateway4.infra }}" - nameservers: *nameservers - optional: true # prevents waiting for network hang - link-local: [ ipv4 ] - games: - net0: - addresses: - - "10.0.{{ subnets.infra }}.70/24" - gateway4: "{{ gateway4.infra }}" - nameservers: *nameservers - optional: true # prevents waiting for network hang - link-local: [ ipv4 ] - webN: - net0: - addresses: - - "10.0.{{ subnets.infra }}.90/24" - gateway4: "{{ gateway4.infra }}" - nameservers: *nameservers - managerN: - net0: - addresses: - - "10.0.{{ subnets.infra }}.100/24" - gateway4: "{{ gateway4.infra }}" - nameservers: *nameservers - # expect +5-10 free after this IP - workerN: - net0: - addresses: - - "10.0.{{ subnets.infra }}.200/24" - gateway4: "{{ gateway4.infra }}" - nameservers: *nameservers - # expect +5-10 free after this IP \ No newline at end of file + infra: + databases: + net0: + match: + macaddress: "b2:eb:14:0a:54:a5" + addresses: + - "{{ subnets.infra | ipaddr(25) }}" + gateway4: "{{ gateway4.infra }}" + nameservers: "{{ nameservers.public }}" + optional: true + link-local: [] + web: + net0: + match: + macaddress: "f2:f5:ee:2b:fb:05" + addresses: + - "{{ subnets.infra | ipaddr(35) }}" + routes: + - to: 0.0.0.0/0 + via: "{{ gateway4.infra }}" + metric: 2047 + nameservers: "{{ nameservers.public }}" + optional: true + link-local: [] + games: + net0: + match: + macaddress: "46:fd:b4:6c:f8:69" + addresses: + - "{{ subnets.infra | ipaddr(55) }}" + gateway4: "{{ gateway4.infra }}" + nameservers: "{{ nameservers.public }}" + optional: true + link-local: [] + minecraft: + net0: + match: + macaddress: "22:1c:7e:3a:77:b4" + addresses: + - "{{ subnets.infra | ipaddr(65) }}" + gateway4: "{{ gateway4.infra }}" + nameservers: "{{ nameservers.public }}" + optional: true + link-local: [] + +databases: + infra: + mysql: "{{ interfaces.infra.databases.net0.addresses[0] | ipaddr('address') }}" + postgres: "{{ interfaces.infra.databases.net0.addresses[0] | ipaddr('address')}}" + keycloak: "{{ interfaces.infra.databases.net0.addresses[0] | ipaddr('address') }}" + ipa: "{{ interfaces.infra.databases.net0.addresses[0] | ipaddr('address') }}" + prometheus: "{{ interfaces.infra.databases.net0.addresses[0] | ipaddr('address') }}" diff --git a/vars/packer.yml b/vars/packer.yml deleted file mode 100644 index 8c0ccaa7..00000000 --- a/vars/packer.yml +++ /dev/null @@ -1,2 +0,0 @@ -provisioning_root_password: "{{ vault_provisioning_root_password }}" -packer: "{{ vault_packer }}" \ No newline at end of file diff --git a/vars/proxmox.yml b/vars/proxmox.yml deleted file mode 100644 index 0376180a..00000000 --- a/vars/proxmox.yml +++ /dev/null @@ -1 +0,0 @@ -proxmox: "{{ vault_proxmox }}" \ No newline at end of file diff --git a/vars/secrets.yml b/vars/secrets.yml index 3c3cd629..4cd294ed 100644 --- a/vars/secrets.yml +++ b/vars/secrets.yml @@ -1,38 +1,320 @@ $ANSIBLE_VAULT;1.1;AES256 -33636665646561623962333566383938343931383862646138626436386432333564303265353235 -6462623636343335393562313538663038303230313436610a333561366432383234653765633331 -66626232353566666561663465323732636534333563616363646533373339623339626565383534 -3363366536656530660a626234336431323265323239353436316331633163393539333338326363 -32336134366663663132656265653036316261643534396161626632396538633162323430616636 -65623534363232316638333766616331353531633063323633643332386166396534366330386464 -63656265633339343731616565366662316138313763396138323337643239383764663834383864 -31666465386136366334306466666565316662373335646562653031313866623236356630346237 -65353735343332663533343864383962613736303961623837306463316262653737626362666332 -65363866316163383838316666333066303638653136623661343237346264346264306664653261 -38623636373532653764396162613262633631383739633066393162636532333933313232653261 -64303366643032393038376433626265656531396234643733646131353234343461353831643261 -64366134363631353231373035616534353033336165333134316336336237653061393765326362 -35363431313630653736663039626466633461356535313539353232656233373765653735313432 -65633437363434653132313237643036313066313739323738343834633762633033316164663236 -34353830353438353237376231626463656562313737366231303933393566333663386430616264 -32373066306231363536626636656465366437623466343534656263373262353966396631386661 -64353966353532386639646130366237383365653534366332356636616664643566363934373638 -36663864663038626462376430316632313933373934636161613961363835333037383934626435 -62323030343164373631376664656334666237643563326464653863396334356331393430376338 -65613535663534356337656264383633643963383836643139633936616136306431353237396666 -39616563626661343763363462636463666235613261363562653831393135383565353666343565 -64643935336166653037633331376332316130613133356638656233333030346235653965346263 -63386335336134363336643138343839343362616331363439333165653261656262343030383736 -36363736313664663864646133396166653839333734316363633538623464313166336539396366 -33643163646634373536326436636537356533666562333236303231356339643966616161666661 -33623534313966333438643230623134336337323333383738323931643739316436363964333064 -36623338666264353966353063396530303037353261326564326461643564303366633933383765 -64633361656533646633373266323763316536613862333433386131373764343935633832666532 -33613165316636353032366466306566386439366434646363366161653863343736663236656264 -37386537313436326461393534353662643935393732333065616165343338376363313834653833 -65313130366236653634626230656562343361663961633063336363633765306132313439653334 -39626166666538393165363962323532366234633033393161366661313839626130306361393865 -38623764393136646561666565363136333636633737623235333335666165303961373266646633 -37356437663165366538336364666431656264313531663134653437626462363162393236663037 -65393138373361633534373262643062363031663235396233376332623535613265373362363039 -6431 +64383537313933616565316136333365316362383036376163373438663266633766666435363064 +3935633565386631376632623062343237383064313162610a306263666330633464303263303139 +32316632343164613237326237316338396533336637373738313132343235646235633563616332 +3338623638616165300a623661643031373566643239323166653035363263666661303134656465 +39633566366662663434343264643862383864393964316531396230303834663332336633316138 +35653339633437393738373338626262613431383638626132633837373563396465313939303930 +64376534333866643562666436366436346364646130333432633735373235356161613765653433 +36633038346161353331616530376565343262663161353631396237393631643763343465653565 +34376563356666653739346430643334383131313464313833366137323239393530333437323863 +61346230386465636533636133326531653037326238613936616639396237633936653235363739 +34666636376132393664366261396466313935356537613363396337623066383064663066313231 +30656132353931623933313331646132386533363761653939363932383339656332363538306239 +37366338326134663730303065373463386561393438633861316639343532653764623865313064 +39396364313662633634633763336633353963363230666463643664303564613230383865616330 +39393465663237323338653832636532353163666636313832363030353133316566616239366637 +34326633303031663132303632306166336264366434383835323037313436396362646664663732 +37333834366239616637326363373034666362663632636639353835316361336562353861393561 +61383832396662643639323834663939643034623838623032306630396637656434393762653363 +34626163353666333364336637643831613933303537633064636164363739646464356632633732 +35363061363339383766386632316530653831613763613031316530336331663763303561346639 +65336230343365366237666132643637306335373934336338313765373464646461393637383636 +65616431313834376436313662613761376263623939343732373338633239373932336334356130 +66333161616339333530346362316162393832346134633961376533633033363432636231396538 +33376633376266306439366133333166643961656133663638376230633535383661323232333538 +34353038363537326161323666303837653866396336396435313261376336333965316139643531 +39633062373065656339626466383934323966326161616536663039383235336136633139636636 +37373066393431316366623163643132663133613935623237313162303462366265623562643135 +39333364343263636238316363343733376238343530306135323131616638666239646465356637 +61326237366632303139333364623365303563316266393432303964353566633232646636663038 +61616636653964303663626664393636386339366535373937643439633833313437336539333265 +65636262353837623665623634343134326334336662353064666361373238363433633137646636 +39313664623632346563393362326231336664613539353532323432663161333430623863363864 +65636166636531353030656661613134613966616565333862376231396431363233376164343435 +30333133366164366364393164623637353934616263303164313633393266306638633164346135 +66353964393064623935316430373432306264336264366131373661663830333630386335346432 +32333639316566653830653137373738303861306535626335393964616434306438383163616533 +36646232346261323133623266383239366138383565646463373138323864656232336631646638 +32643766376263663362383336333465366263626637386264623931323037366532323262376262 +66303935386432653336323161303430376632393534616430323161303134373464353031396131 +31333939393661653935373235666339333032643632333437313563373738303065643331643239 +39663239313639333464323138646636313034623535313535646365626635336265626464633365 +33356432666139393764326636333534363030396363353063663131383232646539373232366632 +38363365353936363962313235386632326533313131636538376162353034386437633030356534 +32306536316133336136633134613833363233376535343635313131366665353133316461636639 +38653435616264313138643161313838346439343035386235353734393661616266633964613538 +35313633366530326538343062396438383462636664393966623230373631663737373763656631 +30336332343634353061396237313539316266383033306566303039636437613335363966623938 +36356663323732666537656364333032386365386436306361643835643866643535646135363866 +30646633623461643266633539613766353963653130366162376536616330636437383931653232 +66363435366663306631336631353161616132666139316235366537343265383064353632306233 +32343862376537653831663238363836333736373136376331346430346333326361363732386363 +61316236333030653463313338663038353665613432333837666666313338623731353136373030 +61346535306130393335336131386630623033363131623963313931646532633933656539326137 +62653564393938623432396632663665653237303637646464383233363434393862303736323661 +66336132653339333762363365666163336439656662653561396161333264373636623061303931 +38633637373166633433313565366234393561353431386330343536366662386561396565363065 +33633236366637303162373739656134303631623961383835376461303566383435343734386662 +66373030616633386232633535373739366236346439633664343536313535663536386265366265 +63393635306130643439326366623663646361663965303331353462303066356164633361393033 +38343735393438633735633334613731333031373735373330663264363836313335363663643363 +31633933626538323130336364363732333231616437316361363164313964613137376238323662 +35366234316362393864393939663232336633333237363163653032393532643932343063356161 +64616432316437633539313734386130306330623330626234303839363866353764313432306561 +37343534316138653936653162393531366539626231646338636666653137313730616465646239 +64303361303337323539663637356432613339393435306564326664346166613762376466363834 +32366534363935313832363337356362653061666339386232393832623863643165306463396438 +62356436643538616234636466353939353563393061633936346462323431646236353239343137 +64386434656664653361626663383064383734663434326537633638633832633839636463643437 +34376665343432356239333136656432353330653665653165613561383062353037616262353933 +39333563663035373536326663373366663938646632346439356364643637636262373036313663 +65323633613931646632616362323262643937623266326562636632663966373836316331313330 +38353262396433313235343565616161656136613266353364366331306265326138616131643736 +64656638306634643931643937313931373662616133343361316136636338326230613962313865 +36383738393462313664333532333735663764396436613335343965343238396163643062623062 +61306537303330373763626365363261343433383536663364346236373734363831356161363238 +30653661313837336465306432626633623462323734313334633565306462636133376436653364 +37383435356563346561316232633733613663313739313639386263306664376239656139393632 +34316464323562353538336636343035373835643736313831326234643636393961643333653539 +35353961343865393066626330333938336164356165333639313262363930646663356136626263 +34343330633536373564653138643739316364653039656334303035336134623762613364343333 +64383034303035633536643831323566623966303962656430626362336161616666636532346666 +38333961643734316362363731326562343135653863616435323465613763356334333366316138 +61363135346663333963306533373739323731623766626235313630646366393465373031376365 +62366665353539343834646437306231613962643131613538373231333636303863656365623966 +65613461353630626663353932656434326363313835383634393365333162396361666136363338 +61623463663166316139616362393166323861356331383464633666333061316636616330656563 +34346661626239306639623737373563306238356166646430353331323834386435383761346434 +66363361366234623830663638383432643766313565363638373862303732303130643865316138 +62346534646265666463656334326435343464373431633464313931633832373438343864663832 +30313135393439616234613736333863306235393036643136633334343234363832336666316634 +30393733383164326437306663356236363930303035373438376361306361366536333433643333 +37623061316266336232613761323436363535613962353634373234333632623330633939323537 +64343665396266663161343839323636613865346330623538623538346163383434373833353966 +66346239343965363833633164643661646162366539633331393032343630373232333937633033 +66663238336434383534343565393062646663323139616131316431396435653131316530626531 +33663831373337363863313663373061646232313562383130613866313863653637623361396464 +63653039373565636265356435653738386138326362646438316563333134623063633865333830 +36663433316364643566636530666136613432363431626230626363316632313864376435353761 +61343966623963646130643063323334363961656339323333346536663538383230356530393737 +63356365363162643364376566666230396134323930373035376631633435653534626530663734 +35646332396635633865623466663733326261636166666233356438326530653931396236613764 +35393663346435633535646163383231633663616436353066633130363535643230643334386664 +30616633326464326466623830393761386231333863323832643032386566376632666438653462 +37633732353934356666373063303762633366323466336161623666343166316533343331373736 +65326535623637316463333035666335643038303066336537666361646561633862396231623066 +66613335353832363363353036616131306565353866393831373433663465633133356563616639 +32663932393039396639643762316665356537316639303937313835346136313133633136343432 +30616135613537346664343238656564303438663038386534633838306336393265646237623039 +66343562393630363439343566353730656530353865663834313836323031363737323237383737 +61643333356666633666656337633562646339376538646131666263623237653365653165643438 +62396134333034316532616631633335353234383862376262663562616137633239323339386637 +36313638373734643230386339643961343261336666393439646566646262343566393364616235 +35323736666439343537376234633766383362656462616662303436393962616333626534333137 +34343738653632396632653230616339613533653063643930643639616233353063306464313238 +38663638353336616434396563626332376665663434316239663935373765376563393164363833 +66326432383535656461666137653236306636633931346432396361316330386265623965653638 +64313732326464666636393362376437623263306434303631656661616530366438613262383835 +66343766363461383465623834323536313032353435666139323634366437303832616266376663 +62353066626634333861396264303465613134653463326133353231643938653430613733373830 +62616535326265353661616531313738626461623732633636663139336632636631396566316262 +38626665306233303162313961393035333932663931626331343633313136616366376235396562 +37646438313066356238373135333936333938636338353437643666346633636163663536653764 +31636139336262373761343839343634373231323464373863366432383461373231636437613739 +39356433303861633338346432303032666366376537393831616432343962663933653531316531 +66636233633434316231646462326538626236613563656462343530356437643235636631376636 +62336439353330376332653631336434363433653139643633613638623036636333306664346566 +35656330653530653734383234333364363362383934353264303336366230346138653666393935 +32366563613261646462323661376233363135626536313662303731326337663765666162653735 +62633665326663666136303537383965663831393062383139633835343333306333616262336431 +66303938336133656565366337376636393031336130653261363736343062353139366465363165 +63643036663435396239323762653532313664646532353162653435376333643064373937636530 +61623437346461393034646665636134326437643863376532383731396439626163393664653436 +32653763623662336635663465653031653235643233633265333937636635633735373761643566 +64643434643165653961623432666665333033323936373939346637353731623831393163633865 +30646530336238323064643233376131656366353138353066626432383838313931653836313332 +63343234336662383062396664663665303539613230393135643662336161346465303565633433 +38346434326563623661656436366533366639313739343636323331383166666661316531363330 +34623536626464393832353964393465316466373063383231636132303238336236643231633032 +61363433613731373335393333613862313866376664346663303762633839633531653930323966 +61653166613335633339336266313634646136666461353765336131366164383265323366666463 +64353933363938303562656238346633353130666136353736306534316132323665396365303037 +35313365636564353461353935353364343332303432353035333365343932643266393331636162 +32343762653865306438613435353566623331633162376533333630353261633164306235363663 +65336237613935373461373837663333353035616334393331643662663330303538346436303839 +35303764643665663130393465656131656437383663353961313637643537636232396235303537 +37646263333261393763343238633036386136653166393165346165623336323030313735643264 +35613362636463353230303432343061383366353864656138633933373465616235653164353637 +30323432303938656437333238363764366331663539373563623135333162386138333664336261 +39653964663031636336656630396662393730396362613935313761656363666661656234346339 +61653031396337303961323031373666366237643638626164323135616163386137313566623265 +31623064616466616563616334323431616131613538333035646333666165326632663838343762 +36313765356362336664363835636563336164653065663335396638666636623738666536373839 +66386131323237363735323839663663663261363231373435366337326163623662393334656166 +35626362643736323635366531396365346263326566623730303736316264363030323934353330 +62363639373266386238366162666264656237656332353562373762333462343366383766633162 +37383862613366626665663934336133643665623362623130343536626362643434633037316635 +61646530313032376564323934633631613264396232333362336365303235646665346336383331 +30356665613736366538653435363832326561653733333739393363643066343234326539386465 +36386363613731656665633936366236363964363632396332623335316335623465636233613763 +62366538373364613264353439663731626138613137313434326131326530626337356533373966 +61333034326137343564643464393864623366303538366665383532306265633363636231363930 +62613835313338383037353366623933333135633431623964313563616130653735633733383665 +32653565363263326461356235653538386563373038323036326634653764333138613031303538 +30386366366463343161636461613739613766393866313537383564646366376635646131396366 +37306539393838616638343236326634323661336265646664346564316432306662643833643561 +35316564346564316562623862383565626263336165613662653339613061646231656562333738 +65343430653062313164656565636437353630316661613765616563343835383463383530336433 +30643339633663323632343334353436316634383434653834636165366163373065306634613636 +62393332396333663162653031366336636262383265323030363036313465373239336665383134 +38333834643666613536326532613637343338613432333739623036643464373438353236633337 +31333363653837323736336563643364373532323132346239323534653135336163626234613962 +36313937396431303833353338646362356462633965353761643336386534613863663035396563 +30653963363236346463646462373034623463666439386235353132313361336433393532643163 +63363032633363373338643039613565376531363062353839613163336264373966626262353565 +38623637373933353537633638366539666166363633343565666564303933633533353564636238 +65326632393966613635663231613461353631633837363962363462313763633130363438393232 +32353461363666373162356361323738616462306630363265396230623335623939313966613239 +61343731653263343665383632396366656635623662386564616536663137633966626339383832 +36376233633337383833626664376262346366323634303032376330366263363733333733316239 +33613233626132616535346363383964373261663734376166633465386461626264356462623935 +33383330323065343263316664653062346231326461626131313661303135386163326134663437 +34383865343161633639376133333639363132623432313337636639386562626534613636356263 +36633565656564623239333630336635643865313137356166336163343439333733333938303232 +66626533626439303936323865663833633061303330663564646462386134656561303539363136 +33613764343638666661633338346534663033326233383861303763663863656232353532393062 +35336631316562323338336631316538343766643364316134316561323062363535653962343535 +33633662363866636463643966353538663533323232656461373434333632376234666261346532 +63343239363532633933336364373663626639653939653934646266653534333936303562626466 +64656564383135393439663064346266613664653133393932306537643566366134336364303263 +65366462366230386364346135373966336637636236373661313935383066643635663063373463 +39356661653562313863656336656137303435396638306535343666643630653637323230393334 +31666164316166626635353039616463363564393033346533636133393163383238616236666433 +34363434376430386266616666303361363933653165313963303530666432356334336232636662 +38636561383066626365353932323666343731353033646163356330656633633830326562343138 +39323961313666396362333062616331373734626563336235326662343534306261633830636163 +64316439383835383966306335343937353139396166656434353465663331386137326330633561 +64316531613262613865653164653161616535666230353365396133633035303532383336346335 +36383161653564663963383031353661343563343966336164653761326539346163643763313561 +33353839656633356333356261356466376161343430333733376531663339636536616236303464 +39393735313039356335386332636637356231643566656530623537366331313931613163333231 +66626163636137373834313030323137343965373865303836626261616630366666343064656230 +61643239643634646566313532626332376664656264623762303966313462343736613939616636 +65633739323663346337346233376635663839313736613764653135626632626530356631386338 +61633632333665393465623032643530393262396533323230323865376330306334613265323562 +61326161623635626439316233306563626661373863653766393032653039646466336365653934 +36353530613631323666363235353464626266376630626231333532306639333134353934326431 +64626263383863363232363635663637373031613938363732303838336337393462323434303137 +66373139646238353831323839663031633964666639363231333130393963303638666339376434 +65623132666566656561653132323864303231356338336164353936623339616635363230383066 +62353236633737333838666332363730663636366537363564626339613633636232613365353933 +35643237303731646536303536383365333936326539373665336264306538323439333636303063 +39653661353839393331613061643235646636626663323164393331616539626561633539646139 +30363730356366363064386336666563613465343431363832366436353633316232643234313566 +36313162326436376234633233333564613136363734653331396436366432363263343832306437 +66386561663564366635323839643164356165336633343230623234306465653565643866663837 +66396436323636336536353932343565326636373464306138616163366338306339393332653261 +63313366356136343632366134333361303235393066396635356131353234306531393965653564 +39663330393762623331613433626666626635343837383734626266373235616665313435303531 +33313863626561613938386639646261393431663731663239363666656537633962373237646364 +30613466393336613265326630306532653338323965383839643565653164336363376136666562 +39666533343739633831636531373230376439373163313161346435656438663833336262653465 +36613366663133316461306230393234313165383433346439393166313333383737363361363734 +36643361343332313738633032633161386439356433326164396531343532336561393666356630 +31386330306537653739633865386330306565343739303335643262646166303930333833646136 +31363739646638346261306166366439373436333932303537326435656262323538336664393461 +66373461386232353930336338393063663838326435323734353364613637303639303062323737 +35393933383833396638666233616366346161303438613331626133333631363732333666333134 +38306266616334626565646462613663376233393830353634626436353962633834333539643865 +64353933636231323564623066626331396338366165353166343862636466343831653561643466 +35633463626630373661353438396437313531336361623837346461623335323438326236633762 +38643132623232343230306335393339636461306337333733353333363832363162333661343664 +39613031313538366439396136396561363164386337353533363161316266303461663864393962 +33346534613435396465633539653064376563343837633536333739326338313064383337623764 +62366165386334653365343361623530356538353736363765393437326133346432306264656166 +36353537353336613364613236663332636335356162326238383465353538393366303536343562 +32383132303563363434383939326139643337376462383336646134353537366530386336356335 +35633734306639303834346230643435636530356666616565306437386464383032653964316563 +35323163356266376433343663633534613162306133623333346265623139303330353135633335 +39306434666139316634383461366163333366373835393432376533616637376139366530386631 +32386266303364373663343438316235363536653838373739336266396434313134323530663239 +35663637616134626439303365343662626539346233656661616238383566336662633164343737 +39626534396439336634646538326134303533663765646233303831393234323964323736376330 +31646562643432396161663933373361316635336232346561613736363634616264373365663432 +33613161353762376635613039643164393338626463363733353235613136353237643736376661 +36383534346336336332656536333466373932343666363864643465633566663236613762656635 +38643131383063656665613366383763646262366464303835386630303165636165393530343530 +30346664323965333863633135393962376530613236393863306566643961666333336433376237 +37306233363831306436656263333633346536366631313663383963663138343861363136616262 +64363732333262646165363839306130316139653962623738643264303462303334626234623137 +37646239366563626562626539646662336136613839663039343138613263343964346131306433 +63383864353631636262633432383837643663653635393436323961376366666639626562656366 +34333532343434333037396133303134346365353632323066393432646666323963323834646235 +35396437653139613061356662613232616563356164396366373961663831326363363432666462 +37343333313339346630653630626337663665373135316436396234386361663033373639316637 +31303465303831303461663836333935646432386562366461663935623366393666363636653765 +32663138616636623738383932633538663933346637383637373233616432353764643730376235 +39623066613964373338343466663036663434623862386238313131363330336238643632373031 +63646534653438303633363865393336333662393937303165313563663964393830323636396232 +33643064396633636334323261666461343766623532663166326637363734346638633737613564 +30333831336263663938653964626436616430353164643665346333373935363766316165653335 +32336164363736336130393361336533303665646335643432313931626432383933333262326631 +35366265376231313833333634623566326262623732643838306162623739396335636335396565 +32323263333939313763383361383739313938346236653938663836663563646634626633363034 +39616566373235623834646638386361383937373539383166646438626639626634356132373838 +33386561653230363033336331393732363562623731613332633530653534353734633338646165 +37636363316434303431343266666165396462373631376364616639626261383465316630613934 +31653963396239613332613537333062633936626263666164373766393134396435376235393161 +30383235613432613633663366313836356561306262323137366637373266653130363134396434 +34333861626464613564383232333030383334613430633033663365366365303461353031653665 +31386334636130333862633533353435343738323066623030323635333137643666366536633937 +37613863393736636132306639363732663861336166306234363063616162636661313736653132 +38313831323934626165396165313130376663663637396435303532343261343965613261323832 +31373366613366663665613363316361333735633261326232653865363465383632663966663533 +33366164636531653337363932303037366239316466623738373561663964653639613030626535 +34356664633537336330616365386331333333663731653766656631376238633563386166643161 +65633962333864666337303766356461313365613061303830633737346535613865633130316663 +31643733326239306665373535393163356136633763363838346265376538396361396461653864 +63633833663338383362303163663238613834623032303534663363346563613263336563656535 +62656433303166366634313362623637306566363862366462636535633932393865386637336538 +31316332353163616662363762366432313730333964653264306464636338653163383062323033 +63383932373461656638666232323938643661613961386634326163613439626563643762663666 +61633761316438383961326634613730343762363964373865363134303231653066356632333731 +32393263613163666364646538316532383230386331623133303235393435643934663333326332 +34373761616566663663346563373165336564666431353632306136323663353532313662363533 +33303665303362623661386639613435636166383531386136303435646139366164373532623838 +65383161353266376135663534313661333933653033633139333537356533623930656366646462 +32656139616336396132323437376461326636646362633932306434326637323932316266653562 +62653239336364633963623964393662396337363632633864636465363233333261306138663764 +64333330393831663366616336393437643864663465323638633662656636323863386636663639 +63613035616533346663333130303933623933343365313066616133353263393732366463653135 +33613039653233643839326530343961333132306566346531326138333133656430666361646165 +66353438323735346338333961306266333233646132336164393731633965383037333131333964 +34663964346466643735356239653532613636366131356439366632333730306532616664383031 +33623335616163656434613138626639373030613239636332326434393764353735346463656361 +38356261386138346233346665633661386432663532363565326438653037343362353966613132 +65343762363866626466376435343961353364623339313762376330396364303439396139313638 +35343361373631306136333030363032613935653866336331386638323864643232643163393334 +36653538626564313064653039663033313263396530653435333765383361326334623932356139 +34343835653261626633626231353166613766366534346664626264643330623234336566396665 +35653639383031363062306331373336373238633735656638616466393232643539626131616632 +62656566373930646533633961383737393134653432666538666431613831666161336265623432 +30383539373230663639636231313738373639373833663564393932383231646631653864613831 +62643533396438633232386265333361333837336534633864646330616431376339323964623836 +34363531336336323934323539323361393665353339666365633239353338386132646564383639 +37303362663539623166333134393238343930326437346434353662363032646230346665333366 +31316532656333633833323966353365356364663032306666336661373631356663306434306363 +66626134653261633131313362346362333830393565393635613037613266343235323861383463 +36363164313939303163353265393265366261613866663235613634356664346234656434323539 +61643737343435396666633039323530376662653936393561636165303836333965313033313732 +66353938653638353238396261336365643033636364656664306533633162663031616535386235 +33346131623137383634643932653436646264393834343839623932326264653764316638326263 +38303262343363613931646439323235613262623431386366623862626164376636326435613431 +35363936626165363331623962633834623762303762343966363631623732653563663061636230 +33623762636438626564333439616230366531306466666262363634376234366134616564373363 +32313336333430636234346138383339613431333037343734376266383634396633353263326466 +64376531623564646230643230373438353637623133616331326535636330316539643732333565 +37303263613031653937363137613630386562303865633362666463323530326265373165306236 +32306336656336613837333431613031366137373664376530636233386232613361386466393264 +393965386163313137316135313565393132 diff --git a/vars/secrets_legacy.yml b/vars/secrets_legacy.yml new file mode 100644 index 00000000..60c92d11 --- /dev/null +++ b/vars/secrets_legacy.yml @@ -0,0 +1,269 @@ +$ANSIBLE_VAULT;1.1;AES256 +31643538323566356362636135616364373132633962336461316338393637373464633364323436 +3038663731396639616433316664643437356432393262370a326531336636663632656134376638 +34653336383331646430373264306136316637343836396238643436616266643633666331626235 +6566383432366339370a633865383130633565613365323635306133323534646163393437353763 +64376362636338333036663966316338366330393161366666643933316630373430383831636464 +36656631323961376366646230333339303165633334313462316632393633333563376138346332 +32653263313730366532616133376439643163323562636134656139373830653232343235326562 +63643238383565303965306534323764386531353661303965396530356539333263383362393164 +64376134396366393636353863643835363638303266343435373732386263393337336139656130 +38366664303539363035376463653463616133383633646235343461626639363762373336303161 +35323936666133653439636464326531303234666239316561636163656134643233393035333163 +38363264323432393930366636366632363232663732333131333566353436366333626634353834 +37306261343861393231383466666632316437333963356430383633383861353433613032663536 +31353139623932393737663266313262643866313431346439343430643765353031396366643031 +61366638393937393161313866373938303164323038323331373532323133373761653537323462 +64386639336661613564613134373266353535653265616366303532353161646139656630623536 +31333439333066356136653666363063653265336366306662386533303035356334346266396636 +39366238343166633762646638363336376234626261633631303236393535333932623165646164 +38353037363939643065646234386236353463373837316361663536336333366564363862383264 +37336233373765646139303532633033373862643437626530323539643338656663323261653662 +30373435613834613563333266323933383964353261353566623833326437303165303831653835 +64343863663665636336663761306534363866646461363238343664373739363434373435613038 +31626234313136326465666339633533323565663537323639626632353437633531393534656166 +34376464653263366461336634623631393064306531626132353966616132633834393337376337 +61663031323862323564616235663261646231653831336536323535373032366538383336336634 +32623939383962313136616661393738303538306432376136613433386261636564313662386231 +62373031333538313534383363393966386563323563613363313364333263353763373166333237 +39653030356161313830613262633664373032393138303731363065633266613561373030393634 +34363166333939303331626233646433316561643133343737353530353763656230343261303133 +30346135353639653734393564306132366362626634316530663131326639303134383330633565 +65353637653637373561376132323634656433643931356139393934323861366536656432656563 +33666230643139613831356462623731633737333931656137633734623630353934613361363639 +62306538653233346161386334373464363334336333323266653762383064336664653434366662 +36316532383462396536656166653436396164313130663466376335616537376661376134323535 +39366461363366633235656536316139653431663261613265306531326263376263643066656537 +65353666633932643931366231383165666337396464643632363064663536646235353233623566 +34303335656462623166646138313363383934636532666332383836366539393166626366383261 +34613933333834353766356534363263373830393564366566643437306335386630383636633439 +31313435316462326333633363613836336364653565316537336232313766336632353862383961 +66303361613235383138386132626433663132306664623336303464343531326566633037303431 +63333963356530346134623063626666323434313036386366663132343266393361626262613461 +66613438383337626535643938373664626438346537363535346132616165656266636331643461 +62303535663539616132363239333663326563656538383265363030346139643033313139613337 +35323864663431656266323363336465373539306231623331373932313337313138666666316564 +63666363333737333932653237303836373264343638323439303031353766356533393064333430 +39656631643062383830383338336366376333376264653963336339663134396333316138366530 +36646265623930343061386538303138373766333732306163613561323638383332636566636262 +37386238656632326433616335313332633536623163663438316232386435373165343132306631 +61336464366432303736613839396432313135313035343262353766326631336666353962383265 +64636365663537363834333639623233623032616463346439623833623634346564363631326464 +37626430623235656136313531366134346333336264313433653535343763623263336265393538 +35353037646132346361656166643337636134363432626638353466633862633461666164643463 +36626261386366653735663465313236623239623036316234613433353264623037663566326231 +35626663353933663935363333633665373264613636333864373639633961313133623535333232 +39376164656132333639653138323935613135326363313832343339313430353864363731666337 +64623462336332306330303533626364666566636563643464356133303066646437353334396664 +33326635336165363761303230663632363139653965643762663632626464363661656331616661 +35396234336530643633393336346134623038363263356532303936386139626365336562666636 +33313936313736313363626362636466303462376638643536656434346665623066346266336430 +64656565613466373362656131306134633964343034343964343837613032653334613035663232 +62313963336237353437623365373837373634363431666633353965383437376635326163663935 +34306235613731386333633933306139616565636336396331343939303137616431636530646236 +35636337363333383836396464636361303562613365303230633137346333376337663562356430 +34333336373162656337346136393236343738336637343863326533376365623231393636626261 +32623737613238306137316233393833366339353963666165386633623463366535633765613639 +33303138653233373739343439623564333666396131313434393035646362343031623162633861 +62666230333132353530383438386238326462396265313733663039356461333661346332373230 +30613365613333666435303431643730663530666531306535653663393030643666613632313262 +65613936323265363338373565386264353937366531386463393335393339323439653734343863 +31353232633539376335316561346265373833613639366530643330303637633438616165346135 +38386439663434613732303966653235636664383437333839666133643465663735383065666664 +62396564333734623133653036366531303738653762633632376261313266623730336465613364 +39626663373335623166636432646462646132376238646561636638316465343937386633323663 +61656563396332656264663739353261316337396663643938366561646665373032373034326238 +31616433646137666534613162396565363366313733386233306565373233386232343965613636 +35326165356132323366363665636231646130356634653732363561626662306637313465333835 +66316137323137626339656661646130646166373938333538656638633361666165306134396137 +34393461643566653232653839663030653362626537396562613761626434633035623264313537 +66313863323337323037663537326632333162653230303938363235623537636235363237376439 +66633762313962333830656236366263316162643064636462666464326462616632666235373930 +65313936663633383137633731303361383030316662616233643337653933613536303563633839 +38373134663932386330656439393131656331663962393336646639653332373332363537613534 +62653136373765383735376162346264343864383665616563383931376539666366306261373230 +36613962366365336435333937656362356461303366373231383963346438363439663364316435 +65636133653934373339366132373339616163343837346164323337626639333539636532643331 +36356263386332643863393731306365653239316635366365383936303938663166623762383463 +65313438616531336563623031373361326465633030313264343534343934643137306339376563 +66356535653962373432663330363534333961323163323961626432636563336639303736383132 +65303834316164663262613063396337396365366139336330336666396238626636396336653762 +30316538356231633933346639383135663530356232666463666463333766363864326537326538 +38303637663563393465393139306165333636343134373162623939663336383763663362333739 +61626534613064306339396331666664313337643061393962316135333463643932363333346566 +34623530353735656633343137393637313263613931393834323765623536343835366335646230 +65393563366238333734326261323065383965616239356536333732653637346437376232353065 +37353037383361376130393066373131346531643530313862373938376662626663653762356664 +31353266373138343962363137313266366131316663373930353466336634643561636364653266 +35666263323231646162353437376339326238633037633533393833633465663837343464666133 +37653831363930313330653931303064653636666531656464646166313831623232643133633532 +39386266653266623335663138326434393733386262343539353266393664323931613932343737 +32393433633437386461376533643734326233373165633038316266656337303130366133316234 +33386334366135313064656533343437313037323334653433663865343337336630636234666464 +66333463393264373936303963633538333165376363323338663439613830333930333133386130 +66636130323130303963306338666433363839643964336461663565383562336463353136643363 +39653533393433353966663061383035373136653331303731363964363239666631616434623331 +62636431396332616664396431303939613237653066333234636665363562623830376636303830 +62623366326233323664666637386238333963333366653838313233633465383130303534613636 +66316230613032373038316530663065306133383665343563353435383737393163653937656265 +36356163623364653337636162343030356332316231326333633035343739653237343938636332 +65343930353836646363636436313030663862396337636163303137306566623264656432656664 +30353561306634386265613139373738343437396363376532386161316464346330326262636565 +32636234613034366232356332663032393933616135663761663964636262656436646634366330 +35373365356236313265303562316365613765306336396166383663346263393738643565623261 +33646537393830646163666362396532343034346135366535386135656662343461646331343964 +38626161653663393830393464616632313762323539663632663561363764303139666261623332 +33383561386363636330373966393665366230373461373135623732616134343339393439386338 +61356163323339623366343364616164333633343833653266366662626566353662656562643836 +33643866323335653866663132653166623135653138663235373766616164343230343530656637 +61343533646263356332303163326365393665393135303737633030323130323735323130343566 +37346561326138663963363763356234343534666236393861346533626434633661366161643461 +38396635633866633331656532323065633066306137663432343630313433383163633639313466 +39333266633234666564323637656233393463316663356632663465393030313530393836346366 +62303134623332316332376539343237646264343662386239663734376131623339613632333262 +36363566646235303662643664663266383732386630663232383336393034616663643364333339 +63373365626661653631636630346362616434373232376631326138636433343135353131646161 +65386339613734386232303933666137653537633766353132393134663764663130623861646564 +39646461613362346533323433306637386662613034353563393666383230363061656463636234 +63663736646533653863376665306535386566653835306139656562626135343339373537326664 +65353266626463623765656463346639393336306438303962333636356365323537636137306437 +31363766626334316632373132613938396536616131656130643039356462343339613935326234 +65393564313732626532626261626436666263363539366565383739643937633766333763383537 +65383666666236343862653361313664616464313066373930396162653764396462663531343665 +32393338613362653438356363346639343737366339326261323532316366623962613733333638 +63343236396330346336623039633733626339393835383963336431386631643634373131653338 +37383430363936666364626136386638353236616439613237386366326166363564643038306631 +61343965333138356230333639326436383433633164386532633064343362623133613565343032 +64323264646337353632363039623539653534653435323265386337363933633365356363303066 +30323362306236303937373232656461323136393131646361653939613231396233633033323762 +31363837376361663665333766373565336465613034313131643763633063366433656230613164 +33633964656334636165663339656239313132653866343065623637646435373638633536626633 +33383164656362323561666666666565643836396433643832306465323566356439336161626436 +63333736326335643033656265336366323831303932343637653366373537356338316666393362 +65666262376431323731363565376165616230363563313837393835643030343936663635633639 +34623465383730383662326339653839643562303939386566373835323062356136363932353338 +33653762613839313032383763333733366131316637653737326464353730326538323637336566 +66363831633565616364373839343661386465613731336239373661306233306266356336666230 +32343265376434363330363136646531343638376364373037323936353263643038643961666364 +64336561336335663137363731343636343233383865626163623065313637366535303936646365 +39363766376639633831613739373831643735323762363237376363626234303939626133653234 +66393732323936646363383934356335633134663361303261393731343832666139326535653035 +30323930373638623437613336376562646462373430613964353138393539303065303030643966 +62643838646331326364663031323565353063353262643937303564313865343563666131323430 +37646139396266356635613863393539636335303365383931316363386661343338616162353665 +63363365383434636339313733666232306166353764366230306233633838353339616636343066 +39616666343639336631383034633466333861666634333833303238643263646433623563336665 +36343937333864306630396333653337646565623338613566316361386637653236666262303930 +38313532393063316139663537376337663263396361613138313063363365363439313065363433 +39333435393034336164353165366230343839336261363631383462326630396636663137353537 +66666333363465323061333434393262326666336564643736623435663733626534626530356561 +37396438363230393636366663383532323734393131656461383639363835366432643566323065 +30376666326339356131366538613361303139346461376635663138633533636334323764656333 +38626634306364616465386361633034393635626433356537636237386338396239313539383765 +65663434663366393437643265653830386135303933643363646264643733313966393939343066 +36306439376163396231333432623932303237353037613930336535613866386462643166373637 +64356164366364623539633964363231653863313961303765386363646235633936323139326563 +33663836626634333233313736633338376336633363633261663863393731383664373461323630 +32363461353735386431643137393361393439393633636138363962336239633865333064303265 +36346564613238333231623535393266373264333464613864373932306166303833383630363466 +38333630373439623264633537376365383233353831653664353764393037663364626437383230 +38663935316435613339383835626534623563333537613839323139366136646238333130396230 +62626535393632643766363739633165356663346337356331636238313732363635316237333633 +35323933333362373231376466636662323263393935363666613662326233343636616434316464 +35333639626137666635376666616332633265643664663330376434626562663662636566376362 +62363734393539623033383563643238353935376430313832653136663965353833656230396163 +63306530323864306563393730316463613162396464613063346231613131393137333562636666 +32626362353130333366333133376462336137343132333138663330386264613536393438613766 +66663863306230323235323133613466356239363139326236623163336637363164623038306164 +38366433316461376563373230343835373838323765353761376564353435376235626338393364 +65613537666230323031386139633264383965373533633739326132623231313465616233646134 +63383836396361613263666533636338383232353333393336643666326335353932363336646337 +64336638393566663331356630323063616331353839626237663164376636353035306666336636 +37643531396661623263666235323438386332316538643361623432376462306131353030343932 +37343062646362393561633835393261333765353431663536363264616232376361316236323435 +34386434313835333337366439313136663735663531363932393764333935646265356264313739 +33396234643332363865656237313731353232383066333738656666343938353138316562643434 +37306661393533363035663334386261313533643731393265623334666338333165336237616666 +66373661313030646462343966663736353530613635623938366565316365356261646330316465 +38663365643839363366623433656163383864616462323934353661663836653632396233313732 +64623131646666396665343962313063306433396430316632306161306336643866346362376662 +63383462663830313438616632613065376464363237303264633363386638366466356462316439 +30646234613139363865316137623433646164386136613932336665643030306266613338323361 +30346664386538393334636364316362653032656432353131396632306563636632656332633339 +30393335633830306330326463333564346333653461343938623131313138346366643337666164 +38356437653331313032613333353734613138653561313730383237353431316536366336643165 +35303531393361616133376637383235393131623231656332656438323063333639313233363039 +33383639646538353335656533623831613338363537613236343135663531326463333962333730 +30343932643862363434306638353731616337316437393131316161306338646566663865313362 +62633263663261353930633466666132663431666336343263613638393137383961396230633833 +39336363653737313761343634396462376263343739633039666161643861333733356232383265 +64363133346662376661643437313332373230626266626262306234616139363865376263326238 +63336462656333666338633138623137663133313833393766313136666134373932313232393262 +31313933396662393262363137346639623134346537626362356161363336643364613932306632 +63326236353238323164323235626230653962643261663362633632626439396266306266353032 +63393963623037323337336232663137303333633134343837343334636633303065376232353264 +36616631616566353863653934356432396665373033363638303166613034366563633563356432 +34613165363637346433373963613334353463353138653766323331326137373862346137363262 +61316465333762613832626664336566643130623938376662646639626335323332376234373233 +36303735643164633863656636616664353134373530323431656330343835356366386662383132 +37313965393062633366646239376532356534626535643061313262663730353838346262343862 +64356132353864663437366230323362613064663962316635626232333233616234623335623366 +34306366626135396231646335616338663439656238333338316634396265336165353937343462 +63343233316433613633373063366663363464303533626464653632313162323064646238396239 +32373731623261633162316538636638333439323936346537386538303764656539613565626465 +33643766623730366463636237323932303364643864363366643334306236306430346131333938 +35336336643837343939656332353338663535353033323262386335323332326437623463316638 +31623938323631646338633537623134343439373365666639326265303931646430306230323664 +37643064333435386430303338303932313338656634656664656539626430633838323139306261 +36333262663836376464623831373137663061326338663762353163663036616331626235363739 +63646334363430633966316232623034306134613338353865613462363434343962656463353933 +31313330386534353939373634386332393065353565653033343832626630666563373730643439 +64643338663561613538653263613731353136333539336161333763326662353566383266623863 +34643462376263633761366563306331633562633363353165613531313437323535316562356462 +36343263353364626165366361333638346236306536316434326161376334313361623539613139 +66636133613336393234646135313633646564323936666166643832303130623762646237636565 +65313135313037353639303331663661386138343230663763353533386634336461336234373832 +64393563373033646265663838373339636334656665343565643461353430636334313831333532 +30633065666636626535623561613464323737613464636439343836333834626538616166353037 +38326630343336643934353666666432333761393231313466373739323133613062666433366339 +61633433643238656465663162356635333030633939373963316262393230653930376138646564 +61666236626263613733306666336139643533653563353838306662663432363634643263636166 +61656564393437636134616531376161393536343532363932633230613066303338623764653865 +38316339383761303366396165333736636165373634303936353032646166636563303232663566 +64656133346264333165363365316232613237623036363333646462356535323363333939633932 +30386230616530643738316261653134623666393365626131663135363065303333633861333738 +36666437373064343865663939633932346132636530373631346133653765656565383334373632 +30646463633661383063353062636264653132383735653962376164393262363936353231643234 +33633132376137633531663261613863313931326137303863323338393337366137343061626666 +65303062633239326138383765313533613738333036343137636663386238396461666361636633 +34303465336263383366336138623463663661626239613665386430366665313437613031343032 +34346632643139326632646331666630626365333730623534656664613332313938383834613634 +30373839656231346530383036613437613135653363343539303135643837386339633163386163 +37326231386665343136356637313362613635666239646632326231386237316231366563653338 +39353430663733643230623732326335343961623732623930396233393730363463373631643538 +34333933376538373132653261323039393739663465366164666465376530326639663032326265 +65343333363134613866663034393836613736616161363238353632336563613639383730613361 +39333861393664316337306435306366663736393062383265353362303732353562656562626533 +36346630353766363565306638396632326533646263613335316265396137646164363938376431 +62323833363266366532636562653163613462343462356339326263656662383963616637386637 +37343838623931646231343736343364316265366233303366363336656461646431376462353135 +37373766616265333331643636626232373039313533656532383062356437643236306137396135 +65666666393332616637656233666438323066386138313638303033366462656433363438663732 +66333732373837326561643930303532633330643833646665356266626663653338396238343735 +35636361383331343138623237316165353162303437316439376566363730393331346263373338 +36323666643262323936646439363134336464383065303163643763663532303836326236396631 +62376535393463643062623137386561666638393031646138383630333533386234646438396535 +37306465333035363732346234633265396138643034326566343435663261326565623266333139 +36633638306365653030303664616134613361363430393162373733383339613365663365306566 +37303939636461353730633665646634353334346430306135323665623765343538303835333438 +30343937636532663663653963343438356465343466396639323838643439323530303731343939 +38663966373761363239643733346638663666336162366333386664326264643333373162656439 +30643737346433393431336561376336313939316166333234353065373434356232336162666263 +66616239386334643938646530613236656431383239386435356366333564626234323230393763 +33346430633439356336623835303562376639626438303865343061303632333530373339633134 +39636364653539633137646339323534613039366339376634316162613261356239346239636637 +33366239613664613538383662353865333961393534313364366534323133313364393265623030 +37303430363835336461653262383462373637333161316338636233653433653265643937636539 +32626364366633363966333430613635323030353931386563633661333535623266373339333037 +33366366316164613861623833393330383330336464636238333363613739353866306337623135 +35303738626164663634 diff --git a/vars/secrets_mapping.yml b/vars/secrets_mapping.yml new file mode 100644 index 00000000..f94017d2 --- /dev/null +++ b/vars/secrets_mapping.yml @@ -0,0 +1,58 @@ +proxmox: '{{ vault_proxmox }}' +auditor: '{{ proxmox.auditor }}' + +ipa: + ds_password: '{{ vault_ipa.ds_password }}' + admin_password: '{{ vault_ipa.admin_password }}' + domain: 'infra.netsoc.co' + server: 'ipa.infra.netsoc.co' + realm: 'INFRA.NETSOC.CO' + +keycloak: '{{ vault_keycloak }}' + +mysql: '{{ vault_mysql }}' +postgres: '{{ vault_postgres }}' + +plausible: '{{ vault_plausible }}' + +traefik_basic_auth: '{{ vault_traefik_basic_auth }}' +traefik: '{{ vault_traefik }}' + +sendgrid: '{{ vault_sendgrid }}' + +netsocbot: '{{ vault_netsocbot }}' + +whodis: '{{ vault_whodis }}' + +wikijs: '{{ vault_wikijs }}' + +prometheus: '{{ vault_prometheus }}' + +ldap: '{{ vault_ldap }}' + +cloudflare: '{{ vault_cloudflare }}' + +grafana: '{{ vault_grafana }}' +grafana_admin_pass: '{{ vault_grafana_admin_pass }}' + +portainer: '{{ vault_portainer }}' + +webhooks: '{{ vault_webhooks }}' + +provisioning_root_password: '{{ vault_provisioning_root_password }}' +packer: '{{ vault_packer }}' + +github: '{{ vault_github }}' + +gdrive: '{{ vault_gdrive }}' +# user_id +# client_id +# client_secret +# cache +# location + +loki: '{{ vault_loki }}' + +shortener: '{{ vault_shortener }}' + +blog: '{{ vault_blog }}' \ No newline at end of file diff --git a/vault-edit.sh b/vault-edit.sh index acda961e..ab227a04 100755 --- a/vault-edit.sh +++ b/vault-edit.sh @@ -1,4 +1,10 @@ #!/bin/bash printf "Run export EDITOR= to change the editor in use\n" printf "If you get permission denied when running this script, you don't have an editor set\n" -ansible-vault edit vars/secrets.yml +if [[ ! -z "${VAULT_PASS}" ]]; then + echo "$VAULT_PASS" > ./_vault_pass + ansible-vault edit vars/secrets.yml --vault-password-file ./_vault_pass + rm _vault_pass +else + ansible-vault edit vars/secrets.yml +fi diff --git a/vault-merge.sh b/vault-merge.sh new file mode 100755 index 00000000..108645e5 --- /dev/null +++ b/vault-merge.sh @@ -0,0 +1,42 @@ +#!/bin/bash + +# Credit to original script: https://victorkoronen.se/2017/07/07/merging-ansible-vaults-in-git/ + +set -e + +ancestor_version=$1 +current_version=$2 +other_version=$3 +conflict_marker_size=$4 +merged_result_pathname=$5 + +ancestor_tempfile=$(mktemp tmp.XXXXXXXXXX) +current_tempfile=$(mktemp tmp.XXXXXXXXXX) +other_tempfile=$(mktemp tmp.XXXXXXXXXX) + +delete_tempfiles() { + rm -f "$ancestor_tempfile" "$current_tempfile" "$other_tempfile" +} +trap delete_tempfiles EXIT + +if [[ ! -z "${VAULT_PASS}" ]]; then + echo "$VAULT_PASS" > ./_vault_pass + ansible-vault decrypt --output "$ancestor_tempfile" "$ancestor_version" --vault-password-file ./_vault_pass + ansible-vault decrypt --output "$current_tempfile" "$current_version" --vault-password-file ./_vault_pass + ansible-vault decrypt --output "$other_tempfile" "$other_version" --vault-password-file ./_vault_pass + rm _vault_pass +else + ansible-vault decrypt --output "$ancestor_tempfile" "$ancestor_version" --ask-vault-pass + ansible-vault decrypt --output "$current_tempfile" "$current_version" --ask-vault-pass + ansible-vault decrypt --output "$other_tempfile" "$other_version" --ask-vault-pass +fi + +git merge-file "$current_tempfile" "$ancestor_tempfile" "$other_tempfile" + +if [[ ! -z "${VAULT_PASS}" ]]; then + echo "$VAULT_PASS" > ./_vault_pass + ansible-vault encrypt --output "$current_version" "$current_tempfile" --vault-password-file ./_vault_pass + rm _vault_pass +else + ansible-vault encrypt --output "$current_version" "$current_tempfile" --ask-vault-pass +fi \ No newline at end of file diff --git a/vault-peek.sh b/vault-peek.sh index 4712e307..4c6cb8ae 100755 --- a/vault-peek.sh +++ b/vault-peek.sh @@ -1,5 +1,11 @@ #!/bin/bash editor=$EDITOR -export EDITOR=less -ansible-vault edit vars/secrets.yml +export EDITOR=cat +if [[ ! -z "${VAULT_PASS}" ]]; then + echo "$VAULT_PASS" > ./_vault_pass + ansible-vault edit vars/secrets.yml --vault-password-file ./_vault_pass + rm _vault_pass +else + ansible-vault edit vars/secrets.yml +fi export EDITOR=$editor diff --git a/vm-get-ip.sh b/vm-get-ip.sh new file mode 100755 index 00000000..ddc20679 --- /dev/null +++ b/vm-get-ip.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +hostname="$1.vm.netsoc.co" +echo `./proxmox_inventory.py --list | jq '._meta.hostvars["'$"$hostname"'"].ansible_host' | sed 's/"//g'` + diff --git a/vm-get-key-path.sh b/vm-get-key-path.sh new file mode 100755 index 00000000..a42d5f75 --- /dev/null +++ b/vm-get-key-path.sh @@ -0,0 +1,3 @@ +#!/bin/bash +hostname=$1 +echo `./proxmox_inventory.py --list | jq '._meta.hostvars["'$"$hostname"'"].ansible_ssh_private_key_file' | sed 's/"//g'` diff --git a/vm-list.sh b/vm-list.sh new file mode 100755 index 00000000..3c8cf0ce --- /dev/null +++ b/vm-list.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +./proxmox_inventory.py --list | jq '._meta.hostvars | with_entries( select(.key|contains("netsoc.co") ) )' diff --git a/vm-ssh.sh b/vm-ssh.sh new file mode 100755 index 00000000..3257069d --- /dev/null +++ b/vm-ssh.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +hostname="$1" +if [[ $hostname == "" ]] ; then + arr=( $(./proxmox_inventory.py --list | jq -r '._meta.hostvars | keys | .[]') ) + select opt in "${arr[@]}"; do + export hostname="$opt" + break + done +fi +ip=`./proxmox_inventory.py --list | jq '._meta.hostvars["'$"$hostname"'"].ansible_host' | sed 's/"//g'` +key=`./proxmox_inventory.py --list | jq '._meta.hostvars["'$"$hostname"'"].ansible_ssh_private_key_file' | sed 's/"//g'` +user=`./proxmox_inventory.py --list | jq '._meta.hostvars["'$"$hostname"'"].ansible_ssh_user' | sed 's/"//g'` +echo "Connectng to $ip using netsoc with $key" +shift +ssh $user@$ip -i $key -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o LogLevel=ERROR $@