commit 25aaa0a4bff08d6cc646621987a14582a32d16fe Author: absurdo Date: Tue Nov 28 00:15:10 2023 +0100 Added files 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..b72312a --- /dev/null +++ b/__init__.py @@ -0,0 +1,3 @@ +from flask import Blueprint, g + +apache_app=Blueprint('apache_app', __name__) diff --git a/admin/app.py b/admin/app.py new file mode 100644 index 0000000..a8d2aa2 --- /dev/null +++ b/admin/app.py @@ -0,0 +1,946 @@ +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 +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.apache.models.webservers import VirtualHost, UsersFtp, WebServer, WebServerPort +from paramecio2.libraries.mtemplates import PTemplate, env_theme +from paramecio2.libraries.formsutils import show_form +from paramecio2.libraries.db.coreforms import HiddenForm, SelectForm, TextForm, PasswordForm +from paramecio2.libraries.slugify import slugify +from modules.pastafari2.libraries.configtask import config_task +from modules.pastafari2.libraries.progress import load_progress +import os + +try: + import ujson as json +except: + import json + +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') + +@admin_app.route('/webservers/servers/') +def webservers(): + + return t.load_template('webservers.phtml', title=I18n.lang('webservers', 'webservers', 'Webservers'), path_module='admin_app.webservers') + +@admin_app.route('/get_webservers', methods=['POST']) +def get_webservers(): + + + db=g.connection + + group_sql='' + + count_data=[] + sql_data=[] + + fields=[[I18n.lang('webservers', 'hostname', 'Hostname'), True], ['IP', True], [I18n.lang('webservers', 'options', 'Options'), False]] + arr_order_fields=['hostname', 'ip'] + + count_query=['select count(webserver.id) as num_elements from webserver', count_data] + + # server.id as select_id, + + # select hostname, ip, date, num_updates, id from serverofuser where user_id=%s; + + #str_query=['select webserver.hostname, webserver.ip, webserver.id from webserver,serverdbtask', sql_data] + + str_query=['select serverdbtask.hostname, serverdbtask.ip, webserver.id as id from webserver, serverdbtask WHERE serverdbtask.id=webserver.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=['{}'.format(url_for('admin_app.virtualhost', server_id=row_id), I18n.lang('webserver', 'server_users', 'Server users'))] + arr_options=['{}'.format(url_for('admin_app.virtualhost', webserver_id=row_id), I18n.lang('webserver', 'websites', 'Websites'))] + # + #arr_options.append('{}'.format(url_for('admin_app.ports', webserver_id=row_id), I18n.lang('webserver', 'http_ports', 'HTTP Ports'))) + #arr_options.append('{}'.format("", I18n.lang('webserver', 'edit', 'Edit'))) + arr_options.append('{}'.format(url_for('admin_app.delete_webserver', webserver_id=row_id), I18n.lang('webserver', 'delete', 'Delete'))) + + return '
'.join(arr_options) + +def post_virtual_update(admin, item_id): + + with admin.model.query('select * from virtualhost where id=%s', [admin.virtualhost_id]) as cursor: + arr_virtualhost=cursor.fetchone() + + with admin.model.query('select uid_hosting, gid_hosting from webserver where id=%s', [arr_virtualhost['webserver_id']]) as cursor: + arr_webserver=cursor.fetchone() + + if virtualhost: + + #arr_user=admin.model.select_a_row(item_id, [], True) + + home_user=arr_virtualhost['home'] + + admin.model.query('update usersftp set uid=%s, gid=%s, home=%s, virtualhost_id=%s WHERE id=%s', [arr_webserver['uid_hosting'], arr_webserver['gid_hosting'], home_user, admin.virtualhost_id, item_id]) + + #virtualhost_id=request.args.get('') + + return True + +@admin_app.route('/webservers/delete/', methods=['GET', 'POST']) +def delete_webserver(webserver_id): + + db=g.connection + + webserver=WebServer(db) + + arr_webserver=webserver.select_a_row(webserver_id) + + if arr_webserver: + + return t.load_template('del_webserver.phtml', title=I18n.lang('webservers', 'remove_webserver', 'Remove webserver'), path_module='admin_app.webservers', webserver_id=arr_webserver['id'], domain=arr_webserver['server_id']) + + else: + return "" + +@admin_app.route('/delete_webserver/', methods=['GET', 'POST']) +def delete_webserver_db(webserver_id): + + db=g.connection + + error=1 + + webserver=WebServer(db) + + if webserver.set_conditions('WHERE id=%s', [webserver_id]).delete(): + + error=0 + + return {'error': error} + +# Ports of ftp server + +@admin_app.route('/webservers/ports/', methods=['GET', 'POST']) +def ports(webserver_id): + + db=g.connection + + ports=WebServerPort(db) + + webserver=WebServer(db) + + arr_webserver=webserver.select_a_row(webserver_id) + + #print(arr_webserver) + + ports.set_conditions('WHERE webserver_id=%s', [webserver_id]) + + ports.fields['webserver_id'].name_form=HiddenForm + ports.fields['webserver_id'].extra_parameters=[] + + ports.fields['webserver_id'].default_value=request.args.get('webserver_id', webserver_id) + + admin=GenerateAdminClass(ports, url_for('admin_app.ports', webserver_id=webserver_id), t) + + admin.list.fields_showed=['ip', 'port'] + + #usersftp=UsersFtp(db) + + #arr_user=usersftp.select_a_row(user_id, [], True) + + form_admin=admin.show() + + if type(form_admin).__name__=='str': + + return t.load_template('ports.phtml', title=I18n.lang('webservers', 'server_ports', 'Server ports'), path_module='admin_app.ports', form_admin=form_admin, webserver_id=webserver_id, hostname=arr_webserver['server_id']) + else: + + return form_admin + + """ + webserver=WebServer(db) + + arr_webserver=webserver.select_a_row(webserver_id, [], True) + + if arr_webserver: + + return t.load_template('virtualhosts.phtml', title=I18n.lang('webservers', 'virtualhost', 'Virtual Hosts'), path_module='admin_app.webservers', webserver_id=webserver_id) + + else: + + return '' + """ + + +# FTP USERS for virtualhost + +@admin_app.route('/webservers/server_users/', methods=['GET', 'POST']) +def server_users(virtualhost_id): + + db=g.connection + + usersftp=UsersFtp(db) + + usersftp.set_conditions('WHERE virtualhost_id=%s', [virtualhost_id]) + + usersftp.fields['passwd'].protected=False + + vhost=VirtualHost(db) + + arr_vhost=vhost.select_a_row(virtualhost_id, [], True) + + webserver_id=arr_vhost['webserver_id'] + + #usersftp.check_user=False + #usersftp.check_email=False + + admin=GenerateAdminClass(usersftp, url_for('admin_app.server_users', virtualhost_id=virtualhost_id), t) + + #admin.arr_fields_edit=['user', 'passwd'] + admin.list.search_fields=['user'] + admin.list.fields_showed=['user', 'quota_mb'] + + admin.arr_fields_edit=['user', 'email', 'passwd', 'repeat_password', 'quota_mb'] + + admin.virtualhost_id=virtualhost_id + + admin.post_update=post_virtual_update + + admin.list.arr_extra_options=[option_users] + + #admin.post_update= + + #return t.load_template('serverusers.phtml', title=I18n.lang('webservers', 'server_users', 'Server users'), path_module='admin_app.server_users', admin=admin) + + form_admin=admin.show() + + if type(form_admin).__name__=='str': + + return t.load_template('serverusers.phtml', title=I18n.lang('webservers', 'ftp_users', 'FTP users'), path_module='admin_app.webservers', form_admin=form_admin, webserver_id=webserver_id) + else: + + return form_admin + +def option_users(url, row_id, row): + + #arr_options=['{}'.format(url_for('admin_app.virtualhost, user_id=user_id), I18n.lang('webserver', 'server_users', 'Server users'))] + # + #arr_options.append('{}'.format("", I18n.lang('webserver', 'edit', 'Edit'))) + #arr_options.append('{}'.format("", I18n.lang('webserver', 'delete', 'Delete'))) + + #return '
'.join(arr_options) + + arr_options=[] #[''+I18n.lang('webservers', 'virtualhosts', 'Virtual Hosts')+''] + + arr_options+=SimpleList.standard_options(url, row_id, row) + + return arr_options + +@admin_app.route('/webservers/virtualhost/') +def virtualhost(webserver_id): + + db=g.connection + + #usersftp=UsersFtp(db) + + #arr_user=usersftp.select_a_row(user_id, [], True) + + webserver=WebServer(db) + + #arr_webserver=webserver.select_a_row(webserver_id, [], True) + arr_webserver=None + with db.query('select webserver.id, serverdbtask.hostname from webserver, serverdbtask where webserver.server_id=serverdbtask.id AND webserver.id=%s', [webserver_id]) as cursor: + arr_webserver=cursor.fetchone() + + if arr_webserver: + + return t.load_template('virtualhosts.phtml', title=I18n.lang('webservers', 'virtualhost', 'Virtual Hosts'), path_module='admin_app.webservers', webserver_id=webserver_id, hostname=arr_webserver['hostname']) + + else: + + return '' + +def options_vhosts(row_id, row): + + arr_options=[] + + #arr_options.append('{}'.format(url_for('admin_app.server_users', virtualhost_id=row_id), I18n.lang('webserver', 'ftp_users', 'Ftp users'))) + arr_options.append('{}'.format(url_for('admin_app.webapps', virtualhost_id=row_id), I18n.lang('webserver', 'webapps', 'Webapps'))) + arr_options.append('{}'.format(url_for('admin_app.edit_virtualhost', virtualhost_id=row_id), I18n.lang('webserver', 'edit', 'Edit'))) + arr_options.append('{}'.format(url_for('admin_app.virtualhost_delete', virtualhost_id=row_id), I18n.lang('webserver', 'delete', 'Delete'))) + + return '
'.join(arr_options) + +def options_username(row_id, row): + + return ''+row['username']+'' + +@admin_app.route('/get_virtualhosts', methods=['POST']) +def get_virtualhosts(): + + db=g.connection + + user_id=request.args.get('webserver_id', '0') + + group_sql='' + + count_data=[] + sql_data=[user_id] + + fields=[[I18n.lang('webservers', 'domain', 'Domain'), True], [I18n.lang('webservers', 'user', 'User'), True], [I18n.lang('webservers', 'options', 'Options'), False]] + arr_order_fields=['domain'] + + count_query=['select count(virtualhost.id) as num_elements from virtualhost', count_data] + + # server.id as select_id, + + # select hostname, ip, date, num_updates, id from serverofuser where user_id=%s; + + #str_query=['select webserver.hostname, webserver.ip, webserver.id from webserver,serverdbtask', sql_data] + + str_query=['select domain, username, id from virtualhost WHERE webserver_id=%s', 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['username']=options_username + ajax.func_fields['id']=options_vhosts + ajax.limit=0 + + return ajax.show() + + +@admin_app.route('/add_virtualhost/', methods=['GET']) +def add_virtualhost(webserver_id): + + db=g.connection + + #usersftp=UsersFtp(db) + + #arr_user=usersftp.select_a_row(user_id, [], True) + + #webserver_id=arr_user['webserver_id'] + + virtual=VirtualHost(db) + + virtual.fields['webserver_id'].name_form=HiddenForm + virtual.fields['webserver_id'].extra_parameters=[] + + virtual.fields['webserver_id'].default_value=request.args.get('webserver_id', webserver_id) + + #virtual.fields['cgi_type'].name_form=SelectForm + #virtual.fields['cgi_type'].extra_parameters=[{'': I18n.lang('webservers', 'anything', 'Anything cgi content'), 'php74': 'PHP 7.4 (php-fpm)', 'php80': 'PHP 8.0 (php-fpm)', 'php81': 'PHP 8.1 (php-fpm)', 'php82': 'PHP 8.2 (php-fpm)', 'python3': 'Python3 (mod_wsgi)'}] + virtual.fields['username'].label=I18n.lang('webservers', 'username_vhost', 'Virtualhost user') + virtual.fields['username'].help=I18n.lang('webservers', 'username_vhost_explain', 'The virtualhost is saved inside unix user. You can set the username in this field') + + virtual.fields['cgi_type'].default_value=request.args.get('cgi_type', '') + + virtual.fields['ip'].label=I18n.lang('webservers', 'ip_if_empty', 'Ip of virtualhost, empty if server default') + virtual.fields['ip'].help=I18n.lang('webservers', 'ip_if_empty_explain', 'Ip of virtualhost, empty if server default. If you don\'t know that value your need, leave it empty') + + virtual.fields['domain'].help=I18n.lang('webservers', 'domain_explain', 'The domain of new website') + + virtual.fields['port'].help=I18n.lang('webservers', 'port_explain', 'Change the base port used for the website if you want use behind of a reverse proxy') + + virtual.fields['port'].default_value=80 + + #virtual.fields['user_id'].name_form= + + #'php74', 'php80', 'php81', 'php82', 'wsgi' + + virtual.create_forms(['domain', 'webserver_id', 'ip', 'username']) + + """ + virtual.forms['password']=PasswordForm('password', '') + virtual.forms['password'].label=I18n.lang('webservers', 'user_password', 'User password') + virtual.forms['password'].help=I18n.lang('webservers', 'user_password_explain', 'User password used for the user if you want access to this server using this user. Remember, the password is not saved in pastafari') + virtual.forms['repeat_password']=PasswordForm('repeat_password', '') + virtual.forms['repeat_password'].label=I18n.lang('webservers', 'rpeat_user_password', 'Repeat User password') + """ + + + #print(virtual.fields.keys()) + + arr_form=virtual.forms + #print(arr_form['user_id'].model.fields.keys()) + + + form=show_form({}, arr_form, t, yes_error=True, pass_values=False, modelform_tpl='forms/modelform.phtml') + + return t.load_template('add_virtualhost.phtml', title=I18n.lang('webservers', 'add_website', 'Add Website'), path_module='admin_app.webservers', form=form, webserver_id=webserver_id) + + +@admin_app.route('/save_virtualhost/', methods=['POST']) +def save_virtualhost(): + + db=g.connection + + domain=request.form.get('domain', '').strip() + + #home=slugify(request.form.get('home' '').strip()) + + webserver_id=request.form.get('webserver_id', '0') + + cgi_type=request.form.get('cgi_type', '') + + port=80 #request.form.get('port', '0') + + ip=request.form.get('ip', '') + + error=0 + + error_form={} + + webserver=WebServer(db) + + virtualhost=VirtualHost(db) + + if virtualhost.fields['domain'].check(domain)=='': + error_form['#domain_error']='Sorry, invalid domain' + error=1 + + check_port=int(virtualhost.fields['port'].check(port)) + + if check_port==0 or check_port<0 or (check_port<1000 and check_port!=80) or check_port>65536: + error_form['#port_error']='Sorry, invalid port' + error=1 + else: + port=check_port + + ip=virtualhost.fields['ip'].check(ip) + + if ip=='': + ip='*' + + username=virtualhost.fields['username'].check(request.form.get('username', '')) + + if username=='': + error_form['#username_error']='Sorry, invalid username' + error=1 + + arr_virtualhost=virtualhost.set_conditions('WHERE domain=%s', [domain]).select_a_row_where([], True) + + if arr_virtualhost: + error_form['#domain_error']='Sorry, domain exists in server' + error=1 + + """ + if 'password' in post and 'repeat_password' in post: + + if post['password'].strip()!='' and post['password']==post['repeat_password']: + + self.data['password']=post['password'].strip() + + else: + + self.arr_form['password'].error=True + self.arr_form['password'].txt_error='Passwords doesn\'t match' + error=True + """ + + """ + password=request.form.get('password', '') + + repeat_password=request.form.get('repeat_password', '') + + if password!=repeat_password: + error_form['#password_error']='Passwords doesn\'t match' + error=1 + """ + + """ + if virtualhost.fields['home'].check(home)=='': + error_form['#home_error']='Sorry, invalid home' + error=1 + """ + + task_id=0 + + serverdb=ServerDbTask(db) + + arr_webserver=webserver.set_conditions('WHERE webserver.id=%s', [webserver_id]).select_a_row_where([], True) + + if arr_webserver and not error: + + arr_server=serverdb.select_a_row(arr_webserver['server_id'], [], True) + + #username=arr_webserver['username'] + + #print(arr_user) + + #server_id=arr_user['webserver_id_server_id'] + + #username=arr_user['webserver_id_username'] + + #Check if not exists domain, etc + + #arr_server=serverdb.select_a_row(server_id) + + #print(arr_server) + + sshtask=SSHTask(db) + + #user=config_task.remote_user + + ssh_key_priv='./ssh/id_rsa' + + #run_task(self, server, path, name_task, codename_task, description_task, data={}, user='', password='', where_sql_server='', url='', ssh_key_priv='', ssh_key_password='', send_task=True) + # user=user, password='', where_sql_server=where_sql, ssh_key_priv=ssh_key_priv, url='', data=data, send_task=True + + root_dir='/home/'+username+'/sites/'+domain + + #ftp_user=arr_user['user'] + + if not sshtask.run_task(arr_server['ip'], 'modules.apache.tasks.apache.apache.add_vhost', 'Add Apache virtualhost', 'add_apache_virtualhost', 'Task for add new virtualhost to Apache Server', {'domain': domain, 'email': config.portal_email, 'webserver_id': arr_webserver['id'], 'user': username, 'root_dir': root_dir, 'cgi_type': cgi_type, 'ip': ip, 'port': port}, config_task.remote_user, '', '', url_for('admin_app.virtualhost', webserver_id=arr_webserver['id']), ssh_key_priv=ssh_key_priv, ssh_key_password='', send_task=True, ssh_port=arr_server['ssh_port']): + error=1 + + task_id=sshtask.task_id + + else: + + + error=1 + + return {'error': error, 'error_form': error_form, 'task_id': task_id} + +@admin_app.route('/virtualhost/progress//') +def virtualhost_progress(webserver_id): + + db=g.connection + + #Webservers list >> Web users >> Virtual Hosts + #cursor=db.query('select `usersftp`.`id` from `usersftp`') + + return_tree='

'+I18n.lang('webservers', 'webservers_list', 'Webservers list')+' >> '+I18n.lang('webservers', 'websites', 'Websites')+'

' + + return load_progress(db, t, return_tree=return_tree, path_module='admin_app.webservers') + +@admin_app.route('/virtualhost/delete/') +def virtualhost_delete(virtualhost_id): + + db=g.connection + + vhost=VirtualHost(db) + + usersftp=UsersFtp(db) + + arr_virtualhost=vhost.select_a_row(virtualhost_id, [], True) + + #arr_user=usersftp.select_a_row(arr_virtualhost['user_id'], [], True) + + return t.load_template('del_virtualhost.phtml', title=I18n.lang('webservers', 'remove_virtualhost', 'Remove Virtual Host'), path_module='admin_app.webservers', webserver_id=arr_virtualhost['webserver_id'], virtualhost_id=virtualhost_id, domain=arr_virtualhost['domain']) + +@admin_app.route('/delete_virtualhost/', methods=['POST']) +def delete_virtualhost(): + + virtualhost_id=request.form.get('virtualhost_id', '0') + + error=0 + + error_form={} + + task_id=0 + + db=g.connection + + vhost=VirtualHost(db) + + #usersftp=UsersFtp(db) + + arr_virtualhost=vhost.select_a_row(virtualhost_id, [], True) + + if arr_virtualhost: + + webserver_id=arr_virtualhost['webserver_id'] + + #arr_user=usersftp.set_conditions('WHERE usersftp.id=%s', [webserver_id]).select_a_row_where([]) + + #server_id=arr_virtualhost['server_id'] + + #username=arr_virtualhost['username'] + + root_dir=arr_virtualhost['home'] + + #ftp_user=arr_user['user'] + + webserver=WebServer(db) + + arr_webserver=webserver.select_a_row(webserver_id, [], True) + + #username=arr_webserver['username'] + + serverdb=ServerDbTask(db) + + arr_server=serverdb.select_a_row(arr_webserver['server_id'], [], True) + + domain=arr_virtualhost['domain'] + username=arr_virtualhost['username'] + + if arr_virtualhost: + + sshtask=SSHTask(db) + + ssh_key_priv='./ssh/id_rsa' + + if not sshtask.run_task(arr_server['ip'], 'modules.apache.tasks.apache.apache.delete_vhost', 'Remove Apache virtualhost', 'remove_apache_virtualhost', 'Task for remove a virtualhost to Apache Server', {'domain': domain, 'email': config.portal_email, 'webserver_id': arr_webserver['id'], 'user': username, 'root_dir': root_dir, 'cgi_type': ''}, config_task.remote_user, '', '', url_for('admin_app.virtualhost', webserver_id=webserver_id), ssh_key_priv=ssh_key_priv, ssh_key_password='', send_task=True, ssh_port=arr_server['ssh_port']): + + error=1 + + task_id=sshtask.task_id + + else: + + error=1 + + pass + else: + error=1 + + return {'error': error, 'error_form': error_form, 'task_id': task_id} + +@admin_app.route('/edit_virtualhost/', methods=['GET']) +def edit_virtualhost(virtualhost_id): + + db=g.connection + + vhost=VirtualHost(db) + + arr_vhost=vhost.select_a_row(virtualhost_id, [], True) + + if arr_vhost: + + virtual=VirtualHost(db) + + virtual.fields['aliases'].label=I18n.lang('webservers', 'domain_alias', 'Domain aliases') + virtual.fields['aliases'].help=I18n.lang('webservers', 'domain_alias_explain', 'Domain aliases are the other domain names of this server. For example www.domain.com, other-site.domain.com. You can separate the domains with commas') + + virtual.fields['webserver_id'].name_form=HiddenForm + virtual.fields['webserver_id'].extra_parameters=[] + + #virtual.fields['webserver_id'].default_value=arr_vhost['webserver_id'] + + #virtual.fields['cgi_type'].name_form=SelectForm + #virtual.fields['cgi_type'].extra_parameters=[{'': I18n.lang('webservers', 'anything', 'Anything cgi content'), 'php74': 'PHP 7.4 (php-fpm)', 'php80': 'PHP 8.0 (php-fpm)', 'php81': 'PHP 8.1 (php-fpm)', 'php82': 'PHP 8.2 (php-fpm)', 'python3': 'Python3 (mod_wsgi)'}] + + #virtual.fields['cgi_type'].default_value=arr_vhost['cgi_type'] + + virtual.fields['ip'].label=I18n.lang('webservers', 'ip_if_empty', 'Ip of virtualhost, empty if server default') + virtual.fields['ip'].help=I18n.lang('webservers', 'ip_if_empty_explain', 'Ip of virtualhost, empty if server default. If you don\'t know that value your need, leave it empty') + + virtual.fields['domain'].help=I18n.lang('webservers', 'domain_explain', 'The domain of new website') + + virtual.fields['port'].help=I18n.lang('webservers', 'port_explain', 'Change the base port used for the website if you want use behind of a reverse proxy. The port need to be specified in http ports edit in webservers') + virtual.fields['ssl_port'].help=I18n.lang('webservers', 'port_explain', 'Change the base port used for the website if you want use behind of a reverse proxy. The port need to be specified in http ports edit in webservers') + + virtual.fields['ssl'].name_form=SelectForm + virtual.fields['ssl'].extra_parameters=[{0: 'No', 1: 'Lets Encrypt', 2: 'SSL Files'}] + + virtual.fields['redirect_ssl'].name_form=SelectForm + virtual.fields['redirect_ssl'].extra_parameters=[{0: I18n.lang('webservers', 'no', 'No'), 1: I18n.lang('webservers', 'yes', 'Yes')}] + + virtual.fields['indexes'].name_form=SelectForm + virtual.fields['indexes'].extra_parameters=[{0: I18n.lang('webservers', 'no', 'No'), 1: I18n.lang('webservers', 'yes', 'Yes')}] + virtual.fields['indexes'].help=I18n.lang('webservers', 'add_support_for_show_files_if_index_not_exists', 'Add support show files if index.html not exists?') + + virtual.fields['allow_override'].name_form=SelectForm + virtual.fields['allow_override'].extra_parameters=[{0: I18n.lang('webservers', 'no', 'No'), 1: I18n.lang('webservers', 'yes', 'Yes')}] + virtual.fields['allow_override'].help=I18n.lang('webservers', 'add_support_for_.htaccess', 'Add support for htaccess?') + + + virtual.fields['php'].label=I18n.lang('webservers', 'php_support', 'PHP support') + virtual.fields['php'].name_form=SelectForm + virtual.fields['php'].extra_parameters=[{'': 'No php support', '7.4': 'PHP 7.4', '8.0': 'PHP 8.0', '8.1': 'PHP 8.1', '8.2': 'PHP 8.2'}] + virtual.fields['php'].help=I18n.lang('webservers', 'add_php_support_to_virtualhost', 'Add support to php to virtualhost. You can choose ophp version that you prefer') + + #'port', 'ssl_port', + + virtual.create_forms(['domain', 'aliases', 'webserver_id', 'ip', 'indexes', 'allow_override', 'redirect_ssl', 'ssl', 'php']) + + + #print(virtual.fields.keys()) + + arr_form=virtual.forms + #print(arr_form['user_id'].model.fields.keys()) + + arr_form['ssl_crt']=TextForm('ssl_crt', '') + + arr_form['ssl_crt'].help=I18n.lang('webservers', 'ssl_crt_explain', 'Certificate text from file of ssl certificate, normally ending with .crt') + + arr_form['ssl_crt'].label=I18n.lang('webservers', 'ssl_crt', 'Ssl certificate') + + arr_form['ssl_crt'].css='hide_form' + + arr_form['ssl_key']=TextForm('ssl_key', '') + + arr_form['ssl_key'].help=I18n.lang('webservers', 'ssl_key_explain', 'Key text from file of ssl certificate, normally ending with .key') + + arr_form['ssl_key'].label=I18n.lang('webservers', 'ssl_key', 'Ssl key') + + arr_form['ssl_key'].css='hide_form' + + if arr_vhost['ssl_port']==0: + arr_vhost['ssl_port']=443 + + form=show_form(arr_vhost, arr_form, t, yes_error=True, pass_values=True, modelform_tpl='forms/modelform.phtml') + + return t.load_template('edit_virtualhost.phtml', title=I18n.lang('webservers', 'edit_virtualhost', 'Edit Virtual Host'), path_module='admin_app.webservers', form=form, webserver_id=arr_vhost['webserver_id'], virtualhost_id=virtualhost_id) + + pass + + return "" + +@admin_app.route('/save_edit_virtualhost/', methods=['POST']) +def save_edit_virtualhost(): + + db=g.connection + + domain=request.form.get('domain', '').strip() + + #home=slugify(request.form.get('home' '').strip()) + + webserver_id=request.form.get('webserver_id', '0') + virtualhost_id=request.args.get('virtualhost_id', '0') + + cgi_type=request.form.get('cgi_type', '') + + #port=request.form.get('port', '0') + + #ssl_port=request.form.get('ssl_port', '0') + port=80 + ssl_port=443 + + + ssl=request.form.get('ssl', '0') + + indexes=request.form.get('indexes', '0') + + redirect_ssl=request.form.get('redirect_ssl', '0') + + if indexes!='1': + indexes='0' + + allow_override=request.form.get('allow_override', '0') + + if allow_override!='1': + allow_override='0' + + ip=request.form.get('ip', '') + + error=0 + + error_form={} + + webserver=WebServer(db) + + virtualhost=VirtualHost(db) + + if virtualhost.fields['domain'].check(domain)=='': + error_form['#domain_error']='Sorry, invalid domain' + error=1 + + check_port=int(virtualhost.fields['port'].check(port)) + + if check_port==0 or check_port<0 or (check_port<1000 and check_port!=80) or check_port>65536: + error_form['#port_error']='Sorry, invalid port' + error=1 + else: + port=check_port + + check_ssl_port=int(virtualhost.fields['ssl_port'].check(ssl_port)) + + if check_ssl_port==0 or check_ssl_port<0 or (check_ssl_port<1000 and check_ssl_port!=443) or check_ssl_port>65536: + error_form['#ssl_port_error']='Sorry, invalid port' + error=1 + else: + ssl_port=check_ssl_port + + check_ssl=int(virtualhost.fields['ssl'].check(ssl)) + + if check_ssl<0 and check_ssl>2: + error_form['#ssl_error']='Sorry, invalid ssl options' + error=1 + else: + ssl=check_ssl + + if ssl==2: + #Load text ssl files + ssl_crt_text=request.form.get('ssl_crt', '').strip() + ssl_key_text=request.form.get('ssl_key', '').strip() + + if ssl_crt_text!='': + with open('modules/webservers/scripts/files/'+domain+'-ssl.crt', 'w') as f: + f.write(ssl_crt_text) + + if ssl_key_text!='': + with open('modules/webservers/scripts/files/'+domain+'-ssl.key', 'w') as f: + f.write(ssl_key_text) + + ip=virtualhost.fields['ip'].check(ip) + + if ip=='': + ip='*' + + """ + if virtualhost.fields['home'].check(home)=='': + error_form['#home_error']='Sorry, invalid home' + error=1 + """ + aliases=request.form.get('aliases', '') + + arr_aliases=[] + + if aliases!='': + arr_aliases=[virtualhost.fields['domain'].check(alias.strip()) for alias in aliases.split(',') if virtualhost.fields['domain'].check(alias.strip())!=''] + + if len(arr_aliases)>0: + aliases=",".join(arr_aliases) + + php=request.form.get('php', '') + + if php!='': + if php!='7.4' and php!='8.0' and php!='8.1' and php!='8.2': + php='' + + task_id=0 + + serverdb=ServerDbTask(db) + + arr_webserver=webserver.set_conditions('WHERE webserver.id=%s', [webserver_id]).select_a_row_where([], True) + + if arr_webserver and not error: + + arr_server=serverdb.select_a_row(arr_webserver['server_id'], [], True) + + arr_virtualhost=virtualhost.select_a_row(virtualhost_id, [], True) + + username=arr_virtualhost['username'] + + #print(arr_user) + + #server_id=arr_user['webserver_id_server_id'] + + #username=arr_user['webserver_id_username'] + + #Check if not exists domain, etc + + #arr_server=serverdb.select_a_row(server_id) + + #print(arr_server) + + sshtask=SSHTask(db) + + #user=config_task.remote_user + + ssh_key_priv='./ssh/id_rsa' + + #run_task(self, server, path, name_task, codename_task, description_task, data={}, user='', password='', where_sql_server='', url='', ssh_key_priv='', ssh_key_password='', send_task=True) + # user=user, password='', where_sql_server=where_sql, ssh_key_priv=ssh_key_priv, url='', data=data, send_task=True + + root_dir=arr_virtualhost['home'] + + #ftp_user=arr_user['user'] + + if not sshtask.run_task(arr_server['ip'], 'modules.apache.tasks.apache.apache.edit_vhost', 'Edit Apache virtualhost', 'edit_apache_virtualhost', 'Task for edit a virtualhost to Apache Server', {'domain': domain, 'email': config.portal_email, 'webserver_id': arr_webserver['id'], 'user': username, 'root_dir': root_dir, 'cgi_type': cgi_type, 'ip': ip, 'port': port, 'ssl': ssl, 'ssl_port': ssl_port, 'aliases': aliases, 'indexes': indexes, 'allow_override': allow_override, 'virtualhost_id': virtualhost_id, 'redirect_ssl': redirect_ssl, 'php': php}, config_task.remote_user, '', '', url_for('admin_app.virtualhost', webserver_id=arr_webserver['id']), ssh_key_priv=ssh_key_priv, ssh_key_password='', send_task=True, ssh_port=arr_server['ssh_port']): + error=1 + + task_id=sshtask.task_id + + else: + + + error=1 + + return {'error': error, 'error_form': error_form, 'task_id': task_id} + +@admin_app.route('/webservers/change_user_password', methods=['POST']) +def change_user_password(): + + webserver_id=request.args.get('webserver_id', '0') + + error=0 + + error_form={} + + task_id=0 + + db=g.connection + + vhost=VirtualHost(db) + + #usersftp=UsersFtp(db) + + webserver=WebServer(db) + + arr_webserver=webserver.select_a_row(webserver_id, [], True) + + if arr_webserver: + """ + password=request.form.get('password', '') + + repeat_password=request.form.get('repeat_password', '') + + if password!=repeat_password and password!='': + error_form['#password_error']='Passwords doesn\'t match' + password='' + error=1 + """ + + #ssh-keygen -l -f id_rsa.pub + + ssh_pub_key=request.form.get('ssh_pub_key', '') + + user=request.form.get('user', '') + + if user=='': + error_form['#user_error']=I18n.lang('webservers', 'error_you_need_an_user', 'Error: you need an user') + error=1 + + if ssh_pub_key=='': + error_form['#ssh_pub_key_error']=I18n.lang('webservers', 'error_you_need_a_ssh_pub_key', 'Error: you need a ssh public key') + error=1 + + #username=arr_webserver['username'] + + serverdb=ServerDbTask(db) + + arr_server=serverdb.select_a_row(arr_webserver['server_id'], [], True) + + sshtask=SSHTask(db) + + ssh_key_priv='./ssh/id_rsa' + + #'password': password + + if not sshtask.run_task(arr_server['ip'], 'modules.pastafari2.tasks.system.change_password_user', 'Change user password', 'Change user password', 'Task for change unix user password', {'user': user, 'ssh_pub_key': ssh_pub_key}, config_task.remote_user, '', '', url_for('admin_app.virtualhost', webserver_id=webserver_id), ssh_key_priv=ssh_key_priv, ssh_key_password='', send_task=True, ssh_port=arr_server['ssh_port']): + + error=1 + + task_id=sshtask.task_id + + else: + error=1 + + return {'error': error, 'error_form': error_form, 'task_id': task_id} + +@admin_app.route('/webservers/users_list', methods=['GET']) +def users_list(): + + return {} diff --git a/admin/install_apps.py b/admin/install_apps.py new file mode 100644 index 0000000..43a1027 --- /dev/null +++ b/admin/install_apps.py @@ -0,0 +1,168 @@ +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 +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.apache.models.webservers import VirtualHost, UsersFtp, WebServer, WebServerPort +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 +import os + +try: + import ujson as json +except: + import json + +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') + +scripts_lists={'wordpress': ('Wordpress', 'modules.apache.tasks.apache.scripts.wordpress'), 'phpmyadmin': ('PHPMyAdmin', 'modules.apache.tasks.apache.scripts.phpmyadmin'), 'flask': ('Flask application', 'modules.apache.tasks.apache.scripts.flask'), 'proxy': ('Webproxy', 'modules.apache.tasks.apache.scripts.proxy')} + +if hasattr(config, 'webservers_scripts_lists'): + scripts_lists.update(config.webservers_scripts_lists) + +arr_paths={v[1]:1 for v in scripts_lists.values()} + +for path in arr_paths.keys(): + t.env.directories.append(path) + + + +@admin_app.route('/webapps/', methods=['GET']) +def webapps(virtualhost_id): + + db=g.connection + + vhost=VirtualHost(db) + + arr_vhost=vhost.select_a_row(virtualhost_id, [], True) + + if arr_vhost: + + with db.query('select serverdbtask.id from serverdbtask, webserver WHERE webserver.id=%s AND serverdbtask.id=webserver.server_id', [arr_vhost['webserver_id']]) as cursor: + + arr_server=cursor.fetchone() + + pass + + return t.load_template('webapps.phtml', title=I18n.lang('webservers', 'webapps', 'Webapps'), path_module='admin_app.webservers', domain=arr_vhost['domain'], webserver_id=arr_vhost['webserver_id'], virtualhost_id=virtualhost_id, server_id=arr_server['id']) + + return {} + +def options_webapps(row_id, row): + + arr_options=[] + + #arr_options.append('{}'.format(url_for('admin_app.server_users', virtualhost_id=row_id), I18n.lang('webserver', 'ftp_users', 'Ftp users'))) + #arr_options.append('{}'.format(url_for('admin_app.webapps', virtualhost_id=row_id), I18n.lang('webserver', 'webapps', 'Webapps'))) + #arr_options.append('{}'.format(url_for('admin_app.edit_virtualhost', virtualhost_id=row_id), I18n.lang('webserver', 'edit', 'Edit'))) + arr_options.append('{}'.format("", I18n.lang('webserver', 'delete', 'Delete'))) + + return '
'.join(arr_options) + + +@admin_app.route('/get_webapps', methods=['POST']) +def get_webapps(): + + db=g.connection + + virtualhost_id=request.args.get('virtualhost_id', '0') + + group_sql='' + + count_data=[] + sql_data=[virtualhost_id] + + fields=[[I18n.lang('webservers', 'app_name', 'App'), True], [I18n.lang('webservers', 'path', 'Path'), True], [I18n.lang('webservers', 'options', 'Options'), False]] + arr_order_fields=['app_name'] + + count_query=['select count(webapp.id) as num_elements from webapp', count_data] + + # server.id as select_id, + + # select hostname, ip, date, num_updates, id from serverofuser where user_id=%s; + + #str_query=['select virtualhost.hostname, virtualhost.ip, virtualhost.id from virtualhost,serverdbtask', sql_data] + + str_query=['select app_name, path, id from webapp WHERE virtualhost_id=%s', 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_webapps + ajax.limit=0 + + return ajax.show() + +@admin_app.route('/add_new_app/') +def add_new_app(virtualhost_id): + + #ids + #task + + db=g.connection + + vhost=VirtualHost(db) + + arr_vhost=vhost.select_a_row(virtualhost_id, [], True) + + if arr_vhost: + + #arr_server=serverdb.set_conditions('WHERE id=%s', [arr_vhost + with vhost.query('select serverdbtask.id as server_id, serverdbtask.ip, webserver.id from serverdbtask, webserver WHERE webserver.id=%s AND webserver.server_id=serverdbtask.id', [arr_vhost['webserver_id']]) as cursor: + arr_server=cursor.fetchone() + + return t.load_template('add_webapp.phtml', title=I18n.lang('webservers', 'add_webapp', 'Add webapp'), path_module='admin_app.webservers', domain=arr_vhost['domain'], webserver_id=arr_vhost['webserver_id'], virtualhost_id=virtualhost_id, scripts_lists=scripts_lists, server_id=arr_server['server_id']) + + return {} + +@admin_app.route('/add_new_app_form/') +def add_new_app_form(virtualhost_id): + + db=g.connection + + vhost=VirtualHost(db) + + arr_vhost=vhost.select_a_row(virtualhost_id, [], True) + + if arr_vhost: + + form_app=request.args.get('name_app', '') + + if form_app in scripts_lists: + tpl_form_path=form_app+'.html' + #with open(tpl_form_path) as f: + # tpl_form=f.read() + tpl_form=t.load_template(tpl_form_path) + + return t.load_template('add_webapp_form.phtml', title=I18n.lang('webservers', 'add_webapp', 'Add webapp'), path_module='admin_app.webservers', domain=arr_vhost['domain'], webserver_id=arr_vhost['webserver_id'], virtualhost_id=virtualhost_id, tpl_form=tpl_form) + + return {} + +@admin_app.route('/delete_webapp/', methods=['GET', 'POST']) +def delete_webapp(webapp_id): + + #db=g.connection + + #return t.load_template('del_virtualhost.phtml', title=I18n.lang('webservers', 'remove_virtualhost', 'Remove Virtual Host'), path_module='admin_app.webservers', webserver_id=arr_virtualhost['webserver_id'], virtualhost_id=virtualhost_id, domain=arr_virtualhost['domain']) + + # Create task and redirect to multiprogress + + pass diff --git a/app.py b/app.py new file mode 100644 index 0000000..e69de29 diff --git a/libraries/webapptask.py b/libraries/webapptask.py new file mode 100644 index 0000000..7dda364 --- /dev/null +++ b/libraries/webapptask.py @@ -0,0 +1,54 @@ +from modules.pastafari2.libraries.task import Task +from flask import url_for +from paramecio2.libraries.i18n import I18n +import re +from paramecio2.libraries.urls import make_url + +class WebAppTask(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={}, ssh_port=22): + + super().__init__(server, conn, remote_user, remote_password, private_key, password_key, remote_path, task_id, data, ssh_port) + + self.path_module='admin_app.webservers' + + webserver_id=0 + + with self.connection.query('select webserver_id from virtualhost WHERE id=%s', [self.data['virtualhost_id']]) as cursor: + + arr_vhost=cursor.fetchone() + + if arr_vhost: + webserver_id=arr_vhost['webserver_id'] + + self.webserver_id=webserver_id + + #

Webservers list >> Websites >> Webapps >> Add webapp

+ + self.links='

{} >> {} >> {} >> {}

'.format(make_url('webservers/servers'), I18n.lang('webservers', 'webservers_list', 'Webservers list'), make_url('webservers/virtualhost/'+str(webserver_id)), I18n.lang('webservers', 'websites', 'Websites'), make_url('webapps/'+str(self.data['virtualhost_id'])), I18n.lang('webservers', 'webapps', 'Webapps'), make_url('add_new_app/'+str(self.data['virtualhost_id'])), I18n.lang('webservers', 'add_webapp', 'Add webapp')) + + self.delete_task=False + + def pre_task(self): + + if not self.delete_task: + + with self.connection.query('select count(*) as num_webapps from webapp where path=%s and virtualhost_id=%s', [self.data['path'], self.data['virtualhost_id']]) as cursor: + + arr_webapp=cursor.fetchone() + + if arr_webapp['num_webapps']>0: + + self.logtask.insert({'status':1, 'progress': 100, 'error': 1, 'task_id': self.id, 'server': self.server, 'message': 'Error: exists an app in the same path %s or exists a webapp %s with the same system, you can install one by domain' % (self.data['path'], self.data['webapp'])}) + + return False + + if self.data['path']!='/' and not re.match('^/[\w.-]*/$', self.data['path'].strip()): + self.logtask.insert({'status':1, 'progress': 100, 'error': 1, 'task_id': self.id, 'server': self.server, 'message': 'Error: format wrong for path, you need this format / or /path/ '+self.data['path']}) + return False + + #self.data['url_return']=make_url('webapps/'+str(self.data['virtualhost_id'])) + + return True + + diff --git a/models/webservers.py b/models/webservers.py new file mode 100644 index 0000000..be9f838 --- /dev/null +++ b/models/webservers.py @@ -0,0 +1,155 @@ +from paramecio2.libraries.db.webmodel import WebModel +from paramecio2.libraries.db.usermodel import UserModel +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.db.extrafields.passwordfield import PasswordField +from paramecio2.libraries.db.extrafields.usernamefield import UserNameField +from paramecio2.libraries.urls import make_media_url +from paramecio2.libraries import datetime +#from modules.monit.models.monit import Server +from modules.pastafari2.models.pastafari2 import ServerDbTask +from paramecio2.libraries.db.extrafields.emailfield import EmailField + +class PortField(corefields.IntegerField): + + def __init__(self, name, size=11, required=False): + + super().__init__(name, size, required) + + def check(self, value): + + value=int(super().check(value)) + + if value<=1000: + value=0 + self.txt_error="A port need to be more higher than 1000" + self.error=True + elif value>65536: + value=0 + self.txt_error="The value of the port need to be more lower than 65536" + self.error=True + + return str(value) + +class UserVirtualHost(UserNameField): + + def show_formatted(value): + + return ''+value+'' + + +class WebServer(WebModel): + + def __init__(self, connection=None): + + super().__init__(connection) + + self.register(corefields.ForeignKeyField('server_id', ServerDbTask(connection), 11, False, 'id', 'hostname', select_fields=[])) + #self.register(corefields.CharField('username'), True) + #self.register(corefields.CharField('home'), True) + #self.register(PasswordField('password'), True) + #self.register(corefields.IntegerField('uid_hosting'), True) + #self.register(corefields.IntegerField('gid_hosting'), True) + +class WebServerPort(WebModel): + + def __init__(self, connection=None): + + super().__init__(connection) + self.register(corefields.ForeignKeyField('webserver_id', WebServer(connection), 11, False, 'id', 'server_id', select_fields=['server_id', 'username'])) + self.register(IpField('ip')) + self.register(PortField('port'), True) + self.fields['port'].unique=True + +class VirtualHost(WebModel): + + def __init__(self, connection=None): + + super().__init__(connection) + + self.register(DomainField('domain'), True) + self.register(corefields.CharField('home'), True) + #(self, name, related_table, size=11, required=False, identifier_field='id', named_field="id", select_fields=[]) + #self.register(corefields.ForeignKeyField('user_id', UsersFtp(connection), 11, False, 'id', 'user', select_fields=[])) + + self.register(UserVirtualHost('username'), True) + #self.register(corefields.CharField('home'), True) + + self.register(corefields.ForeignKeyField('webserver_id', WebServer(connection), 11, False, 'id', 'id', select_fields=['server_id', 'username'])) + self.register(IpField('ip')) + self.register(corefields.IntegerField('port')) + self.register(corefields.IntegerField('ssl_port')) + self.register(corefields.CharField('cgi_type')) + + # 0= NoSSL 1=Letsencrypt 2=other cert, show form + + self.register(corefields.IntegerField('ssl')) + + self.register(corefields.TextField('aliases')) + + self.register(corefields.BooleanField('redirect_ssl')) + self.register(corefields.BooleanField('indexes')) + self.register(corefields.BooleanField('allow_override')) + + self.register(corefields.CharField('php')) + + """ + self.register(corefields.BooleanField('php74')) + self.register(corefields.BooleanField('php80')) + self.register(corefields.BooleanField('php81')) + self.register(corefields.BooleanField('php82')) + self.register(corefields.BooleanField('wsgi')) + """ + +class WebApp(WebModel): + + def __init__(self, connection=None): + + super().__init__(connection) + self.register(corefields.ForeignKeyField('virtualhost_id', VirtualHost(connection), 11, False, 'id', 'domain', select_fields=[])) + self.register(corefields.CharField('app_name')) + self.register(corefields.CharField('app_type')) + self.register(corefields.CharField('path')) + self.register(corefields.CharField('code')) + self.register(JsonValueField('data')) + +class UsersFtp(UserModel): + """ + CREATE TABLE `users` ( + `user` varchar(1000) NOT NULL, + `passwd` varchar(1000) NOT NULL, + `uid` int(11) DEFAULT NULL, + `gid` int(11) DEFAULT NULL, + `home` varchar(255) DEFAULT NULL, + UNIQUE KEY `user` (`user`) USING HASH, + KEY `users_user_idx` (`user`(768)) + ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; + """ + + def __init__(self, connection=None): + + super().__init__(connection) + + self.register(corefields.CharField('user'), True) + self.register(PasswordField('passwd'), True) + self.register(EmailField('email'), True) + self.register(corefields.IntegerField('uid')) + self.register(corefields.IntegerField('gid')) + self.register(corefields.CharField('home')) + self.register(corefields.IntegerField('upload_bw')) + self.register(corefields.IntegerField('download_bw')) + self.register(corefields.IntegerField('num_files')) + self.register(corefields.IntegerField('quota_mb')) + self.register(corefields.ForeignKeyField('virtualhost_id', VirtualHost(connection), 11, False, 'id', 'domain', select_fields=[])) + + self.username_field='user' + self.password_field='passwd' diff --git a/scripts/add_php_vhost.py b/scripts/add_php_vhost.py new file mode 100644 index 0000000..a0c2cdc --- /dev/null +++ b/scripts/add_php_vhost.py @@ -0,0 +1,180 @@ +#!/usr/bin/python3 -u + +import sys, os +from subprocess import call, DEVNULL +import argparse +import platform +import shutil +import pathlib +import distro +import json + +#import pymysql.cursors +#pymysql.install_as_MySQLdb + +pyv=platform.python_version_tuple() + +if pyv[0]!='3': + print('Need python 3 for execute this script') + sys.exit(1) + +parser = argparse.ArgumentParser(description='Script for add php to virtualhost.') + +parser.add_argument('--user', help='The unix user owner of domain', required=True) + +parser.add_argument('--php_version', help='The php version for add to apache', required=True) + +parser.add_argument('--domain', help='The domain of the new wordpress', required=True) + +args = parser.parse_args() + +print("Updating vhost for use php...") + +json_return={} + +apache_cmd='apache2' + +apachectl='apache2ctl' + +linux_distro=distro.id() + +if linux_distro!='debian' and linux_distro!='ubuntu': + apache_cmd='httpd' + apachectl='apachectl' + +# # PHP Options + +socket_php='' + +php_version=args.php_version + +print("PHP Version is "+php_version) + +# PHP-fpm things + +if linux_distro=='debian' or linux_distro=='ubuntu': + + socket_php='/run/php/php{}-{}-fpm.sock'.format(php_version, args.user) + + if not os.path.isfile(socket_php): + shutil.copy('/etc/php/{}/fpm/pool.d/www.conf'.format(php_version), '/etc/php/{}/fpm/pool.d/{}.conf'.format(php_version, args.user)) + + # listen = /run/php/php8.2-fpm.sock + + # run/php/php8.1-fpm.sock + + php_edit="sudo sed -i 's/user = www-data/user = {}/g' /etc/php/{}/fpm/pool.d/{}.conf".format(args.user, php_version, args.user) + php_edit+=" && sudo sed -i 's/group = www-data/group = {}/g' /etc/php/{}/fpm/pool.d/{}.conf".format(args.user, php_version, args.user) + php_edit+=" && sudo sed -i 's/\/run\/php\/php{}-fpm.sock/\/run\/php\/php{}-{}-fpm.sock/g' /etc/php/{}/fpm/pool.d/{}.conf".format(php_version.replace('.', '\.'), php_version, args.user, php_version, args.user) + php_edit+=" && sudo sed -i 's/\[www\]/[{}]/g' /etc/php/{}/fpm/pool.d/{}.conf".format(args.user, php_version, args.user) + php_edit+=" && sudo systemctl restart php{}-fpm.service".format(php_version) + + if call(php_edit, shell=True, stdout=DEVNULL) > 0: + json_return['error']=1 + json_return['status']=1 + json_return['progress']=100 + json_return['message']='Error: the config is wrong '+args.domain + + print(json.dumps(json_return)) + + exit(1) + else: + print("Update php-fpm configuration") + +elif linux_distro=='rocky' or linux_distro=='fedora' or linux_distro=='almalinux' or linux_distro=='centos': + + php_version=php_version.replace('.', '') + + socket_php='/var/opt/remi/php'+php_version+'/run/php-fpm/{}-fpm.sock'.format(args.user) + + if not os.path.isfile(socket_php): + shutil.copy('/etc/opt/remi/php'+php_version+'/php-fpm.d/www.conf', '/etc/opt/remi/php'+php_version+'/php-fpm.d/{}.conf'.format(args.user)) + + #sudo sed -i 's/user = apache/user = hosting/g' /etc/opt/remi/php82/php-fpm.d/www.conf + #sudo sed -i 's/group = apache/group = hosting/g' /etc/opt/remi/php82/php-fpm.d/www.conf + + php_edit="sudo sed -i 's/user = apache/user = {}/g' /etc/opt/remi/php{}/php-fpm.d/{}.conf && sudo sed -i 's/group = apache/group = {}/g' /etc/opt/remi/php{}/php-fpm.d/{}.conf".format(args.user, php_version, args.user, args.user, php_version, args.user) + php_edit+=" && sudo sed -i 's/\/var\/opt\/remi\/php{}\/run\/php-fpm\/www\.sock/\/var\/opt\/remi\/php{}\/run\/php-fpm\/{}-fpm.sock/g' /etc/opt/remi/php{}/php-fpm.d/{}.conf".format(php_version, php_version, args.user, php_version, args.user) + php_edit+="&& sudo sed -i 's/\[www\]/[{}]/g' /etc/opt/remi/php{}/php-fpm.d/{}.conf".format(args.user, php_version, args.user) + php_edit+="&& sudo systemctl restart php{}-php-fpm.service".format(php_version) + + if call(php_edit, shell=True, stdout=DEVNULL) > 0: + json_return['error']=1 + json_return['status']=1 + json_return['progress']=100 + json_return['message']='Error: the config is wrong '+vhost + + print(json.dumps(json_return)) + + exit(1) + +elif linux_distro=='arch': + + # /etc/php-legacy/php-fpm.d + + # Use php-legacy for arch. + + # pacman -S php-legacy php-legacy-gd php-legacy-fpm + + # listen = /run/php-fpm-legacy/php-fpm.sock + + # Install php + + socket_php='/run/php-fpm-legacy/{}-fpm.sock'.format(args.user) + + if not os.path.isfile(socket_php): + shutil.copy('/etc/php-legacy/php-fpm.d/www.conf', '/etc/php-legacy/php-fpm.d/{}.conf'.format(args.user)) + + if call("sudo sed -i 's/user = http/user = {}/g' /etc/php-legacy/php-fpm.d/{}.conf && sudo sed -i 's/group = http/group = {}/g' /etc/php-legacy/php-fpm.d/{}.conf \ + && sudo sed -i 's/\/run\/php-fpm-legacy\/php-fpm\.sock/\/run\/php-fpm-legacy\/{}-fpm.sock/g' /etc/php-legacy/php-fpm.d/{}.conf \ + && sudo sed -i 's/\[www\]/[{}]/g' /etc/php-legacy/php-fpm.d/{}.conf \ + && sudo sed -i 's/pm = dynamic/pm = ondemand/g' /etc/php-legacy/php-fpm.d/{}.conf \ + && sudo systemctl restart php-legacy-fpm.service \ + ".format(args.user, args.user, args.user, args.user, args.user, args.user, args.user, args.user, args.user), shell=True, stdout=DEVNULL) > 0: + json_return['error']=1 + json_return['status']=1 + json_return['progress']=100 + json_return['message']='Error: the config is wrong' + + + print(json.dumps(json_return)) + + exit(1) + + pass + + +# Apache things + +directory_match="# PHP Options \n \ + \n \ + SetHandler \"proxy:unix:{}|fcgi://localhost/\" \n \ +".format(socket_php) + +with open('/etc/%s/vhosts.d/php/%s-php.conf' % (apache_cmd, args.domain), 'w') as f: + f.write(directory_match) + +print("Checking Apache configuration...") + +if call("sudo "+apachectl+" configtest", shell=True, stdout=DEVNULL) > 0: + json_return['error']=1 + json_return['status']=1 + json_return['progress']=100 + json_return['message']='Error: the config is wrong '+vhost + + print(json.dumps(json_return)) + + exit(1) + +print("Restarting apache...") + +if call("sudo systemctl restart "+apache_cmd, shell=True, stdout=DEVNULL) > 0: + json_return['error']=1 + json_return['status']=1 + json_return['progress']=100 + json_return['message']='Error: I cannot reload the httpd server' + + print(json.dumps(json_return)) + + exit(1) + diff --git a/scripts/check_php.sh b/scripts/check_php.sh new file mode 100644 index 0000000..4903283 --- /dev/null +++ b/scripts/check_php.sh @@ -0,0 +1,274 @@ +#!/bin/bash + +echo "Checking php..." + +# Install last php version supported by wordpress + +DISTRO=`python3 -c 'import distro; print(distro.id())'` + +PHP_VERSION=$(php -v 2>/dev/null | grep -oE "PHP ([0-9]+\.[0-9]+)" | grep -oE "[0-9]+\.[0-9]+") + +CHOOSE_PHP_VERSION="8.2" + +if [ -n $1 ]; then + + CHOOSE_PHP_VERSION=$1 + +fi + +#echo '{"error": 0, "status": 0, "progress": 100, "no_progress":0, "message": "PHP Version is "}' + +# sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 1F3045A5DF7587C3 + +if [ "$DISTRO" = 'debian' ] || [ "$DISTRO" = 'ubuntu' ]; then + + + + echo "Update PHP if you need..." + + if [ ! -f '/etc/apt/sources.list.d/php.list' ]; then + + echo '{"error": 0, "status": 0, "progress": 100, "no_progress":0, "message": "Installing Sury repos..."}' + + if [ "$DISTRO" = 'debian' ]; then + + # sudo wget -O - https://packages.sury.org/php/README.txt | sh -s + + 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' + sudo apt-get update + + + else + + sudo LC_ALL=C.UTF-8 add-apt-repository ppa:ondrej/php + + fi + + fi + + if [ $? -eq 0 ]; then + + echo '{"error": 0, "status": 0, "progress": 100, "no_progress":0, "message": "Installed Sury repos sucessfully..."}' + + else + + echo '{"error": 1, "status": 1, "progress": 100, "no_progress":0, "message": "Error: cannot install Sury repos..."}' + + exit + + fi + + sudo apt-get update + + if [ $? -eq 0 ]; then + + echo '{"error": 0, "status": 0, "progress": 100, "no_progress":0, "message": "Updated with sury repos sucessfully..."}' + + else + + echo '{"error": 1, "status": 1, "progress": 100, "no_progress":0, "message": "Error: cannot update apt repos with sury repos..."}' + + exit + + fi + + + if [ "$PHP_VERSION" = "$CHOOSE_PHP_VERSION" ]; then + + echo "Ok, you have php ${CHOOSE_PHP_VERSION}" + + echo "Updating php-fpm pm to ondemand" + + sudo sed -i 's/pm = dynamic/pm = ondemand/g' /etc/php/${CHOOSE_PHP_VERSION}/fpm/pool.d/www.conf + + else + + sudo apt-get install -y php${CHOOSE_PHP_VERSION} php${CHOOSE_PHP_VERSION}-fpm php${CHOOSE_PHP_VERSION}-gd php${CHOOSE_PHP_VERSION}-mysql php${CHOOSE_PHP_VERSION}-curl php${CHOOSE_PHP_VERSION}-mbstring php${CHOOSE_PHP_VERSION}-intl php${CHOOSE_PHP_VERSION}-imagick php${CHOOSE_PHP_VERSION}-xml php${CHOOSE_PHP_VERSION}-zip php${CHOOSE_PHP_VERSION}-redis unzip mariadb-client + + if [ $? -eq 0 ]; then + + echo "{\"error\": 0, \"status\": 0, \"progress\": 100, \"no_progress\":0, \"message\": \"Installed php ${CHOOSE_PHP_VERSION} sucessfully...\"}" + + else + + echo "{\"error\": 1, \"status\": 1, \"progress\": 100, \"no_progress\":0, \"message\": \"Error: cannot install php ${CHOOSE_PHP_VERSION}\"}" + + exit; + + fi + + sudo systemctl restart php${CHOOSE_PHP_VERSION}-fpm.service + + if [ $? -eq 0 ]; then + + echo "{\"error\": 0, \"status\": 0, \"progress\": 100, \"no_progress\":0, \"message\": \"Restarted php ${CHOOSE_PHP_VERSION} sucessfully...\"}" + + else + + echo "{\"error\": 1, \"status\": 1, \"progress\": 100, \"no_progress\":0, \"message\": \"Cannot restart php ${CHOOSE_PHP_VERSION}...\"}" + + exit; + + fi + + echo "Updating php-fpm pm to ondemand" + + sudo sed -i 's/pm = dynamic/pm = ondemand/g' /etc/php/${CHOOSE_PHP_VERSION}/fpm/pool.d/www.conf + + fi + + if [ -f "/usr/local/bin/composer" ]; then + + echo "Updating composer..." + + # need sudo for composer autoupdate + + sudo /usr/local/bin/composer self-update + + else + + echo "Installing composer..." + + EXPECTED_CHECKSUM="$(php -r 'copy("https://composer.github.io/installer.sig", "php://stdout");')" + php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" + ACTUAL_CHECKSUM="$(php -r "echo hash_file('sha384', 'composer-setup.php');")" + + if [ "$EXPECTED_CHECKSUM" != "$ACTUAL_CHECKSUM" ] + then + >&2 echo 'ERROR: Invalid installer checksum' + rm composer-setup.php + exit 1 + fi + + php composer-setup.php --quiet + RESULT=$? + rm composer-setup.php + + sudo mv composer.phar /usr/local/bin/composer + + if [ $RESULT -eq 0 ]; then + + echo '{"error": 0, "status": 0, "progress": 100, "no_progress":0, "message": "Composer installed sucessfully..."}' + + else + echo '{"error": 1, "status": 1, "progress": 100, "no_progress":0, "message": "Error: cannot install composer!"}' + + exit 1 + + fi + fi + + +elif [ "$DISTRO" = 'rocky' ] || [ "$DISTRO" = 'fedora' ]; then + + echo "Update PHP if you need..." + + sudo dnf -y update + + FINAL_PHP_VERSION="${CHOOSE_PHP_VERSION/\./}" + + #echo $FINAL_PHP_VERSION + + if [ "$PHP_VERSION" = "$CHOOSE_PHP_VERSION" ]; then + + echo "Ok, you have php ${CHOOSE_PHP_VERSION}" + + # Check mariadb installed + + sudo dnf -y install mariadb + + echo "Updating php-fpm pm to ondemand" + + sudo sed -i 's/pm = dynamic/pm = ondemand/g' /etc/opt/remi/php${FINAL_PHP_VERSION}/php-fpm.d/www.conf + + else + + sudo dnf -y install php${FINAL_PHP_VERSION} php${FINAL_PHP_VERSION}-php-gd php${FINAL_PHP_VERSION}-php-mysqlnd php${FINAL_PHP_VERSION}-php-imap php${FINAL_PHP_VERSION}-php-intl php${FINAL_PHP_VERSION}-php-fpm php${FINAL_PHP_VERSION}-php-process composer unzip mariadb + + if [ $? -eq 0 ]; then + + echo "{\"error\": 0, \"status\": 0, \"progress\": 100, \"no_progress\":0, \"message\": \"Installed php ${FINAL_PHP_VERSION} sucessfully...\"}" + + else + + echo "{\"error\": 1, \"status\": 1, \"progress\": 100, \"no_progress\":0, \"message\": \"Error: cannot install php ${FINAL_PHP_VERSION} for wordpress\"}" + + exit; + + fi + + #Installing php8.2-fpm + + #/etc/opt/remi/php82/php-fpm.d/www.conf + + #sudo sed -i 's/user = apache/user = hosting/g' /etc/opt/remi/php82/php-fpm.d/www.conf + #sudo sed -i 's/group = apache/group = hosting/g' /etc/opt/remi/php82/php-fpm.d/www.conf + #pm = dynamic + + sudo systemctl restart php${FINAL_PHP_VERSION}-php-fpm.service + + if [ $? -eq 0 ]; then + + echo "{\"error\": 0, \"status\": 0, \"progress\": 100, \"no_progress\":0, \"message\": \"Restart php ${FINAL_PHP_VERSION} sucessfully...\"}" + + else + + echo "{\"error\": 1, \"status\": 1, \"progress\": 100, \"no_progress\":0, \"message\": \"Error: cannot restart php ${FINAL_PHP_VERSION}\"}" + + exit; + + fi + + fi + +else + + sudo pacman -S --needed --noconfirm php-legacy php-legacy-gd php-legacy-fpm php-legacy-sodium composer mariadb + + if [ $? -eq 0 ]; then + + echo '{"error": 0, "status": 0, "progress": 100, "no_progress":0, "message": "php-legacy installed..."}' + + else + + echo '{"error": 0, "status": 0, "progress": 100, "no_progress":0, "message": "Cannot install php legacy in arch..."}' + + exit; + + fi + + sed -i 's/pm = dynamic/pm = ondemand/g' /etc/php-legacy/php-fpm.d/www.conf + sudo sed -i 's/^;zend_extension=opcache$/zend_extension=opcache/g' /etc/php-legacy/php.ini + sudo sed -i 's/^;extension=iconv$/extension=iconv/g' /etc/php-legacy/php.ini + sudo sed -i 's/^;extension=intl$/extension=intl/g' /etc/php-legacy/php.ini + sudo sed -i 's/^;extension=mysqli$/extension=mysqli/g' /etc/php-legacy/php.ini + sudo sed -i 's/^;extension=gd$/extension=gd/g' /etc/php-legacy/php.ini + sudo sed -i 's/^;extension=bcmath$/extension=bcmath/g' /etc/php-legacy/php.ini + sudo sed -i 's/^;extension=bz2$/extension=bz2/g' /etc/php-legacy/php.ini + sudo sed -i 's/^;extension=ftp$/extension=ftp/g' /etc/php-legacy/php.ini + sudo sed -i 's/^;extension=gd$/extension=gd/g' /etc/php-legacy/php.ini + sudo sed -i 's/^;extension=gettext$/extension=gettext/g' /etc/php-legacy/php.ini + sudo sed -i 's/^;extension=sockets$/extension=sockets/g' /etc/php-legacy/php.ini + sudo sed -i 's/^;extension=sodium$/extension=sodium/g' /etc/php-legacy/php.ini + sudo sed -i 's/^;extension=pdo_mysql$/extension=pdo_mysql/g' /etc/php-legacy/php.ini + + sudo systemctl enable php-legacy-fpm.service && sudo systemctl restart php-legacy-fpm.service + + if [ $? -eq 0 ]; then + + echo '{"error": 0, "status": 0, "progress": 100, "no_progress":0, "message": "Restarted php legacy sucessfully..."}' + + else + + echo '{"error": 1, "status": 1, "progress": 100, "no_progress":0, "message": "Error: cannot restart php-legacy"}' + + exit; + + fi + + +fi diff --git a/scripts/files/vhost.tpl b/scripts/files/vhost.tpl new file mode 100644 index 0000000..31d6051 --- /dev/null +++ b/scripts/files/vhost.tpl @@ -0,0 +1,22 @@ +#The most simple virtual host possible. + + ServerAdmin $email + ServerName $domain + $ServerAlias + DocumentRoot $rootDir + DirectoryIndex index.html index.htm index.php + # PHP Options + IncludeOptional vhosts.d/php/$domain-php.conf + + Options $Indexes FollowSymLinks MultiViews + $AllowOverride + Require all granted + + IncludeOptional vhosts.d/extra/$domain-*.conf + ErrorLog /var/log/$apache_cmd/$domain-error.log + LogLevel error + CustomLog /var/log/$apache_cmd/$domain-access.log combined + # Space for extra configurations + # Space for extra directories + # SSL Options + diff --git a/scripts/install_apache.php b/scripts/install_apache.php new file mode 100644 index 0000000..3d76db9 --- /dev/null +++ b/scripts/install_apache.php @@ -0,0 +1,63 @@ + 'apache2 logrotate socat curl', 'ubuntu' => 'apache2 logrotate socat curl', 'fedora' => $redhat_package, 'almalinux' => $redhat_package, 'rocky' => $redhat_package, 'arch' => 'apache']; + +Linux::install_package($linux_package); + +Linux::json_log('Create directories for Apache manager...', $error=0, $status=0, $progress=0, $no_progress=1); + +$create_dirs=['debian' => ["sudo mkdir -p /etc/apache2/vhosts.d/ && sudo mkdir -p /etc/apache2/vhosts.d/php/ && sudo mkdir -p /etc/apache2/vhosts.d/extra/"]]; + +$create_dirs['ubuntu']=$create_dirs['debian']; + +Linux::exec($create_dirs); + +if(!file_put_contents('vhosts.conf', $conf_vhosts)) { + + Linux::json_log('Error: cannot create vhosts.conf', $error=1, $status=1, $progress=100, $no_progress=0); + exit(1); +} + +$create_vhost_file=['debian' => ["sudo mv vhosts.conf /etc/apache2/sites-enabled/ && sudo chown root:root /etc/apache2/sites-enabled/vhosts.conf"]]; + +$create_vhost_file['ubuntu']=$create_vhost_file['debian']; + +Linux::exec($create_vhost_file); + +//Modifying apache configuration + +Linux::json_log('Modifying Apache configuration...', $error=0, $status=0, $progress=0, $no_progress=1); + +$sed_apache=['debian' => ['ServerTokens OS', "ServerTokens Prod", '/etc/apache2/conf-enabled/security.conf']]; + +$sed_apache['ubuntu']=$sed_apache['debian']; + +Linux::sed($sed_apache); + +//Activating modules for apache. + +$activate_modules=['debian' => ["sudo a2enmod ssl rewrite proxy proxy_fcgi"]]; + +$activate_modules['ubuntu']=$create_vhost_file['debian']; + +Linux::exec($activate_modules); + +//Restart apache + +$linux_service=['debian' => 'apache2', 'ubuntu' => 'apache2', 'fedora' => 'httpd', 'almalinux' => 'httpd', 'rocky' => 'httpd', 'arch' => 'apache']; + +Linux::systemd_service('restart', $linux_service); + +Linux::json_log('Apache server installed successfully!', $error=0, $status=0, $progress=100, $no_progress=0); diff --git a/scripts/manage_apache.py b/scripts/manage_apache.py new file mode 100644 index 0000000..1417c05 --- /dev/null +++ b/scripts/manage_apache.py @@ -0,0 +1,727 @@ +#!/usr/bin/python3 -u + +import sys +import argparse +import os +#from pastafariutils.unix import add_user, del_user, change_password +from pathlib import Path +from subprocess import call, DEVNULL +import json +import time +import shutil +import pwd +import distro +import subprocess +import pwd + +php_version={'php74': 'php7.4', 'php80': 'php8.0', 'php81': 'php8.1', 'php82': 'php8.2'} + +def manage(): + + parser=argparse.ArgumentParser(prog='manage_apache.py', description='A tool for admin an apache server') + + parser.add_argument('--operation', help='The operation', required=True) + + parser.add_argument('--domain', help='The domain for this operation', required=True) + + parser.add_argument('--aliases', help='The Domain aliases for the domain') + + parser.add_argument('--port', help='The http port where petitions are listened') + + parser.add_argument('--ssl_port', help='The https port where petitions are listened') + + parser.add_argument('--ip', help='The IP where http petitions are listened') + + parser.add_argument('--email', help='If add an domain, you can use an email for apache errors') + + parser.add_argument('--user', help='You need an user for the virtualhost') + + parser.add_argument('--root_dir', help='If add an domain, you need define where the virtualhost is installed') + + parser.add_argument("--indexes", action='store_true') + + parser.add_argument("--allow_override", action='store_true') + + parser.add_argument("--ssl", help='SSL Type: 0, no SSL') + + parser.add_argument("--redirect_ssl", action='store_true') + + parser.add_argument("--debug", action='store_true') + + parser.add_argument('--type_cgi', help='The CGI type for this virtualhost') + + parser.add_argument('--password', help='The password of the unix user') + + #parser.add_argument('--ftp_user', help='The CGI type for this virtualhost', required=True) + + args=parser.parse_args() + + apache_cmd='apache2' + + apachectl='apache2ctl' + + apache_group='www-data' + + linux_distro=distro.id() + + if linux_distro!='debian' and linux_distro!='ubuntu': + apache_cmd='httpd' + apachectl='apachectl' + if linux_distro=='rocky' or linux_distro=='fedora': + apache_group='apache' + + if linux_distro=='arch': + apache_group='http' + + + port=80 + ssl_port=443 + ip='*' + yes_ssl=False + + debug=False + + if args.debug: + debug=True + + json_return={'error':0, 'status': 0, 'progress': 0, 'no_progress':0, 'message': ''} + + if args.operation=='add' or args.operation=='edit': + + if not args.email: + parser.error('You need --email option if you add a new virtual host.') + + if not args.root_dir: + parser.error('You need --root_dir option if you add a new virtual host.') + + + if not args.user: + parser.error('You need --user option if you add a new virtual host.') + + if args.port: + port=args.port + + if args.ip: + ip=args.ip + + if ip.find(':')!=-1: + ip='['+ip+']' + + real_root_dir=args.root_dir+'/htdocs' + + aliases='ServerAlias www.'+args.domain + + if args.aliases: + aliases='ServerAlias '+args.aliases.replace(',', ' ') + + indexes='' + + if args.indexes: + indexes='Indexes' + + allow_override='' + + if args.allow_override: + allow_override='AllowOverride all' + + type_ssl=0 + + if args.ssl: + try: + + type_ssl=int(args.ssl) + except: + json_return['error']=1 + json_return['status']=1 + json_return['progress']=100 + json_return['message']='Error: bad SSL configuration type' + + print(json.dumps(json_return)) + + exit(1) + + #print( os.path.basename(__file__)+'/files/vhost.tpl') + + vhost_file=os.path.dirname(os.path.abspath(__file__))+'/files/vhost.tpl' + + with open(vhost_file) as f_vhost: + vhost=f_vhost.read() + vhost_ssl=vhost + + vhost=vhost.replace('$port', args.port) + vhost=vhost.replace('$ip', args.ip) + vhost=vhost.replace('$email', args.email) + vhost=vhost.replace('$domain', args.domain) + #ServerAlias www.$domain + vhost=vhost.replace('$ServerAlias', aliases) + vhost=vhost.replace('$rootDir', real_root_dir) + vhost=vhost.replace('$Indexes', indexes) + vhost=vhost.replace('$AllowOverride', allow_override) + vhost=vhost.replace('$apache_cmd', apache_cmd) + + if type_ssl>0: + if type_ssl==1: + + json_return['error']=0 + json_return['status']=0 + json_return['progress']=0 + json_return['message']='Preparing SSL virtualhost' + + print(json.dumps(json_return)) + + #Make letsencrypt + + ssl_debug='' + + if debug: + ssl_debug='--test-cert' + + #certbot certonly --test-cert --webroot -w /var/www/sites/prueba.cuchulu.com/htdocs/ -d prueba.cuchulu.com + + final_aliases='' + + if args.aliases: + #arr_aliases=[alias.strip() for args.aliases.split(',')] + final_aliases=" ".join(['-d '+alias.strip() for alias in args.aliases.split(',')]) + + expand='' + + if os.path.isfile('/etc/letsencrypt/live/{}/fullchain.pem'.format(args.domain)): + expand='--expand' + + + certbot_cmd='certbot certonly --noninteractive --agree-tos -m {} {} --webroot -w /home/{}/sites/{}/htdocs/ -d {} {} {}'.format(args.email, ssl_debug, args.user, args.domain, args.domain, final_aliases, expand) + + json_return={'error':0, 'status': 0, 'progress': 0, 'no_progress':0, 'message': 'Creating SSL Cert with Letsencrypt...'} + print(json.dumps(json_return)) + + if call("sudo "+certbot_cmd, shell=True) > 0: + + #If error, not stop the virtualhost, simply not creater ssl. + + json_return['error']=0 + json_return['status']=0 + json_return['progress']=100 + json_return['message']='Error: the ssl command is wrong '+certbot_cmd + print(json.dumps(json_return)) + + else: + + json_return={'error':0, 'status': 0, 'progress': 100, 'no_progress':0, 'message': 'Created SSL Cert with Letsencrypt...'} + print(json.dumps(json_return)) + + # /etc/letsencrypt/live/prueba.cuchulu.com/fullchain.pem + # /etc/letsencrypt/live/prueba.cuchulu.com/privkey.pem + + vhost_ssl=vhost_ssl.replace('$port', args.ssl_port) + vhost_ssl=vhost_ssl.replace('$ip', args.ip) + vhost_ssl=vhost_ssl.replace('$email', args.email) + vhost_ssl=vhost_ssl.replace('$domain', args.domain) + #ServerAlias www.$domain + vhost_ssl=vhost_ssl.replace('$ServerAlias', aliases) + vhost_ssl=vhost_ssl.replace('$rootDir', real_root_dir) + vhost_ssl=vhost_ssl.replace('$Indexes', indexes) + vhost_ssl=vhost_ssl.replace('$AllowOverride', allow_override) + vhost_ssl=vhost_ssl.replace('$apache_cmd', apache_cmd) + + ssl_cert='/etc/letsencrypt/live/{}/fullchain.pem'.format(args.domain) + ssl_key='/etc/letsencrypt/live/{}/privkey.pem'.format(args.domain) + + ssl_options=("SSLEngine on", + "SSLCertificateFile %s" % ssl_cert, + "SSLCertificateKeyFile %s" % ssl_key) + + vhost_ssl=vhost_ssl.replace('# SSL Options', "\n".join(ssl_options)) + + if args.redirect_ssl: + print("Adding redirect http to https...") + ssl_options_http=("RewriteEngine On", + "RewriteCond %{HTTPS} !=on", + "RewriteRule ^/?(.*) https://%{SERVER_NAME}/$1 [R,L]") + vhost=vhost.replace('# SSL Options', "\n".join(ssl_options_http)) + + vhost+="\n\n"+vhost_ssl + + pass + + if type_ssl==2: + vhost_ssl=vhost_ssl.replace('$port', args.ssl_port) + vhost_ssl=vhost_ssl.replace('$ip', args.ip) + vhost_ssl=vhost_ssl.replace('$email', args.email) + vhost_ssl=vhost_ssl.replace('$domain', args.domain) + #ServerAlias www.$domain + vhost_ssl=vhost_ssl.replace('$ServerAlias', aliases) + vhost_ssl=vhost_ssl.replace('$rootDir', real_root_dir) + vhost_ssl=vhost_ssl.replace('$Indexes', indexes) + vhost_ssl=vhost_ssl.replace('$AllowOverride', allow_override) + vhost_ssl=vhost_ssl.replace('$apache_cmd', apache_cmd) + + #Create dir for ssl + + if call("sudo mkdir -p /etc/"+apache_cmd+"/ssl/", shell=True) > 0: + print('Error, cannot create SSL Cert directory if not exists...') + exit(1) + + ssl_cert='/etc/'+apache_cmd+'/ssl/'+args.domain+'-ssl.crt' + ssl_key='/etc/'+apache_cmd+'/ssl/'+args.domain+'-ssl.key' + + ssl_orig_cert=os.path.dirname(os.path.abspath(__file__))+'/files/'+args.domain+'-ssl.crt' + ssl_orig_key=os.path.dirname(os.path.abspath(__file__))+'/files/'+args.domain+'-ssl.key' + + if os.path.isfile(ssl_orig_cert): + shutil.copy(ssl_orig_cert, ssl_cert) + shutil.copy(ssl_orig_key, ssl_key) + + if not os.path.isfile(ssl_cert): + print('Error, you have not uploaded crt files for ssl vhost...') + exit(1) + + ssl_options=("SSLEngine on", + "SSLCertificateFile %s" % ssl_cert, + "SSLCertificateKeyFile %s" % ssl_key) + + vhost_ssl=vhost_ssl.replace('# SSL Options', "\n".join(ssl_options)) + + if args.redirect_ssl: + print("Adding redirect http to https...") + ssl_options_http=("RewriteEngine On", + "RewriteCond %{HTTPS} !=on", + "RewriteRule ^/?(.*) https://%{SERVER_NAME}/$1 [R,L]") + vhost=vhost.replace('# SSL Options', "\n".join(ssl_options_http)) + + vhost+="\n\n"+vhost_ssl + + pass + + # Get php version and install + """ + if args.type_cgi!=None: + if 'php' in args.type_cgi: + check_php_version(args.type_cgi, args.user) + #Add php support to virtualhost + # ProxyPassMatch ^/(.*\.php(/.*)?)$ fcgi://127.0.0.1:9000/path/to/your/documentroot/$1 + # ProxyPassMatch ^/(.*\.php(/.*)?)$ unix:/path/to/socket.sock|fcgi://localhost/path/to/your/documentroot/ + # ProxyPassMatch ^/(.*\.php(/.*)?)$ unix:/run/php/php-8.2-hosting.sock|fcgi://localhost/var/www/sites/coesinfo/prueba.cuchulu.com/htdocs/$1 + + number_version=php_version[args.type_cgi].replace('php', '') + + # /run\/php\/php-"+number_version.replace('.', '\.')+"-{}.sock + + php_line="# PHP Options\nProxyPassMatch ^/(.*\.php(/.*)?)$ unix:/run/php/php-{}-{}.sock|fcgi://localhost{}/$1".format(number_version, args.user, real_root_dir) + #print(php_line) + vhost=vhost.replace('# PHP Options', php_line) + print('Adding php configuration to virtualhost...') + + """ + + #time.sleep(1) + + + # Add user + + #err, txt=add_user(args.user) + """ + if err: + json_return['error']=1 + json_return['status']=1 + json_return['progress']=100 + json_return['message']='Error: user exists' + + print(json.dumps(json_return)) + sys.exit(1) + """ + """ + json_return['progress']=30 + json_return['message']='Created user for this site' + print(json.dumps(json_return)) + time.sleep(1) + """ + + if args.operation=='add': + + # Add site directory + """ + yes_chown=False + + if not os.path.isdir(args.root_dir): + yes_chown=True + + p=Path(real_root_dir) + + try: + p.mkdir(mode=0o755, parents=True, exist_ok=False) + #Change owner + #if yes_chown: + #shutil.chown('../'+args.root_dir, args.user, args.user) + if call(("sudo chown -R {}:{} "+args.root_dir).format(args.user, args.user), shell=True, stdout=DEVNULL) > 0: + json_return['error']=1 + json_return['status']=1 + json_return['progress']=100 + json_return['message']='Error: cannot set the directory permissions' + else: + shutil.chown(real_root_dir, args.user, args.user) + + except FileNotFoundError: + + json_return['error']=1 + json_return['status']=1 + json_return['progress']=100 + json_return['message']='Error: cannot create the site directory' + + print(json.dumps(json_return)) + sys.exit(1) + """ + + # Add user + + if args.user=='root': + + json_return['error']=1 + json_return['status']=1 + json_return['progress']=100 + json_return['message']='Error: you cannot use user root for sites' + + print(json.dumps(json_return)) + sys.exit(1) + + #ret_user=add_user(args.user, '', '', user_directory='', shell='/bin/bash') + + + func_user="sudo useradd -m -s %s %s" % ('/bin/bash', args.user) + + ret_user=True + + if call(func_user, shell=True, stdout=DEVNULL) > 0: + ret_user=False + + if not ret_user: + + print("User %s exists, used for the new site" % args.user) + + else: + + """ + if call("sudo usermod -a -G %s %s" % (apache_group, args.user), shell=True) > 0: + print('Error, cannot add group to user') + exit(1) + """ + + # Add ssh key for diverses uses + print("Adding ssh key for user...") + + if call('sudo su - %s -s /bin/bash -c \'ssh-keygen -f /home/%s/.ssh/id_rsa.pub -N \\"\\"\'' % (args.user, args.user), shell=True) > 0: + print('Error, cannot add ssh key for user...') + exit(1) + + if call("sudo chmod +x %s" % '/home/'+args.user, shell=True) > 0: + print('Error, cannot set permissions for folder %s...' % real_root_dir) + exit(1) + + if call("sudo su - %s -s /bin/bash -c 'mkdir -p %s'" % (args.user, real_root_dir), shell=True) > 0: + print('Error, cannot create Virtualhost folder %s...' % real_root_dir) + exit(1) + + password_user='' + + if args.password: + password_user=args.password + + ret_pass=change_password(args.user, password_user) + + if not ret_pass[0]: + print('Error, cannot change password for %s' % args.user ) + exit(1) + + if call("sudo getenforce", shell=True)==0: + + # If selinux enabled, set permissions to /home/hosting/sites for sites. + + #if call("sudo setsebool -P httpd_enable_homedirs true && sudo chcon -R -t httpd_sys_content_t /var/www/sites && sudo setsebool -P httpd_can_network_connect 1 && sudo semanage fcontext -a -t httpd_sys_rw_content_t \"/var/www/sites(/.*)?\"", shell=True) > 0: + print('Setting selinux permissions for the http folder %s...' % real_root_dir) + if call("sudo setsebool -P httpd_enable_homedirs true && sudo chcon -R -t httpd_sys_content_t %s && sudo setsebool -P httpd_can_network_connect 1 && chcon -R -t httpd_sys_rw_content_t %s" % (real_root_dir, real_root_dir), shell=True) > 0: + print('Error, cannot set selinux permissions...') + exit(1) + + # Save virtualhost + + virtualhost_base='/etc/'+apache_cmd+'/vhosts.d' + """ + p=Path(virtualhost_base) + + try: + p.mkdir(mode=0o755, parents=True, exist_ok=True) + + except FileNotFoundError: + + json_return['error']=1 + json_return['status']=1 + json_return['progress']=100 + json_return['message']='Error: cannot create the apache vhost directory' + + print(json.dumps(json_return)) + sys.exit(1) + """ + + virtualhost_path=virtualhost_base+'/%s.conf' % (args.domain) + #virtualhost_enabled_path='/etc/'+apache_cmd+'/vhosts.d/%s.conf' % args.domain + + + with open(virtualhost_path, 'w') as f: + f.write(vhost) + + json_return['progress']=60 + json_return['message']='Created or edited virtualhost' + print(json.dumps(json_return)) + #time.sleep(1) + + # Activate virtualhost + + #os.symlink(virtualhost_path, virtualhost_enabled_path) + + # Check apache configuration, if not delete user and virtualhost. + + if call("sudo "+apachectl+" configtest", shell=True) > 0: + json_return['error']=1 + json_return['status']=1 + json_return['progress']=100 + json_return['message']='Error: the config is wrong '+vhost + + # Delete user + + #os.unlink(virtualhost_enabled_path) + os.remove(virtualhost_path) + + #err, txt=del_user(args.user) + + print(json.dumps(json_return)) + + exit(1) + + json_return['progress']=75 + json_return['message']='Finished virtualhost configuration' + print(json.dumps(json_return)) + #time.sleep(1) + + # Restart config + + if call("sudo systemctl restart "+apache_cmd, shell=True) > 0: + json_return['error']=1 + json_return['status']=1 + json_return['progress']=100 + json_return['message']='Error: I cannot reload the httpd server' + + # Delete user + + #os.unlink(virtualhost_enabled_path) + os.remove(virtualhost_path) + + #err, txt=del_user(args.user) + + print(json.dumps(json_return)) + + exit(1) + + json_return['progress']=85 + json_return['message']='Apache2 restarted...' + print(json.dumps(json_return)) + #time.sleep(1) + + # Finish + + json_return['progress']=100 + json_return['message']='Virtualhost done' + json_return['status']=0 + print(json.dumps(json_return)) + #time.sleep(1) + + elif args.operation=='remove': + + # Change uid to user id of the + + if args.root_dir=='/': + json_return['error']=1 + json_return['status']=1 + json_return['progress']=100 + json_return['message']='Error: I cannot delete this place...' + + + #if not args.user: + # parser.error('You need --user option if you want to remove a virtual host.') + + virtualhost_path='/etc/'+apache_cmd+'/vhosts.d/%s.conf' % (args.domain) + + virtualhost_php_path='/etc/'+apache_cmd+'/vhosts.d/php/%s-php.conf' % (args.domain) + + #virtualhost_enabled_path='/etc/'+apache_cmd+'/vhosts.d/%s.conf' % args.domain + + # Delete first apache configuration + """ + try: + + os.unlink(virtualhost_enabled_path) + + except: + + json_return['error']=1 + json_return['status']=1 + json_return['progress']=100 + json_return['message']='Error: I cannot remove symbolic link of apache file config' + print(json.dumps(json_return)) + + exit(1) + """ + + try: + os.remove(virtualhost_path) + except: + json_return['error']=1 + json_return['status']=1 + json_return['progress']=100 + json_return['message']='Error: I cannot remove symbolic link of apache file config' + print(json.dumps(json_return)) + + exit(1) + + if os.path.isfile(virtualhost_php_path): + try: + os.remove(virtualhost_php_path) + except: + json_return['error']=1 + json_return['status']=1 + json_return['progress']=100 + json_return['message']='Error: I cannot remove symbolic link of apache file config' + print(json.dumps(json_return)) + + exit(1) + + + json_return['progress']=25 + json_return['message']='Deleted virtualhost in Apache configuration' + print(json.dumps(json_return)) + #time.sleep(1) + + # Test apache config + + if call("sudo "+apachectl+" configtest", shell=True) > 0: + json_return['error']=1 + json_return['status']=1 + json_return['progress']=100 + json_return['message']='Error: the config is wrong' + + exit(1) + + json_return['progress']=50 + json_return['message']='Apache configuration checked correctly...' + print(json.dumps(json_return)) + #time.sleep(1) + + + # Restart apache + + if call("sudo systemctl restart "+apache_cmd, shell=True) > 0: + json_return['error']=1 + json_return['status']=1 + json_return['progress']=100 + json_return['message']='Error: I cannot reload the httpd server' + + print(json.dumps(json_return)) + + exit(1) + + json_return['progress']=75 + json_return['message']='Apache restarted successfully...' + print(json.dumps(json_return)) + #time.sleep(1) + + # Delete root_dir if exists + # Change effective uid + + pw=pwd.getpwnam(args.user) + os.setuid(pw[2]) + + if args.root_dir: + shutil.rmtree(args.root_dir) + #os.seteuid(0) + + # Delete user of virtualhost + + #err, txt=del_user(args.user) + """ + if err: + json_return['error']=1 + json_return['status']=1 + json_return['progress']=100 + json_return['message']='Error: I cannot remove the user' + + print(json.dumps(json_return)) + + exit(1) + """ + + # Done + + json_return['progress']=100 + json_return['message']='VHost removed successfully. Done all.' + json_return['status']=0 + print(json.dumps(json_return)) + #time.sleep(1) + + + +# Function check php version and install if necessary + +def check_php_version(version, user): + + linux_distro=distro.id() + + if linux_distro=='debian' or linux_distro=='ubuntu': + + php_packages={'php74': 'php7.4 php7.4-curl php7.4-dom php7.4-gd php7.4-xml php7.4-mbstring php7.4-zip php7.4-fileinfo php7.4-ctype php7.4-simplexml php7.4-xmlreader php7.4-xmlwriter php7.4-mysql php7.4-bz2 php7.4-intl php7.4-ldap php7.4-imap php7.4-bcmath php7.4-gmp php7.4-exif php7.4-opcache php7.4-redis php7.4-memcached php7.4-fpm', 'php80': 'php8.0 php8.0-curl php8.0-dom php8.0-gd php8.0-xml php8.0-mbstring php8.0-zip php8.0-fileinfo php8.0-ctype php8.0-simplexml php8.0-xmlreader php8.0-xmlwriter php8.0-mysql php8.0-bz2 php8.0-intl php8.0-ldap php8.0-imap php8.0-bcmath php8.0-gmp php8.0-exif php8.0-opcache php8.0-redis php8.0-memcached php8.0-fpm', 'php81': 'php8.1 php8.1-curl php8.1-dom php8.1-gd php8.1-xml php8.1-mbstring php8.1-zip php8.1 php8.1-fileinfo php8.1-ctype php8.1-simplexml php8.1-xmlreader php8.1-xmlwriter php8.1-mysql php8.1-bz2 php8.1-intl php8.1-ldap php8.1-imap php8.1-bcmath php8.1-gmp php8.1-exif php8.1-opcache php8.1-redis php8.1-memcached php8.1-fpm', 'php82': 'php8.2 php8.2-curl php8.2-dom php8.2-gd php8.2-xml php8.2-mbstring php8.2-zip php8.2 php8.2-fileinfo php8.2-ctype php8.2-simplexml php8.2-xmlreader php8.2-xmlwriter php8.2-mysql php8.2-bz2 php8.2-intl php8.2-ldap php8.2-imap php8.2-bcmath php8.2-gmp php8.2-exif php8.2-opcache php8.2-redis php8.2-memcached php8.2-fpm'} + + if version in php_version: + + #apt-get install php php-curl php-dom php-gd php-xml php-mbstring php-zip php-json php-fileinfo php-ctype php-simplexml php-xmlreader php-xmlwriter php-mysql php-bz2 php-intl php-ldap php-imap php-bcmath php-gmp php-exif php-opcache php-redis php-memcached + print('Checking install of php %s' % php_version[version]) + + number_version=php_version[version].replace('php', '') + + try: + + output=subprocess.check_output(['dpkg', '-l', 'php-'+number_version+'*']) + output=output.decode('utf-8') + + except: + + + + if call("sudo apt-get -y install %s && a2dismod mpm_prefork && a2enmod mpm_event proxy proxy_fcgi rewrite" % (php_packages[version]), shell=True) > 0: + print('Error, cannot install PHP...') + exit(1) + + # Install php-fpm + # /etc/php/8.2/fpm/pool.d/www.conf + + # sed -i 's/old-text/new-text/g' input.txt + + #listen = /run/php/php8.2-fpm.sock + + cmd="sudo cp /etc/php/"+number_version+"/fpm/pool.d/www.conf /etc/php/"+number_version+"/fpm/pool.d/{}.conf && sudo sed -i 's/^user = www-data/user = {}/g' /etc/php/"+number_version+"/fpm/pool.d/{}.conf && sudo sed -i 's/^group = www-data/group = {}/g' /etc/php/"+number_version+"/fpm/pool.d/{}.conf && sudo sed -i 's/\[www\]/[{}]/g' /etc/php/"+number_version+"/fpm/pool.d/{}.conf \ + && sudo sed -i 's/^listen = \/run\/php\/php"+number_version.replace('.', '\.')+"\-fpm\.sock/listen = \/run\/php\/php-"+number_version.replace('.', '\.')+"-{}.sock/g' /etc/php/"+number_version+"/fpm/pool.d/{}.conf" + + cmd=cmd.format(user, user, user, user, user, user, user, user, user) + + if call(cmd, shell=True) > 0: + print('Error, cannot update PHP-FPM...') + exit(1) + + if call('systemctl restart php'+number_version+'-fpm.service', shell=True) > 0: + print('Error, cannot restart PHP-FPM...') + exit(1) + + + pass + + # Reinstall php-fpm + +if __name__=='__main__': + manage() diff --git a/scripts/webapps/wordpress/install_wordpress_site.py b/scripts/webapps/wordpress/install_wordpress_site.py new file mode 100644 index 0000000..24dc7b3 --- /dev/null +++ b/scripts/webapps/wordpress/install_wordpress_site.py @@ -0,0 +1,176 @@ +#!/usr/bin/python3 -u + +import sys, os +import subprocess +import argparse +import platform +import shutil +import pathlib +import distro +import pwd +import getpass + +#import pymysql.cursors +#pymysql.install_as_MySQLdb + +pyv=platform.python_version_tuple() + +if pyv[0]!='3': + print('Need python 3 for execute this script') + sys.exit(1) + +parser = argparse.ArgumentParser(description='Script for create a new wordpress site.') + +parser.add_argument('--home_user', help='The name of the new user', required=True) +parser.add_argument('--user', help='The name of the new user', required=True) +parser.add_argument('--password', help='The password of the new user', required=True) +parser.add_argument('--path', help='The path of the wordpress install', required=True) +parser.add_argument('--email', help='The email of the new user', required=True) +parser.add_argument('--domain', help='The domain of the new wordpress', required=True) +parser.add_argument('--title', help='The title of the new wordpress', required=True) + +parser.add_argument('--user_mysql', help='The password of the root mysql', required=True) +parser.add_argument('--password_mysql', help='The password of the root mysql', required=True) + +parser.add_argument('--db_mysql', help='Database for new wp site', required=True) + +parser.add_argument('--server_mysql', help='Server of MySQL database', required=True) + +parser.add_argument('--port_mysql', help='The port of the MySQL server', required=True, type=int) + +parser.add_argument('--php_version', help='The version of php used', required=True) + +args = parser.parse_args() + +wp_command='/usr/local/bin/wp' + +php_command='' + +linux_distro=distro.id() + +if linux_distro=='arch': + + php_command='/usr/bin/php-legacy' + +if linux_distro=='fedora' or linux_distro=='rocky': + + php_command='/usr/bin/php'+args.php_version.replace('.', '') + +if linux_distro=='debian' or linux_distro=='ubuntu': + + php_command='/usr/bin/php'+args.php_version + + +system_user=getpass.getuser() + +apache_cmd='apache2' +apachectl='apache2ctl' + +if linux_distro!='debian' and linux_distro!='ubuntu': + + apache_cmd='httpd' + apachectl='apachectl' + + if linux_distro=='rocky' or linux_distro=='fedora': + apache_group='apache' + + if linux_distro=='arch': + apache_group='http' + + +home_user=args.home_user + +stat_group=os.stat(home_user) +uid=stat_group.st_uid + +user=pwd.getpwuid(uid)[0] + +if args.path!='/': + + home_user=args.home_user.replace('/htdocs', args.path) + + if not os.path.isdir(home_user): + #os.mkdir(home_user) + if subprocess.call("sudo su %s -s /bin/bash -c 'mkdir -p %s'" % (user, home_user), shell=True) > 0: + print("Error, cannot create wordpress folder sudo su %s -s /bin/bash -c 'mkdir -p %s'" % (args.user, home_user)+"\n") + sys.exit(1) + else: + print("Error, exists a directory with same name, i cannot install wordpress in this folder\n") + sys.exit(1) + + os.chdir(home_user) +else: + home_user=args.home_user+'/' + + os.chdir(home_user) + +if os.path.isfile(home_user+'/index.php'): + + print("WARNING, Deleting old installations of wordpress in document root") + + if subprocess.call("sudo su %s -s /bin/bash -c 'rm -f -r %s/*'" % (user, home_user), shell=True) > 0: + print("Error, ") + sys.exit(1) + +# Php-fpm for user + +print('Installing Wordpress...') + +if subprocess.call("sudo su %s -s /bin/bash -c '%s %s core download'" % (user, php_command, wp_command), shell=True) > 0: + print('Error') + sys.exit(1) + +mysql_user=args.user_mysql +mysql_password=args.password_mysql + +host_db=args.server_mysql + +if args.port_mysql!=3306: + host_db=host_db+':'+str(args.port_mysql) + +if subprocess.call("sudo su %s -s /bin/bash -c '%s %s config create --dbname=%s --dbuser=%s --dbpass=%s --dbhost=%s'" % (user, php_command, wp_command, args.db_mysql, mysql_user, mysql_password, host_db), shell=True) > 0: + print('Error') + sys.exit(1) + +print('Created basic config...') + +# Add cronjob for wordpress + +if subprocess.call("sudo su %s -s /bin/bash -c '%s %s core install --url=%s --title=\"%s\" --admin_user=%s --admin_password=%s --admin_email=%s'" % (user, php_command, wp_command, args.domain+args.path, args.title, args.user, args.password, args.email), shell=True) > 0: + print('Error: cannot install wordpress') + sys.exit(1) +else: + print('Installed Wordpress successfully...') + +if args.path!='/': + + alias_apache=" Alias {} {} \n\ + \n\ + Options FollowSymLinks MultiViews \n\ + AllowOverride All \n\ + Require all granted \n\ + \n\ + \n\ + ProxyPass ! \n\ + \n\ + ".format(args.path[:-1], home_user, home_user, args.path[:-1]) + + name_file='/home/{}/{}-{}.conf'.format(system_user, args.domain, os.path.basename(args.path[:-1])) + + with open(name_file, 'w') as f: + f.write(alias_apache) + + + print('Updating apache configuration for wordpress outside of htdocs...') + if subprocess.call('sudo mv {} /etc/{}/vhosts.d/extra'.format(name_file, apache_cmd), shell=True) > 0: + print('Error') + sys.exit(1) + +print('Restarting apache...') + +if subprocess.call("sudo systemctl restart "+apache_cmd, shell=True) > 0: + print("Error: cannot update and restart apache") + sys.exit(1) + + +print('Apache restarted!') diff --git a/scripts/webapps/wordpress/install_wp.php b/scripts/webapps/wordpress/install_wp.php new file mode 100644 index 0000000..386d2a6 --- /dev/null +++ b/scripts/webapps/wordpress/install_wp.php @@ -0,0 +1,34 @@ +Mariadb/MySQL configuration'+show_form(values, self.arr_form, t, yes_error, pass_values) + + def check_form(self, post): + + 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.extra_data={'mysql_password': post['mysql_password'].strip()} + return True + + else: + + self.arr_form['mysql_password'].txt_error='Passwords doesn\'t match' + + return False + """ + """ + def post_task(self): + + server=Server(self.connection) + + hostname=server.set_conditions('WHERE ip=%s', [self.server]).select_a_row_where()['hostname'] + + webserver=WebServer(self.connection) + webserver.safe_query() + + data={'hostname': hostname, 'ip': self.server} + + webserver.insert(data) + + return True + """ + + def post_task(self): + + #real_root_dir=args.root_dir+'/'+args.domain+'/htdocs' + + vhost=VirtualHost(self.connection) + vhost.safe_query() + + ssl_crt='modules/apache/scripts/files/'+self.data['domain']+'-ssl.crt' + ssl_key='modules/apache/scripts/files/'+self.data['domain']+'-ssl.key' + + if os.path.isfile(ssl_crt): + os.remove(ssl_crt) + os.remove(ssl_key) + + #vhost.insert({'servers': servers, 'principal_ip': servers[0], 'domain': self.extra_data['domain'], 'email': self.extra_data['email'], 'user': self.extra_data['user'], 'root_dir': self.extra_data['root_dir'], 'indexes': self.extra_data['indexes'], 'allow_override': self.extra_data['allow_override']}) + if not vhost.set_conditions('WHERE id=%s', [self.data['virtualhost_id']]).update({'domain': self.data['domain'], 'home': self.data['root_dir'], 'webserver_id': self.data['webserver_id'], 'indexes': self.data['indexes'], 'allow_override': self.data['allow_override'], 'port': self.data['port'], 'aliases': self.data['aliases'], 'ip': self.data['ip'], 'redirect_ssl': self.data['redirect_ssl'], 'ssl_port': self.data['ssl_port'], 'ssl': self.data['ssl'], 'php': self.data.get('php', '')}): + return False + + return True diff --git a/tasks/apache/apache/install_apache.py b/tasks/apache/apache/install_apache.py new file mode 100644 index 0000000..d7b4a8c --- /dev/null +++ b/tasks/apache/apache/install_apache.py @@ -0,0 +1,86 @@ +#!/opt/pythonenv/bin/python3 -u + +from modules.pastafari2.libraries.task import Task +#from modules.pastafari.models.tasks import TaskModel +from paramecio2.libraries.db import coreforms +from paramecio2.libraries.db.webmodel import WebModel +from paramecio2.libraries.formsutils import show_form +from collections import OrderedDict +from modules.pastafari2.models.tasks import ResultTask +from modules.pastafari2.models.pastafari2 import ServerDbTask +from modules.apache.models.webservers import WebServer +from settings import config +import json + +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='Apache installation' + + self.description_task='Installation of a Apache webserver' + + self.codename_task='apache_webserver' + + #['modules/webservers/scripts/install_quota_home.py', 0o700], + + self.files=[['modules/apache/scripts/install_apache.php', 0o700]] + + #self.commands_to_execute=[] + + #self.commands_to_execute.append(['modules/webservers/scripts/add_httpd.py', '']) + + #mysql_server=config.webserver_host_db + + #mysql_db=WebModel.connections['default']['db'] + + #--mysql_server={} --mysql_db={} --mysql_user={} --mysql_pass={}'.format(mysql_server, mysql_db, config.webserver_user_db, config.webserver_user_pass) + + self.commands_to_execute=[['php modules/apache/scripts/install_apache.php', '']] + + #self.commands_to_execute.append(['modules/webservers/scripts/install_quota_home.py', '', 'sudo']) + + #self.delete_files=['modules/webservers/scripts/add_httpd.py'] + + self.delete_directories=['modules/apache/scripts'] + + #self.task=Task(conn) + + self.one_time=True + + self.version='1.0' + + + def post_task(self): + + serverdb=ServerDbTask(self.connection) + + server=WebServer(self.connection) + + resulttask=ResultTask(self.connection) + + #arr_result=resulttask.set_conditions('WHERE task_id=%s', [self.id]).select_a_row_where() + + #result=json.loads(arr_result['message']) + + #if arr_result: + + + server.safe_query() + + #'subdomain_id': self.data['subdomain_id'] + #arr_ids=json.loads(self.data['server_ids']) + + #server.insert({'hostname': self.data['hostname'], 'ip': self.data['ip'], 'group_id': self.data['group_id']}) + #for server_id in arr_ids: + # server.insert({'server_id': server_id}) + + arr_server=serverdb.set_conditions('WHERE ip=%s', [self.server]).select_a_row_where() + + if arr_server: + #server.insert({'server_id': arr_server['id'], 'username': result['username'], 'uid_hosting': result['uid'], 'gid_hosting': result['gid'], 'home': result['home']}) + server.insert({'server_id': arr_server['id']}) + + return True diff --git a/tasks/apache/info.cfg b/tasks/apache/info.cfg new file mode 100644 index 0000000..4710ed6 --- /dev/null +++ b/tasks/apache/info.cfg @@ -0,0 +1,8 @@ +[info] +name=Apache WebServer +description=Install apachewebserver infraestructure + + +[modules] +apache/install_apache=Apache server, the best web server available on the Internet with unix users support + diff --git a/tasks/apache/scripts/wordpress.py b/tasks/apache/scripts/wordpress.py new file mode 100644 index 0000000..fc4b982 --- /dev/null +++ b/tasks/apache/scripts/wordpress.py @@ -0,0 +1,318 @@ +#/usr/bin/env python3 + +from collections import OrderedDict +import os +#from modules.pastafari2.models.servers import Server +from modules.apache.models.webservers import WebServer, VirtualHost +import json + +from modules.pastafari2.libraries.task import Task +from modules.pastafari2.models.pastafari2 import ServerDbTask +from paramecio2.libraries.db import coreforms +from paramecio2.libraries.i18n import I18n +from paramecio2.libraries.formsutils import show_form +from paramecio2.libraries.db.extrafields.usernamefield import UserNameField +from paramecio2.libraries.db.extrafields.emailfield import EmailField +from paramecio2.libraries.db.extrafields.urlfield import DomainField +from modules.apache.libraries.webapptask import WebAppTask +from flask import url_for + +class ServerTask(WebAppTask): + + 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='Install Wordpress in an Apache Httpd Server' + + self.description_task='Installation of Wordpress site in an Apache httpd server.' + + self.codename_task='apache_webserver_wordpress' + + #self.files=[['modules/webservers/scripts/check_php.sh', 0o700], ['modules/webservers/scripts/install_wp.sh', 0o700], ['modules/webservers/scripts/install_wordpress_site.py', 0o700], ['modules/webservers/scripts/add_php_vhost.py', 0o700]] + + self.files=[ ['modules/apache/scripts/webapps/wordpress/install_wp.php', 0o700], ['modules/apache/scripts/webapps/wordpress/install_wordpress_site.py', 0o700]] + + + #THe files to delete + + self.delete_files=[] + + self.delete_directories=['modules/apache/scripts'] + + self.arr_form=OrderedDict() + + self.arr_form['path']=coreforms.BaseForm('path', '') + + self.arr_form['path'].required=True + + self.arr_form['path'].label='The path of wordpress application' + self.arr_form['path'].help='The path of wordpress application.

For example, if you have a domain called http://example.com, if you install in / path, you access to wordpress, directly in http://example.com.
If you add path to /wordpress/, the wordpress site will be accesible using http://example.com/wordpress' + + self.arr_form['user_wp']=coreforms.BaseForm('user_wp', '') + + self.arr_form['user_wp'].required=True + + self.arr_form['user_wp'].label='The admin username of wordpress site' + self.arr_form['user_wp'].help='The username for the user used for admin the wordpress site via /wp-admin' + + self.arr_form['email_wp']=coreforms.BaseForm('email_wp', '') + + self.arr_form['email_wp'].required=True + + self.arr_form['email_wp'].label='The admin email for notifications of wordpress site' + + self.arr_form['title_wp']=coreforms.BaseForm('title_wp', '') + + self.arr_form['title_wp'].required=True + + self.arr_form['title_wp'].label='The title of the wordpress site' + + + self.arr_form['password_wp']=coreforms.PasswordForm('password_wp', '') + + self.arr_form['password_wp'].required=True + + self.arr_form['password_wp'].label='The password for the admin user of wordpress site' + self.arr_form['password_wp'].help='You need a password for login how admin user in wordpress site' + + self.arr_form['repeat_password_wp']=coreforms.PasswordForm('repeat_password_wp', '') + + self.arr_form['repeat_password_wp'].required=True + + self.arr_form['repeat_password_wp'].label='Repeat the password for the admin user of wordpress site' + + self.arr_form['mysql_host']=coreforms.BaseForm('mysql_host', '') + + self.arr_form['mysql_host'].required=True + + self.arr_form['mysql_host'].label='The mysql/mariadb server used for the wordpress site' + self.arr_form['mysql_host'].help='You can get the host from "MariaDB servers" section in the control panel' + + self.arr_form['mysql_db']=coreforms.BaseForm('mysql_db', '') + + self.arr_form['mysql_db'].required=True + + self.arr_form['mysql_db'].label='The mysql/mariadb database name for the wordpress site' + self.arr_form['mysql_db'].help='The database used for the wordpress site' + + self.arr_form['mysql_user']=coreforms.BaseForm('mysql_user', '') + + self.arr_form['mysql_user'].required=True + + self.arr_form['mysql_user'].label='The mysql/mariadb user for the wordpress site' + + self.arr_form['mysql_password']=coreforms.PasswordForm('mysql_password', '') + + self.arr_form['mysql_password'].required=True + + self.arr_form['mysql_password'].label='The password for the mysql/mariadb database user' + + #self.arr_form['user_wp']=coreforms.BaseForm('user_wp', '') + #self.arr_form['user_wp'].required=True + """ + self.path_module='admin_app.webservers' + + webserver_id=0 + + with self.connection.query('select webserver_id from virtualhost WHERE id=%s', [self.data['virtualhost_id']]) as cursor: + + arr_vhost=cursor.fetchone() + + if arr_vhost: + webserver_id=arr_vhost['webserver_id'] + + self.links='

{} >> {} >> {} >> {}

'.format(url_for('admin_app.webservers'), I18n.lang('webservers', 'webservers_list', 'Webservers list'), url_for('admin_app.virtualhost', webserver_id=webserver_id), I18n.lang('webservers', 'websites', 'Websites'), url_for('admin_app.webapps', virtualhost_id=self.data['virtualhost_id']), I18n.lang('webservers', 'webapps', 'Webapps'), url_for('admin_app.add_new_app', virtualhost_id=self.data['virtualhost_id']), I18n.lang('webservers', 'add_webapp', 'Add webapp')) + """ + + #print(self.data) + + #Webservers list >> Websites >> Webapps >> Add webapp + #

${lang('webservers', 'webservers_list', 'Webservers list')} >> ${lang('webservers', 'websites', 'Websites')} >> ${lang('webservers', 'webapps', 'Webapps')}

+ + def pre_task(self): + + if not super().pre_task(): + return False + + with self.connection.query('select php from virtualhost where id=%s', [self.data['virtualhost_id']]) as cursor: + arr_virtualhost=cursor.fetchone() + + if arr_virtualhost['php']=='': + + self.logtask.insert({'status':1, 'progress': 100, 'error': 1, 'task_id': self.id, 'server': self.server, 'message': 'You need install php for this virtualhost!'}) + + return False + else: + self.logtask.insert({'status':0, 'progress': 0, 'error': 0, 'task_id': self.id, 'server': self.server, 'message': 'PHP '+arr_virtualhost['php']+' is installed'}) + + #self.commands_to_execute.append(['modules/webservers/scripts/install_mariadb.py', '--password=%s' % self.extra_data['mysql_password']]) + + #self.commands_to_execute.append(['modules/webservers/scripts/check_php.sh', '8.2']) + + self.commands_to_execute.append(['php', 'modules/apache/scripts/webapps/wordpress/install_wp.php']) + + #self.commands_to_execute.append(['modules/webservers/scripts/add_php_vhost.py', '--user=%s --php_version=8.2 --domain=%s' % (self.data['username'], self.data['domain_wp']), 'sudo']) + + install_wordpress='--home_user=%s --user=%s --password=%s --email=%s --domain=%s --title="%s" --db_mysql=%s --user_mysql=%s --password_mysql=%s --server_mysql=%s --port_mysql=%i --path=%s --php_version=%s' % (self.data['home'], self.data['user_wp'], self.data['password_wp'], self.data['email_wp'], self.data['domain_wp'], self.data['title_wp'], self.data['mysql_db'], self.data['mysql_user'], self.data['mysql_password'], self.data['mysql_host'], 3306, self.data['path'], arr_virtualhost['php']) + + #print(install_wordpress) + + self.commands_to_execute.append(['modules/apache/scripts/webapps/wordpress/install_wordpress_site.py', install_wordpress]) + + + + return True + + def form(self, t, yes_error=False, pass_values=False, values={}): + + #Here load the form for it task + + return '

'+I18n.lang('webservers', 'add_wordpress_site', 'Add wordpress site')+'

'+show_form(values, self.arr_form, t, yes_error, pass_values) + + def check_form(self, post): + + usernamefield=UserNameField('user_wp') + + emailfield=EmailField('email_wp') + + return_val=True + + if 'mysql_host' in post and 'mysql_user' in post and 'mysql_password' in post: + + for i in ('mysql_host', 'mysql_user', 'mysql_password', 'mysql_db'): + if post[i].strip()=='': + + self.arr_form[i].error=True + self.arr_form[i].txt_error='Empty value.' + + return_val=False + + else: + return_val=False + + path=post['path'].strip() + + if 'path' in post: + if path=='': + + self.arr_form['path'].error=True + self.arr_form['path'].txt_error='Empty value.' + + return_val=False + + + user_wp=usernamefield.check(post.get('user_wp')) + + if user_wp=='': + self.arr_form['user_wp'].error=True + self.arr_form['user_wp'].txt_error='Invalid username.' + + return_val=False + + email_wp=emailfield.check(post.get('email_wp')) + + if email_wp=='': + self.arr_form['email_wp'].error=True + self.arr_form['email_wp'].txt_error='Invalid email.' + + return_val=False + + title_wp=post.get('title_wp').strip().replace('"', '"') + + if title_wp=='': + self.arr_form['title_wp'].error=True + self.arr_form['title_wp'].txt_error='Empty value.' + + return_val=False + + + password_wp=post.get('password_wp', '').strip() + + if password_wp=='': + + self.arr_form['password_wp'].error=True + self.arr_form['password_wp'].txt_error='Empty value.' + + return_val=False + + repeat_password_wp=post.get('repeat_password_wp', '').strip() + + if repeat_password_wp=='': + + self.arr_form['repeat_password_wp'].error=True + self.arr_form['repeat_password_wp'].txt_error='Empty value.' + + return_val=False + + if repeat_password_wp!=password_wp: + self.arr_form['password_wp'].error=True + self.arr_form['password_wp'].txt_error='Passwords not equal!' + + return_val=False + + virtualhost_id=self.data.get('virtualhost_id', '0') + # ImmutableMultiDict([('send_task', '1'), ('amp;virtualhost_id', '42')]) + + #print(virtualhost_id) + + domain='' + home='' + + with self.connection.query('select domain, home, username from virtualhost where id=%s', [virtualhost_id]) as cursor: + arr_virtualhost=cursor.fetchone() + + if arr_virtualhost: + domain=arr_virtualhost['domain'] + home=arr_virtualhost['home']+'/htdocs' + username=arr_virtualhost['username'] + + if domain=='': + return_val=False + + if return_val: + + # (self.data['user_wp'], self.data['password_wp'], self.data['mysql_user'], self.data['mysql_password'], self.data['mysql_db'], self.data['email_wp'], self.data['domain_wp'], self.data['title_wp'], self.data['mysql_host'], 3306) + + self.data['path']=path + + self.data['user_wp']=user_wp + self.data['password_wp']=password_wp + self.data['email_wp']=email_wp + self.data['title_wp']=title_wp + self.data['domain_wp']=domain + + self.data['mysql_host']=post['mysql_host'].strip() + self.data['mysql_user']=post['mysql_user'].strip() + self.data['mysql_password']=post['mysql_password'].strip() + self.data['mysql_db']=post['mysql_db'].strip() + + self.data['virtualhost_id']=virtualhost_id + + self.data['home']=home + self.data['username']=username + self.data['webapp']='wordpress' + + return return_val + + def post_task(self): + + #virtualhost=VirtualHost(self.connection) + + #virtualhost.safe_query() + + #if not virtualhost.insert({'virtualhost_id': int(self.data['virtualhost_id']), 'app_name': 'wordpress', 'path': self.data['path']}): + # return False + #print(virtualhost.show_errors()) + + #virtua + + app_name=os.path.basename(os.path.dirname(self.data['path'])) + + if app_name=='': + app_name='wordpress' + + self.connection.query('insert into webapp (`virtualhost_id`, `app_name`, `app_type`, `path`, `data`) VALUES (%s, %s, %s, %s, %s)', [int(self.data['virtualhost_id']), app_name, 'wordpress', self.data['path'], json.dumps({'mysql_host': self.data['mysql_host'], 'mysql_db': self.data['mysql_db']})]) + + + return True diff --git a/templates/admin/add_virtualhost.phtml b/templates/admin/add_virtualhost.phtml new file mode 100644 index 0000000..bdccdcc --- /dev/null +++ b/templates/admin/add_virtualhost.phtml @@ -0,0 +1,36 @@ +<%inherit file="dashboard.phtml"/> +<%block name="content"> +

${lang('webservers', 'webservers_list', 'Webservers list')} >> ${lang('webservers', 'websites', 'Websites')} >> ${lang('webservers', 'add_website', 'Add website')}

+
+${form|n} +

+

+

${lang('webservers', 'webservers_list', 'Webservers list')} >> ${lang('webservers', 'websites', 'Websites')} >> ${lang('webservers', 'add_website', 'Add website')}

+ +<%block name="jscript_block"> + + + diff --git a/templates/admin/add_webapp.phtml b/templates/admin/add_webapp.phtml new file mode 100644 index 0000000..6a9ea3d --- /dev/null +++ b/templates/admin/add_webapp.phtml @@ -0,0 +1,54 @@ +<%inherit file="dashboard.phtml"/> +<%block name="content"> +<% + +import json + +ids=json.dumps([server_id]) + +%> +

${domain}

+

${lang('webservers', 'webservers_list', 'Webservers list')} >> ${lang('webservers', 'websites', 'Websites')} >> ${lang('webservers', 'webapps', 'Webapps')} >> ${lang('webservers', 'add_webapp', 'Add webapp')}

+
+
+

+ +

+
+

+

+

${lang('webservers', 'webservers_list', 'Webservers list')} >> ${lang('webservers', 'websites', 'Websites')} >> ${lang('webservers', 'webapps', 'Webapps')} >> ${lang('webservers', 'add_webapp', 'Add webapp')}

+ +<%block name="jscript_block"> + + + diff --git a/templates/admin/add_webapp_form.phtml b/templates/admin/add_webapp_form.phtml new file mode 100644 index 0000000..34ab578 --- /dev/null +++ b/templates/admin/add_webapp_form.phtml @@ -0,0 +1,37 @@ +<%inherit file="dashboard.phtml"/> +<%block name="content"> +

${domain}

+

${lang('webservers', 'webservers_list', 'Webservers list')} >> ${lang('webservers', 'websites', 'Websites')} >> ${lang('webservers', 'webapps', 'Webapps')} >> ${lang('webservers', 'add_webapp', 'Add webapp')} >> ${lang('webservers', 'add_webapp_form', 'Webapp form')}

+
+${tpl_form|n} +

+

+

${lang('webservers', 'webservers_list', 'Webservers list')} >> ${lang('webservers', 'websites', 'Websites')} >> ${lang('webservers', 'webapps', 'Webapps')} >> ${lang('webservers', 'add_webapp', 'Add webapp')} >> ${lang('webservers', 'add_webapp_form', 'Webapp form')}

+ +<%block name="jscript_block"> + + + diff --git a/templates/admin/del_virtualhost.phtml b/templates/admin/del_virtualhost.phtml new file mode 100644 index 0000000..7e435a9 --- /dev/null +++ b/templates/admin/del_virtualhost.phtml @@ -0,0 +1,27 @@ +<%inherit file="dashboard.phtml"/> +<%block name="content"> +

${lang('webservers', 'webservers_list', 'Webservers list')} >> ${lang('webservers', 'websites', 'Websites')} >> ${lang('webservers', 'remove_website', 'Remove website')}

+
+ +

${domain}

+

+

+

${lang('webservers', 'webservers_list', 'Webservers list')} >> ${lang('webservers', 'websites', 'Websites')} >> ${lang('webservers', 'remove_website', 'Remove website')}

+ +<%block name="jscript_block"> + + + diff --git a/templates/admin/del_webserver.phtml b/templates/admin/del_webserver.phtml new file mode 100644 index 0000000..825db2b --- /dev/null +++ b/templates/admin/del_webserver.phtml @@ -0,0 +1,28 @@ +<%inherit file="dashboard.phtml"/> +<%block name="content"> +

${lang('webservers', 'webservers_list', 'Webservers list')} >> ${lang('webservers', 'remove_webserver', 'Remove webserver')}

+
+ +

${domain}

+

${lang('webservers', 'the_webserver_delete_explain', 'The Webserver was deleted from database, you should delete the webserver from your VPS or Barebone server service')}

+

+

+

${lang('webservers', 'webservers_list', 'Webservers list')} >> ${lang('webservers', 'remove_webserver', 'Remove webserver')}

+ +<%block name="jscript_block"> + + + diff --git a/templates/admin/edit_virtualhost.phtml b/templates/admin/edit_virtualhost.phtml new file mode 100644 index 0000000..6541d1c --- /dev/null +++ b/templates/admin/edit_virtualhost.phtml @@ -0,0 +1,49 @@ +<%inherit file="dashboard.phtml"/> +<%block name="extra_css"> + +<%block name="content"> +

${lang('webservers', 'webservers_list', 'Webservers list')} >> ${lang('webservers', 'websites', 'Websites')} >> ${lang('webservers', 'edit_website', 'Edit website')}

+
+${form|n} + +

+

+

${lang('webservers', 'webservers_list', 'Webservers list')} >> ${lang('webservers', 'websites', 'Websites')} >> ${lang('webservers', 'edit_website', 'Edit website')}

+ +<%block name="jscript_block"> + + + diff --git a/templates/admin/ports.phtml b/templates/admin/ports.phtml new file mode 100644 index 0000000..62f56c9 --- /dev/null +++ b/templates/admin/ports.phtml @@ -0,0 +1,6 @@ +<%inherit file="dashboard.phtml"/> +<%block name="content"> +

${lang('ports', 'webservers', 'Webservers')} >> ${hostname} - ${lang('ports', 'http_ports', 'HTTP Ports')}

+${form_admin|n} +

${lang('ports', 'webservers', 'Webservers')} >> ${hostname} - ${lang('ports', 'http_ports', 'HTTP Ports')}

+ diff --git a/templates/admin/serverusers.phtml b/templates/admin/serverusers.phtml new file mode 100644 index 0000000..1912a13 --- /dev/null +++ b/templates/admin/serverusers.phtml @@ -0,0 +1,6 @@ +<%inherit file="dashboard.phtml"/> +<%block name="content"> +

${lang('webservers', 'webservers_list', 'Webservers list')} >> ${lang('webservers', 'website', 'Website')} >> ${lang('webservers', 'Web users', 'Web users')}

+${form_admin|n} +

${lang('webservers', 'webservers_list', 'Webservers list')} >> ${lang('webservers', 'website', 'Website')} >> ${lang('webservers', 'Web users', 'Web users')}

+ diff --git a/templates/admin/virtualhosts.phtml b/templates/admin/virtualhosts.phtml new file mode 100644 index 0000000..3e749d0 --- /dev/null +++ b/templates/admin/virtualhosts.phtml @@ -0,0 +1,70 @@ +<%inherit file="dashboard.phtml"/> +<%block name="extra_css"> + + + +<%block name="content"> +

${hostname}

+

${lang('webservers', 'webservers_list', 'Webservers list')} >> ${lang('webservers', 'websites', 'Websites')}

+

${lang('webservers', 'add_new_website', 'Add new website')}

+
+
+

${lang('webservers', 'webservers_list', 'Webservers list')} >> ${lang('webservers', 'websites', 'Websites')}

+ +<%block name="jscript_block"> + + + + + + diff --git a/templates/admin/webapps.phtml b/templates/admin/webapps.phtml new file mode 100644 index 0000000..5ac3c66 --- /dev/null +++ b/templates/admin/webapps.phtml @@ -0,0 +1,109 @@ +<%inherit file="dashboard.phtml"/> +<%block name="extra_css"> + + + +<%block name="content"> +<% + +import json + +ids=json.dumps([server_id]) + +%> +

${domain}

+

${lang('webservers', 'add_new_app', 'Add new app')}

+

${lang('webservers', 'webservers_list', 'Webservers list')} >> ${lang('webservers', 'websites', 'Websites')} >> ${lang('webservers', 'webapps', 'Webapps')}

+
+
+

${lang('webservers', 'webservers_list', 'Webservers list')} >> ${lang('webservers', 'websites', 'Websites')} >> ${lang('webservers', 'webapps', 'Webapps')}

+ + +<%block name="jscript_block"> + + + + diff --git a/templates/admin/webservers.phtml b/templates/admin/webservers.phtml new file mode 100644 index 0000000..aeb03cf --- /dev/null +++ b/templates/admin/webservers.phtml @@ -0,0 +1,16 @@ +<%inherit file="dashboard.phtml"/> +<%block name="content"> +
+
+<%block name="jscript_block"> + + + + +