From 3d44998c5ad75eb618c8e4958b898b8f4a10bcca Mon Sep 17 00:00:00 2001 From: Yohann D'ANELLO Date: Sat, 27 Feb 2021 16:28:42 +0100 Subject: [PATCH] [etherpad] PEPCRANSIFICATION Signed-off-by: Yohann D'ANELLO --- group_vars/etherpad.yml | 40 ++ plays/etherpad.yml | 2 + roles/etherpad/handlers/main.yml | 8 + roles/etherpad/tasks/main.yml | 33 +- .../templates/etherpad/settings.json.j2 | 564 ++++++++++++++++++ .../systemd/system/etherpad-lite.service.j2 | 2 +- 6 files changed, 632 insertions(+), 17 deletions(-) create mode 100644 group_vars/etherpad.yml create mode 100644 roles/etherpad/handlers/main.yml create mode 100644 roles/etherpad/templates/etherpad/settings.json.j2 diff --git a/group_vars/etherpad.yml b/group_vars/etherpad.yml new file mode 100644 index 00000000..c69f2ab0 --- /dev/null +++ b/group_vars/etherpad.yml @@ -0,0 +1,40 @@ +glob_etherpad: + instances: + - name: etherpad-lite + title: Crans Etherpad + favicon: https://www.crans.org/images/favicon.ico + skin: crans + ip: 0.0.0.0 + port: 9001 + database: + user: crans + host: pgsql.adm.crans.org + name: etherpad + default_pad_text: "Etherpad du Crans.\\n\\nCe pad est vide, à vous de le remplir.\\n\\nhttps:\/\/etherpad.org" + admin: + user: admin + password: "{{ vault.etherpad_admin_password }}" + temporary: + enabled: false + + - name: etherpad-lite-tmp + title: Crans Etherpad Temporaire + favicon: https://www.crans.org/images/favicon.ico + skin: crans + ip: 0.0.0.0 + port: 9002 + database: + user: crans + host: pgsql.adm.crans.org + name: etherpad_tmp + default_pad_text: "Etherpad du Crans.\\n\\nCe pad est vide et expirera dans 1 an, à vous de le remplir.\\n\\nhttps:\/\/etherpad.org" + admin: + user: admin + password: "{{ vault.etherpad_admin_password }}" + temporary: + enabled: true + delay: 31536000 # one year, in seconds + loop: true + loop_delay: 86400 # one day, in seconds + delete_at_start: true + deleted_text: "Etherpad du Crans.\\n\\nCe pad est vide et expirera dans 1 an, à vous de le remplir.\\n\\nhttps:\/\/etherpad.org" diff --git a/plays/etherpad.yml b/plays/etherpad.yml index 36cb54a1..5572eeba 100755 --- a/plays/etherpad.yml +++ b/plays/etherpad.yml @@ -2,5 +2,7 @@ --- # Deploy EtherPad - hosts: etherpad + vars: + etherpad: "{{ glob_etherpad | default({}) | combine(loc_etherpad | default({})) }}" roles: - etherpad diff --git a/roles/etherpad/handlers/main.yml b/roles/etherpad/handlers/main.yml new file mode 100644 index 00000000..bf5b290f --- /dev/null +++ b/roles/etherpad/handlers/main.yml @@ -0,0 +1,8 @@ +--- +- name: Restart Etherpad + systemd: + name: "{{ item.name }}" + state: restarted + loop: "{{ etherpad.instances }}" + + diff --git a/roles/etherpad/tasks/main.yml b/roles/etherpad/tasks/main.yml index 84320183..00b6d37a 100644 --- a/roles/etherpad/tasks/main.yml +++ b/roles/etherpad/tasks/main.yml @@ -14,36 +14,37 @@ - name: Clone EtherPad git: repo: https://github.com/ether/etherpad-lite.git - dest: "/var/www/{{ item }}" + dest: "/var/www/{{ item.name }}" version: 1.8.4 - loop: - - "etherpad-lite" - - "etherpad-lite-tmp" + loop: "{{ etherpad.instances }}" become: true become_user: etherpad + notify: Restart Etherpad -#- name: Configure EtherPad -# template: -# src: etherpad/settings.json.j2 -# dest: /var/www/etherpad-lite/settings.json +- name: Configure EtherPad + template: + src: etherpad/settings.json.j2 + dest: "/var/www/{{ item.name }}/settings.json" + owner: etherpad + group: etherpad + mode: 0600 + loop: "{{ etherpad.instances }}" + notify: Restart Etherpad - name: Install EtherPad systemd unit template: src: systemd/system/etherpad-lite.service.j2 - dest: "/etc/systemd/system/{{ item }}.service" - loop: - - "etherpad-lite" - - "etherpad-lite-tmp" + dest: "/etc/systemd/system/{{ item.name }}.service" + loop: "{{ etherpad.instances }}" + notify: Restart Etherpad - name: Activate EtherPad service systemd: daemon_reload: true - name: "{{ item }}" + name: "{{ item.name }}" enabled: true state: started - loop: - - "etherpad-lite" - - "etherpad-lite-tmp" + loop: "{{ etherpad.instances }}" - name: Indicate role in motd template: diff --git a/roles/etherpad/templates/etherpad/settings.json.j2 b/roles/etherpad/templates/etherpad/settings.json.j2 new file mode 100644 index 00000000..f7fcbef5 --- /dev/null +++ b/roles/etherpad/templates/etherpad/settings.json.j2 @@ -0,0 +1,564 @@ +/* + * This file must be valid JSON. But comments are allowed + * + * Please edit settings.json, not settings.json.template + * + * Please note that starting from Etherpad 1.6.0 you can store DB credentials in + * a separate file (credentials.json). + * + * + * ENVIRONMENT VARIABLE SUBSTITUTION + * ================================= + * + * All the configuration values can be read from environment variables using the + * syntax "${ENV_VAR}" or "${ENV_VAR:default_value}". + * + * This is useful, for example, when running in a Docker container. + * + * EXAMPLE: + * "port": "${PORT:9001}" + * "minify": "${MINIFY}" + * "skinName": "${SKIN_NAME:colibris}" + * + * Would read the configuration values for those items from the environment + * variables PORT, MINIFY and SKIN_NAME. + * + * If PORT and SKIN_NAME variables were not defined, the default values 9001 and + * "colibris" would be used. + * The configuration value "minify", on the other hand, does not have a + * designated default value. Thus, if the environment variable MINIFY were + * undefined, "minify" would be null. + * + * REMARKS: + * 1) please note that variable substitution always needs to be quoted. + * + * "port": 9001, <-- Literal values. When not using + * "minify": false substitution, only strings must be + * "skinName": "colibris" quoted. Booleans and numbers must not. + * + * "port": "${PORT:9001}" <-- CORRECT: if you want to use a variable + * "minify": "${MINIFY:true}" substitution, put quotes around its name, + * "skinName": "${SKIN_NAME}" even if the required value is a number or + * a boolean. + * Etherpad will take care of rewriting it + * to the proper type if necessary. + * + * "port": ${PORT:9001} <-- ERROR: this is not valid json. Quotes + * "minify": ${MINIFY} around variable names are missing. + * "skinName": ${SKIN_NAME} + * + * 2) Beware of undefined variables and default values: nulls and empty strings + * are different! + * + * This is particularly important for user's passwords (see the relevant + * section): + * + * "password": "${PASSW}" // if PASSW is not defined would result in password === null + * "password": "${PASSW:}" // if PASSW is not defined would result in password === '' + * + * If you want to use an empty value (null) as default value for a variable, + * simply do not set it, without putting any colons: "${ABIWORD}". + * + * 3) if you want to use newlines in the default value of a string parameter, + * use "\n" as usual. + * + * "defaultPadText" : "${DEFAULT_PAD_TEXT}Line 1\nLine 2" + */ +{ + /* + * Name your instance! + */ + "title": "{{ item.title }}", + + /* + * favicon default name + * alternatively, set up a fully specified Url to your own favicon + */ + "favicon": "{{ item.favicon }}", + + /* + * Skin name. + * + * Its value has to be an existing directory under src/static/skins. + * You can write your own, or use one of the included ones: + * + * - "no-skin": an empty skin (default). This yields the unmodified, + * traditional Etherpad theme. + * - "colibris": the new experimental skin (since Etherpad 1.8), candidate to + * become the default in Etherpad 2.0 + */ + "skinName": "{{ item.skin }}", + + /* + * Skin Variants + * + * Use the UI skin variants builder at /p/test#skinvariantsbuilder + * + * For the colibris skin only, you can choose how to render the three main + * containers: + * - toolbar (top menu with icons) + * - editor (containing the text of the pad) + * - background (area outside of editor, mostly visible when using page style) + * + * For each of the 3 containers you can choose 4 color combinations: + * super-light, light, dark, super-dark. + * + * For example, to make the toolbar dark, you will include "dark-toolbar" into + * skinVariants. + * + * You can provide multiple skin variants separated by spaces. Default + * skinVariant is "super-light-toolbar super-light-editor light-background". + * + * For the editor container, you can also make it full width by adding + * "full-width-editor" variant (by default editor is rendered as a page, with + * a max-width of 900px). + */ + "skinVariants": "dark-toolbar super-light-editor light-background full-width-editor", + + /* + * IP and port which Etherpad should bind at. + * + * Binding to a Unix socket is also supported: just use an empty string for + * the ip, and put the full path to the socket in the port parameter. + * + * EXAMPLE USING UNIX SOCKET: + * "ip": "", // <-- has to be an empty string + * "port" : "/somepath/etherpad.socket", // <-- path to a Unix socket + */ + "ip": "{{ item.ip }}", + "port": {{ item.port }}, + + /* + * Option to hide/show the settings.json in admin page. + * + * Default option is set to true + */ + "showSettingsInAdminPage": true, + + /* + * Node native SSL support + * + * This is disabled by default. + * Make sure to have the minimum and correct file access permissions set so + * that the Etherpad server can access them + */ + + /* + "ssl" : { + "key" : "/path-to-your/epl-server.key", + "cert" : "/path-to-your/epl-server.crt", + "ca": ["/path-to-your/epl-intermediate-cert1.crt", "/path-to-your/epl-intermediate-cert2.crt"] + }, + */ + + /* + * The type of the database. + * + * You can choose between many DB drivers, for example: dirty, postgres, + * sqlite, mysql. + * + * You shouldn't use "dirty" for for anything else than testing or + * development. + * + * + * Database specific settings are dependent on dbType, and go in dbSettings. + * Remember that since Etherpad 1.6.0 you can also store these informations in + * credentials.json. + * + * For a complete list of the supported drivers, please refer to: + * https://www.npmjs.com/package/ueberdb2 + */ + + "dbType": "postgres", + "dbSettings": { + "user" : "{{ item.database.user }}", + "host" : "{{ item.database.host }}", + "database": "{{ item.database.name }}" + }, + + /* + * An Example of MySQL Configuration (commented out). + * + * See: https://github.com/ether/etherpad-lite/wiki/How-to-use-Etherpad-Lite-with-MySQL + */ + + /* + "dbType" : "mysql", + "dbSettings" : { + "user": "etherpaduser", + "host": "localhost", + "port": 3306, + "password": "PASSWORD", + "database": "etherpad_lite_db", + "charset": "utf8mb4" + }, + */ + + /* + * The default text of a pad + */ + "defaultPadText" : "{{ item.default_pad_text }}", + + /* + * Default Pad behavior. + * + * Change them if you want to override. + */ + "padOptions": { + "noColors": false, + "showControls": true, + "showChat": true, + "showLineNumbers": true, + "useMonospaceFont": false, + "userName": false, + "userColor": false, + "rtl": false, + "alwaysShowChat": false, + "chatAndUsers": false, + "lang": "fr-fr" + }, + + /* + * Pad Shortcut Keys + */ + "padShortcutEnabled" : { + "altF9": true, /* focus on the File Menu and/or editbar */ + "altC": true, /* focus on the Chat window */ + "cmdShift2": true, /* shows a gritter popup showing a line author */ + "delete": true, + "return": true, + "esc": true, /* in mozilla versions 14-19 avoid reconnecting pad */ + "cmdS": true, /* save a revision */ + "tab": true, /* indent */ + "cmdZ": true, /* undo/redo */ + "cmdY": true, /* redo */ + "cmdI": true, /* italic */ + "cmdB": true, /* bold */ + "cmdU": true, /* underline */ + "cmd5": true, /* strike through */ + "cmdShiftL": true, /* unordered list */ + "cmdShiftN": true, /* ordered list */ + "cmdShift1": true, /* ordered list */ + "cmdShiftC": true, /* clear authorship */ + "cmdH": true, /* backspace */ + "ctrlHome": true, /* scroll to top of pad */ + "pageUp": true, + "pageDown": true + }, + + /* + * Should we suppress errors from being visible in the default Pad Text? + */ + "suppressErrorsInPadText": false, + + /* + * If this option is enabled, a user must have a session to access pads. + * This effectively allows only group pads to be accessed. + */ + "requireSession": false, + + /* + * Users may edit pads but not create new ones. + * + * Pad creation is only via the API. + * This applies both to group pads and regular pads. + */ + "editOnly": false, + + /* + * If set to true, those users who have a valid session will automatically be + * granted access to password protected pads. + */ + "sessionNoPassword": false, + + /* + * If true, all css & js will be minified before sending to the client. + * + * This will improve the loading performance massively, but makes it difficult + * to debug the javascript/css + */ + "minify": true, + + /* + * How long may clients use served javascript code (in seconds)? + * + * Not setting this may cause problems during deployment. + * Set to 0 to disable caching. + */ + "maxAge": 21600, // 60 * 60 * 6 = 6 hours + + /* + * Absolute path to the Abiword executable. + * + * Abiword is needed to get advanced import/export features of pads. Setting + * it to null disables Abiword and will only allow plain text and HTML + * import/exports. + */ + "abiword": null, + + /* + * This is the absolute path to the soffice executable. + * + * LibreOffice can be used in lieu of Abiword to export pads. + * Setting it to null disables LibreOffice exporting. + */ + "soffice": null, + + /* + * Path to the Tidy executable. + * + * Tidy is used to improve the quality of exported pads. + * Setting it to null disables Tidy. + */ + "tidyHtml": null, + + /* + * Allow import of file types other than the supported ones: + * txt, doc, docx, rtf, odt, html & htm + */ + "allowUnknownFileEnds": true, + + /* + * This setting is used if you require authentication of all users. + * + * Note: "/admin" always requires authentication. + */ + "requireAuthentication": false, + + /* + * Require authorization by a module, or a user with is_admin set, see below. + */ + "requireAuthorization": false, + + /* + * When you use NGINX or another proxy/load-balancer set this to true. + * + * This is especially necessary when the reverse proxy performs SSL + * termination, otherwise the cookies will not have the "secure" flag. + * + * The other effect will be that the logs will contain the real client's IP, + * instead of the reverse proxy's IP. + */ + "trustProxy": true, + + /* + * Privacy: disable IP logging + */ + "disableIPlogging": false, + + /* + * Time (in seconds) to automatically reconnect pad when a "Force reconnect" + * message is shown to user. + * + * Set to 0 to disable automatic reconnection. + */ + "automaticReconnectionTimeout": 0, + + /* + * By default, when caret is moved out of viewport, it scrolls the minimum + * height needed to make this line visible. + */ + "scrollWhenFocusLineIsOutOfViewport": { + + /* + * Percentage of viewport height to be additionally scrolled. + * + * E.g.: use "percentage.editionAboveViewport": 0.5, to place caret line in + * the middle of viewport, when user edits a line above of the + * viewport + * + * Set to 0 to disable extra scrolling + */ + "percentage": { + "editionAboveViewport": 0, + "editionBelowViewport": 0 + }, + + /* + * Time (in milliseconds) used to animate the scroll transition. + * Set to 0 to disable animation + */ + "duration": 0, + + /* + * Flag to control if it should scroll when user places the caret in the + * last line of the viewport + */ + "scrollWhenCaretIsInTheLastLineOfViewport": false, + + /* + * Percentage of viewport height to be additionally scrolled when user + * presses arrow up in the line of the top of the viewport. + * + * Set to 0 to let the scroll to be handled as default by Etherpad + */ + "percentageToScrollWhenUserPressesArrowUp": 0 + }, + + /* + * Users for basic authentication. + * + * is_admin = true gives access to /admin. + * If you do not uncomment this, /admin will not be available! + * + * WARNING: passwords should not be stored in plaintext in this file. + * If you want to mitigate this, please install ep_hash_auth and + * follow the section "secure your installation" in README.md + */ + + "users": { + "{{ item.admin.user }}": { + // 1) "password" can be replaced with "hash" if you install ep_hash_auth + // 2) please note that if password is null, the user will not be created + "password": "{{ item.admin.password }}", + "is_admin": true + } + }, + + /* + * Restrict socket.io transport methods + */ + "socketTransportProtocols" : ["xhr-polling", "jsonp-polling", "htmlfile"], + + /* + * Allow Load Testing tools to hit the Etherpad Instance. + * + * WARNING: this will disable security on the instance. + */ + "loadTest": false, + + /* + * Disable indentation on new line when previous line ends with some special + * chars (':', '[', '(', '{') + */ + + /* + "indentationOnNewLine": false, + */ + + /* + * From Etherpad 1.8.3 onwards, import and export of pads is always rate + * limited. + * + * The default is to allow at most 10 requests per IP in a 90 seconds window. + * After that the import/export request is rejected. + * + * See https://github.com/nfriedly/express-rate-limit for more options + */ + "importExportRateLimiting": { + // duration of the rate limit window (milliseconds) + "windowMs": 90000, + + // maximum number of requests per IP to allow during the rate limit window + "max": 10 + }, + + /* + * From Etherpad 1.8.3 onwards, the maximum allowed size for a single imported + * file is always bounded. + * + * File size is specified in bytes. Default is 50 MB. + */ + "importMaxFileSize": 52428800, // 50 * 1024 * 1024 + + /* + * Toolbar buttons configuration. + * + * Uncomment to customize. + */ + + /* + "toolbar": { + "left": [ + ["bold", "italic", "underline", "strikethrough"], + ["orderedlist", "unorderedlist", "indent", "outdent"], + ["undo", "redo"], + ["clearauthorship"] + ], + "right": [ + ["importexport", "timeslider", "savedrevision"], + ["settings", "embed"], + ["showusers"] + ], + "timeslider": [ + ["timeslider_export", "timeslider_returnToPad"] + ] + }, + */ + + /* + * Expose Etherpad version in the web interface and in the Server http header. + * + * Do not enable on production machines. + */ + "exposeVersion": false, + + /* + * The log level we are using. + * + * Valid values: DEBUG, INFO, WARN, ERROR + */ + "loglevel": "INFO", + + /* + * Logging configuration. See log4js documentation for further information: + * https://github.com/nomiddlename/log4js-node + * + * You can add as many appenders as you want here. + */ + "logconfig" : + { "appenders": [ + { "type": "console" + //, "category": "access"// only logs pad access + } + + , { "type": "file" + , "filename": "/var/log/etherpad/etherpad-lite.log" + // Les deux lignes ci-dessous ne permettent d'avoir que trois fichiers de log d'une taille de 1024 octets en tout, les laisser commentées + //, "maxLogSize": 1024 + //, "backups": 3 // how many log files there're gonna be at max + //, "category": "test" // only log a specific category + } + + /* + , { "type": "logLevelFilter" + , "level": "warn" // filters out all log messages that have a lower level than "error" + , "appender": + { Use whatever appender you want here } + } + */ + + /* + , { "type": "logLevelFilter" + , "level": "error" // filters out all log messages that have a lower level than "error" + , "appender": + { "type": "smtp" + , "subject": "An error occurred in your EPL instance!" + , "recipients": "bar@blurdybloop.com, baz@blurdybloop.com" + , "sendInterval": 300 // 60 * 5 = 5 minutes -- will buffer log messages; set to 0 to send a mail for every message + , "transport": "SMTP", "SMTP": { // see https://github.com/andris9/Nodemailer#possible-transport-methods + "host": "smtp.example.com", "port": 465, + "secureConnection": true, + "auth": { + "user": "foo@example.com", + "pass": "bar_foo" + } + } + } + } + */ + + ] +{% if item.temporary is defined and item.temporary.enabled %} + }, // logconfig + "ep_delete_after_delay": { + "delay": {{ item.temporary.delay }}, + "loop": {% if item.temporary.loop %}true{% else %}false{% endif %}, + "loopDelay": {{ item.temporary.loop_delay }}, + "deleteAtStart": {% if item.temporary.delete_at_start %}true{% else %}false{% endif %}, + "text": "{{ item.temporary.deleted_text }}" + } +{% else %} + } // logconfig +{% endif %} +} diff --git a/roles/etherpad/templates/systemd/system/etherpad-lite.service.j2 b/roles/etherpad/templates/systemd/system/etherpad-lite.service.j2 index abec8251..9014ec46 100644 --- a/roles/etherpad/templates/systemd/system/etherpad-lite.service.j2 +++ b/roles/etherpad/templates/systemd/system/etherpad-lite.service.j2 @@ -9,7 +9,7 @@ Type=simple User=etherpad Group=etherpad Environment=NODE_ENV=production -ExecStart=/var/www/{{ item }}/bin/run.sh --stack-size=4096 +ExecStart=/var/www/{{ item.name }}/bin/run.sh --stack-size=4096 Restart=always RestartSec=5s