mirror of
https://github.com/YunoHost/moulinette.git
synced 2024-09-03 20:06:31 +02:00
Merge branch 'dev' of github.com:YunoHost/moulinette into dev
This commit is contained in:
commit
4ca2abfde6
10 changed files with 230 additions and 73 deletions
|
@ -132,6 +132,7 @@ git checkout -b dev_beudbeud ``
|
|||
git rebase origin/dev
|
||||
```
|
||||
|
||||
|
||||
Do your modifications, then :
|
||||
```
|
||||
git commit -am 'My commit message'
|
||||
|
|
|
@ -220,7 +220,6 @@ app:
|
|||
-n:
|
||||
full: --name
|
||||
help: Name of the list (default fapp)
|
||||
pattern: '^[a-z0-9_]+$'
|
||||
|
||||
### app_listlists()
|
||||
listlists:
|
||||
|
@ -491,6 +490,24 @@ firewall:
|
|||
action: store_true
|
||||
|
||||
|
||||
### firewall_installupnp()
|
||||
installupnp:
|
||||
action_help: Add upnp cron
|
||||
|
||||
|
||||
### firewall_removeupnp()
|
||||
removeupnp:
|
||||
action_help: Remove upnp cron
|
||||
|
||||
|
||||
### firewall_stop()
|
||||
stop:
|
||||
action_help: Stop iptables and ip6tables
|
||||
|
||||
|
||||
### firewall_checkupnp()
|
||||
checkupnp:
|
||||
action_help: check if UPNP is install or not (0 yes 1 no)
|
||||
#############################
|
||||
# Tools #
|
||||
#############################
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
UPNP: false
|
||||
ipv4:
|
||||
TCP: [22, 25, 53, 80, 443, 5222, 5269, 5280]
|
||||
UDP: []
|
||||
TCP: [22, 25, 53, 80, 443, 5222, 5269, 5280, 6767]
|
||||
UDP: [53]
|
||||
ipv6:
|
||||
TCP: [22]
|
||||
UDP: []
|
||||
TCP: [22]
|
||||
UDP: [53]
|
||||
|
|
|
@ -57,9 +57,9 @@ childs:
|
|||
- sudoRole
|
||||
- top
|
||||
|
||||
cn=www-data,ou=sudo:
|
||||
cn: www-data
|
||||
sudoUser: www-data
|
||||
cn=yunohost-admin,ou=sudo:
|
||||
cn: yunohost-admin
|
||||
sudoUser: yunohost-admin
|
||||
sudoHost: ALL
|
||||
sudoCommand: /usr/bin/yunohost
|
||||
sudoOption: "!authenticate"
|
||||
|
|
18
parse_args
18
parse_args
|
@ -38,7 +38,7 @@ if not __debug__:
|
|||
gettext.install('YunoHost')
|
||||
|
||||
try:
|
||||
from yunohost import YunoHostError, YunoHostLDAP, str_to_func, colorize, pretty_print_dict, display_error, validate
|
||||
from yunohost import YunoHostError, YunoHostLDAP, str_to_func, colorize, pretty_print_dict, display_error, validate, win
|
||||
except ImportError:
|
||||
sys.stderr.write('Error: Yunohost CLI Require YunoHost lib\n')
|
||||
sys.exit(1)
|
||||
|
@ -202,15 +202,21 @@ def main():
|
|||
#print(_("Not (yet) implemented function"))
|
||||
#return 1
|
||||
except YunoHostError, error:
|
||||
display_error(error)
|
||||
display_error(error, json_print)
|
||||
return error.code
|
||||
else:
|
||||
if result is None:
|
||||
pass
|
||||
elif os.isatty(1) and not json_print:
|
||||
if json_print or not os.isatty(1):
|
||||
if result is None:
|
||||
result = {}
|
||||
if len(win) > 0:
|
||||
result['success'] = []
|
||||
for msg in win:
|
||||
result['success'].append(msg)
|
||||
print(json.dumps(result))
|
||||
elif result is not None:
|
||||
pretty_print_dict(result)
|
||||
else:
|
||||
print(json.dumps(result))
|
||||
pass
|
||||
|
||||
return 0
|
||||
|
||||
|
|
15
yunohost.py
15
yunohost.py
|
@ -17,6 +17,7 @@ import string
|
|||
if not __debug__:
|
||||
import traceback
|
||||
|
||||
win = []
|
||||
lemon_tmp_conf = '/tmp/tmplemonconf'
|
||||
|
||||
def random_password(length=8):
|
||||
|
@ -51,9 +52,11 @@ def pretty_print_dict(d, depth=0):
|
|||
pretty_print_dict(v, depth+1)
|
||||
elif isinstance(v, list):
|
||||
print((" ") * depth + ("%s: " % str(k)))
|
||||
for value in v:
|
||||
for key, value in enumerate(v):
|
||||
if isinstance(value, tuple):
|
||||
pretty_print_dict({value[0]: value[1]}, depth+1)
|
||||
elif isinstance(value, dict):
|
||||
pretty_print_dict({key: value}, depth+1)
|
||||
else:
|
||||
print((" ") * (depth+1) + "- " +str(value))
|
||||
else:
|
||||
|
@ -87,8 +90,12 @@ def win_msg(astr):
|
|||
astr -- Win message to display
|
||||
|
||||
"""
|
||||
global win
|
||||
if os.isatty(1):
|
||||
print('\n' + colorize(_("Success: "), 'green') + astr + '\n')
|
||||
else:
|
||||
win.append(astr)
|
||||
|
||||
|
||||
|
||||
def str_to_func(astr):
|
||||
|
@ -175,17 +182,17 @@ def get_required_args(args, required_args, password=False):
|
|||
return args
|
||||
|
||||
|
||||
def display_error(error):
|
||||
def display_error(error, json_print=False):
|
||||
"""
|
||||
Nice error displaying
|
||||
|
||||
"""
|
||||
if not __debug__ :
|
||||
traceback.print_exc()
|
||||
if os.isatty(1):
|
||||
if os.isatty(1) and not json_print:
|
||||
print('\n' + colorize(_("Error: "), 'red') + error.message)
|
||||
else:
|
||||
print(json.dumps({ 'error' : error.message }))
|
||||
print(json.dumps({ error.code : error.message }))
|
||||
|
||||
|
||||
def lemon_configuration(conf_dict):
|
||||
|
|
|
@ -56,8 +56,8 @@ def app_fetchlist(url=None, name=None):
|
|||
except OSError: os.makedirs(repo_path)
|
||||
|
||||
if not url:
|
||||
url = 'http://fapp.yunohost.org/app/list/raw'
|
||||
name = "fapp"
|
||||
url = 'http://app.yunohost.org/list.json'
|
||||
name = 'yunohost'
|
||||
else:
|
||||
if not name: raise YunoHostError(22, _("You must indicate a name for your custom list"))
|
||||
|
||||
|
@ -316,10 +316,9 @@ def app_install(app, domain, path='/', label=None, mode='private'):
|
|||
# Apache #
|
||||
##########
|
||||
|
||||
a2_conf_lines = [
|
||||
'Alias '+ path +' '+ app_final_path + manifest['launch_path'],
|
||||
'Alias '+ path[:len(path)-1] +' '+ app_final_path + manifest['launch_path']
|
||||
]
|
||||
a2_conf_lines = [ 'Alias '+ path +' '+ app_final_path + manifest['launch_path'] ]
|
||||
if path != '/':
|
||||
a2_conf_lines.append('Alias '+ path[:len(path)-1] +' '+ app_final_path + manifest['launch_path'])
|
||||
|
||||
if lvl(manifest, 'yunohost', 'webapp', 'language') and manifest['yunohost']['webapp']['language'] == 'php':
|
||||
for line in open(a2_template_path +'/php.conf'): a2_conf_lines.append(line.rstrip())
|
||||
|
@ -573,7 +572,7 @@ def _install_app_dependencies(dep_dict):
|
|||
"""
|
||||
if ('debian' in dep_dict) and (len(dep_dict['debian']) > 0):
|
||||
#os.system('apt-get update')
|
||||
if os.system('apt-get install "'+ '" "'.join(dep_dict['debian']) +'"') != 0:
|
||||
if os.system('apt-get install -y "'+ '" "'.join(dep_dict['debian']) +'"') != 0:
|
||||
raise YunoHostError(1, _("Dependency installation failed: ") + dependency)
|
||||
|
||||
# TODO: Install npm, pip, gem and pear dependencies
|
||||
|
|
|
@ -33,7 +33,7 @@ def firewall_allow(protocol=None, port=None, ipv6=None, upnp=False):
|
|||
"""
|
||||
port = int(port)
|
||||
if (upnp):
|
||||
add_portmapping(protocol, upnp, ipv6)
|
||||
add_portmapping(protocol, upnp, ipv6,'a')
|
||||
|
||||
if 0 < port < 65536:
|
||||
if protocol == "Both":
|
||||
|
@ -108,27 +108,40 @@ def firewall_reload(upnp=False):
|
|||
os.system ("iptables -P INPUT ACCEPT")
|
||||
os.system ("iptables -F")
|
||||
os.system ("iptables -X")
|
||||
os.system ("iptables -A INPUT -m state --state ESTABLISHED -j ACCEPT")
|
||||
|
||||
if 22 not in firewall['ipv4']['TCP']:
|
||||
update_yml(22, 'TCP', 'a', False)
|
||||
|
||||
|
||||
os.system ("ip6tables -P INPUT ACCEPT")
|
||||
os.system ("ip6tables -F")
|
||||
os.system ("ip6tables -X")
|
||||
if(os.path.exists("/proc/net/if_inet6")):
|
||||
os.system ("ip6tables -P INPUT ACCEPT")
|
||||
os.system ("ip6tables -F")
|
||||
os.system ("ip6tables -X")
|
||||
os.system ("ip6tables -A INPUT -m state --state ESTABLISHED -j ACCEPT")
|
||||
|
||||
if 22 not in firewall['ipv6']['TCP']:
|
||||
update_yml(22, 'TCP', 'a', False)
|
||||
|
||||
if upnp:
|
||||
remove_portmapping()
|
||||
|
||||
add_portmapping('TCP', upnp, False,'r');
|
||||
add_portmapping('UDP', upnp, False,'r');
|
||||
|
||||
if(os.path.exists("/proc/net/if_inet6")):
|
||||
add_portmapping('TCP', upnp, True,'r');
|
||||
add_portmapping('UDP', upnp, True,'r');
|
||||
|
||||
add_portmapping('TCP', upnp, False);
|
||||
add_portmapping('UDP', upnp, False);
|
||||
add_portmapping('TCP', upnp, True);
|
||||
add_portmapping('UDP', upnp, True);
|
||||
|
||||
os.system ("iptables -A INPUT -i lo -j ACCEPT")
|
||||
os.system ("iptables -A INPUT -p icmp -j ACCEPT")
|
||||
os.system ("iptables -P INPUT DROP")
|
||||
os.system ("ip6tables -P INPUT DROP")
|
||||
|
||||
if(os.path.exists("/proc/net/if_inet6")):
|
||||
os.system ("ip6tables -A INPUT -i lo -j ACCEPT")
|
||||
os.system ("ip6tables -A INPUT -p icmp -j ACCEPT")
|
||||
os.system ("ip6tables -P INPUT DROP")
|
||||
|
||||
os.system("service fail2ban restart")
|
||||
win_msg(_("Firewall successfully reloaded"))
|
||||
|
||||
return firewall_list()
|
||||
|
@ -174,46 +187,156 @@ def update_yml(port=None, protocol=None, mode=None, ipv6=None):
|
|||
yaml.dump(firewall, f)
|
||||
|
||||
|
||||
def add_portmapping(protocol=None, upnp=False, ipv6=None):
|
||||
def add_portmapping(protocol=None, upnp=False, ipv6=None,mode=None,):
|
||||
"""
|
||||
Send a port mapping rules to igd device
|
||||
Keyword arguments:
|
||||
protocol -- Protocol used
|
||||
port -- Port to open
|
||||
upnp -- Boolean upnp
|
||||
ipv6 -- Boolean ipv6
|
||||
mode -- Add a rule (a) or reload all rules (r)
|
||||
|
||||
Return
|
||||
None
|
||||
"""
|
||||
os.system ("iptables -P INPUT ACCEPT")
|
||||
if upnp:
|
||||
upnp = miniupnpc.UPnP()
|
||||
upnp.discoverdelay = 200
|
||||
nbigd = upnp.discover()
|
||||
if nbigd:
|
||||
try:
|
||||
upnp.selectigd()
|
||||
except:
|
||||
firewall_reload(False)
|
||||
raise YunoHostError(167,_("No upnp devices found"))
|
||||
else:
|
||||
firewall_reload(False)
|
||||
raise YunoHostError(22,_("Can't connect to the igd device"))
|
||||
|
||||
# list the redirections :
|
||||
for i in xrange(100):
|
||||
p = upnp.getgenericportmapping(i)
|
||||
if p is None: break
|
||||
upnp.deleteportmapping(p[0], p[1])
|
||||
|
||||
if ipv6:
|
||||
os.system ("ip6tables -P INPUT ACCEPT")
|
||||
else:
|
||||
os.system ("iptables -P INPUT ACCEPT")
|
||||
|
||||
if upnp and mode=='a':
|
||||
remove_portmapping()
|
||||
|
||||
if ipv6: ip = 'ipv6'
|
||||
else: ip = 'ipv4'
|
||||
with open('firewall.yml', 'r') as f:
|
||||
firewall = yaml.load(f)
|
||||
|
||||
for i,port in enumerate (firewall[ip][protocol]):
|
||||
os.system ("iptables -A INPUT -p "+ protocol +" -i eth0 --dport "+ str(port) +" -j ACCEPT")
|
||||
if ipv6:
|
||||
os.system ("ip6tables -A INPUT -p "+ protocol +" -i eth0 --dport "+ str(port) +" -j ACCEPT")
|
||||
else:
|
||||
os.system ("iptables -A INPUT -p "+ protocol +" -i eth0 --dport "+ str(port) +" -j ACCEPT")
|
||||
if upnp:
|
||||
upnp.addportmapping(port, protocol, upnp.lanaddr, port, 'yunohost firewall : port %u' % port, '')
|
||||
upnpc = miniupnpc.UPnP()
|
||||
upnpc.discoverdelay = 200
|
||||
nbigd = upnpc.discover()
|
||||
if nbigd:
|
||||
upnpc.selectigd()
|
||||
upnpc.addportmapping(port, protocol, upnpc.lanaddr, port, 'yunohost firewall : port %u' % port, '')
|
||||
|
||||
os.system ("iptables -P INPUT DROP")
|
||||
|
||||
def remove_portmapping():
|
||||
"""
|
||||
Remove all portmapping rules in the igd device
|
||||
Keyword arguments:
|
||||
None
|
||||
Return
|
||||
None
|
||||
"""
|
||||
upnp = miniupnpc.UPnP()
|
||||
upnp.discoverdelay = 200
|
||||
nbigd = upnp.discover()
|
||||
if nbigd:
|
||||
try:
|
||||
upnp.selectigd()
|
||||
except:
|
||||
firewall_reload(False)
|
||||
raise YunoHostError(167,_("No upnp devices found"))
|
||||
else:
|
||||
firewall_reload(False)
|
||||
raise YunoHostError(22,_("Can't connect to the igd device"))
|
||||
|
||||
# list the redirections :
|
||||
for i in xrange(100):
|
||||
p = upnp.getgenericportmapping(i)
|
||||
if p is None: break
|
||||
upnp.deleteportmapping(p[0], p[1])
|
||||
|
||||
|
||||
def firewall_installupnp():
|
||||
"""
|
||||
Add upnp cron
|
||||
Keyword arguments:
|
||||
None
|
||||
Return
|
||||
None
|
||||
"""
|
||||
|
||||
with open('firewall.yml', 'r') as f:
|
||||
firewall = yaml.load(f)
|
||||
|
||||
firewall['UPNP']=True;
|
||||
|
||||
os.system("touch /etc/cron.d/yunohost-firewall")
|
||||
os.system("echo '*/50 * * * * root yunohost firewall reload -u>>/dev/null'>/etc/cron.d/yunohost-firewall")
|
||||
win_msg(_("UPNP cron installed"))
|
||||
|
||||
os.system("mv firewall.yml firewall.yml.old")
|
||||
|
||||
with open('firewall.yml', 'w') as f:
|
||||
yaml.dump(firewall, f)
|
||||
|
||||
|
||||
def firewall_removeupnp():
|
||||
"""
|
||||
Remove upnp cron
|
||||
Keyword arguments:
|
||||
None
|
||||
Return
|
||||
None
|
||||
"""
|
||||
with open('firewall.yml', 'r') as f:
|
||||
firewall = yaml.load(f)
|
||||
|
||||
firewall['UPNP']=False;
|
||||
|
||||
try:
|
||||
os.remove("/etc/cron.d/yunohost-firewall")
|
||||
except:
|
||||
raise YunoHostError(167,_("UPNP cron was not installed!"))
|
||||
|
||||
win_msg(_("UPNP cron removed"))
|
||||
|
||||
os.system("mv firewall.yml firewall.yml.old")
|
||||
|
||||
with open('firewall.yml', 'w') as f:
|
||||
yaml.dump(firewall, f)
|
||||
|
||||
def firewall_checkupnp():
|
||||
"""
|
||||
Check if UPNP is installed
|
||||
Keyword arguments:
|
||||
None
|
||||
Return
|
||||
0 if installed
|
||||
1 if not
|
||||
"""
|
||||
with open('firewall.yml', 'r') as f:
|
||||
firewall = yaml.load(f)
|
||||
|
||||
if firewall['UPNP']:
|
||||
win_msg(_("UPNP is activated"))
|
||||
else:
|
||||
raise YunoHostError(167,_("UPNP not activated!"))
|
||||
|
||||
def firewall_stop():
|
||||
"""
|
||||
Stop firewall
|
||||
Keyword arguments:
|
||||
None
|
||||
Return
|
||||
None
|
||||
"""
|
||||
|
||||
os.system ("iptables -P INPUT ACCEPT")
|
||||
os.system ("iptables -F")
|
||||
os.system ("iptables -X")
|
||||
|
||||
os.system ("ip6tables -P INPUT ACCEPT")
|
||||
os.system ("ip6tables -F")
|
||||
os.system ("ip6tables -X")
|
||||
if(os.path.exists("/etc/cron.d/yunohost-firewall")):
|
||||
firewall_removeupnp()
|
||||
|
||||
|
|
|
@ -81,16 +81,18 @@ def tools_maindomain(old_domain, new_domain):
|
|||
|
||||
"""
|
||||
if not old_domain:
|
||||
with open('/usr/share/yunohost/yunohost-config/others/current_host', 'r') as f:
|
||||
with open('/etc/yunohost/current_host', 'r') as f:
|
||||
old_domain = f.readline().rstrip()
|
||||
|
||||
validate(r'^([a-zA-Z0-9]{1}([a-zA-Z0-9\-]*[a-zA-Z0-9])*)(\.[a-zA-Z0-9]{1}([a-zA-Z0-9\-]*[a-zA-Z0-9])*)*(\.[a-zA-Z]{1}([a-zA-Z0-9\-]*[a-zA-Z0-9])*)$', old_domain)
|
||||
|
||||
config_files = [
|
||||
'/etc/prosody/conf.avail/localhost.cfg.lua',
|
||||
'/etc/postfix/main.cf',
|
||||
'/etc/dovecot/dovecot.conf',
|
||||
'/etc/lemonldap-ng/lemonldap-ng.ini',
|
||||
'/etc/hosts',
|
||||
'/usr/share/yunohost/yunohost-config/others/startup',
|
||||
]
|
||||
|
||||
config_dir = []
|
||||
|
@ -122,12 +124,13 @@ def tools_maindomain(old_domain, new_domain):
|
|||
lemon_conf.write(line + '\n')
|
||||
|
||||
|
||||
os.system('rm /etc/yunohost/apache/domains/' + old_domain + '.d/*.sso.conf') # remove SSO apache conf dir from old domain conf (fail if postinstall)
|
||||
os.system('rm /etc/yunohost/apache/domains/' + old_domain + '.d/*.fixed.conf') # remove SSO apache conf dir from old domain conf (fail if postinstall)
|
||||
|
||||
tmp = '/usr/share/yunohost/yunohost-config'
|
||||
|
||||
command_list = [
|
||||
'cp /etc/yunohost/apache/templates/fixed.sso.conf /etc/yunohost/apache/domains/' + new_domain + '.d/fixed.sso.conf', # add SSO apache conf dir to new domain conf
|
||||
'cp /etc/yunohost/apache/templates/sso.fixed.conf /etc/yunohost/apache/domains/' + new_domain + '.d/sso.fixed.conf', # add SSO apache conf dir to new domain conf
|
||||
'cp /etc/yunohost/apache/templates/admin.fixed.conf /etc/yunohost/apache/domains/' + new_domain + '.d/admin.fixed.conf',
|
||||
'/usr/share/lemonldap-ng/bin/lmYnhMoulinette',
|
||||
'/etc/init.d/hostname.sh',
|
||||
'echo "01" > '+ tmp +'/ssl/yunoCA/serial',
|
||||
|
@ -140,7 +143,7 @@ def tools_maindomain(old_domain, new_domain):
|
|||
'cp '+ tmp +'/ssl/yunoCA/ca/cacert.pem /etc/ssl/certs/ca-yunohost_crt.pem',
|
||||
'cp '+ tmp +'/ssl/yunoCA/certs/yunohost_key.pem /etc/ssl/private/',
|
||||
'cp '+ tmp +'/ssl/yunoCA/newcerts/01.pem /etc/ssl/certs/yunohost_crt.pem',
|
||||
'echo '+ new_domain +' > /usr/share/yunohost/yunohost-config/others/current_host',
|
||||
'echo '+ new_domain +' > /etc/yunohost/current_host',
|
||||
'service apache2 restart',
|
||||
'service postfix restart'
|
||||
]
|
||||
|
@ -166,7 +169,7 @@ def tools_postinstall(domain, password):
|
|||
"""
|
||||
with YunoHostLDAP(password='yunohost') as yldap:
|
||||
try:
|
||||
with open('/usr/share/yunohost/yunohost-config/others/installed') as f: pass
|
||||
with open('/etc/yunohost/installed') as f: pass
|
||||
except IOError:
|
||||
print('Installing YunoHost')
|
||||
else:
|
||||
|
@ -181,6 +184,6 @@ def tools_postinstall(domain, password):
|
|||
# Change LDAP admin password
|
||||
tools_adminpw(old_password='yunohost', new_password=password)
|
||||
|
||||
os.system('touch /usr/share/yunohost/yunohost-config/others/installed')
|
||||
os.system('touch /etc/yunohost/installed')
|
||||
|
||||
win_msg(_("YunoHost has been successfully configured"))
|
||||
|
|
|
@ -25,7 +25,7 @@ def user_list(fields=None, filter=None, limit=None, offset=None):
|
|||
with YunoHostLDAP() as yldap:
|
||||
user_attrs = ['uid', 'mail', 'cn', 'mailalias']
|
||||
attrs = []
|
||||
result_dict = {}
|
||||
result_list = []
|
||||
if offset: offset = int(offset)
|
||||
else: offset = 0
|
||||
if limit: limit = int(limit)
|
||||
|
@ -46,7 +46,7 @@ def user_list(fields=None, filter=None, limit=None, offset=None):
|
|||
if result and len(result) > (0 + offset) and limit > 0:
|
||||
i = 0 + offset
|
||||
for user in result[i:]:
|
||||
if i <= limit:
|
||||
if i - offset < limit:
|
||||
entry = {
|
||||
'Username': user['uid'][0],
|
||||
'Fullname': user['cn'][0],
|
||||
|
@ -57,12 +57,12 @@ def user_list(fields=None, filter=None, limit=None, offset=None):
|
|||
if 'mailalias' in user:
|
||||
entry['Mail Aliases'] = user['mailalias']
|
||||
|
||||
result_dict[str(i)] = entry
|
||||
result_list.append(entry)
|
||||
i += 1
|
||||
else:
|
||||
raise YunoHostError(167, _("No user found"))
|
||||
|
||||
return result_dict
|
||||
return { 'Users' : result_list }
|
||||
|
||||
|
||||
def user_create(username, firstname, lastname, mail, password):
|
||||
|
@ -300,8 +300,8 @@ def user_info(user_or_mail):
|
|||
raise YunoHostError(22, _("Unknown user/mail"))
|
||||
|
||||
result_dict = {
|
||||
'Username': user['uid'],
|
||||
'Fullname': user['cn'],
|
||||
'Username': user['uid'][0],
|
||||
'Fullname': user['cn'][0],
|
||||
'Mail': user['mail'][0]
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue