diff --git a/roles/privacyidea_ha/defaults/main.yml b/roles/privacyidea_ha/defaults/main.yml index c0c9ea4..b801821 100644 --- a/roles/privacyidea_ha/defaults/main.yml +++ b/roles/privacyidea_ha/defaults/main.yml @@ -80,4 +80,8 @@ certificate_sync_target_directory: "/synced_certificates" ha_cluster_exporter_version: 1.3.3 # The public key used to verify subscription signatures -subscription_auth_public_key: "" \ No newline at end of file +subscription_auth_public_key: "" +privacyidea_mariadb_root_password: "" + +exporter_username: "exporter" +exporter_password: "" \ No newline at end of file diff --git a/roles/privacyidea_ha/handlers/main.yml b/roles/privacyidea_ha/handlers/main.yml index adad147..6e65b78 100644 --- a/roles/privacyidea_ha/handlers/main.yml +++ b/roles/privacyidea_ha/handlers/main.yml @@ -17,20 +17,26 @@ enabled: true state: reloaded -- name: reload nginx +- name: restart uwsgi command: - cmd: /usr/sbin/pcs resource restart nginx + cmd: /usr/sbin/pcs resource restart uwsgi become: true ignore_errors: true -- name: restart nginx +- name: Restart exporter command: - cmd: /usr/sbin/pcs resource restart nginx + cmd: /usr/sbin/pcs resource restart privacyidea-exporter become: true ignore_errors: true -- name: restart uwsgi +- name: reload nginx command: - cmd: /usr/sbin/pcs resource restart uwsgi + cmd: /usr/sbin/pcs resource reload nginx become: true ignore_errors: true + +- name: restart nginx + command: + cmd: /usr/sbin/pcs resource restart nginx + become: true + ignore_errors: true \ No newline at end of file diff --git a/roles/privacyidea_ha/tasks/configure_privacyidea.yml b/roles/privacyidea_ha/tasks/configure_privacyidea.yml index 324c857..9c508ad 100644 --- a/roles/privacyidea_ha/tasks/configure_privacyidea.yml +++ b/roles/privacyidea_ha/tasks/configure_privacyidea.yml @@ -56,13 +56,6 @@ group: www-data mode: '0644' -#- name: Copy NetKnight pem file -# copy: -# src: NetKnights.pem -# dest: /etc/privacyidea/NetKnights.pem -# owner: www-data -# group: www-data -# mode: 0644 # /etc/privacyidea/enckey is copied from /data/privacyidea - name: Set PrivacyIDEA file permissions diff --git a/roles/privacyidea_ha/tasks/generate_keys.yml b/roles/privacyidea_ha/tasks/generate_keys.yml index af196c4..6d6a9a7 100644 --- a/roles/privacyidea_ha/tasks/generate_keys.yml +++ b/roles/privacyidea_ha/tasks/generate_keys.yml @@ -63,3 +63,4 @@ path: "/tmp/certificate_sync_key_*" state: absent delegate_to: localhost + ignore_errors: true diff --git a/roles/privacyidea_ha/tasks/hacluster_nginx.yml b/roles/privacyidea_ha/tasks/hacluster_nginx.yml index 702ef57..ab690f4 100644 --- a/roles/privacyidea_ha/tasks/hacluster_nginx.yml +++ b/roles/privacyidea_ha/tasks/hacluster_nginx.yml @@ -62,3 +62,70 @@ resource1: "nginx" resource2: "galera" when: is_main_node + +- name: Create the PrivacyIDEA cronjob + copy: + dest: /etc/privacyidea/privacyidea_cron + content: | + # Script to run scheduled tasks for PrivacyIDEA + */5 * * * * www-data /opt/privacyidea/virtualenv/bin/privacyidea-cron run_scheduled + mode: '0644' + +- name: Create Symlink for Cron Job + pcs_resource: + name: "privacyidea_cron_symlink" + resource_type: 'ocf:heartbeat:symlink' + options: >- + target=/etc/privacyidea/privacyidea_cron + link=/etc/cron.d/privacyidea_cron + backup_suffix=.disabled + op monitor interval=10s timeout=20s + op start timeout=60s interval=0s + op stop timeout=60s interval=0s + meta failure-timeout=15m migration-threshold=2 + --group {{ cluster_name }}_group + when: is_main_node + +- name: Add Order Constraint for Symlink after uWSGI + pcs_constraint_order: + resource1: "uwsgi" + resource2: "privacyidea_cron_symlink" + when: is_main_node + become: true + +- name: Add Colocation Constraint for Symlink with uWSGI + pcs_constraint_colocation: + resource1: "privacyidea_cron_symlink" + resource2: "uwsgi" + score: "INFINITY" + when: is_main_node + become: true + +- name: Add custom exporter resource + pcs_resource: + name: "custom-exporter" + resource_type: 'systemd:privacyidea-exporter' + options: > + op monitor timeout=1s interval=1s + meta failure-timeout=15m migration-threshold=2 + --group {{ cluster_name }}_group + when: is_main_node + +- name: Add colocation for custom exporter with uwsgi + pcs_constraint_colocation: + resource1: "custom-exporter" + resource2: "uwsgi" + score: "INFINITY" + when: is_main_node + +- name: Add order for galera and then custom-exporter + pcs_constraint_order: + resource1: "galera" + resource2: "custom-exporter" + when: is_main_node + +#- name: Start custom exporter PCS resource +# pcs_resource: +# name: "custom-exporter" +# state: started +# when: is_main_node \ No newline at end of file diff --git a/roles/privacyidea_ha/tasks/import_data.yml b/roles/privacyidea_ha/tasks/import_data.yml index 6408f10..397071b 100644 --- a/roles/privacyidea_ha/tasks/import_data.yml +++ b/roles/privacyidea_ha/tasks/import_data.yml @@ -7,7 +7,9 @@ group: www-data mode: '0755' -# - name: Execute the privacyidea_data_import_and_cleanup.sh script -# shell: /etc/privacyidea/privacyidea_data_import_and_cleanup.sh -# args: -# executable: /bin/bash +#- name: Execute the privacyidea_data_import_and_cleanup.sh script +# shell: /etc/privacyidea/privacyidea_data_import_and_cleanup.sh +# args: +# executable: /bin/bash +# notify: restart uwsgi + diff --git a/roles/privacyidea_ha/tasks/install_packages.yml b/roles/privacyidea_ha/tasks/install_packages.yml index 5e6ee23..aff1fd3 100644 --- a/roles/privacyidea_ha/tasks/install_packages.yml +++ b/roles/privacyidea_ha/tasks/install_packages.yml @@ -5,3 +5,7 @@ state: present update_cache: yes +- name: Install prometheus_client in PrivacyIDEA + ansible.builtin.command: + cmd: sudo -H /opt/privacyidea/virtualenv/bin/pip install prometheus_client + become: true \ No newline at end of file diff --git a/roles/privacyidea_ha/tasks/main.yml b/roles/privacyidea_ha/tasks/main.yml index 53b8a9d..757f237 100644 --- a/roles/privacyidea_ha/tasks/main.yml +++ b/roles/privacyidea_ha/tasks/main.yml @@ -2,10 +2,10 @@ - import_tasks: prepare.yml - import_tasks: setup_directories.yml - import_tasks: install_privacyidea.yml -- import_tasks: setup_database.yml - import_tasks: generate_keys.yml - import_tasks: configure_privacyidea.yml - import_tasks: create_admin.yml +- import_tasks: privacyidea_exporter.yml - import_tasks: setup_nginx.yml - import_tasks: security.yml - import_tasks: hacluster.yml diff --git a/roles/privacyidea_ha/tasks/privacyidea_exporter.yml b/roles/privacyidea_ha/tasks/privacyidea_exporter.yml new file mode 100644 index 0000000..5b7a643 --- /dev/null +++ b/roles/privacyidea_ha/tasks/privacyidea_exporter.yml @@ -0,0 +1,35 @@ + +--- +- name: Deploy custom exporter script + template: + src: custom_exporter.py.j2 + dest: /etc/privacyidea/custom_exporter.py + owner: www-data + group: www-data + mode: '0775' + +- name: Create uWSGI configuration for custom exporter + template: + src: privacyidea-exporter.ini.j2 + dest: /etc/uwsgi/apps-available/privacyidea-exporter.ini + owner: www-data + group: www-data + mode: '0644' + +- name: Link uWSGI config for custom exporter + file: + src: /etc/uwsgi/apps-available/privacyidea-exporter.ini + dest: /etc/uwsgi/apps-enabled/privacyidea-exporter.ini + state: link + +- name: Deploy custom exporter Systemd service + template: + src: privacyidea-exporter.service.j2 + dest: /etc/systemd/system/privacyidea-exporter.service + owner: www-data + group: www-data + mode: '0644' + +- name: Reload systemd daemon + systemd: + daemon_reload: true \ No newline at end of file diff --git a/roles/privacyidea_ha/tasks/setup_database.yml b/roles/privacyidea_ha/tasks/setup_database.yml deleted file mode 100644 index a479025..0000000 --- a/roles/privacyidea_ha/tasks/setup_database.yml +++ /dev/null @@ -1,8 +0,0 @@ ---- -- name: Copy MySQL root credentials to .mysql.cnf file - template: - src: privacyidea-mysql-root.cnf.j2 - dest: "{{ mysql_root_home }}/.my.cnf" - owner: root - group: root - mode: 0600 diff --git a/roles/privacyidea_ha/tasks/setup_directories.yml b/roles/privacyidea_ha/tasks/setup_directories.yml index 22580d6..40b4d67 100644 --- a/roles/privacyidea_ha/tasks/setup_directories.yml +++ b/roles/privacyidea_ha/tasks/setup_directories.yml @@ -12,6 +12,8 @@ - { path: '/var/log/privacyidea', mode: '0755' } - { path: '/var/log/uwsgi', mode: '0755' } - { path: '/usr/lib/ocf/resource.d/privacyidea/', mode: '0755' } + - { path: '/run/uwsgi/app/privacyidea-exporter/', mode: '0775' } + become: true - name: Create uWSGI and privacyidea log files @@ -26,4 +28,5 @@ - { path: '/var/log/uwsgi/error.log' } - { path: '/var/log/uwsgi/request.log' } - { path: '/var/log/privacyidea/privacyidea.log' } - become: true \ No newline at end of file + - { path: '/var/log/uwsgi/privacyidea-exporter.log' } + become: true diff --git a/roles/privacyidea_ha/templates/custom_exporter.py.j2 b/roles/privacyidea_ha/templates/custom_exporter.py.j2 new file mode 100644 index 0000000..ea30562 --- /dev/null +++ b/roles/privacyidea_ha/templates/custom_exporter.py.j2 @@ -0,0 +1,116 @@ +import os +import sys +import socket +import time +import logging +from prometheus_client import start_http_server, Gauge, Counter, generate_latest +from privacyidea.app import create_app +from flask import Flask, Response, request +import sqlalchemy +from sqlalchemy.pool import QueuePool +from functools import wraps + +# Set up logging +logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') + +# Get the hostname +hostname = socket.gethostname() + +config_name = "{{ config_name }}" +debug_mode = {{ debug_mode }} + +# Create the PrivacyIDEA application +application = create_app(config_name=config_name, config_file="/etc/privacyidea/pi.cfg") +application.debug = debug_mode + +# Get credentials from environment variables +EXPORTER_USERNAME = os.environ.get('EXPORTER_USERNAME') +EXPORTER_PASSWORD = os.environ.get('EXPORTER_PASSWORD') + +def check_auth(username, password): + """Check if a username/password combination is valid.""" + return username == EXPORTER_USERNAME and password == EXPORTER_PASSWORD + +def authenticate(): + """Sends a 401 response that enables basic auth""" + return Response( + 'Could not verify your access level for that URL.\n' + 'You have to login with proper credentials', 401, + {'WWW-Authenticate': 'Basic realm="Login Required"'}) + +def requires_auth(f): + @wraps(f) + def decorated(*args, **kwargs): + auth = request.authorization + if not auth or not check_auth(auth.username, auth.password): + return authenticate() + return f(*args, **kwargs) + return decorated + +# Define the /metrics endpoint function outside the PrivacyIDEAExporter class +@requires_auth +def metrics(): + exporter.collect_metrics() + return Response(generate_latest(), mimetype="text/plain") + +class PrivacyIDEAExporter: + def __init__(self, app, port=9101): + self.app = app + self.port = port + self.flask_app = Flask(__name__) + + # Define Prometheus metrics + self.auth_success = Gauge('privacyidea_auth_success_total', 'Total successful authentications') + self.auth_failure = Gauge('privacyidea_auth_failure_total', 'Total failed authentications') + self.tokens_total = Gauge('privacyidea_tokens_total', 'Total number of tokens') + self.hardware_tokens = Gauge('privacyidea_hardware_tokens', 'Number of hardware tokens') + self.software_tokens = Gauge('privacyidea_software_tokens', 'Number of software tokens') + self.unassigned_hardware_tokens = Gauge('privacyidea_unassigned_hardware_tokens', 'Number of unassigned hardware tokens') + self.assigned_tokens = Gauge('privacyidea_assigned_tokens', 'Number of assigned tokens') + self.new_users = Gauge('privacyidea_new_users', 'Number of new users') + self.token_init = Gauge('privacyidea_token_init', 'Number of token initializations') + self.token_assign = Gauge('privacyidea_token_assign', 'Number of token assignments') + self.token_unassign = Gauge('privacyidea_token_unassign', 'Number of token unassignments') + + # Create a connection pool + self.engine = sqlalchemy.create_engine( + application.config['SQLALCHEMY_DATABASE_URI'], + poolclass=QueuePool, + pool_size=5, + max_overflow=10 + ) + + def fetch_latest_stat(self, connection, stats_key): + query = """ + SELECT stats_value + FROM monitoringstats + WHERE stats_key = :key + ORDER BY timestamp DESC + LIMIT 1 + """ + result = connection.execute(sqlalchemy.text(query), {"key": stats_key}) + return result.scalar() or 0 + + def collect_metrics(self): + with self.app.app_context(): + try: + with self.engine.connect() as connection: + # Fetch and set metrics + self.tokens_total.set(self.fetch_latest_stat(connection, 'total_tokens')) + self.hardware_tokens.set(self.fetch_latest_stat(connection, 'hardware_tokens')) + self.software_tokens.set(self.fetch_latest_stat(connection, 'software_tokens')) + self.unassigned_hardware_tokens.set(self.fetch_latest_stat(connection, 'unassigned_hardware_tokens')) + self.assigned_tokens.set(self.fetch_latest_stat(connection, 'assigned_tokens')) + self.auth_success.set(self.fetch_latest_stat(connection, 'successful_auth_counter')) + self.auth_failure.set(self.fetch_latest_stat(connection, 'failed_auth_counter')) + self.new_users.set(self.fetch_latest_stat(connection, 'new_users_counter')) + self.token_init.set(self.fetch_latest_stat(connection, 'token_init_counter')) + self.token_assign.set(self.fetch_latest_stat(connection, 'token_assign_counter')) + self.token_unassign.set(self.fetch_latest_stat(connection, 'token_unassign_counter')) + + logging.info("Metrics collected successfully") + except Exception as e: + logging.error(f"Error fetching metrics: {e}", exc_info=True) + +exporter = PrivacyIDEAExporter(application) +application.add_url_rule('/metrics', 'metrics', metrics) \ No newline at end of file diff --git a/roles/privacyidea_ha/templates/nginx_privacyidea.conf.j2 b/roles/privacyidea_ha/templates/nginx_privacyidea.conf.j2 index aecdb81..2c5b0b9 100644 --- a/roles/privacyidea_ha/templates/nginx_privacyidea.conf.j2 +++ b/roles/privacyidea_ha/templates/nginx_privacyidea.conf.j2 @@ -19,7 +19,7 @@ # #} # location / { -# include uwsgi_params; +# include /etc/nginx/uwsgi_params; # uwsgi_pass unix:/run/uwsgi/app/privacyidea/privacyidea.socket; # } #} @@ -44,8 +44,14 @@ server { {% endif %} access_log /var/log/nginx/privacyidea.access.log privacyidea; error_log /var/log/nginx/privacyidea.error.log; + + location /metrics { + include /etc/nginx/uwsgi_params; + uwsgi_pass unix:/run/uwsgi/app/privacyidea-exporter/socket; + } + location / { - include uwsgi_params; + include /etc/nginx/uwsgi_params; uwsgi_pass unix:/run/uwsgi/app/privacyidea/privacyidea.socket; } location /static { diff --git a/roles/privacyidea_ha/templates/pi.cfg.j2 b/roles/privacyidea_ha/templates/pi.cfg.j2 index a1cd3bc..0f54bd1 100644 --- a/roles/privacyidea_ha/templates/pi.cfg.j2 +++ b/roles/privacyidea_ha/templates/pi.cfg.j2 @@ -24,4 +24,6 @@ PI_ENCFILE = '/etc/privacyidea/enckey' # This is used to encrypt the admin passwords PI_PEPPER = '{{ privacyidea_pi_pepper }}' SECRET_KEY = '{{ privacyidea_secret_key }}' -PI_PREFERRED_LANGUAGE = ["de"] \ No newline at end of file +PI_PREFERRED_LANGUAGE = ["de"] +PI_AUDIT_SQL_TRUNCATE = True +PI_AUDIT_SQL_COLUMN_LENGTH = {"info": 1000, "action": 100, "action_detail": 100, "policies": 1000} \ No newline at end of file diff --git a/roles/privacyidea_ha/templates/privacyidea-exporter.ini.j2 b/roles/privacyidea_ha/templates/privacyidea-exporter.ini.j2 new file mode 100644 index 0000000..d1bd162 --- /dev/null +++ b/roles/privacyidea_ha/templates/privacyidea-exporter.ini.j2 @@ -0,0 +1,20 @@ +[uwsgi] +plugin = python3,logfile +virtualenv = /opt/privacyidea/virtualenv +chdir = /etc/privacyidea +module = custom_exporter:application +processes = 2 +master = true +vacuum = true +harakiri = 60 +max-requests = 2000 +uid = www-data +gid = www-data + +# Socket configuration +socket = /run/uwsgi/app/privacyidea-exporter/socket +chmod-socket = 660 + +# Logging +logto = /var/log/uwsgi/privacyidea-exporter.log + diff --git a/roles/privacyidea_ha/templates/privacyidea-exporter.service.j2 b/roles/privacyidea_ha/templates/privacyidea-exporter.service.j2 new file mode 100644 index 0000000..c647148 --- /dev/null +++ b/roles/privacyidea_ha/templates/privacyidea-exporter.service.j2 @@ -0,0 +1,14 @@ +[Unit] +Description=PrivacyIDEA Prometheus Exporter +After=network.target + +[Service] +ExecStart=/usr/bin/uwsgi --ini /etc/uwsgi/apps-enabled/privacyidea-exporter.ini +Restart=always +User=www-data +Group=www-data +Environment=EXPORTER_USERNAME={{ exporter_username }} +Environment=EXPORTER_PASSWORD={{ exporter_password }} + +[Install] +WantedBy=multi-user.target \ No newline at end of file diff --git a/roles/privacyidea_ha/templates/privacyidea-mysql-root.cnf.j2 b/roles/privacyidea_ha/templates/privacyidea-mysql-root.cnf.j2 deleted file mode 100644 index 0f072ce..0000000 --- a/roles/privacyidea_ha/templates/privacyidea-mysql-root.cnf.j2 +++ /dev/null @@ -1,4 +0,0 @@ -[client] -# MySQL root credentials for PrivacyIDEA -user="{{ privacyidea_mariadb_username }}" -password="{{ privacyidea_mariadb_password }}" diff --git a/roles/privacyidea_ha/templates/privacyidea_data_import_and_cleanup.sh b/roles/privacyidea_ha/templates/privacyidea_data_import_and_cleanup.sh index 9145054..9e7dab4 100644 --- a/roles/privacyidea_ha/templates/privacyidea_data_import_and_cleanup.sh +++ b/roles/privacyidea_ha/templates/privacyidea_data_import_and_cleanup.sh @@ -134,4 +134,120 @@ mysql -h $DB_HOST -u $DB_USER -p$DB_PASSWORD $DB_NAME -e " INSERT INTO policycondition (policy_id, section, \`Key\`, comparator, Value, active) VALUES ($POLICY_ID, 'HTTP Request header', 'SelfService', 'equals', 'true', 1); " -echo "Policy condition added." \ No newline at end of file +echo "Policy condition added." + +# Create periodic tasks for various counting operations +# Create event handlers for various events +mysql -h $DB_HOST -u $DB_USER -p$DB_PASSWORD $DB_NAME -e " +INSERT INTO periodictask (name, active,\`interval\`, nodes, taskmodule, ordering, last_update, retry_if_failed) VALUES + ('Count Successful Authentications', 1, '*/5 * * * *', 'localnode', 'EventCounter', 1, NOW(), 1), + ('Count Failed Authentications', 1, '*/5 * * * *', 'localnode', 'EventCounter', 2, NOW(), 1), + ('Count Token Initializations', 1, '*/5 * * * *', 'localnode', 'EventCounter', 3, NOW(), 1), + ('Count Token Assignments', 1, '*/5 * * * *', 'localnode', 'EventCounter', 4, NOW(), 1), + ('Count Token Unassignments', 1, '*/5 * * * *', 'localnode', 'EventCounter', 5, NOW(), 1), + ('Count New Users', 1, '*/5 * * * *', 'localnode', 'EventCounter', 6, NOW(), 1), + ('Update Token Statistics', 1, '*/5 * * * *', 'localnode', 'SimpleStats', 7, NOW(), 1); + +INSERT INTO periodictaskoption (periodictask_id, \`Key\`, value) + SELECT id, 'event_counter', 'successful_auth_counter' FROM periodictask WHERE name = 'Count Successful Authentications'; +INSERT INTO periodictaskoption (periodictask_id, \`Key\`, value) + SELECT id, 'stats_key', 'successful_auth_counter' FROM periodictask WHERE name = 'Count Successful Authentications'; +INSERT INTO periodictaskoption (periodictask_id, \`Key\`, value) + SELECT id, 'reset_event_counter', 'True' FROM periodictask WHERE name = 'Count Successful Authentications'; + +INSERT INTO periodictaskoption (periodictask_id, \`Key\`, value) + SELECT id, 'event_counter', 'failed_auth_counter' FROM periodictask WHERE name = 'Count Failed Authentications'; +INSERT INTO periodictaskoption (periodictask_id, \`Key\`, value) + SELECT id, 'stats_key', 'failed_auth_counter' FROM periodictask WHERE name = 'Count Failed Authentications'; +INSERT INTO periodictaskoption (periodictask_id, \`Key\`, value) + SELECT id, 'reset_event_counter', 'True' FROM periodictask WHERE name = 'Count Failed Authentications'; + +INSERT INTO periodictaskoption (periodictask_id, \`Key\`, value) + SELECT id, 'event_counter', 'token_init_counter' FROM periodictask WHERE name = 'Count Token Initializations'; +INSERT INTO periodictaskoption (periodictask_id, \`Key\`, value) + SELECT id, 'stats_key', 'token_init_counter' FROM periodictask WHERE name = 'Count Token Initializations'; +INSERT INTO periodictaskoption (periodictask_id, \`Key\`, value) + SELECT id, 'reset_event_counter', 'True' FROM periodictask WHERE name = 'Count Token Initializations'; + +INSERT INTO periodictaskoption (periodictask_id, \`Key\`, value) + SELECT id, 'event_counter', 'token_assign_counter' FROM periodictask WHERE name = 'Count Token Assignments'; +INSERT INTO periodictaskoption (periodictask_id, \`Key\`, value) + SELECT id, 'stats_key', 'token_assign_counter' FROM periodictask WHERE name = 'Count Token Assignments'; +INSERT INTO periodictaskoption (periodictask_id, \`Key\`, value) + SELECT id, 'reset_event_counter', 'True' FROM periodictask WHERE name = 'Count Token Assignments'; + +INSERT INTO periodictaskoption (periodictask_id, \`Key\`, value) + SELECT id, 'event_counter', 'token_unassign_counter' FROM periodictask WHERE name = 'Count Token Unassignments'; +INSERT INTO periodictaskoption (periodictask_id, \`Key\`, value) + SELECT id, 'stats_key', 'token_unassign_counter' FROM periodictask WHERE name = 'Count Token Unassignments'; +INSERT INTO periodictaskoption (periodictask_id, \`Key\`, value) + SELECT id, 'reset_event_counter', 'True' FROM periodictask WHERE name = 'Count Token Unassignments'; + +INSERT INTO periodictaskoption (periodictask_id, \`Key\`, value) + SELECT id, 'event_counter', 'new_users_counter' FROM periodictask WHERE name = 'Count New Users'; +INSERT INTO periodictaskoption (periodictask_id, \`Key\`, value) + SELECT id, 'stats_key', 'new_users_counter' FROM periodictask WHERE name = 'Count New Users'; +INSERT INTO periodictaskoption (periodictask_id, \`Key\`, value) + SELECT id, 'reset_event_counter', 'True' FROM periodictask WHERE name = 'Count New Users'; + +INSERT INTO periodictaskoption (periodictask_id, \`Key\`, value) + SELECT id, 'total_tokens', 'True' FROM periodictask WHERE name = 'Update Token Statistics'; +INSERT INTO periodictaskoption (periodictask_id, \`Key\`, value) + SELECT id, 'hardware_tokens', 'True' FROM periodictask WHERE name = 'Update Token Statistics'; +INSERT INTO periodictaskoption (periodictask_id, \`Key\`, value) + SELECT id, 'software_tokens', 'True' FROM periodictask WHERE name = 'Update Token Statistics'; +INSERT INTO periodictaskoption (periodictask_id, \`Key\`, value) + SELECT id, 'assigned_tokens', 'True' FROM periodictask WHERE name = 'Update Token Statistics'; +INSERT INTO periodictaskoption (periodictask_id, \`Key\`, value) + SELECT id, 'unassigned_hardware_tokens', 'True' FROM periodictask WHERE name = 'Update Token Statistics'; + +INSERT INTO eventhandler (name, active, ordering, position, event, handlermodule, action) VALUES + ('Successful Authentication', 1, 1, 'post', 'validate_check', 'Counter', 'increase_counter'), + ('Failed Authentication', 1, 2, 'post', 'validate_check', 'Counter', 'increase_counter'), + ('Token Initialization', 1, 3, 'post', 'token_init', 'Counter', 'increase_counter'), + ('Token Assignment', 1, 4, 'post', 'token_assign', 'Counter', 'increase_counter'), + ('New User Created', 1, 5, 'post', 'user_add', 'Counter', 'increase_counter'), + ('Token Unassignment', 1, 6, 'post', 'token_unassign', 'Counter', 'increase_counter'), + ('Update Token Statistics', 1, 7, 'post', 'update_statistics', 'SimpleStats', 'update_statistics'); + +INSERT INTO eventhandleroption (eventhandler_id, \`Key\`, Value, Type, Description) + SELECT id, 'counter_name', 'successful_auth_counter', 'string', 'Counter name for successful authentications' FROM eventhandler WHERE name = 'Successful Authentication'; +INSERT INTO eventhandleroption (eventhandler_id, \`Key\`, Value, Type, Description) + SELECT id, 'counter_name', 'failed_auth_counter', 'string', 'Counter name for failed authentications' FROM eventhandler WHERE name = 'Failed Authentication'; +INSERT INTO eventhandleroption (eventhandler_id, \`Key\`, Value, Type, Description) + SELECT id, 'counter_name', 'token_init_counter', 'string', 'Counter name for token initializations' FROM eventhandler WHERE name = 'Token Initialization'; +INSERT INTO eventhandleroption (eventhandler_id, \`Key\`, Value, Type, Description) + SELECT id, 'counter_name', 'token_assign_counter', 'string', 'Counter name for Token Assignment' FROM eventhandler WHERE name = 'Token Assignment'; +INSERT INTO eventhandleroption (eventhandler_id, \`Key\`, Value, Type, Description) + SELECT id, 'counter_name', 'new_users_counter', 'string', 'Counter name for New User Created' FROM eventhandler WHERE name = 'New User Created'; +INSERT INTO eventhandleroption (eventhandler_id,\`Key\`, Value, Type, Description) + SELECT id, 'counter_name', 'token_unassign_counter', 'string', 'Counter name for token unassignments' FROM eventhandler WHERE name = 'Token Unassignment'; + +INSERT INTO eventhandlercondition (eventhandler_id, \`Key\`, Value, comparator) + SELECT eventhandler_id, 'result_value', 'True', '=' FROM eventhandleroption WHERE Value = 'successful_auth_counter'; +INSERT INTO eventhandlercondition (eventhandler_id, \`Key\`, Value, comparator) + SELECT eventhandler_id, 'result_value', 'False', '=' FROM eventhandleroption WHERE Value = 'failed_auth_counter'; +INSERT INTO eventhandlercondition (eventhandler_id, \`Key\`, Value, comparator) + SELECT eventhandler_id, 'tokentype', 'hotp', '=' FROM eventhandleroption WHERE Value = 'token_init_counter'; +INSERT INTO eventhandlercondition (eventhandler_id, \`Key\`, Value, comparator) + SELECT eventhandler_id, 'token_has_owner', 'True', '=' FROM eventhandleroption WHERE Value = 'token_assign_counter'; +INSERT INTO eventhandlercondition (eventhandler_id, \`Key\`, Value, comparator) + SELECT eventhandler_id, 'token_has_owner', 'False', '=' FROM eventhandleroption WHERE Value = 'token_unassign_counter'; + +INSERT INTO eventhandleroption (eventhandler_id, \`Key\`, Value, Type, Description) + SELECT id, 'total_tokens', 'True', 'boolean', 'Include total number of tokens' FROM eventhandler WHERE name = 'Update Token Statistics'; +INSERT INTO eventhandleroption (eventhandler_id, \`Key\`, Value, Type, Description) + SELECT id, 'hardware_tokens', 'True', 'boolean', 'Include number of hardware tokens' FROM eventhandler WHERE name = 'Update Token Statistics'; +INSERT INTO eventhandleroption (eventhandler_id, \`Key\`, Value, Type, Description) + SELECT id, 'software_tokens', 'True', 'boolean', 'Include number of software tokens' FROM eventhandler WHERE name = 'Update Token Statistics'; +INSERT INTO eventhandleroption (eventhandler_id, \`Key\`, Value, Type, Description) + SELECT id, 'assigned_tokens', 'True', 'boolean', 'Include number of assigned tokens' FROM eventhandler WHERE name = 'Update Token Statistics'; +INSERT INTO eventhandleroption (eventhandler_id, \`Key\`, Value, Type, Description) + SELECT id, 'unassigned_hardware_tokens', 'True', 'boolean', 'Include number of unassigned hardware tokens' FROM eventhandler WHERE name = 'Update Token Statistics'; + +ALTER TABLE pidea_audit MODIFY COLUMN info VARCHAR(1000); +ALTER TABLE pidea_audit MODIFY COLUMN action VARCHAR(100); +ALTER TABLE pidea_audit MODIFY COLUMN action_detail VARCHAR(100); +ALTER TABLE pidea_audit MODIFY COLUMN policies VARCHAR(1000); + +" \ No newline at end of file diff --git a/roles/privacyidea_ha/templates/user_sql_resolver_config.ini.j2 b/roles/privacyidea_ha/templates/user_sql_resolver_config.ini.j2 index 5571085..41afca0 100644 --- a/roles/privacyidea_ha/templates/user_sql_resolver_config.ini.j2 +++ b/roles/privacyidea_ha/templates/user_sql_resolver_config.ini.j2 @@ -6,6 +6,6 @@ "Password": "{{ privacyidea_db_user_password }}", "Table": "users_service", "Editable": "1", - "Map": "{\"userid\": \"id\", \"username\": \"username\"}", + "Map": "{\"userid\": \"username\", \"username\": \"username\"}", "Limit": 500 } \ No newline at end of file