From 4bfd948989acdde45fab48c777b09f142e3bfe26 Mon Sep 17 00:00:00 2001 From: Antonio de la Rosa Date: Sat, 17 May 2025 18:42:02 +0200 Subject: [PATCH] Added files --- .gitignore | 108 ++++++++++++++++ __init__.py | 17 +++ dashboard.py | 85 +++++++++++++ models/php.py | 29 +++++ scripts/install_php.py | 70 +++++++++++ settings/config_admin.py | 15 +++ tasks/php/info.cfg | 9 ++ tasks/php/php/install_php.py | 207 +++++++++++++++++++++++++++++++ templates/admin/phpservers.phtml | 17 +++ 9 files changed, 557 insertions(+) create mode 100644 .gitignore create mode 100644 __init__.py create mode 100644 dashboard.py create mode 100644 models/php.py create mode 100644 scripts/install_php.py create mode 100644 settings/config_admin.py create mode 100644 tasks/php/info.cfg create mode 100644 tasks/php/php/install_php.py create mode 100644 templates/admin/phpservers.phtml diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..17c45be --- /dev/null +++ b/.gitignore @@ -0,0 +1,108 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +.hypothesis/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +.static_storage/ +.media/ +local_settings.py + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# pyenv +.python-version + +# celery beat schedule file +celerybeat-schedule + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ + +/backups +/settings/config.py +/media/js/jsutils diff --git a/__init__.py b/__init__.py new file mode 100644 index 0000000..f4f7e0f --- /dev/null +++ b/__init__.py @@ -0,0 +1,17 @@ +from flask import Blueprint, g +from paramecio2.modules.admin.libraries.admin_auth import admin_prepare, admin_finished + +php_app=Blueprint('php_app', __name__) + +#@admin_app.before_request +#def admin_prepare(): + +@php_app.before_request +def admin_prepare_php(): + + return admin_prepare() + +@php_app.after_request +def admin_finished_php(response): + + return admin_finished(response) diff --git a/dashboard.py b/dashboard.py new file mode 100644 index 0000000..1700e50 --- /dev/null +++ b/dashboard.py @@ -0,0 +1,85 @@ +from modules.phpserver import php_app +from settings import config +from flask import g, url_for, request, session, make_response +from paramecio2.libraries.generate_admin_class import GenerateAdminClass +from paramecio2.libraries.lists import SimpleList +from paramecio2.libraries.i18n import I18n, PGetText +from paramecio2.modules.admin import admin_app, t as admin_t +from paramecio2.libraries.db.webmodel import WebModel +from paramecio2.libraries.lists import AjaxList +from modules.pastafari2.models.pastafari2 import ServerGroup, ServerDbTask, UpdateServerScripts +from modules.pastafari2.models.tasks import Task as SSHTask +from modules.mariadb.models.mariadb import DbServerMariaDb +from paramecio2.libraries.mtemplates import PTemplate, env_theme +from paramecio2.libraries.formsutils import show_form +from paramecio2.libraries.db.coreforms import HiddenForm, SelectForm, TextForm +from paramecio2.libraries.slugify import slugify +from modules.pastafari2.libraries.configtask import config_task +from modules.pastafari2.libraries.progress import load_progress +from modules.pastafari2.models.tasks import Task as SSHTask +from modules.pastafari2.libraries.configtask import config_task +import os + +try: + import ujson as json +except: + import json + +pgettext=PGetText(__file__+'/../') + +_=pgettext.gettext + +env=env_theme(__file__) + +t=PTemplate(env) + +t.env.directories=admin_t.env.directories + +t.env.directories.insert(1, os.path.dirname(__file__).replace('/admin', '')+'/templates/admin') +t.env.directories.insert(2, '../pastafari2/templates/admin') + +@php_app.route('/pastafari2/php/servers') +def php_dashboard(): + + return t.load_template('phpservers.phtml', title=_('PHP Servers'), path_module='php_app.php_dashboard') + +@php_app.route('/get_phpservers', methods=['POST']) +def get_phpservers(): + + + db=g.connection + + group_sql='' + + count_data=[] + sql_data=[] + + fields=[[_('Version'), True], [_('Hostname'), True], ['IP', True], [_('Options'), False]] + arr_order_fields=['version', 'hostname', 'ip'] + + count_query=['select count(phpserver.id) as num_elements from phpserver', count_data] + + str_query=['select phpserver.version, serverdbtask.hostname, serverdbtask.ip, phpserver.id as id from serverdbtask, phpserver WHERE serverdbtask.id=phpserver.server_id', sql_data] + + ajax=AjaxList(db, fields, arr_order_fields, count_query, str_query) + + #ajax.func_fields['id']=options_server + #ajax.func_fields['ip']=options_ip + #ajax.func_fields['select_id']=options_selected + ajax.func_fields['id']=options_options + ajax.limit=0 + + return ajax.show() + +def options_options(row_id, row): + + arr_options=[] + + #arr_options=['{}'.format(url_for('admin_app.virtualhost', server_id=row_id), I18n.lang('dbservermariadb', 'server_users', 'Server users'))] + #arr_options=['{}'.format(url_for('admin_app.virtualhost', dbservermariadb_id=row_id), _('Websites'))] + # + #arr_options.append('{}'.format(url_for('admin_app.ports', dbservermariadb_id=row_id), I18n.lang('dbservermariadb', 'http_ports', 'HTTP Ports'))) + arr_options.append('{}'.format("", _('Edit'))) + arr_options.append('{}'.format("", _('Delete'))) + + return '
'.join(arr_options) diff --git a/models/php.py b/models/php.py new file mode 100644 index 0000000..edd029d --- /dev/null +++ b/models/php.py @@ -0,0 +1,29 @@ +from paramecio2.libraries.db.webmodel import WebModel +from paramecio2.libraries.db import corefields +from paramecio2.libraries.db.extrafields.dictfield import DictField +from paramecio2.libraries.db.extrafields.datefield import DateField +from paramecio2.libraries.db.extrafields.datetimefield import DateTimeField +from paramecio2.libraries.db.extrafields.ipfield import IpField +from paramecio2.libraries.db.extrafields.urlfield import UrlField +from paramecio2.libraries.db.extrafields.urlfield import DomainField +from paramecio2.libraries.db.extrafields.dictfield import DictField +from paramecio2.libraries.db.extrafields.jsonfield import JsonValueField +from paramecio2.libraries.db.extrafields.parentfield import ParentField +from paramecio2.libraries.db.extrafields.filefield import FileField +from paramecio2.libraries.urls import make_media_url +from paramecio2.libraries import datetime +from paramecio2.modules.admin.models.admin import UserAdmin +from modules.pastafari2.models.tasks import LonelyIpField +from modules.pastafari2.models.pastafari2 import ServerDbTask + +#languages={'php': ['8.2', '8.3', '8.4']} + +class PHPServer(WebModel): + + def __init__(self, connection): + + super().__init__(connection) + self.register(corefields.CharField('version'), True) + self.register(corefields.ForeignKeyField('server_id', ServerDbTask(connection), 11, False, 'id', 'hostname', select_fields=[])) + self.register(IpField('access_ip')) + diff --git a/scripts/install_php.py b/scripts/install_php.py new file mode 100644 index 0000000..6eab4ca --- /dev/null +++ b/scripts/install_php.py @@ -0,0 +1,70 @@ + +from pastafariutils import linux +import distro +import argparse +import os + +php_versions=['8.2', '8.3', '8.4'] + +linux_distro=distro.id() + +parser=argparse.ArgumentParser(prog='install_php.py', description='Script for install php') + +parser.add_argument('--version', help='The version of php', required=True) + +parser.add_argument('--ip', help='The IP where php-fpm receive orders') + +args=parser.parse_args() + +ip=None + +if args.ip: + ip=args.ip + + +version=args.version + +if not version in php_versions: + linux.json_log('Error: php version not supported', error=1, status=1, progress=100, no_progress=0); + exit(1) + + +linux.json_log('Installing repos...', error=0, status=0, progress=0, no_progress=0); + +if linux_distro=='debian': + + if not os.path.isfile('/etc/apt/sources.list.d/php.list'): + + # Add sury repos + add_repos={'debian': "sudo apt-get update & sudo apt-get -y install lsb-release ca-certificates curl & sudo curl -sSLo /usr/share/keyrings/deb.sury.org-php.gpg https://packages.sury.org/php/apt.gpg &sudo ln -s /usr/share/keyrings/deb.sury.org-php.gpg /etc/apt/trusted.gpg.d/deb.sury.org-php.gpg & sudo sh -c 'echo \"deb [signed-by=/usr/share/keyrings/deb.sury.org-php.gpg] https://packages.sury.org/php/ $(lsb_release -sc) main\" > /etc/apt/sources.list.d/php.list'"} + + linux.exec(add_repos) + +linux.exec({'debian': 'sudo apt-get update'}) + +if linux_distro=='almalinux' or linux_distro=='rocky' or linux_distro=='fedora': + + pass + +linux.json_log('Repos installed...', error=0, status=0, progress=100, no_progress=0); + +# Install php-fpm version + +install_php={'debian': 'sudo DEBIAN_FRONTEND="noninteractive" apt-get install -y php{version}-fpm php{version}-gd php{version}-mysql php{version}-curl php{version}-mbstring php{version}-intl php{version}-imagick php{version}-xml php{version}-zip php{version}-redis unzip'.format(version=version)} + +linux.json_log('Install php {}...'.format(version), error=0, status=0, progress=0, no_progress=1); + +linux.exec(install_php) + +#sed_php={'debian' : ['ServerTokens OS', "ServerTokens Prod", '\/etc\/apache2\/conf-enabled\/security.conf']} + +""" +debian_package='apache2 logrotate socat curl' + +redhat_package='httpd mod_ssl mod_md openssl tar socat policycoreutils-python-utils wget' + +linux_package={'debian' : debian_package, 'ubuntu' : debian_package, 'fedora' : redhat_package, 'almalinux' : redhat_package, 'rocky' : redhat_package, 'arch' : 'apache'} + +linux.install_package(linux_package); + +""" diff --git a/settings/config_admin.py b/settings/config_admin.py new file mode 100644 index 0000000..b1b7b87 --- /dev/null +++ b/settings/config_admin.py @@ -0,0 +1,15 @@ +from paramecio2.libraries.config_admin import config_admin +from paramecio2.libraries.i18n import I18n, PGetText +from settings import config +import os + +pgettext=PGetText(__file__+'/../') +_=pgettext.gettext + +def php(): + + return _('PHP servers') + +config_admin.append(['PHP']) + +config_admin.append([php(), 'modules.phpserver.dashboard', 'php_app.php_dashboard', '']) diff --git a/tasks/php/info.cfg b/tasks/php/info.cfg new file mode 100644 index 0000000..c70c510 --- /dev/null +++ b/tasks/php/info.cfg @@ -0,0 +1,9 @@ +[info] +name=PHP FPM +description=Install php-fpm in a server + +[modules] +php/install_php=Install php-fpm in a server. + +[form] +php/install_php=1 diff --git a/tasks/php/php/install_php.py b/tasks/php/php/install_php.py new file mode 100644 index 0000000..e26bcf4 --- /dev/null +++ b/tasks/php/php/install_php.py @@ -0,0 +1,207 @@ +#/usr/bin/env python3 + +from modules.pastafari2.libraries.task import Task +#from modules.pastafari.models.tasks import TaskModel +from paramecio2.libraries.db import coreforms +from paramecio2.libraries.db.extrafields.ipfield import IpField +from paramecio2.libraries.formsutils import show_form +from collections import OrderedDict +from paramecio2.libraries.urls import make_media_url, make_url +from modules.pastafari2.models.pastafari2 import ServerDbTask +from modules.pastafari2.libraries.configtask import config_task +import json +try: + from modules.phpserver.models.php import PHPServer + server_db=True +except: + server_db=False + +php_version=['8.2', '8.3', '8.4'] + +class ServerTask(Task): + + def __init__(self, server, conn, remote_user='root', remote_password='', private_key='./ssh/id_rsa', password_key='', remote_path='pastafari2', task_id=0, data={}, port=22): + + super().__init__(server, conn, remote_user, remote_password, private_key, password_key, remote_path, task_id, data, port) + + self.name_task='PHP-FPM installation' + + self.description_task='Installation of a standalone php-fpm server' + + self.codename_task='php-fpm' + + self.files=[['modules/php/scripts/install_php.py', 0o700]] + + # Format first array element is command with the interpreter, the task is agnostic, the files in os directory. The commands are setted with 750 permission. + # First element is the file, next elements are the arguments + + #self.commands_to_execute=[['modules/pastafari/scripts/servers/databases/mysql/install_mariadb.py', '']]; + + #THe files to delete + + self.delete_files=[] + + self.delete_directories=['modules/php/scripts/'] + + #self.task=Task(conn) + + #self.one_time=True + + self.version='1.0' + + self.links='

{}

'.format(make_url('pastafari2/php/servers'), _('PHP-FPM servers list')) + + self.arr_form=OrderedDict() + + self.arr_form['version']=coreforms.SelectForm('version', '8.2', {'8.2': '8.2', '8.3': '8.3', '8.4': '8.4'}) + + self.arr_form['version'].required=True + + self.arr_form['version'].label=_('Version') + + """ + self.arr_form['mysql_password']=coreforms.PasswordForm('mysql_password', '') + + self.arr_form['mysql_password'].required=True + + self.arr_form['mysql_password'].label='The MySQL password used by all servers' + + self.arr_form['repeat_mysql_password']=coreforms.PasswordForm('repeat_mysql_password', '') + + self.arr_form['repeat_mysql_password'].required=True + + self.arr_form['repeat_mysql_password'].label='Repeat MySQL password' + + self.arr_form['access_localhost']=coreforms.SimpleTextForm('access_localhost', '') + + self.arr_form['access_localhost'].required=True + + #self.arr_form['access_localhost'].default_value='1' + + self.arr_form['access_localhost'].label='IP for access to mariadb server' + self.arr_form['access_localhost'].help='Empty if you want only localhost access. If you want all ips, use 0.0.0.0 or if you want other ip, put it' + """ + + #self.commands_to_execute=[['modules/pastafari/scripts/servers/databases/mariadb/install_mariadb.py', '--password=%s' % self.data['mysql_password']]] + + def post_task(self): + + if server_db: + dbserver=PHPServer(self.connection) + + dbserver.safe_query() + + serverdb=ServerDbTask(self.connection) + + arr_server=serverdb.set_conditions('WHERE ip=%s', [self.server]).select_a_row_where() + + if arr_server: + dbserver.insert({'version': self.data['version'], 'server_id': arr_server['id']}) + + return True + + + def pre_task(self): + + ip_option='' + + #if 'ip' in self.data: + # ip_option='--ip='+self.data['ip'] + + version='8.2' + + if 'version' in self.data: + version=self.data['version'] + + self.commands_to_execute=[['/home/{}/pythonenv/bin/python3 -u modules/php/scripts/install_php.py'.format(config_task.remote_user), '--version={}'.format(version)]] + #self.commands_to_execute=[['/home/{}/pythonenv/bin/python3 -u modules/apache/scripts/install_apache.py'.format(config_task.remote_user), '']] + + return True + + def form(self, t, yes_error=False, pass_values=False, values={}): + + #Here load the form for it task + + return '

PHP-FPM configuration

'+show_form(values, self.arr_form, t, yes_error, pass_values) + + def check_form(self, post): + + error=False + """ + if 'mysql_password' in post and 'repeat_mysql_password' in post: + + if post['mysql_password'].strip()!='' and post['mysql_password']==post['repeat_mysql_password']: + + self.data['mysql_password']=post['mysql_password'].strip() + + else: + + self.arr_form['mysql_password'].error=True + self.arr_form['mysql_password'].txt_error='Passwords doesn\'t match' + error=True + + if 'access_localhost' in post: + + self.data['ip']='' + + ip_check=IpField('ip') + + ip_host=post['access_localhost'].strip() + + if ip_host!='': + + ip_host=ip_check.check(ip_host) + + if ip_host!='': + self.data['ip']=ip_host + + if ip_check.error: + + self.arr_form['access_localhost'].error=True + self.arr_form['access_localhost'].txt_error='Wrong ip format' + error=True + + """ + + self.data['version']=post['version'].strip() + #print(self.data['version']) + if not self.data['version'] in php_version: + + self.arr_form['version'].error=True + self.arr_form['version'].txt_error='Incorrect version' + + error=1 + + dbserver=PHPServer(self.connection) + + dbserver.safe_query() + + serverdb=ServerDbTask(self.connection) + + server_id=json.loads(post['ids'])[0] + print(server_id) + arr_server=serverdb.select_a_row(server_id) + + if arr_server: + #dbserver.insert({'version': self.data['version'], 'server_id': arr_server['id']}) + + c=dbserver.set_conditions('WHERE server_id=%s and version=%s', [arr_server['id'], self.data['version']]).select_count() + + if c>0: + self.arr_form['version'].error=True + self.arr_form['version'].txt_error='Error: version installed' + + error=1 + + else: + self.arr_form['version'].error=True + self.arr_form['version'].txt_error='Server incorrect' + + error=1 + + if error: + return False + else: + return True + + diff --git a/templates/admin/phpservers.phtml b/templates/admin/phpservers.phtml new file mode 100644 index 0000000..cb9dce6 --- /dev/null +++ b/templates/admin/phpservers.phtml @@ -0,0 +1,17 @@ +<%inherit file="dashboard.phtml"/> +<%block name="content"> +

${_('Add PHP server')} +

+
+<%block name="jscript_block"> + + + + +