Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Infra ansible pinnwand #47

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 74 additions & 0 deletions roles/pinnwand/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# PINNWAND
=========

The aim of the role is to install [pinnwand](https://pinnwand.readthedocs.io/en/latest/) (a python pastebin webapp), alongside with mysql (as dbserver) and basic configuration for the pastebin app and a virtual host as reverse proxy. The webapp is run as an standard operating sytem user with a **/sbin/nologin** shell for security reason.

## Requirements
------------

Apache web server has to be previously installed on the target node

## Role Variables
--------------

Variables have been defined in the **vars/main.yml** and in **default/main.yml** In vars/main.yml there are:

In *vars/main.yml* there is the fqdn of pastebin website (used to configure the apache virtual host)

`pinnwand_fqdn: pinnwand.local`

In *default/main.yml* there are:

Operating system user variables
```
pinnwand_os_user: pinnwand
pinnwand_home_dir: /opt
```
pinnwand webapp configuration
```
pinwwnad_http_port: 8000
pinnwand_cfg_file: pinnwand.toml
```

pinnwand database configuration parameters
```
dbserver: mysql-server
dbclient: mysql
dbserver_service: mysqld
pinnwand_db_name: pinnwand_db
pinnwand_db_user: pinnwand
pinnwand_db_pass: pinnwand
pinnwand_db_driver: mysql+pymysql
pinnwand_db_host: 127.0.0.1
```

## Dependencies
------------

None

## Example Playbook
----------------

Including an example of how to use your role (for instance, with variables passed in as parameters) is always nice for users too:
```
---
- hosts: mantis
become: yes

tasks:
- name: pinnwand role
ansible.builtin.include_role:
name: pinnwand
...
```

License
-------

BSD

Author Information
------------------

Luca Ceccarani
18 changes: 18 additions & 0 deletions roles/pinnwand/defaults/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#SPDX-License-Identifier: MIT-0

Check failure on line 1 in roles/pinnwand/defaults/main.yml

View workflow job for this annotation

GitHub Actions / Ansible Lint

yaml[comments]

Missing starting space in comment
---
# defaults file for pinnwand
pinnwand_os_user: pinnwand
pinnwand_home_dir: /opt

pinwwnad_http_port: 8000

Check failure on line 7 in roles/pinnwand/defaults/main.yml

View workflow job for this annotation

GitHub Actions / Ansible Lint

var-naming[no-role-prefix]

Variables names from within roles should use pinnwand_ as a prefix. (vars: pinwwnad_http_port)
pinnwand_cfg_file: pinnwand.toml

dbserver: mysql-server

Check failure on line 10 in roles/pinnwand/defaults/main.yml

View workflow job for this annotation

GitHub Actions / Ansible Lint

var-naming[no-role-prefix]

Variables names from within roles should use pinnwand_ as a prefix. (vars: dbserver)
dbclient: mysql

Check failure on line 11 in roles/pinnwand/defaults/main.yml

View workflow job for this annotation

GitHub Actions / Ansible Lint

var-naming[no-role-prefix]

Variables names from within roles should use pinnwand_ as a prefix. (vars: dbclient)
dbserver_service: mysqld

Check failure on line 12 in roles/pinnwand/defaults/main.yml

View workflow job for this annotation

GitHub Actions / Ansible Lint

var-naming[no-role-prefix]

Variables names from within roles should use pinnwand_ as a prefix. (vars: dbserver_service)

pinnwand_db_name: pinnwand_db
pinnwand_db_user: pinnwand
pinnwand_db_pass: pinnwand
pinnwand_db_driver: mysql+pymysql
pinnwand_db_host: 127.0.0.1
7 changes: 7 additions & 0 deletions roles/pinnwand/handlers/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#SPDX-License-Identifier: MIT-0

Check failure on line 1 in roles/pinnwand/handlers/main.yml

View workflow job for this annotation

GitHub Actions / Ansible Lint

yaml[comments]

Missing starting space in comment
---
# handlers file for pinnwand
- name: reload httpd webserver

Check failure on line 4 in roles/pinnwand/handlers/main.yml

View workflow job for this annotation

GitHub Actions / Ansible Lint

name[casing]

All names should start with an uppercase letter.
ansible.builtin.systemd:
name: httpd
state: reloaded
10 changes: 10 additions & 0 deletions roles/pinnwand/tasks/configure_webserver.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
- name: configure web server to forward http request toward pinnwand web server

Check failure on line 2 in roles/pinnwand/tasks/configure_webserver.yml

View workflow job for this annotation

GitHub Actions / Ansible Lint

name[casing]

All names should start with an uppercase letter.
ansible.builtin.template:
src: virtual_host_pinnwand.conf.j2
dest: /etc/httpd/conf.d/pinnwand.conf
backup: yes

Check failure on line 6 in roles/pinnwand/tasks/configure_webserver.yml

View workflow job for this annotation

GitHub Actions / Ansible Lint

yaml[truthy]

Truthy value should be one of [false, true]
mode: 0644

Check failure on line 7 in roles/pinnwand/tasks/configure_webserver.yml

View workflow job for this annotation

GitHub Actions / Ansible Lint

yaml[octal-values]

Forbidden implicit octal value "0644"
notify:
- reload httpd webserver
...
14 changes: 14 additions & 0 deletions roles/pinnwand/tasks/install_dbserver.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
- name: install db server {{ dbserver}}

Check warning on line 1 in roles/pinnwand/tasks/install_dbserver.yml

View workflow job for this annotation

GitHub Actions / Ansible Lint

jinja[spacing]

Jinja2 spacing could be improved: install db server {{ dbserver}} -> install db server {{ dbserver }}
ansible.builtin.dnf:
name:

Check warning on line 3 in roles/pinnwand/tasks/install_dbserver.yml

View workflow job for this annotation

GitHub Actions / Ansible Lint

jinja[spacing]

Jinja2 spacing could be improved: {{ dbserver}} -> {{ dbserver }}
- '{{ dbserver}}'
- '{{ dbclient }}'
state: latest

- name: enable dbserver service
ansible.builtin.service:
name: '{{ dbserver_service }}'
enabled: true
state: started

...
78 changes: 78 additions & 0 deletions roles/pinnwand/tasks/install_pinnwand.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
---
- name: create pinnwand os user
ansible.builtin.user:
name: '{{ pinnwand_os_user }}'
state: present
shell: /sbin/nologin
home: '{{ pinnwand_home_dir }}/{{ pinnwand_os_user }}'

- name: install pinwnwand inside a dedicated virtualenvironment
ansible.builtin.pip:
name: pinnwand
virtualenv: '{{ pinnwand_home_dir }}/{{ pinnwand_os_user }}/virtual-environment'
virtualenv_command: '/usr/bin/python3 -m venv'
state: latest
become_user: '{{ pinnwand_os_user }}'

- name: install PyMySQL inside the virtualenvironment
ansible.builtin.pip:
name: pymysql
virtualenv: '{{ pinnwand_home_dir }}/{{ pinnwand_os_user }}/virtual-environment'
virtualenv_command: '/usr/bin/python3 -m venv'
state: latest
become_user: '{{ pinnwand_os_user }}'

- name: Install python packages needed to create databases and db users
ansible.builtin.dnf:
name: python3-PyMySQL
when:
- dbserver == 'mariadb-server' or dbserver == 'mysql-server'

#We have to run as root in order to login without password, but we are running as a privileged user != from root
- name: Create pinnwand database.
community.mysql.mysql_db:
name: "{{ pinnwand_db_name }}"
state: present
login_user: root
login_unix_socket: /var/lib/mysql/mysql.sock
become: true
become_user: root

#We have to run as root in order to login without password, but we are running as a privileged user != from root
- name: Create pinnwand database user
community.mysql.mysql_user:
name: "{{ pinnwand_db_user }}"
password: "{{ pinnwand_db_pass }}"
priv: "{{ pinnwand_db_name }}.*:ALL"
state: present
login_user: root
login_unix_socket: /var/lib/mysql/mysql.sock
become: true
become_user: root

#Deploy pinnwand toml configuration file
- name: deploy pinnwand toml configuration file
ansible.builtin.template:
src: pinnwand.toml.j2
dest: '{{ pinnwand_home_dir }}/{{ pinnwand_os_user }}/pinnwand.toml'
backup: yes
owner: '{{ pinnwand_os_user }}'
group: '{{ pinnwand_os_user }}'
mode: 0600

#Create systemd service for pinnwand automatic startup
- name: deploy the service unit file for pinnwand
ansible.builtin.template:
src: pinnwand.service.j2
dest: /etc/systemd/system/pinnwand.service
backup: yes
register: deployed_pinnwand_service

- name: Enable and start deployed pinnwand service
ansible.builtin.systemd:
daemon_reload: true
enabled: true
name: pinnwand
state: started
when: deployed_pinnwand_service.changed
...
14 changes: 14 additions & 0 deletions roles/pinnwand/tasks/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#SPDX-License-Identifier: MIT-0
---
- name: install pinnwand creating a virtualenvironment
ansible.builtin.include_tasks:
file: install_dbserver.yml

- name: install pinnwand creating a virtualenvironment
ansible.builtin.include_tasks:
file: install_pinnwand.yml

- name: configure webserver to proxying the request toward apache webserver
ansible.builtin.include_tasks:
file: configure_webserver.yml
...
11 changes: 11 additions & 0 deletions roles/pinnwand/templates/pinnwand.service.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[Unit]
Description=pinnwand pastebin

[Service]
User={{ pinnwand_os_user }}
{# ExecStart={{ pinnwand_home_dir }}/{{ pinnwand_os_user }}/virtual-environment/bin/pinnwand --configuration-path {{ pinnwand_home_dir }}/{{ pinnwand_os_user }}/{{ pinnwand_cfg_file }} http #}
ExecStart={{ pinnwand_home_dir }}/{{ pinnwand_os_user }}/virtual-environment/bin/python -m pinnwand --configuration-path {{ pinnwand_home_dir }}/{{ pinnwand_os_user }}/{{ pinnwand_cfg_file }} http
Restart=always

[Install]
WantedBy=multi-user.target
82 changes: 82 additions & 0 deletions roles/pinnwand/templates/pinnwand.toml.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
# Example configuration file for `pinnwand`. Shows what you can adjust. More
# information can be found at `pinnwand`'s documentation:
# https://pinnwand.readthedocs.io/en/latest/ or you can file an issue at our
# GitHub: https://github.com/supakeen/pinnwand

# Database URI to connect to see: https://docs.sqlalchemy.org/en/13/core/engines.html#database-urls
# if you want to use databases other than sqlite be sure to install the
# appropriate packages and then format this url to correspond to them.
database_uri = "{{ pinnwand_db_driver }}://{{ pinnwand_db_user}}:{{ pinnwand_db_pass }}@{{ pinnwand_db_host }}/{{ pinnwand_db_name }}"

# Maximum paste size you want to allow.
paste_size = 262144 # 256kB in bytes

# Preferred lexers. This list of lexers will appear on top of the dropdown
# on the website allowing you to preselect commonly used lexers. Note that the
# names here have to be the identifiers used by pygments, not the human names.
# The keys returned by /api/v1/lexer are an exhaustive list of supported lexers.
# If empty no preferred lexers are shown.
preferred_lexers = []

# The lexer selected by default when creating a new paste.
# Similar to preferred_lexers, only supports lexer identifiers used by pygments.
default_selected_lexer = "text"

# Logo path, used to render your logo. If left out the default logo will be
# used. This file must be a png file.
# logo_path = "/path/to/a/file.png"

# The page path is used to find the pages listed in the page_list
page_path = "/tmp"

# This is the whitelist of files that should exist in the `page_path`
# configuration directive. `pinnwand` will look for `$file.rst` in the
# `page_path` directory and serve it at `/$file`.
page_list = ["about", "removal", "expiry"]

# The footer in raw HTML, shown at the bottom of the page and handy to link to
# your previously configured pages.
footer = 'View <a href="//github.com/supakeen/pinnwand" target="_BLANK">source code</a>, the <a href="/removal">removal</a> or <a href="/expiry">expiry</a> stories, or read the <a href="/about">about</a> page.'

# HTML for the 'help text' that can be shown above the paste area, if left
# empty no help text will be shown.
paste_help = "<p>Welcome to pinnwand, this site is a pastebin. It allows you to share code with others. If you write code in the text area below and press the paste button you will be given a link you can share with others so they can view your code as well.</p><p>People with the link can view your pasted code, only you can remove your paste and it expires automatically. Note that anyone could guess the URI to your paste so don't rely on it being private.</p>"

# Email used for file reporting. If the value is not None then a href with a mailto link will be added to every paste page thus allowing the users to report pastes that may need removal.
report_email = "[email protected]"

# Expiries are given by a name and their duration in seconds, if you want to do
# 'forever' set a really large number...
expiries.1hour = 3600
expiries.1day = 86400
expiries.1week = 604800

# These are application level ratelimits, if you use proxies for your pinnwand
# instance you should set limits there as well. These limits describe a token
# bucket and are per-IP.
#
# The capacity is how many tokens there are available, the consumption is how
# many tokens are used by an action and the refill is how many tokens are added
# per second. So the read bucket below allows a burst of a 100 reads then another
# 2 per second.
ratelimit.read.capacity = 100
ratelimit.read.consume = 1
ratelimit.read.refill = 2

ratelimit.create.capacity = 2
ratelimit.create.consume = 2
ratelimit.create.refill = 1

ratelimit.delete.capacity = 2
ratelimit.delete.consume = 2
ratelimit.delete.refill = 1

# pinnwand uses a naive anti-spam measure where a regex is ran over the text
# that is pasted. It then checks how large a percentage of the incoming bytes
# consist of links. If that percentage is larger than the number below the
# paste is denied. Set to a 100 to disable.
spamscore = 50

# pinnwand has a background job that deletes all expired pastes in order to not have an overloaded database.
# The period every which the task is executed is expressed in milliseconds
reaping_periodicity = 1_800_000
6 changes: 6 additions & 0 deletions roles/pinnwand/templates/virtual_host_pinnwand.conf.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<VirtualHost *:80>
ServerName {{ pinnwand_fqdn }}
ProxyPreserveHost On
ProxyPass / http://127.0.0.1:8000/
ProxyPassReverse / http://127.0.0.1:8000/
</VirtualHost>
4 changes: 4 additions & 0 deletions roles/pinnwand/vars/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#SPDX-License-Identifier: MIT-0
---
# vars file for pinnwand
pinnwand_fqdn: pinnwand.local