diff --git a/ansible/roles/neo4j/README.md b/ansible/roles/neo4j/README.md new file mode 100644 index 0000000..537d403 --- /dev/null +++ b/ansible/roles/neo4j/README.md @@ -0,0 +1,5 @@ +## Tags + +* Install : Installe Neo4j et déploie son fichier de configuration. +* Config : Déploie le fichier de configuration. +* Backup : Déploie les configurations relatives aux sauvegardes. diff --git a/ansible/roles/neo4j/defaults/main.yml b/ansible/roles/neo4j/defaults/main.yml new file mode 100644 index 0000000..f9c89cf --- /dev/null +++ b/ansible/roles/neo4j/defaults/main.yml @@ -0,0 +1,4 @@ +--- + +neo4j_default_listen_address: "0.0.0.0" +neo4j_default_advertised_address: "" diff --git a/ansible/roles/neo4j/files/neo4j-dump-database.sh b/ansible/roles/neo4j/files/neo4j-dump-database.sh new file mode 100644 index 0000000..0af245a --- /dev/null +++ b/ansible/roles/neo4j/files/neo4j-dump-database.sh @@ -0,0 +1,89 @@ +#!/bin/sh + +# {{ ansible_managed }} + +set -eu + +NOW=$(date +%Y%m%d-%H%M%S) +HOSTNAME=$(hostname -s) +STATUS=0 +EXITSTATUS=0 +OUTPUT="" +LOGFILE="/data/log/scripts/neo4j-dump-databases.log" +COMPRESS=false + +touch ${LOGFILE} + +# +# Functions +# + +checkNas() +{ + if [ ! -e "${BACKUPDIR}/.mount" ]; then + echo "${BACKUPDIR} not mounted. Backup aborted." | tee -a ${LOGFILE} + exit 1 + fi +} + +usage() +{ + echo "$0 -r -d -c (compression)" + echo "Exemple : /data/scripts/neo4j-dump-databases -r 20 -d /nas -c" +} + +# +# Main +# + +while getopts "hcr:d:" option +do + case "${option}" + in + r) + RETENTION=${OPTARG};; + d) + BACKUPDIR=${OPTARG};; + c) + COMPRESS=true;; + h | *) + usage + exit 1;; + esac +done + +echo "[$(date '+%Y%m%d %H%M%S')] Lancement du dump neo4j de ${HOSTNAME} - Retention : ${RETENTION} - Repertoire de destination : ${BACKUPDIR}" | tee -a ${LOGFILE} + +mkdir -p "$BACKUPDIR"/neo4jdump/ +find "$BACKUPDIR"/neo4jdump/ -mindepth 1 -maxdepth 1 -type f -daystart -mtime +"$RETENTION" -delete + +echo "[$(date '+%Y%m%d %H%M%S')][INFO] Arret de Neo4j" | tee -a ${LOGFILE} +systemctl stop neo4j.service + +for db in neo4j system ; do + echo "[$(date '+%Y%m%d %H%M%S')][INFO] dump de $db" | tee -a ${LOGFILE} + if [ "$COMPRESS" = true ]; then + neo4j-admin database dump --to-stdout $db | gzip -1 > "$BACKUPDIR"/neo4jdump/"${NOW}"_"${HOSTNAME}"_"${db}".dump.gz | tee -a ${LOGFILE} + else + neo4j-admin database dump --to-stdout $db > "$BACKUPDIR"/neo4jdump/"${NOW}"_"${HOSTNAME}"_"${db}".dump | tee -a ${LOGFILE} + fi + STATUS=$? + if [ ! ${STATUS} -eq 0 ]; then + echo "[$(date '+%Y%m%d %H%M%S')][CRIT] neo4jdump failed" | tee -a ${LOGFILE} + OUTPUT="${OUTPUT} neo4j" + EXITSTATUS=1 + break + fi +done + +echo "[$(date '+%Y%m%d %H%M%S')][INFO] Demarrage de Neo4j" | tee -a ${LOGFILE} +systemctl start neo4j.service + +if [ ${EXITSTATUS} -eq 0 ]; then + echo "$(date '+%s')|${EXITSTATUS}|Everything has been successfully backuped !" | tee /var/tmp/batch.`basename $0` +else + echo "$(date '+%s')|${EXITSTATUS}|Problem with mysqldump backup (${OUTPUT}) !" | tee /var/tmp/batch.`basename $0` +fi + +echo "[$(date '+%Y%m%d %H%M%S')] Fin du dump neo4j de ${HOSTNAME} - Retention : ${RETENTION} - Repertoire de destination : ${BACKUPDIR}" | tee -a ${LOGFILE} +exit ${EXITSTATUS} diff --git a/ansible/roles/neo4j/handlers/main.yml b/ansible/roles/neo4j/handlers/main.yml new file mode 100644 index 0000000..a8f66c5 --- /dev/null +++ b/ansible/roles/neo4j/handlers/main.yml @@ -0,0 +1,6 @@ +--- + +- name: restart neo4j + ansible.builtin.systemd_service: + name: neo4j.service + state: restarted diff --git a/ansible/roles/neo4j/tasks/backup.yml b/ansible/roles/neo4j/tasks/backup.yml new file mode 100644 index 0000000..676de95 --- /dev/null +++ b/ansible/roles/neo4j/tasks/backup.yml @@ -0,0 +1,47 @@ +--- + +- name: Setting up mount point for /nas + ansible.posix.mount: + path: "/nas" + src: "{{ neo4j_nfs_server }}:/data/shares/neo4j" + fstype: "nfs4" + opts: "rw,noatime,nodiratime,_netdev" + state: mounted + tags: backup + +- name: Ensure scripts folder exists + ansible.builtin.file: + path: "/data/scripts" + owner: root + group: root + mode: 0644 + state: directory + tags: backup + +- name: Deploy backup script + ansible.builtin.copy: + src: "neo4j-dump-database.sh" + dest: "/data/scripts/neo4j-dump-database.sh" + owner: root + group: root + mode: 0750 + tags: backup + +- name: Setting up backup cron + ansible.builtin.cron: + name: "neo4j backup" + minute: "0" + hour: "04" + job: "/data/scripts/neo4j-dump-database.sh -r 7 -d /nas -c" + disabled: true + user: root + cron_file: neo4j-backup + state: present + tags: backup + +- name: Adding checkmk config for backup script + ansible.builtin.lineinfile: + path: "/etc/check_mk/mrpe.cfg" + regexp: "^#?neo4j_dump /usr/local/nagios/plugins/check_batch neo4j-dump-database.sh 129600" + line: "#neo4j_dump /usr/local/nagios/plugins/check_batch neo4j-dump-database.sh 129600" + tags: backup diff --git a/ansible/roles/neo4j/tasks/install.yml b/ansible/roles/neo4j/tasks/install.yml new file mode 100644 index 0000000..fcf9984 --- /dev/null +++ b/ansible/roles/neo4j/tasks/install.yml @@ -0,0 +1,56 @@ +--- + +- name: checking dependencies + ansible.builtin.apt: + package: "{{ item }}" + state: present + with_items: + - apt-transport-https + - ca-certificates + - gnupg2 + - openjdk-17-jdk + - nfs-common + tags: install + +- name: adding neo4j pgp key + ansible.builtin.get_url: + url: "https://debian.neo4j.com/neotechnology.gpg.key" + dest: "/usr/share/keyrings/neo4j.asc" + mode: 0644 + force: true + tags: install + +- name: adding repo + ansible.builtin.apt_repository: + repo: "deb [signed-by=/usr/share/keyrings/neo4j.asc] https://debian.neo4j.com stable latest" + update_cache: true + state: present + tags: install + +- name: install package + ansible.builtin.apt: + package: "neo4j" + state: present + tags: install + +- name: holding package + ansible.builtin.dpkg_selections: + name: neo4j + selection: hold + tags: install + +- name: Enable neo4j service + ansible.builtin.systemd_service: + name: neo4j.service + enabled: true + tags: install + +- name: Deploy neo4j.yml + ansible.builtin.template: + src: neo4j.conf.j2 + dest: "/etc/neo4j/neo4j.conf" + owner: neo4j + group: neo4j + mode: 0660 + tags: install,config + notify: restart neo4j diff --git a/ansible/roles/neo4j/tasks/main.yml b/ansible/roles/neo4j/tasks/main.yml new file mode 100644 index 0000000..a6e2418 --- /dev/null +++ b/ansible/roles/neo4j/tasks/main.yml @@ -0,0 +1,7 @@ +--- + +- include_tasks: install.yml + tags: install,config + +- include_tasks: backup.yml + tags: backup diff --git a/ansible/roles/neo4j/templates/neo4j.conf.j2 b/ansible/roles/neo4j/templates/neo4j.conf.j2 new file mode 100644 index 0000000..b6a3485 --- /dev/null +++ b/ansible/roles/neo4j/templates/neo4j.conf.j2 @@ -0,0 +1,196 @@ +#***************************************************************** +# Neo4j configuration +# +# For more details and a complete list of settings, please see +# https://neo4j.com/docs/operations-manual/current/reference/configuration-settings/ +#***************************************************************** + +# The name of the default database +#initial.dbms.default_database=neo4j + +# Paths of directories in the installation. +server.directories.data=/var/lib/neo4j/data +server.directories.plugins=/var/lib/neo4j/plugins +server.directories.logs=/var/log/neo4j +server.directories.lib=/usr/share/neo4j/lib +#server.directories.run=run +#server.directories.licenses=licenses +#server.directories.transaction.logs.root=data/transactions +server.logs.config=/etc/neo4j/server-logs.xml +server.logs.user.config=/etc/neo4j/user-logs.xml + +server.directories.import=/var/lib/neo4j/import +dbms.usage_report.enabled=false + + +#******************************************************************** +# Memory Settings +#******************************************************************** +# +# Memory settings are specified kibibytes with the 'k' suffix, mebibytes with +# 'm' and gibibytes with 'g'. +# If Neo4j is running on a dedicated server, then it is generally recommended +# to leave about 2-4 gigabytes for the operating system, give the JVM enough +# heap to hold all your transaction state and query context, and then leave the +# rest for the page cache. + +# Java Heap Size: by default the Java heap size is dynamically calculated based +# on available system resources. Uncomment these lines to set specific initial +# and maximum heap size. +server.memory.heap.initial_size={{ neo4j_heap_initial_size }} +server.memory.heap.max_size={{ neo4j_heap_max_size }} + +# The amount of memory to use for mapping the store files. +# The default page cache memory assumes the machine is dedicated to running +# Neo4j, and is heuristically set to 50% of RAM minus the Java heap size. +server.memory.pagecache.size={{ neo4j_pagecache_size }} + +# Limit the amount of memory that all of the running transaction can consume. +# The default value is 70% of the heap size limit. +dbms.memory.transaction.total.max={{ neo4j_memory_transaction_total_max }} + +# Limit the amount of memory that a single transaction can consume. +# By default there is no limit. +#db.memory.transaction.max=16m + +#***************************************************************** +# Network connector configuration +#***************************************************************** + +# With default configuration Neo4j only accepts local connections. +# To accept non-local connections, uncomment this line: +server.default_listen_address={{ neo4j_default_listen_address }} +server.default_advertised_address={{ neo4j_default_advertised_address }} + +# Bolt connector +server.bolt.enabled=true +server.bolt.tls_level=DISABLED +server.bolt.listen_address=:7687 +server.bolt.advertised_address=:7687 + +# HTTP Connector. There can be zero or one HTTP connectors. +server.http.enabled=true +server.http.listen_address=:7474 +server.http.advertised_address=:7474 + +# HTTPS Connector. There can be zero or one HTTPS connectors. +server.https.enabled=false + +#***************************************************************** +# Logging configuration +#***************************************************************** + +# To enable HTTP logging, uncomment this line +dbms.logs.http.enabled=true + +# To enable GC Logging, uncomment this line +#server.logs.gc.enabled=true + +# GC Logging Options +# see https://docs.oracle.com/en/java/javase/11/tools/java.html#GUID-BE93ABDC-999C-4CB5-A88B-1994AAAC74D5 +#server.logs.gc.options=-Xlog:gc*,safepoint,age*=trace + +# Number of GC logs to keep. +#server.logs.gc.rotation.keep_number=5 + +# Size of each GC log that is kept. +#server.logs.gc.rotation.size=20m + +#***************************************************************** +# Miscellaneous configuration +#***************************************************************** + +# Retention policy for transaction logs needed to perform recovery and backups. +db.tx_log.rotation.retention_policy=2 days 2G + +#******************************************************************** +# JVM Parameters +#******************************************************************** + +# G1GC generally strikes a good balance between throughput and tail +# latency, without too much tuning. +server.jvm.additional=-XX:+UseG1GC + +# Have common exceptions keep producing stack traces, so they can be +# debugged regardless of how often logs are rotated. +server.jvm.additional=-XX:-OmitStackTraceInFastThrow + +# Make sure that `initmemory` is not only allocated, but committed to +# the process, before starting the database. This reduces memory +# fragmentation, increasing the effectiveness of transparent huge +# pages. It also reduces the possibility of seeing performance drop +# due to heap-growing GC events, where a decrease in available page +# cache leads to an increase in mean IO response time. +# Try reducing the heap memory, if this flag degrades performance. +server.jvm.additional=-XX:+AlwaysPreTouch + +# Trust that non-static final fields are really final. +# This allows more optimizations and improves overall performance. +# NOTE: Disable this if you use embedded mode, or have extensions or dependencies that may use reflection or +# serialization to change the value of final fields! +server.jvm.additional=-XX:+UnlockExperimentalVMOptions +server.jvm.additional=-XX:+TrustFinalNonStaticFields + +# Disable explicit garbage collection, which is occasionally invoked by the JDK itself. +server.jvm.additional=-XX:+DisableExplicitGC + +# Restrict size of cached JDK buffers to 1 KB +server.jvm.additional=-Djdk.nio.maxCachedBufferSize=1024 + +# More efficient buffer allocation in Netty by allowing direct no cleaner buffers. +server.jvm.additional=-Dio.netty.tryReflectionSetAccessible=true + +# Exits JVM on the first occurrence of an out-of-memory error. Its preferable to restart VM in case of out of memory errors. +# server.jvm.additional=-XX:+ExitOnOutOfMemoryError + +# Expand Diffie Hellman (DH) key size from default 1024 to 2048 for DH-RSA cipher suites used in server TLS handshakes. +# This is to protect the server from any potential passive eavesdropping. +server.jvm.additional=-Djdk.tls.ephemeralDHKeySize=2048 + +# This mitigates a DDoS vector. +server.jvm.additional=-Djdk.tls.rejectClientInitiatedRenegotiation=true + +# Enable remote debugging +#server.jvm.additional=-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005 + +# This filter prevents deserialization of arbitrary objects via java object serialization, addressing potential vulnerabilities. +# By default this filter whitelists all neo4j classes, as well as classes from the hazelcast library and the java standard library. +# These defaults should only be modified by expert users! +# For more details (including filter syntax) see: https://openjdk.java.net/jeps/290 +#server.jvm.additional=-Djdk.serialFilter=java.**;org.neo4j.**;com.neo4j.**;com.hazelcast.**;net.sf.ehcache.Element;com.sun.proxy.*;org.openjdk.jmh.**;!* + +# Increase the default flight recorder stack sampling depth from 64 to 256, to avoid truncating frames when profiling. +server.jvm.additional=-XX:FlightRecorderOptions=stackdepth=256 + +# Allow profilers to sample between safepoints. Without this, sampling profilers may produce less accurate results. +server.jvm.additional=-XX:+UnlockDiagnosticVMOptions +server.jvm.additional=-XX:+DebugNonSafepoints + +# Open modules for neo4j to allow internal access +server.jvm.additional=--add-opens=java.base/java.nio=ALL-UNNAMED +server.jvm.additional=--add-opens=java.base/java.io=ALL-UNNAMED +server.jvm.additional=--add-opens=java.base/sun.nio.ch=ALL-UNNAMED + +# Enable access to JDK vector API +# server.jvm.additional=--add-modules=jdk.incubator.vector + +# Disable logging JMX endpoint. +server.jvm.additional=-Dlog4j2.disable.jmx=true + +# Limit JVM metaspace and code cache to allow garbage collection. Used by cypher for code generation and may grow indefinitely unless constrained. +# Useful for memory constrained environments +#server.jvm.additional=-XX:MaxMetaspaceSize=1024m +#server.jvm.additional=-XX:ReservedCodeCacheSize=512m + +# Allow big methods to be JIT compiled. +# Useful for big queries and big expressions where cypher code generation can create large methods. +#server.jvm.additional=-XX:-DontCompileHugeMethods + +#******************************************************************** +# Other Neo4j system properties +#******************************************************************** +browser.remote_content_hostname_whitelist="localhost, guides.neo4j.com" +dbms.security.http_access_control_allow_origin="*" +dbms.security.procedures.allowlist=gds.*,apoc.* +dbms.security.procedures.unrestricted=gds.*,apoc.* +db.lock.acquisition.timeout=10s