Compare commits
No commits in common. "master" and "branch-v1" have entirely different histories.
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,3 +1,2 @@
|
||||
*.sh
|
||||
*.tar.*
|
||||
*.rpm
|
||||
|
@ -1,15 +0,0 @@
|
||||
#!/usr/bin/perl -w
|
||||
|
||||
use esmith::Build::CreateLinks qw(:all);
|
||||
use File::Basename;
|
||||
use File::Path;
|
||||
|
||||
|
||||
$event = "doraemon-reboot";
|
||||
event_actions($event, 'doraemon-reboot' => 50);
|
||||
|
||||
$event = "doraemon-shutdown";
|
||||
event_actions($event, 'doraemon-shutdown' => 50);
|
||||
|
||||
$event = "doraemon-wake";
|
||||
event_actions($event, 'doraemon-wake' => 50);
|
1
defaults/access
Normal file
1
defaults/access
Normal file
@ -0,0 +1 @@
|
||||
private
|
16
doraemon.ini
Normal file
16
doraemon.ini
Normal file
@ -0,0 +1,16 @@
|
||||
[Daemon]
|
||||
Database = /var/lib/doraemon/doraemon.db
|
||||
LogFile = /var/log/doraemon.log
|
||||
PIDFile = /var/run/doraemon.pid
|
||||
BindAddress = 0.0.0.0
|
||||
Port = 3000
|
||||
|
||||
[NameSettings]
|
||||
Base = lab
|
||||
Role = client
|
||||
Digits = 2
|
||||
|
||||
[Files]
|
||||
Domain = /etc/domain.yml
|
||||
MgmtKey = /home/amgmt/.ssh/id_rsa.pub
|
||||
VaultPassFile = /home/amgmt/.ansible/vault.txt
|
6
doraemon.logrotate
Normal file
6
doraemon.logrotate
Normal file
@ -0,0 +1,6 @@
|
||||
/var/log/doraemon.log {
|
||||
daily
|
||||
rotate 15
|
||||
compress
|
||||
missingok
|
||||
}
|
234
doraemon.py
Normal file
234
doraemon.py
Normal file
@ -0,0 +1,234 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""Helps a client to join domain and maintain itself."""
|
||||
__author__ = 'BgLUG'
|
||||
__email__ = 'info@bglug.it'
|
||||
|
||||
from contextlib import contextmanager, closing
|
||||
from subprocess import Popen, PIPE
|
||||
from sqlite3 import connect
|
||||
from bottle import Bottle, request
|
||||
from json import dumps
|
||||
from ConfigParser import ConfigParser
|
||||
from Crypto.Hash import MD5
|
||||
from Crypto.Cipher import AES
|
||||
import base64
|
||||
import json
|
||||
import sys
|
||||
import re
|
||||
import os
|
||||
|
||||
class MyApp:
|
||||
def __init__(self, configfile = '/etc/mac2hostname.ini'):
|
||||
if not os.path.isfile(configfile):
|
||||
print "Cannot find main file, %s. Exiting." % configfile
|
||||
sys.exit(1)
|
||||
|
||||
# Loads configurations
|
||||
config = ConfigParser()
|
||||
config.read(configfile)
|
||||
# Populates private properties with configuration
|
||||
self.__dbfile = config.get('Daemon', 'Database') if config.has_option('Daemon', 'Database') else '/var/lib/doraemon/doraemon.db'
|
||||
self.__logdir = config.get('Daemon', 'LogFile') if config.has_option('Daemon', 'LogFile') else '/var/log/doraemon.log'
|
||||
self.__pidfile = config.get('Daemon', 'PIDFile') if config.has_option('Daemon', 'PIDFile') else '/var/run/doraemon.pid'
|
||||
self.__bindaddress = config.get('Daemon', 'BindAddress') if config.has_option('Daemon', 'BindAddress') else '127.0.0.1'
|
||||
self.__port = config.getint('Daemon', 'Port') if config.has_option('Daemon',
|
||||
'Port') else 8080
|
||||
self.__defaultbase = config.get('NameSettings', 'Base') if config.has_option('NameSettings', 'Base') else 'client'
|
||||
self.__defaultrole = config.get('NameSettings', 'Role') if config.has_option('NameSettings', 'Role') else 'client'
|
||||
self.__namedigits = config.get('NameSettings', 'Digits') if config.has_option('NameSettings', 'Digits') else '2'
|
||||
self.__domainfile = config.get('Files', 'Domain') if config.has_option('Files', 'Domain') else None
|
||||
self.__mgmtfile = config.get('Files', 'MgmtKey') if config.has_option('Files', 'MgmtKey') else None
|
||||
self.__vaultpassfile = config.get('Files', 'VaultPassFile') if config.has_option('Files', 'VaultPassFile') else None
|
||||
self.__app = Bottle()
|
||||
# Applies routes
|
||||
self.__route()
|
||||
# Assures table creation
|
||||
self.__init_tables()
|
||||
|
||||
@contextmanager
|
||||
def __getcursor(self):
|
||||
with connect(self.__dbfile) as connection:
|
||||
with closing(connection.cursor()) as cursor:
|
||||
yield cursor
|
||||
|
||||
# Private methods
|
||||
def __route(self):
|
||||
self.__app.get('/mac2hostname', callback=self.mac2hostname)
|
||||
self.__app.get('/whatsmyhostname', callback=self.whatsmyhostname)
|
||||
self.__app.get('/hosts', callback=self.hosts)
|
||||
self.__app.get('/domain', callback=self.domain)
|
||||
self.__app.get('/mgmtkey', callback=self.mgmtkey)
|
||||
self.__app.get('/vaultpass', callback=self.vaultpass)
|
||||
self.__app.get('/ansible_list', callback=self.ansible_list)
|
||||
self.__app.get('/ansible_host', callback=self.ansible_host)
|
||||
self.__app.get('/epoptes-srv', callback=self.epoptes_srv)
|
||||
|
||||
def __init_tables(self):
|
||||
with self.__getcursor() as cursor:
|
||||
cursor.execute('CREATE TABLE IF NOT EXISTS client (id INT PRIMARY KEY,'
|
||||
'hostname TEXT NOT NULL UNIQUE, mac TEXT UNIQUE, role TEXT)')
|
||||
cursor.execute('CREATE INDEX IF NOT EXISTS idxmac ON client(mac)')
|
||||
|
||||
def __getmac(self, ip):
|
||||
Popen(['ping', '-c1', '-t2', ip], stdout=PIPE).communicate()
|
||||
arp = Popen(['arp', '-n', ip], stdout=PIPE).communicate()[0]
|
||||
return re.search(r'(([\da-fA-F]{1,2}\:){5}[\da-fA-F]{1,2})', arp).group(1).lower()
|
||||
|
||||
def __normalizemac(self, mac):
|
||||
return ':'.join(x.zfill(2) for x in mac.split('_')).lower()
|
||||
|
||||
def __gethostname(self, mac, base = None, role = None):
|
||||
if base == None:
|
||||
base = self.__defaultbase
|
||||
if role == None:
|
||||
role = self.__defaultrole
|
||||
|
||||
with self.__getcursor() as cursor:
|
||||
(newid,) = cursor.execute('SELECT COALESCE(MAX(id) + 1, 1) FROM client').fetchone()
|
||||
# Constucts the hostname format
|
||||
formatstring = '%s-%0' + self.__namedigits + 'd'
|
||||
data = (newid, formatstring % (base, newid), mac, role)
|
||||
# Since MAC is Unique, this fails with the same MAC address
|
||||
cursor.execute('INSERT OR IGNORE INTO client VALUES (?, ?, ?, ?)', data)
|
||||
(hostname,) = cursor.execute('SELECT hostname FROM client WHERE mac = "%s"' % mac).fetchone()
|
||||
return hostname
|
||||
|
||||
# This should be used only after registration of the client
|
||||
# (whatsmyhostname)
|
||||
def __getrole(self):
|
||||
macaddress = self.__normalizemac(self.__getmac(request['REMOTE_ADDR']))
|
||||
hostname = self.__gethostname(macaddress)
|
||||
|
||||
with self.__getcursor() as cursor:
|
||||
(role,) = cursor.execute("SELECT role FROM client WHERE hostname = '%s' AND mac = '%s'" % (hostname, macaddress)).fetchone()
|
||||
return role
|
||||
|
||||
# Variables returned to the client
|
||||
def __rolevars(self, role=None):
|
||||
retval = {'role': role, 'addpkg': [], 'delpkg': []}
|
||||
try:
|
||||
db = Popen(['/sbin/e-smith/db', 'roles', 'getjson'], stdout=PIPE).communicate()[0]
|
||||
for data in json.loads(db):
|
||||
if data['name'] == role:
|
||||
retval['addpkg'] = re.split(r'[\s,;]+', data['props']['Addpkg'])
|
||||
retval['delpkg'] = re.split(r'[\s,;]+', data['props']['Delpkg'])
|
||||
continue
|
||||
except: pass
|
||||
return retval
|
||||
|
||||
# Instance methods AKA routes
|
||||
def mac2hostname(self):
|
||||
# Ensure required parameters have been passed
|
||||
if not request.query.mac:
|
||||
return "Usage: GET /mac2hostname?mac=XX_XX_XX_XX_XX_XX[&base=YYY][&role=ZZZ]"
|
||||
# Sets up variables for possible parameters
|
||||
mac = self.__normalizemac(request.query.mac)
|
||||
base = request.query.base or self.__defaultbase
|
||||
role = request.query.role or self.__defaultrole
|
||||
return self.__gethostname(mac, base, role)
|
||||
|
||||
def whatsmyhostname(self):
|
||||
# No required parameters
|
||||
ip = request.query.ip or request['REMOTE_ADDR']
|
||||
base = request.query.base or self.__defaultbase
|
||||
role = request.query.role or self.__defaultrole
|
||||
return self.__gethostname(self.__getmac(ip), base, role)
|
||||
|
||||
def hosts(self):
|
||||
# Default where clause: no where specifications
|
||||
where = ''
|
||||
# If a role parameter is passed, list the hosts for that role
|
||||
if request.query.role:
|
||||
where = "WHERE role = '%s'" % request.query.role
|
||||
with self.__getcursor() as cursor:
|
||||
return dumps([dict((meta[0], data)
|
||||
for meta, data in zip(cursor.description, row))
|
||||
for row in cursor.execute('SELECT role, hostname, mac FROM client '
|
||||
+ where + 'ORDER BY role ASC, hostname ASC')], indent=4)
|
||||
|
||||
def domain(self):
|
||||
with open(self.__domainfile, 'r') as f:
|
||||
return f.read()
|
||||
|
||||
def mgmtkey(self):
|
||||
with open(self.__mgmtfile, 'r') as f:
|
||||
return f.read()
|
||||
|
||||
def vaultpass(self):
|
||||
with open(self.__vaultpassfile, 'r') as f:
|
||||
ip = request.query.ip or request['REMOTE_ADDR']
|
||||
base = request.query.base or self.__defaultbase
|
||||
role = request.query.role or self.__defaultrole
|
||||
hostname = self.__gethostname(self.__getmac(ip), base, role)
|
||||
# Encryption key
|
||||
key = MD5.new(hostname).digest()
|
||||
# Secret
|
||||
secret = f.read().strip()
|
||||
# Creating a secret that is multiple of 16 in length
|
||||
i = 16 - (len(secret) % 16)
|
||||
lengthy_secret = secret + i * 'x'
|
||||
cipher = AES.new(key, AES.MODE_ECB)
|
||||
crypted = cipher.encrypt(lengthy_secret)
|
||||
# Encode in base64 because of unicode strings
|
||||
return base64.b64encode(crypted)
|
||||
|
||||
def ansible_list(self):
|
||||
# Faking calls
|
||||
if request.query.role:
|
||||
role = request.query.role
|
||||
else:
|
||||
role = self.__getrole()
|
||||
|
||||
result = {
|
||||
'localhost': {
|
||||
'hosts': [ 'localhost' ],
|
||||
'vars': {
|
||||
'ansible_connection': 'local'
|
||||
}
|
||||
},
|
||||
'_meta': {
|
||||
'hostvars': {
|
||||
'localhost': self.__rolevars(role)
|
||||
}
|
||||
}
|
||||
}
|
||||
return dumps(result)
|
||||
|
||||
def ansible_host(self):
|
||||
# Ignoring 'host' parameter, since it should always be 'localhost'.
|
||||
# Instead, for testing purposes, if asked for a role, use it
|
||||
if request.query.role:
|
||||
role = request.query.role
|
||||
else:
|
||||
role = self.__getrole()
|
||||
return dumps(self.__rolevars(role))
|
||||
|
||||
def epoptes_srv(self):
|
||||
hostname = None
|
||||
try:
|
||||
with self.__getcursor() as cursor:
|
||||
(hostname,) = cursor.execute('SELECT hostname FROM client WHERE role = \'docenti\' ORDER BY id DESC LIMIT 1').fetchone()
|
||||
except TypeError:
|
||||
return 'none'
|
||||
|
||||
return hostname
|
||||
|
||||
def start(self):
|
||||
# Opens up a PID file
|
||||
pid = os.getpid()
|
||||
pidfile = open(self.__pidfile, 'w')
|
||||
pidfile.write('%s' % pid)
|
||||
pidfile.close()
|
||||
|
||||
# Runs Bottle, at last.
|
||||
self.__app.run(host=self.__bindaddress, port=self.__port)
|
||||
|
||||
# Main body
|
||||
if __name__ == '__main__':
|
||||
cfgfile = '/etc/doraemon.ini'
|
||||
if len(sys.argv) > 1:
|
||||
cfgfile = sys.argv[1]
|
||||
app = MyApp(cfgfile)
|
||||
app.start()
|
172
doraemon.spec
172
doraemon.spec
@ -1,165 +1,85 @@
|
||||
Summary: Helps client to join domain and maintain itself
|
||||
Name: doraemon
|
||||
Version: 2.0.4
|
||||
Release: 1.ns6
|
||||
Version: 1.2.1
|
||||
Release: 2.ns6
|
||||
URL: https://github.com/bglug-it/doraemon/
|
||||
License: GPLv2+
|
||||
Packager: Paolo Asperti <paolo@asperti.com>
|
||||
Group: System Environment/Daemons
|
||||
BuildRoot: %{_tmppath}/%{name}-root
|
||||
BuildRequires: nethserver-devtools > 1.0.1
|
||||
BuildRequires: hunspell-en
|
||||
Requires: httpd, php, sudo, php-xml, php-mcrypt
|
||||
Requires: nethserver-base, nethserver-php
|
||||
Requires: net-tools
|
||||
Requires: upstart
|
||||
Source0: %{name}-%{version}.tar.gz
|
||||
Requires: python python-bottle python-crypto2.6 nethserver-base
|
||||
Requires(post): chkconfig nethserver-base
|
||||
Requires(preun): chkconfig initscripts nethserver-base
|
||||
Source0: doraemon-1.2.1.tar.gz
|
||||
BuildArch: noarch
|
||||
|
||||
%description
|
||||
Helps client on a domain network to get information for its maintenance.
|
||||
|
||||
%prep
|
||||
%setup
|
||||
%setup -q
|
||||
|
||||
%build
|
||||
%{makedocs}
|
||||
perl createlinks.pl
|
||||
|
||||
%install
|
||||
rm -Rf $RPM_BUILD_ROOT
|
||||
(cd root ; find . -depth -print | cpio -dump %{buildroot})
|
||||
rm -f %{name}-%{version}-%{release}-filelist
|
||||
%{genfilelist} %{buildroot} > %{name}-%{version}-%{release}-filelist
|
||||
mkdir -p %{buildroot}%{_localstatedir}/log/doraemon
|
||||
mkdir -p %{buildroot}%{_localstatedir}/cache/doraemon
|
||||
|
||||
|
||||
%pre
|
||||
#if [ "$1" = 1 ]; then
|
||||
# #installation
|
||||
#fi
|
||||
if [ "$1" = 2 ]; then
|
||||
#upgrade
|
||||
/sbin/service %{name} stop >/dev/null 2>&1 || :
|
||||
/sbin/stop %{name} >/dev/null 2>&1 || :
|
||||
DATABASE=/var/lib/doraemon/doraemon.db
|
||||
INI=/etc/doraemon.ini
|
||||
if [ -f $INI ]; then
|
||||
DATABASE=$(awk -F "=" '/Database/ {print $2}' $INI)
|
||||
PORT=$(awk -F "=" '/Port/ {print $2}' $INI)
|
||||
BASE=$(awk -F "=" '/Base/ {print $2}' $INI)
|
||||
ROLE=$(awk -F "=" '/Role/ {print $2}' $INI)
|
||||
DIGITS=$(awk -F "=" '/Digits/ {print $2}' $INI)
|
||||
DOMAIN=$(awk -F "=" '/Domain/ {print $2}' $INI)
|
||||
MGMTKEY=$(awk -F "=" '/MgmtKey/ {print $2}' $INI)
|
||||
VAULTPASSFILE=$(awk -F "=" '/VaultPassFile/ {print $2}' $INI)
|
||||
rm $INI
|
||||
/sbin/e-smith/db configuration set %{name} service \
|
||||
status enabled \
|
||||
TCPPort $PORT \
|
||||
access private \
|
||||
DefaultRole $ROLE \
|
||||
DomainFile $DOMAIN \
|
||||
ManagementKeyFile $MGMTKEY \
|
||||
NamingBase $BASE \
|
||||
NamingDigits $DIGITS \
|
||||
VaultPassFile $VAULTPASSFILE
|
||||
else
|
||||
/sbin/e-smith/db configuration set %{name} service \
|
||||
status enabled \
|
||||
TCPPort 3000 \
|
||||
access private \
|
||||
DefaultRole client \
|
||||
DomainFile /etc/domain.yml \
|
||||
ManagementKeyFile /home/amgmt/.ssh/id_rsa.pub \
|
||||
NamingBase lab \
|
||||
NamingDigits 2 \
|
||||
VaultPassFile /home/amgmt/.ansible/vault.txt
|
||||
fi
|
||||
if [ -f $DATABASE ]; then
|
||||
sqlite3 -separator " " $DATABASE \
|
||||
"select * from client" | while read id hostname mac role; do
|
||||
/sbin/e-smith/db hosts set $hostname local \
|
||||
MacAddress $mac Role $role
|
||||
done
|
||||
rm $DATABASE
|
||||
fi
|
||||
fi
|
||||
rm -rf %{buildroot}
|
||||
install -d %{buildroot}
|
||||
install -d -m 755 %{buildroot}%{_sysconfdir}
|
||||
install -m 644 doraemon.ini %{buildroot}%{_sysconfdir}/%{name}.ini
|
||||
# Installo il servizio
|
||||
install -d -m 755 %{buildroot}%{_initrddir}
|
||||
install -m 755 initrd %{buildroot}%{_initrddir}/%{name}
|
||||
# Installo lo script vero e proprio
|
||||
install -d -m 755 %{buildroot}%{_bindir}
|
||||
install -m 755 doraemon.py %{buildroot}%{_bindir}/%{name}.py
|
||||
# Cartella del database
|
||||
install -d %{buildroot}%{_sharedstatedir}/%{name}
|
||||
# File per il rotate
|
||||
install -d %{buildroot}%{_sysconfdir}/logrotate.d
|
||||
install -m 644 doraemon.logrotate %{buildroot}%{_sysconfdir}/logrotate.d/%{name}
|
||||
# File di Nethserver
|
||||
install -d %{buildroot}%{_sysconfdir}/e-smith/db/configuration/defaults/%{name}
|
||||
install -m 644 type %{buildroot}%{_sysconfdir}/e-smith/db/configuration/defaults/%{name}/type
|
||||
install -m 644 status %{buildroot}%{_sysconfdir}/e-smith/db/configuration/defaults/%{name}/status
|
||||
install -m 644 access %{buildroot}%{_sysconfdir}/e-smith/db/configuration/defaults/%{name}/access
|
||||
install -m 644 TCPPort %{buildroot}%{_sysconfdir}/e-smith/db/configuration/defaults/%{name}/TCPPort
|
||||
|
||||
%post
|
||||
/etc/e-smith/events/actions/initialize-default-databases
|
||||
[ -e /usr/sbin/doraemon ] && [ ! -L /usr/sbin/doraemon ] && rm /usr/sbin/doraemon
|
||||
[ ! -L /usr/sbin/doraemon ] && ln -s httpd /usr/sbin/doraemon
|
||||
if [ "$1" = 1 ]; then
|
||||
#installation
|
||||
/sbin/e-smith/db configuration set %{name} service status enabled TCPPort 3000 access private DefaultRole client DomainFile /etc/domain.yml ManagementKeyFile /home/amgmt/.ssh/id_rsa.pub NamingBase lab NamingDigits 2 VaultPassFile /home/amgmt/.ansible/vault.txt
|
||||
/sbin/e-smith/expand-template /etc/sudoers
|
||||
/sbin/e-smith/expand-template /etc/httpd/doraemon/httpd.conf
|
||||
/sbin/start %{name} >/dev/null 2>&1 || :
|
||||
/sbin/chkconfig --add %{name}
|
||||
/sbin/service %{name} start >/dev/null 2>&1
|
||||
/sbin/e-smith/db configuration set %{name} service status enabled TCPPort 3000 access private
|
||||
/sbin/e-smith/signal-event runlevel-adjust
|
||||
/sbin/e-smith/signal-event firewall-adjust
|
||||
fi
|
||||
if [ "$1" = 2 ]; then
|
||||
#upgrade
|
||||
# TODO: this won't be needed in the next version
|
||||
/sbin/e-smith/expand-template /etc/sudoers
|
||||
/sbin/e-smith/expand-template /etc/httpd/doraemon/httpd.conf
|
||||
/sbin/start %{name} >/dev/null 2>&1 || :
|
||||
/sbin/e-smith/signal-event runlevel-adjust
|
||||
/sbin/e-smith/signal-event firewall-adjust
|
||||
fi
|
||||
|
||||
|
||||
%preun
|
||||
#if [ "$1" = 1 ]; then
|
||||
# #upgrade
|
||||
#fi
|
||||
if [ "$1" = 0 ]; then
|
||||
#uninstallation
|
||||
/sbin/stop %{name} >/dev/null 2>&1 || :
|
||||
fi
|
||||
|
||||
|
||||
%postun
|
||||
#if [ "$1" = 1 ]; then
|
||||
# #upgrade
|
||||
#fi
|
||||
if [ "$1" = 0 ]; then
|
||||
#uninstallation
|
||||
/sbin/e-smith/db configuration delete %{name}
|
||||
/sbin/e-smith/expand-template /etc/sudoers
|
||||
/sbin/service %{name} stop >/dev/null 2>&1
|
||||
chkconfig --del %{name}
|
||||
/sbin/e-smith/signal-event runlevel-adjust
|
||||
/sbin/e-smith/signal-event firewall-adjust
|
||||
fi
|
||||
|
||||
|
||||
%clean
|
||||
rm -rf %{buildroot}
|
||||
|
||||
%files -f %{name}-%{version}-%{release}-filelist
|
||||
%defattr(0644,root,root,755)
|
||||
%doc README.md LICENSE.txt
|
||||
%attr(0644,srvmgr,srvmgr) %ghost %{_localstatedir}/log/doraemon/access_log
|
||||
%attr(0644,srvmgr,srvmgr) %ghost %{_localstatedir}/log/doraemon/error_log
|
||||
%files
|
||||
%defattr(644,root,root,755)
|
||||
%doc README.md LICENSE
|
||||
%config(noreplace) %{_sysconfdir}/%{name}.ini
|
||||
%attr(755,-,-) %{_initrddir}/%{name}
|
||||
%attr(755,-,-) %{_bindir}/%{name}.py
|
||||
|
||||
%dir %attr(755,-,-) %{_sharedstatedir}/%{name}
|
||||
%{_sysconfdir}/logrotate.d/%{name}
|
||||
%dir %attr(755,-,-) %{_sysconfdir}/e-smith/db/configuration/defaults/%{name}
|
||||
%{_sysconfdir}/e-smith/db/configuration/defaults/%{name}/status
|
||||
%{_sysconfdir}/e-smith/db/configuration/defaults/%{name}/type
|
||||
%{_sysconfdir}/e-smith/db/configuration/defaults/%{name}/access
|
||||
%{_sysconfdir}/e-smith/db/configuration/defaults/%{name}/TCPPort
|
||||
|
||||
%changelog
|
||||
* Sun Jun 17 2018 Emiliano Vavassori <syntaxerrormmm-AT-gmail.com> - 2.0.4-1
|
||||
- FIX: Doraemon doesn't start after installation
|
||||
|
||||
* Sun Jun 17 2018 Emiliano Vavassori <syntaxerrormmm-AT-gmail.com> - 2.0.3-1
|
||||
- FIX: whatsmyhostname correctly parse role variable
|
||||
- Minor aesthetic syntax fixes
|
||||
|
||||
* Sun Oct 8 2017 Paolo Asperti <paolo@asperti.com> - 2.0.2-1
|
||||
- FIX: bug in WOL
|
||||
- FIX: small language typos
|
||||
|
||||
* Wed Nov 9 2016 Paolo Asperti <paolo@asperti.com> - 2.0.1-1
|
||||
- PHP porting
|
||||
- Added a basic UI
|
||||
|
||||
* Tue Oct 27 2015 Emiliano Vavassori <syntaxerrormmm-AT-gmail.com> - 1.2.1-2.ns6
|
||||
- Packing corrections to rpm to fix upgrading issue
|
||||
|
||||
|
79
initrd
Normal file
79
initrd
Normal file
@ -0,0 +1,79 @@
|
||||
#!/bin/sh
|
||||
|
||||
# chkconfig: 2345 20 80
|
||||
# description: Manage assignation of hostnames for clients
|
||||
# pidfile: /var/run/doraemon.pid
|
||||
# config: /etc/doraemon.ini
|
||||
|
||||
### BEGIN INIT INFO
|
||||
# Provides: doraemon
|
||||
# Required-Start: $remote_fs $syslog
|
||||
# Required-Stop: $remote_fs $syslog
|
||||
# Default-Start: 2 3 4 5
|
||||
# Default-Stop: 0 1 6
|
||||
# Short-Description: Helps client to join the domain and maintain itself
|
||||
# Description: Helps client to join the domain and maintain itself
|
||||
### END INIT INFO
|
||||
|
||||
# Change the next 3 lines to suit where you install your script and what you want to call it
|
||||
DAEMON=/usr/bin/doraemon.py
|
||||
DAEMON_NAME=doraemon
|
||||
|
||||
# Add any command line options for your daemon here
|
||||
DAEMON_OPTS=""
|
||||
|
||||
# This next line determines what user the script runs as.
|
||||
# Root generally not recommended but necessary if you are using the Raspberry Pi GPIO from Python.
|
||||
#DAEMON_USER=mac2hostname
|
||||
#DAEMON_GROUP=mac2hostname
|
||||
|
||||
# The process ID of the script when it runs is stored here:
|
||||
LOGFILE=/var/log/$DAEMON_NAME.log
|
||||
PIDFILE=/var/run/$DAEMON_NAME.pid
|
||||
lockfile=/var/lock/subsys/$DAEMON_NAME
|
||||
|
||||
. /etc/rc.d/init.d/functions
|
||||
. /etc/sysconfig/network
|
||||
|
||||
[ "$NETWORKING" = "no" ] && exit 0
|
||||
|
||||
do_start () {
|
||||
echo -n $"Starting $DAEMON_NAME: "
|
||||
daemon --pidfile=$PIDFILE "python $DAEMON >>$LOGFILE 2>/dev/null &"
|
||||
RETVAL=$?
|
||||
echo
|
||||
[ $RETVAL -eq 0 ] && touch $lockfile
|
||||
return $RETVAL
|
||||
}
|
||||
|
||||
do_stop () {
|
||||
echo -n $"Stopping $DAEMON_NAME: "
|
||||
killproc -p $PIDFILE python
|
||||
RETVAL=$?
|
||||
echo
|
||||
[ $RETVAL -eq 0 ] && rm -f $lockfile
|
||||
return $RETVAL
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
|
||||
start|stop)
|
||||
do_${1}
|
||||
;;
|
||||
|
||||
restart|reload|force-reload)
|
||||
do_stop
|
||||
do_start
|
||||
;;
|
||||
|
||||
status)
|
||||
status -p $PIDFILE python
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "Usage: /etc/init.d/$DAEMON_NAME {start|stop|restart|status}"
|
||||
exit 1
|
||||
;;
|
||||
|
||||
esac
|
||||
exit 0
|
@ -1 +0,0 @@
|
||||
client
|
@ -1 +0,0 @@
|
||||
/etc/domain.yml
|
@ -1 +0,0 @@
|
||||
/home/amgmt/.ssh/id_rsa.pub
|
@ -1 +0,0 @@
|
||||
lab
|
@ -1 +0,0 @@
|
||||
/home/amgmt/.ansible/vault.txt
|
@ -1 +0,0 @@
|
||||
public
|
@ -1,34 +0,0 @@
|
||||
#!/usr/bin/perl -w
|
||||
|
||||
package esmith;
|
||||
|
||||
use strict;
|
||||
use Errno;
|
||||
use esmith::DB::db;
|
||||
use IO::File;
|
||||
use English;
|
||||
|
||||
my $db_hosts = esmith::DB::db->open('hosts') || die("Could not open e-smith db (" . esmith::DB::db->error . ")\n");
|
||||
|
||||
my $event = $ARGV[0];
|
||||
|
||||
defined $ARGV[1] || die "No host specified";
|
||||
my $host = $ARGV[1];
|
||||
|
||||
reboot_host($host);
|
||||
|
||||
exit 0;
|
||||
|
||||
sub reboot_host
|
||||
{
|
||||
my ($hostName) = @_;
|
||||
#------------------------------------------------------------
|
||||
# Reboot the host
|
||||
#------------------------------------------------------------
|
||||
|
||||
my $h = $db_hosts->get($hostName) or die "No host record for $hostName";
|
||||
|
||||
system("/usr/bin/sudo -u amgmt /usr/bin/ssh -o StrictHostKeyChecking=no amgmt\@$hostName /usr/bin/sudo /sbin/reboot") == 0
|
||||
or die "Error rebooting $hostName";
|
||||
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
#!/usr/bin/perl -w
|
||||
|
||||
package esmith;
|
||||
|
||||
use strict;
|
||||
use Errno;
|
||||
use esmith::DB::db;
|
||||
use IO::File;
|
||||
use English;
|
||||
|
||||
my $db_hosts = esmith::DB::db->open('hosts') || die("Could not open e-smith db (" . esmith::DB::db->error . ")\n");
|
||||
|
||||
my @items = $db_hosts->get_all('local');
|
||||
foreach my $item (@items) {
|
||||
my $hostName = $item->key;
|
||||
system("/usr/bin/sudo -u amgmt /usr/bin/ssh -o StrictHostKeyChecking=no amgmt\@$hostName /usr/bin/sudo /sbin/reboot &") == 0
|
||||
or die "Error rebooting $hostName";
|
||||
}
|
||||
|
||||
exit 0;
|
@ -1,34 +0,0 @@
|
||||
#!/usr/bin/perl -w
|
||||
|
||||
package esmith;
|
||||
|
||||
use strict;
|
||||
use Errno;
|
||||
use esmith::DB::db;
|
||||
use IO::File;
|
||||
use English;
|
||||
|
||||
my $db_hosts = esmith::DB::db->open('hosts') || die("Could not open e-smith db (" . esmith::DB::db->error . ")\n");
|
||||
|
||||
my $event = $ARGV[0];
|
||||
|
||||
defined $ARGV[1] || die "No host specified";
|
||||
my $host = $ARGV[1];
|
||||
|
||||
shutdown_host($host);
|
||||
|
||||
exit 0;
|
||||
|
||||
sub shutdown_host
|
||||
{
|
||||
my ($hostName) = @_;
|
||||
#------------------------------------------------------------
|
||||
# Shutdown the host
|
||||
#------------------------------------------------------------
|
||||
|
||||
my $h = $db_hosts->get($hostName) or die "No host record for $hostName";
|
||||
|
||||
system("/usr/bin/sudo -u amgmt /usr/bin/ssh -o StrictHostKeyChecking=no amgmt\@$hostName /usr/bin/sudo /sbin/poweroff") == 0
|
||||
or die "Error shutting down $hostName";
|
||||
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
#!/usr/bin/perl -w
|
||||
|
||||
package esmith;
|
||||
|
||||
use strict;
|
||||
use Errno;
|
||||
use esmith::DB::db;
|
||||
use IO::File;
|
||||
use English;
|
||||
|
||||
my $db_hosts = esmith::DB::db->open('hosts') || die("Could not open e-smith db (" . esmith::DB::db->error . ")\n");
|
||||
|
||||
my @items = $db_hosts->get_all('local');
|
||||
foreach my $item (@items) {
|
||||
my $hostName = $item->key;
|
||||
system("/usr/bin/sudo -u amgmt /usr/bin/ssh -o StrictHostKeyChecking=no amgmt\@$hostName /usr/bin/sudo /sbin/poweroff &") == 0
|
||||
or die "Error shutting down $hostName";
|
||||
}
|
||||
|
||||
exit 0;
|
@ -1,35 +0,0 @@
|
||||
#!/usr/bin/perl -w
|
||||
|
||||
package esmith;
|
||||
|
||||
use strict;
|
||||
use Errno;
|
||||
use esmith::DB::db;
|
||||
use IO::File;
|
||||
use English;
|
||||
|
||||
my $db_hosts = esmith::DB::db->open('hosts') || die("Could not open e-smith db (" . esmith::DB::db->error . ")\n");
|
||||
|
||||
my $event = $ARGV[0];
|
||||
|
||||
defined $ARGV[1] || die "No host specified";
|
||||
my $host = $ARGV[1];
|
||||
|
||||
wake_host($host);
|
||||
|
||||
exit 0;
|
||||
|
||||
sub wake_host
|
||||
{
|
||||
my ($hostName) = @_;
|
||||
#------------------------------------------------------------
|
||||
# Wake up the host
|
||||
#------------------------------------------------------------
|
||||
|
||||
my @h = $db_hosts->get($hostName) or die "No host record for $hostName";
|
||||
my $client = $h[0];
|
||||
my $mac = $client->prop('MacAddress');
|
||||
system("/sbin/ether-wake -b -i lan0 $mac") == 0
|
||||
or die "Error waking up $hostName";
|
||||
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
#!/usr/bin/perl -w
|
||||
|
||||
package esmith;
|
||||
|
||||
use strict;
|
||||
use Errno;
|
||||
use esmith::DB::db;
|
||||
use IO::File;
|
||||
use English;
|
||||
|
||||
my $db_hosts = esmith::DB::db->open('hosts') || die("Could not open e-smith db (" . esmith::DB::db->error . ")\n");
|
||||
|
||||
my @items = $db_hosts->get_all('local');
|
||||
foreach my $item (@items) {
|
||||
my $hostName = $item->key;
|
||||
my $mac = $item->prop('MacAddress');
|
||||
system("/sbin/ether-wake -b -i lan0 $mac &") == 0
|
||||
or die "Error waking up $hostName";
|
||||
}
|
||||
|
||||
exit 0;
|
@ -1 +0,0 @@
|
||||
../actions/doraemon-reboot-all
|
@ -1 +0,0 @@
|
||||
../actions/doraemon-reboot
|
@ -1 +0,0 @@
|
||||
../actions/doraemon-shutdown-all
|
@ -1 +0,0 @@
|
||||
../actions/doraemon-shutdown
|
@ -1 +0,0 @@
|
||||
../actions/doraemon-wake-all
|
@ -1 +0,0 @@
|
||||
../actions/doraemon-wake
|
@ -1,3 +0,0 @@
|
||||
TEMPLATE_PATH='upstart-job'
|
||||
OUTPUT_FILENAME='/etc/init/doraemon.conf'
|
||||
MORE_DATA={ name => 'doraemon', description => 'Apache instance that runs the doraemon service', author => 'Paolo Asperti <paolo@asperti.com>', daemon_bin => '/usr/sbin/doraemon', daemon_args => '-f /etc/httpd/doraemon/httpd.conf', respawn => 1, 'expect' => 'fork', stop_on => 'stopping network', start_on => 'started network' }
|
@ -1,10 +0,0 @@
|
||||
{
|
||||
#
|
||||
# 00template_defaults
|
||||
#
|
||||
|
||||
$localAccess = '';
|
||||
$port = ${'doraemon'}{TCPPort} || "3000";
|
||||
|
||||
"";
|
||||
}
|
@ -1,127 +0,0 @@
|
||||
{
|
||||
|
||||
$OUT .= <<HERE;
|
||||
Listen $port
|
||||
HostnameLookups off
|
||||
|
||||
ServerAdmin root@$DomainName
|
||||
ServerRoot /etc/httpd
|
||||
ServerTokens ProductOnly
|
||||
|
||||
User srvmgr
|
||||
Group srvmgr
|
||||
|
||||
ErrorLog /var/log/doraemon/error_log
|
||||
LogLevel warn
|
||||
HERE
|
||||
|
||||
foreach (qw(
|
||||
env
|
||||
log_config
|
||||
mime
|
||||
negotiation
|
||||
include
|
||||
autoindex
|
||||
dir
|
||||
alias
|
||||
rewrite
|
||||
access
|
||||
authz_host
|
||||
expires
|
||||
headers
|
||||
setenvif
|
||||
ssl
|
||||
))
|
||||
{
|
||||
next unless -f "/usr/lib/httpd/modules/mod_${_}.so" ||
|
||||
-f "/usr/lib64/httpd/modules/mod_${_}.so";
|
||||
$OUT .= "LoadModule ${_}_module modules/mod_${_}.so\n";
|
||||
}
|
||||
|
||||
$OUT .= <<HERE;
|
||||
PidFile /var/run/doraemon.pid
|
||||
ScoreBoardFile /var/run/doraemon.scoreboard
|
||||
UseCanonicalName off
|
||||
LogFormat "%h %l %u %t \\"%r\\" %>s %b" common
|
||||
LogFormat "%{User-agent}i" agent
|
||||
|
||||
CustomLog /var/log/doraemon/access_log common
|
||||
|
||||
KeepAlive On
|
||||
MaxKeepAliveRequests 100
|
||||
KeepAliveTimeout 15
|
||||
|
||||
MaxClients 150
|
||||
MaxRequestsPerChild 100
|
||||
|
||||
MinSpareServers 1
|
||||
MaxSpareServers 5
|
||||
StartServers 1
|
||||
Timeout 300
|
||||
|
||||
DefaultIcon /icons/unknown.gif
|
||||
DirectoryIndex index.htm index.html index.shtml index.cgi
|
||||
IndexOptions FancyIndexing VersionSort NameWidth=*
|
||||
IndexIgnore .??* *~ *# HEADER* README* RCS CVS *,v *,t
|
||||
AccessFileName .htaccess
|
||||
|
||||
AddIconByEncoding (CMP,/icons/compressed.gif) x-compress x-gzip
|
||||
AddIconByType (TXT,/icons/text.gif) text/*
|
||||
AddIconByType (IMG,/icons/image2.gif) image/*
|
||||
AddIconByType (SND,/icons/sound2.gif) audio/*
|
||||
AddIconByType (VID,/icons/movie.gif) video/*
|
||||
DefaultType text/plain
|
||||
TypesConfig /etc/mime.types
|
||||
|
||||
AddEncoding x-compress Z
|
||||
AddEncoding x-gzip gz
|
||||
|
||||
AddIcon /icons/binary.gif .bin .exe
|
||||
AddIcon /icons/binhex.gif .hqx
|
||||
AddIcon /icons/tar.gif .tar
|
||||
AddIcon /icons/world2.gif .wrl .wrl.gz .vrml .vrm .iv
|
||||
AddIcon /icons/compressed.gif .Z .z .tgz .gz .zip
|
||||
AddIcon /icons/a.gif .ps .ai .eps
|
||||
AddIcon /icons/layout.gif .html .shtml .htm .pdf
|
||||
AddIcon /icons/text.gif .txt
|
||||
AddIcon /icons/c.gif .c
|
||||
AddIcon /icons/p.gif .pl .py
|
||||
AddIcon /icons/f.gif .for
|
||||
AddIcon /icons/dvi.gif .dvi
|
||||
AddIcon /icons/uuencoded.gif .uu
|
||||
AddIcon /icons/script.gif .conf .sh .shar .csh .ksh .tcl
|
||||
AddIcon /icons/tex.gif .tex
|
||||
AddIcon /icons/bomb.gif core
|
||||
|
||||
AddIcon /icons/back.gif ..
|
||||
AddIcon /icons/hand.right.gif README
|
||||
AddIcon /icons/folder.gif ^^DIRECTORY^^
|
||||
AddIcon /icons/blank.gif ^^BLANKICON^^
|
||||
|
||||
AddLanguage en .en
|
||||
AddLanguage fr .fr
|
||||
AddLanguage de .de
|
||||
AddLanguage da .da
|
||||
AddLanguage el .el
|
||||
AddLanguage it .it
|
||||
|
||||
LanguagePriority en it de fr
|
||||
|
||||
AddType text/html .shtml
|
||||
AddType application/x-pkcs7-crl .crl
|
||||
|
||||
AddType application/x-x509-ca-cert .crt
|
||||
|
||||
BrowserMatch "Mozilla/2" nokeepalive
|
||||
BrowserMatch "MSIE 4\.0b2;" nokeepalive downgrade-1.0 force-response-1.0
|
||||
BrowserMatch "RealPlayer 4\.0" force-response-1.0
|
||||
BrowserMatch "Java/1\.0" force-response-1.0
|
||||
BrowserMatch "JDK/1\.0" force-response-1.0
|
||||
|
||||
AddHandler cgi-script .cgi
|
||||
AddHandler server-parsed .shtml
|
||||
AddHandler imap-file map
|
||||
|
||||
HERE
|
||||
}
|
||||
|
@ -1,16 +0,0 @@
|
||||
|
||||
# First, we configure the "default" to be a very restrictive set of
|
||||
# permissions.
|
||||
|
||||
<Directory />
|
||||
Options None
|
||||
AllowOverride None
|
||||
order deny,allow
|
||||
deny from all
|
||||
allow from none
|
||||
</Directory>
|
||||
|
||||
<Directory /var/www/icons>
|
||||
Allow from all
|
||||
</Directory>
|
||||
|
@ -1,23 +0,0 @@
|
||||
|
||||
DocumentRoot /usr/share/doraemon
|
||||
Alias /icons/ /var/www/icons/
|
||||
|
||||
<Directory /usr/share/doraemon/>
|
||||
Options +Indexes
|
||||
Order Deny,Allow
|
||||
Deny from all
|
||||
Allow from { $localAccess || 'all' }
|
||||
AddType application/x-httpd-php .php
|
||||
Options +FollowSymlinks
|
||||
RewriteEngine on
|
||||
RewriteBase /
|
||||
RewriteRule ^(js/|fonts/|css/|images/|icons/|.+\.php) - [PT,L]
|
||||
RewriteRule ^favicon.ico$ images/favicon.ico [L]
|
||||
RewriteRule ^(.*)$ index.php/$1 [L]
|
||||
php_value session.save_path /var/cache/doraemon
|
||||
php_flag magic_quotes_gpc off
|
||||
</Directory>
|
||||
|
||||
|
||||
|
||||
|
@ -1 +0,0 @@
|
||||
Include conf.d/php.conf
|
@ -1,15 +0,0 @@
|
||||
{
|
||||
$OUT = 'srvmgr ALL=NOPASSWD: /bin/cat ';
|
||||
|
||||
use esmith::ConfigDB;
|
||||
my $confdb = esmith::ConfigDB->open;
|
||||
my $backup = $confdb->get('doraemon') or die "No doraemon db entry found\n";
|
||||
my $VaultPassFile = $backup->prop('VaultPassFile') || '/home/amgmt/.ansible/vault.txt';
|
||||
my $ManagementKeyFile = $backup->prop('ManagementKeyFile') || '/home/amgmt/.ssh/id_rsa.pub';
|
||||
my $DomainFile = $backup->prop('DomainFile') || '/etc/domain.yml';
|
||||
|
||||
$OUT = 'srvmgr ALL=NOPASSWD: /bin/cat ' . $VaultPassFile . '
|
||||
srvmgr ALL=NOPASSWD: /bin/cat ' . $ManagementKeyFile .'
|
||||
srvmgr ALL=NOPASSWD: /bin/cat ' . $DomainFile;
|
||||
|
||||
}
|
@ -1,162 +0,0 @@
|
||||
# ================= DO NOT MODIFY THIS FILE =================
|
||||
#
|
||||
# Manual changes will be lost when this file is regenerated.
|
||||
#
|
||||
# Please read the developer's guide, which is available
|
||||
# at https://dev.nethesis.it/projects/nethserver/wiki/NethServer
|
||||
# original work from http://www.contribs.org/development/
|
||||
#
|
||||
# Copyright (C) 2013 Nethesis S.r.l.
|
||||
# http://www.nethesis.it - support@nethesis.it
|
||||
#
|
||||
Listen 3000
|
||||
HostnameLookups off
|
||||
|
||||
ServerAdmin root
|
||||
ServerRoot /etc/httpd
|
||||
ServerTokens ProductOnly
|
||||
|
||||
User srvmgr
|
||||
Group srvmgr
|
||||
|
||||
ErrorLog /var/log/doraemon/error_log
|
||||
LogLevel warn
|
||||
LoadModule env_module modules/mod_env.so
|
||||
LoadModule log_config_module modules/mod_log_config.so
|
||||
LoadModule mime_module modules/mod_mime.so
|
||||
LoadModule negotiation_module modules/mod_negotiation.so
|
||||
LoadModule include_module modules/mod_include.so
|
||||
LoadModule autoindex_module modules/mod_autoindex.so
|
||||
LoadModule dir_module modules/mod_dir.so
|
||||
LoadModule alias_module modules/mod_alias.so
|
||||
LoadModule rewrite_module modules/mod_rewrite.so
|
||||
LoadModule authz_host_module modules/mod_authz_host.so
|
||||
LoadModule expires_module modules/mod_expires.so
|
||||
LoadModule headers_module modules/mod_headers.so
|
||||
LoadModule setenvif_module modules/mod_setenvif.so
|
||||
LoadModule ssl_module modules/mod_ssl.so
|
||||
PidFile /var/run/doraemon.pid
|
||||
ScoreBoardFile /var/run/doraemon.scoreboard
|
||||
UseCanonicalName off
|
||||
LogFormat "%h %l %u %t \"%r\" %>s %b" common
|
||||
LogFormat "%{User-agent}i" agent
|
||||
|
||||
CustomLog /var/log/doraemon/access_log common
|
||||
|
||||
KeepAlive On
|
||||
MaxKeepAliveRequests 100
|
||||
KeepAliveTimeout 15
|
||||
|
||||
MaxClients 150
|
||||
MaxRequestsPerChild 100
|
||||
|
||||
MinSpareServers 1
|
||||
MaxSpareServers 5
|
||||
StartServers 1
|
||||
Timeout 300
|
||||
|
||||
DefaultIcon /icons/unknown.gif
|
||||
DirectoryIndex index.htm index.html index.shtml index.cgi
|
||||
IndexOptions FancyIndexing VersionSort NameWidth=*
|
||||
IndexIgnore .??* *~ *# HEADER* README* RCS CVS *,v *,t
|
||||
AccessFileName .htaccess
|
||||
|
||||
AddIconByEncoding (CMP,/icons/compressed.gif) x-compress x-gzip
|
||||
AddIconByType (TXT,/icons/text.gif) text/*
|
||||
AddIconByType (IMG,/icons/image2.gif) image/*
|
||||
AddIconByType (SND,/icons/sound2.gif) audio/*
|
||||
AddIconByType (VID,/icons/movie.gif) video/*
|
||||
DefaultType text/plain
|
||||
TypesConfig /etc/mime.types
|
||||
|
||||
AddEncoding x-compress Z
|
||||
AddEncoding x-gzip gz
|
||||
|
||||
AddIcon /icons/binary.gif .bin .exe
|
||||
AddIcon /icons/binhex.gif .hqx
|
||||
AddIcon /icons/tar.gif .tar
|
||||
AddIcon /icons/world2.gif .wrl .wrl.gz .vrml .vrm .iv
|
||||
AddIcon /icons/compressed.gif .Z .z .tgz .gz .zip
|
||||
AddIcon /icons/a.gif .ps .ai .eps
|
||||
AddIcon /icons/layout.gif .html .shtml .htm .pdf
|
||||
AddIcon /icons/text.gif .txt
|
||||
AddIcon /icons/c.gif .c
|
||||
AddIcon /icons/p.gif .pl .py
|
||||
AddIcon /icons/f.gif .for
|
||||
AddIcon /icons/dvi.gif .dvi
|
||||
AddIcon /icons/uuencoded.gif .uu
|
||||
AddIcon /icons/script.gif .conf .sh .shar .csh .ksh .tcl
|
||||
AddIcon /icons/tex.gif .tex
|
||||
AddIcon /icons/bomb.gif core
|
||||
|
||||
AddIcon /icons/back.gif ..
|
||||
AddIcon /icons/hand.right.gif README
|
||||
AddIcon /icons/folder.gif ^^DIRECTORY^^
|
||||
AddIcon /icons/blank.gif ^^BLANKICON^^
|
||||
|
||||
AddLanguage en .en
|
||||
AddLanguage fr .fr
|
||||
AddLanguage de .de
|
||||
AddLanguage da .da
|
||||
AddLanguage el .el
|
||||
AddLanguage it .it
|
||||
|
||||
LanguagePriority en it de fr
|
||||
|
||||
AddType text/html .shtml
|
||||
AddType application/x-pkcs7-crl .crl
|
||||
|
||||
AddType application/x-x509-ca-cert .crt
|
||||
|
||||
BrowserMatch "Mozilla/2" nokeepalive
|
||||
BrowserMatch "MSIE 4.0b2;" nokeepalive downgrade-1.0 force-response-1.0
|
||||
BrowserMatch "RealPlayer 4.0" force-response-1.0
|
||||
BrowserMatch "Java/1.0" force-response-1.0
|
||||
BrowserMatch "JDK/1.0" force-response-1.0
|
||||
|
||||
AddHandler cgi-script .cgi
|
||||
AddHandler server-parsed .shtml
|
||||
AddHandler imap-file map
|
||||
|
||||
|
||||
|
||||
|
||||
# First, we configure the "default" to be a very restrictive set of
|
||||
# permissions.
|
||||
|
||||
<Directory />
|
||||
Options None
|
||||
AllowOverride None
|
||||
order deny,allow
|
||||
deny from all
|
||||
allow from none
|
||||
</Directory>
|
||||
|
||||
<Directory /var/www/icons>
|
||||
Allow from all
|
||||
</Directory>
|
||||
|
||||
|
||||
DocumentRoot /usr/share/doraemon
|
||||
Alias /icons/ /var/www/icons/
|
||||
|
||||
<Directory /usr/share/doraemon/>
|
||||
Options +Indexes
|
||||
Order Deny,Allow
|
||||
Deny from all
|
||||
Allow from all
|
||||
AddType application/x-httpd-php .php
|
||||
Options +FollowSymlinks
|
||||
RewriteEngine on
|
||||
RewriteBase /
|
||||
RewriteRule ^(js/|fonts/|css/|images/|icons/|.+\.php) - [PT,L]
|
||||
RewriteRule ^favicon.ico$ images/favicon.ico [L]
|
||||
RewriteRule ^(.*)$ index.php/$1 [L]
|
||||
php_value session.save_path /var/cache/doraemon
|
||||
php_flag magic_quotes_gpc off
|
||||
</Directory>
|
||||
|
||||
|
||||
|
||||
|
||||
Include conf.d/php.conf
|
@ -1,12 +0,0 @@
|
||||
#
|
||||
# doraemon-reload task
|
||||
#
|
||||
# Signals an Apache graceful restart for doraemon instance
|
||||
#
|
||||
|
||||
# service job, runs asynchronously
|
||||
|
||||
script
|
||||
sleep 5
|
||||
exec /usr/sbin/doraemon -f /etc/httpd/doraemon/httpd.conf -k graceful
|
||||
end script
|
@ -1,42 +0,0 @@
|
||||
# ================= DO NOT MODIFY THIS FILE =================
|
||||
#
|
||||
# Manual changes will be lost when this file is regenerated.
|
||||
#
|
||||
# Please read the developer's guide, which is available
|
||||
# at https://dev.nethesis.it/projects/nethserver/wiki/NethServer
|
||||
# original work from http://www.contribs.org/development/
|
||||
#
|
||||
# Copyright (C) 2013 Nethesis S.r.l.
|
||||
# http://www.nethesis.it - support@nethesis.it
|
||||
#
|
||||
#
|
||||
# 10base doraemon - Apache instance that runs the doraemon service
|
||||
#
|
||||
|
||||
description "Apache instance that runs the doraemon service"
|
||||
author "Paolo Asperti <paolo@asperti.com>"
|
||||
respawn
|
||||
respawn limit 10 5
|
||||
expect fork
|
||||
start on started network
|
||||
stop on stopping network
|
||||
|
||||
|
||||
#
|
||||
# 20pre_start
|
||||
#
|
||||
pre-start script
|
||||
STAT=`/sbin/e-smith/config getprop doraemon status`
|
||||
if test "x$STAT" = "xenabled" \
|
||||
-a -f "/etc/e-smith/db/configuration/defaults/doraemon/status" \
|
||||
-a -x /usr/sbin/doraemon; then
|
||||
exit 0;
|
||||
fi
|
||||
stop; exit 0;
|
||||
end script
|
||||
|
||||
|
||||
#
|
||||
# 30script
|
||||
#
|
||||
exec /usr/sbin/doraemon -f /etc/httpd/doraemon/httpd.conf
|
@ -1,9 +0,0 @@
|
||||
/var/log/doraemon/*log {
|
||||
missingok
|
||||
notifempty
|
||||
sharedscripts
|
||||
delaycompress
|
||||
postrotate
|
||||
/sbin/reload doraemon > /dev/null 2>/dev/null || true
|
||||
endscript
|
||||
}
|
@ -1,391 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright (C) 2011 Nethesis S.r.l.
|
||||
*
|
||||
* This script is part of NethServer.
|
||||
*
|
||||
* NethServer is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* NethServer is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with NethServer. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Read and write parameters into SME DB
|
||||
*
|
||||
* Ths class implements an interface to SME database executing the command /sbin/e-smith/db with sudo.
|
||||
* The class needs /etc/sudoers configurazione. In the sudoers file you must have something like this:
|
||||
* <code>
|
||||
* Cmnd_Alias SME = /sbin/e-smith/db, /sbin/e-smith/signal-event
|
||||
* www ALL=NOPASSWD: SME
|
||||
* </code>
|
||||
*
|
||||
*
|
||||
* @author Giacomo Sanchietti <giacomo.sanchietti@nethesis.it>
|
||||
* @author Davide Principi <davide.principi@nethesis.it>
|
||||
* @since 1.0
|
||||
* @internal
|
||||
*/
|
||||
class EsmithDatabase
|
||||
{
|
||||
|
||||
/**
|
||||
* @var SME DB database command
|
||||
* */
|
||||
private $command = "/usr/bin/sudo /sbin/e-smith/db";
|
||||
|
||||
/**
|
||||
* @var $db Database name, it's translated into the db file path. For example: /home/e-smith/db/testdb
|
||||
* */
|
||||
private $db;
|
||||
|
||||
/**
|
||||
* This static class variable shares a socket connection to smwingsd
|
||||
*
|
||||
* @var resource
|
||||
*/
|
||||
private static $socket;
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Construct an object to access a SME Configuration database file
|
||||
* with $user's privileges.
|
||||
*
|
||||
* @param string $database Database name
|
||||
*/
|
||||
public function __construct($database)
|
||||
{
|
||||
if ( ! $database)
|
||||
sprintf("%s: You must provide a valid database name.", get_class($this));
|
||||
|
||||
$this->db = $database;
|
||||
}
|
||||
|
||||
public function getAll($type = NULL)
|
||||
{
|
||||
$output = "";
|
||||
|
||||
$ret = $this->dbRead('getjson', array(), $output);
|
||||
if ($ret !== 0) {
|
||||
sprintf("%s: internal database command failed!", __CLASS__);
|
||||
}
|
||||
|
||||
$data = json_decode($output, TRUE);
|
||||
if ( ! is_array($data)) {
|
||||
sprintf("%s: unexpected json string `%s`", __CLASS__, substr($output, 0, 8));
|
||||
}
|
||||
|
||||
$result = array();
|
||||
|
||||
foreach ($data as $item) {
|
||||
// Apply type check filter:
|
||||
if (isset($type) && $type !== $item['type']) {
|
||||
continue;
|
||||
}
|
||||
$props = isset($item['props']) ? $item['props'] : array();
|
||||
$result[$item['name']] = array_merge($props, array('type' => $item['type']));
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function getAllByProp($propName = NULL, $propValue = NULL)
|
||||
{
|
||||
$output = "";
|
||||
|
||||
$ret = $this->dbRead('getjson', array(), $output);
|
||||
if ($ret !== 0) {
|
||||
sprintf("%s: internal database command failed!", __CLASS__);
|
||||
}
|
||||
|
||||
$data = json_decode($output, TRUE);
|
||||
if ( ! is_array($data)) {
|
||||
sprintf("%s: unexpected json string `%s`", __CLASS__, substr($output, 0, 8));
|
||||
}
|
||||
|
||||
$result = array();
|
||||
|
||||
foreach ($data as $item) {
|
||||
$item['props']['type'] = $item['type'];
|
||||
$item['props']['name'] = $item['name'];
|
||||
|
||||
if (isset($propName) && isset($propValue)) {
|
||||
if (isset($item['props'][$propName]) && $propValue == $item['props'][$propName]) {
|
||||
$result[$item['name']] = $item['props'];
|
||||
}
|
||||
} else {
|
||||
$result[$item['name']] = $item['props'];
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function getKey($key)
|
||||
{
|
||||
$output = '';
|
||||
|
||||
$ret = $this->dbRead('getjson', array($key), $output);
|
||||
if ($ret !== 0) {
|
||||
sprintf("%s: internal database command failed", __CLASS__);
|
||||
}
|
||||
|
||||
$data = json_decode($output, TRUE);
|
||||
|
||||
if ($data === 1) {
|
||||
// Key has not been found
|
||||
return array();
|
||||
} elseif ( ! is_array($data)) {
|
||||
sprintf("%s: unexpected json string `%s`", __CLASS__, substr($output, 0, 8));
|
||||
}
|
||||
|
||||
$data['props']['type'] = $data['type'];
|
||||
$data['props']['name'] = $data['name'];
|
||||
return $data['props'];
|
||||
}
|
||||
|
||||
public function getKeyValue($key)
|
||||
{
|
||||
$output = '';
|
||||
|
||||
$ret = $this->dbRead('getjson', array($key), $output);
|
||||
if ($ret !== 0) {
|
||||
sprintf("%s: internal database command failed", __CLASS__);
|
||||
}
|
||||
|
||||
$data = json_decode($output, TRUE);
|
||||
|
||||
if ($data === 1) {
|
||||
// Key has not been found
|
||||
return array();
|
||||
} elseif ( ! is_array($data)) {
|
||||
sprintf("%s: unexpected json string `%s`", __CLASS__, substr($output, 0, 8));
|
||||
}
|
||||
|
||||
return $data['type'];
|
||||
}
|
||||
|
||||
public function setKey($key, $type, $props)
|
||||
{
|
||||
$output = NULL;
|
||||
$ret = $this->dbExec('set', $this->prepareArguments($key, $type, $props), $output);
|
||||
return ($ret == 0);
|
||||
}
|
||||
|
||||
public function deleteKey($key)
|
||||
{
|
||||
$output = NULL;
|
||||
$output = NULL;
|
||||
$ret = $this->dbExec('delete', $this->prepareArguments($key), $output);
|
||||
return ($ret == 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the type of a key
|
||||
* Act like: /sbin/e-smith/db dbfile gettype key
|
||||
*
|
||||
* @param string $key the key to retrieve
|
||||
* @access public
|
||||
* @return string the type of the key
|
||||
*/
|
||||
public function getType($key)
|
||||
{
|
||||
$output = NULL;
|
||||
$ret = $this->dbRead('gettype', array($key), $output);
|
||||
return trim($output);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the type of a key
|
||||
* Act like: /sbin/e-smith/db dbfile settype key type
|
||||
*
|
||||
* @param string $key the key to change
|
||||
* @param string $type the new type
|
||||
* @access public
|
||||
* @return bool true on success, FALSE otherwise
|
||||
*/
|
||||
public function setType($key, $type)
|
||||
{
|
||||
$output = NULL;
|
||||
$ret = $this->dbExec('settype', $this->prepareArguments($key, $type), $output);
|
||||
return ($ret == 0);
|
||||
}
|
||||
|
||||
public function getProp($key, $prop)
|
||||
{
|
||||
$output = NULL;
|
||||
$ret = $this->dbRead('getprop', array($key, $prop), $output);
|
||||
return trim($output);
|
||||
}
|
||||
|
||||
public function setProp($key, $props)
|
||||
{
|
||||
$output = NULL;
|
||||
$ret = $this->dbExec('setprop', $this->prepareArguments($key, $props), $output);
|
||||
return ($ret == 0);
|
||||
}
|
||||
|
||||
public function delProp($key, $props)
|
||||
{
|
||||
$output = NULL;
|
||||
$ret = $this->dbExec('delprop', array_merge(array($key), array_values($props)), $output);
|
||||
return ($ret == 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the db command
|
||||
* @param string $command The command to invoke
|
||||
* @param array $args The command arguments
|
||||
* @param string &$output The output from the command process
|
||||
* @return int The command exit code
|
||||
*/
|
||||
private function dbExec($command, $args, &$output)
|
||||
{
|
||||
// prepend the database name and command
|
||||
array_unshift($args, $this->db, $command);
|
||||
$exitCode = 0;
|
||||
$oArr = array();
|
||||
exec($this->command . ' ' . implode(' ', array_map('escapeshellarg', $args)), $oArr, $exitCode);
|
||||
$output = implode("\n", $oArr);
|
||||
return $exitCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read db data from memory cache daemon
|
||||
* @param string $command The command to invoke
|
||||
* @param array $args The command arguments
|
||||
* @param string &$output The output from the read socket
|
||||
* @return int The command exit code
|
||||
*/
|
||||
private function dbRead($command, $args, &$output)
|
||||
{
|
||||
if ( ! isset(self::$socket) ) {
|
||||
$socketPath = '/var/run/smwingsd.sock';
|
||||
$errno = 0;
|
||||
$errstr = '';
|
||||
self::$socket = fsockopen('unix://' . $socketPath, -1, $errno, $errstr);
|
||||
if( ! is_resource(self::$socket)) {
|
||||
sprintf("Invalid socket (%d): %s. Fall back to exec().", $errno, $errstr);
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! is_resource(self::$socket)) {
|
||||
return $this->dbExec($command, call_user_func_array(array($this, 'prepareArguments'), $args), $output);
|
||||
}
|
||||
|
||||
// prepend the database name and command
|
||||
array_unshift($args, $this->db, $command);
|
||||
|
||||
$ret = $this->sendMessage(self::$socket, 0x10, $args);
|
||||
if ( ! $ret ) {
|
||||
return 1;
|
||||
}
|
||||
$ret = $this->recvMessage(self::$socket);
|
||||
if ( ! $ret ) {
|
||||
return 1;
|
||||
}
|
||||
if ($command === 'getjson') {
|
||||
$output = $ret;
|
||||
} else {
|
||||
$output = json_decode($ret, TRUE);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
private function sendMessage($socket, $type, $args = array())
|
||||
{
|
||||
$payload = json_encode($args);
|
||||
$data = pack('CN', (int) $type, strlen($payload)) . $payload;
|
||||
$written = fwrite($socket, $data);
|
||||
if ($written !== strlen($data)) {
|
||||
echo 'Socket write error';
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
private function recvMessage($socket)
|
||||
{
|
||||
$buf = $this->safeRead($socket, 5);
|
||||
if ($buf === FALSE) {
|
||||
echo 'Socket read error';
|
||||
return false;
|
||||
}
|
||||
|
||||
$header = unpack('Ctype/Nsize', $buf);
|
||||
if ( ! is_array($header)) {
|
||||
echo 'Invalid message header';
|
||||
return false;
|
||||
}
|
||||
|
||||
$message = $this->safeRead($socket, $header['size']);
|
||||
if ($message === FALSE) {
|
||||
echo 'Socket read error';
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($header['type'] & 0x02) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return $message;
|
||||
}
|
||||
|
||||
private function safeRead($socket, $size)
|
||||
{
|
||||
$buffer = "";
|
||||
$count = 0;
|
||||
while($count < $size) {
|
||||
if(feof($socket)) {
|
||||
return FALSE;
|
||||
}
|
||||
$chunk = fread($socket, $size - $count);
|
||||
$count += strlen($chunk);
|
||||
if($chunk === FALSE) {
|
||||
return FALSE;
|
||||
}
|
||||
$buffer .= $chunk;
|
||||
}
|
||||
return $buffer;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Take arbitrary arguments and flattenize to an array
|
||||
*
|
||||
* @param mixed $_
|
||||
* @return array
|
||||
*/
|
||||
private function prepareArguments()
|
||||
{
|
||||
$args = array();
|
||||
|
||||
foreach (func_get_args() as $arg) {
|
||||
if (is_array($arg)) {
|
||||
foreach ($arg as $propName => $propValue) {
|
||||
$args[] = $propName;
|
||||
$args[] = $propValue;
|
||||
}
|
||||
} else {
|
||||
$args[] = (String) $arg;
|
||||
}
|
||||
}
|
||||
|
||||
return $args;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
@ -1,261 +0,0 @@
|
||||
<?php
|
||||
include_once("EsmithDatabase.php");
|
||||
define('CONFIG_KEY', 'doraemon');
|
||||
|
||||
$hosts_db = new EsmithDatabase('hosts');
|
||||
$roles_db = new EsmithDatabase('roles');
|
||||
$config_db = new EsmithDatabase('configuration');
|
||||
|
||||
$uri = $_SERVER['REQUEST_URI'];
|
||||
// add leading '/' to uri string, works if $uri is empty
|
||||
$uri = (substr($uri, 0, 1) == '/') ? $uri : '/' . $uri;
|
||||
$pos = strpos($uri, '?');
|
||||
if (false !== $pos) {
|
||||
$route = substr($uri, 0, (int) $pos);
|
||||
} else {
|
||||
$route = $uri;
|
||||
}
|
||||
// remove trailing '/'
|
||||
$route = rtrim($route, '/');
|
||||
|
||||
$query_string = $_SERVER['QUERY_STRING'];
|
||||
$get_params = array();
|
||||
parse_str($query_string, $get_params);
|
||||
|
||||
// determine internal function name (all lowercase, dash2underscore, named ROUTE_routename )
|
||||
$function = preg_replace(':\-:', '_', strtolower($route));
|
||||
$function = preg_replace(':^/:', 'ROUTE_', $function);
|
||||
|
||||
if (function_exists($function)) {
|
||||
$function();
|
||||
} else {
|
||||
die('Go away.');
|
||||
}
|
||||
|
||||
function varsForRole($role, $json=true) {
|
||||
global $roles_db;
|
||||
$result = $roles_db->getKey($role);
|
||||
$return = array('role'=>$role,'delpkg'=>'','addpkg'=>'');
|
||||
if (is_array($result)) {
|
||||
if (is_string($result['Addpkg']))
|
||||
$return['addpkg'] = preg_split("/[\s,]+/", $result['Addpkg']);
|
||||
if (is_string($result['Delpkg']))
|
||||
$return['delpkg'] = preg_split("/[\s,]+/", $result['Delpkg']);
|
||||
}
|
||||
if ($json) {
|
||||
return json_encode($return);
|
||||
} else {
|
||||
return $return;
|
||||
}
|
||||
}
|
||||
|
||||
function getClient($mac=false) {
|
||||
global $hosts_db;
|
||||
if (!$mac) {
|
||||
$mac = getClientMac();
|
||||
if (!$mac)
|
||||
return false;
|
||||
}
|
||||
$hosts = $hosts_db->getAllByProp('MacAddress',$mac);
|
||||
if (count($hosts)>0) {
|
||||
return array_pop($hosts);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function getClientMac($ip=false) {
|
||||
if (false === $ip) {
|
||||
$ip = $_SERVER['REMOTE_ADDR'];
|
||||
}
|
||||
$result = pingHost($ip,1);
|
||||
if (!$result)
|
||||
return false;
|
||||
$macAddr=false;
|
||||
$arptable=`arp -n $ip`;
|
||||
$lines=explode("\n", $arptable);
|
||||
foreach($lines as $line) {
|
||||
$cols=preg_split('/\s+/', trim($line));
|
||||
if ($cols[0]==$ip)
|
||||
{
|
||||
return $cols[2];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function newHostname($mac, $base, $role) {
|
||||
global $config_db, $hosts_db;
|
||||
if(!preg_match('/^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$/', $mac)) {
|
||||
echo "invalid mac address";
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($client=getClient($mac)) {
|
||||
echo $client['name'];
|
||||
return;
|
||||
}
|
||||
|
||||
$domainName = (string)$config_db->getKeyValue('DomainName');
|
||||
$digits = $config_db->getProp(CONFIG_KEY,'NamingDigits');
|
||||
$formatstring = '%s-%0'.$digits.'d';
|
||||
$nr=0;
|
||||
$hostname = '';
|
||||
do {
|
||||
$nr++;
|
||||
$hostname = sprintf($formatstring, $base, $nr);
|
||||
# TODO: we'll use the hostname in future, maybe
|
||||
# if (trim($domainName) != '') {
|
||||
# $hostname .= '.' . $domainName;
|
||||
# }
|
||||
} while ($hosts_db->getKey($hostname));
|
||||
|
||||
$hosts_db->setKey($hostname, 'local', array(
|
||||
'MacAddress' => $mac,
|
||||
'Role' => $role,
|
||||
'Description' => ''
|
||||
));
|
||||
|
||||
echo $hostname;
|
||||
}
|
||||
|
||||
function pingHost($host, $timeout=1) {
|
||||
$pingresult = exec("/bin/ping -c 1 -t 2 -W $timeout $host", $output, $retvar);
|
||||
return (0 == $retvar);
|
||||
}
|
||||
|
||||
function ROUTE_domain() {
|
||||
global $config_db;
|
||||
$theFile = $config_db->getProp(CONFIG_KEY,'DomainFile');
|
||||
passthru("/usr/bin/sudo /bin/cat $theFile");
|
||||
}
|
||||
|
||||
function ROUTE_mgmtkey() {
|
||||
global $config_db;
|
||||
$theFile = $config_db->getProp(CONFIG_KEY,'ManagementKeyFile');
|
||||
passthru("/usr/bin/sudo /bin/cat $theFile");
|
||||
}
|
||||
|
||||
function ROUTE_epoptes_srv() {
|
||||
global $hosts_db;
|
||||
$hosts = $hosts_db->getAllByProp('Role','docenti');
|
||||
ksort($hosts);
|
||||
if (count($hosts) == 0) {
|
||||
echo 'none';
|
||||
} else {
|
||||
$host = array_pop($hosts);
|
||||
echo $host['name'];
|
||||
}
|
||||
}
|
||||
|
||||
function ROUTE_ansible_host() {
|
||||
global $get_params;
|
||||
if (isset($get_params['role'])) {
|
||||
$role = $get_params['role'];
|
||||
} elseif ($client = getClient()) {
|
||||
$role = $client['Role'];
|
||||
} else {
|
||||
$role = 'unknown';
|
||||
}
|
||||
echo varsForRole($role);
|
||||
}
|
||||
|
||||
function ROUTE_hosts() {
|
||||
global $hosts_db, $get_params;
|
||||
if (isset($get_params['role'])) {
|
||||
$items = $hosts_db->getAllByProp('Role', $get_params['role']);
|
||||
} else {
|
||||
$items = $hosts_db->getAll('local');
|
||||
}
|
||||
$results=array();
|
||||
foreach ($items as $name=>$item) {
|
||||
$results[]=array(
|
||||
'mac'=>$item['MacAddress'],
|
||||
'hostname'=>$name,
|
||||
'role'=>$item['Role']
|
||||
);
|
||||
}
|
||||
echo json_encode($results);
|
||||
}
|
||||
|
||||
function ROUTE_ansible_list() {
|
||||
global $get_params;
|
||||
if (isset($get_params['role'])) {
|
||||
$role = $get_params['role'];
|
||||
} elseif ($client = getClient()) {
|
||||
$role = $client['Role'];
|
||||
} else {
|
||||
$role = 'unknown';
|
||||
}
|
||||
$vars = varsForRole($role, false);
|
||||
echo json_encode(array(
|
||||
'localhost'=>array(
|
||||
'hosts'=>array('localhost'),
|
||||
'vars'=>array('ansible_connection'=>'local')
|
||||
),
|
||||
'_meta'=> array('hostvars'=>array('localhost'=>$vars))
|
||||
));
|
||||
}
|
||||
|
||||
function ROUTE_vaultpass() {
|
||||
global $config_db;
|
||||
$theFile = $config_db->getProp(CONFIG_KEY,'VaultPassFile');
|
||||
$oArr = array();
|
||||
exec('/usr/bin/sudo /bin/cat ' . $theFile, $oArr, $exitCode);
|
||||
$content = trim(implode("\n", $oArr));
|
||||
if (false === $content) {
|
||||
echo 'no file';
|
||||
return false;
|
||||
}
|
||||
if (!$client = getClient()) {
|
||||
echo 'no client';
|
||||
return false;
|
||||
}
|
||||
$key = md5($client['name'], true);
|
||||
$padlenght = 16 - (strlen($content) % 16);
|
||||
$content_padded = $content . str_repeat('x', $padlenght);
|
||||
$ciphertext = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $content_padded, MCRYPT_MODE_ECB);
|
||||
echo base64_encode($ciphertext);
|
||||
}
|
||||
|
||||
function ROUTE_whatsmyhostname() {
|
||||
global $config_db, $get_params;
|
||||
if (isset($get_params['role'])) {
|
||||
$role = $get_params['role'];
|
||||
} else {
|
||||
$role = $config_db->getProp(CONFIG_KEY,'DefaultRole');
|
||||
}
|
||||
if (isset($get_params['base'])) {
|
||||
$base = $get_params['base'];
|
||||
} else {
|
||||
$base = $config_db->getProp(CONFIG_KEY,'NamingBase');
|
||||
}
|
||||
$mac = getClientMac();
|
||||
if (!$mac) {
|
||||
echo 'no-mac-address';
|
||||
return false;
|
||||
}
|
||||
newHostname($mac, $base, $role);
|
||||
}
|
||||
|
||||
function ROUTE_mac2hostname() {
|
||||
global $config_db, $get_params;
|
||||
if (isset($get_params['mac'])) {
|
||||
$mac = $get_params['mac'];
|
||||
} else {
|
||||
echo 'Usage: GET /mac2hostname?mac=XX_XX_XX_XX_XX_XX[&base=YYY][&role=ZZZ]';
|
||||
return false;
|
||||
}
|
||||
if (isset($get_params['role'])) {
|
||||
$role = $get_params['role'];
|
||||
} else {
|
||||
$role = $config_db->getProp(CONFIG_KEY,'DefaultRole');
|
||||
}
|
||||
|
||||
if (isset($get_params['base'])) {
|
||||
$base = $get_params['base'];
|
||||
} else {
|
||||
$base = $config_db->getProp(CONFIG_KEY,'NamingBase');
|
||||
}
|
||||
|
||||
newHostname($mac, $base, $role);
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
<?php
|
||||
|
||||
/* /usr/share/nethesis/NethServer/Language/en/NethServer_Module_Doraemon.php */
|
||||
|
||||
$L['Doraemon_Title'] = 'Doraemon';
|
||||
$L['hostname_label'] = 'Hostname';
|
||||
$L['MacAddress_label'] = 'MAC Address';
|
||||
$L['shutdown_label'] = 'Shutdown';
|
||||
$L['reboot_label'] = 'Reboot';
|
||||
$L['wake_label'] = 'Wake Up';
|
||||
$L['shutdown-all_label'] = 'Shutdown all';
|
||||
$L['reboot-all_label'] = 'Reboot all';
|
||||
$L['wake-all_label'] = 'Wake Up all';
|
@ -1,9 +0,0 @@
|
||||
<?php
|
||||
|
||||
/* /usr/share/nethesis/NethServer/Language/en/NethServer_Module_Doraemon_Hosts.php */
|
||||
|
||||
$L['Hosts_Title'] = 'Hosts';
|
||||
$L['Create_Host_Header'] = 'Create a new host';
|
||||
$L['Update_Host_Header'] = 'Update host "${0}"';
|
||||
$L['Role_label'] = 'Role';
|
||||
$L['Key_label'] = 'Hostname';
|
@ -1,13 +0,0 @@
|
||||
<?php
|
||||
|
||||
/* /usr/share/nethesis/NethServer/Language/it/NethServer_Module_Doraemon.php */
|
||||
|
||||
$L['Doraemon_Title'] = 'Doraemon';
|
||||
$L['hostname_label'] = 'Hostname';
|
||||
$L['MacAddress_label'] = 'MAC Address';
|
||||
$L['shutdown_label'] = 'Spegni';
|
||||
$L['reboot_label'] = 'Riavvia';
|
||||
$L['wake_label'] = 'Accendi';
|
||||
$L['shutdown-all_label'] = 'Spegni tutti';
|
||||
$L['reboot-all_label'] = 'Riavvia tutti';
|
||||
$L['wake-all_label'] = 'Accendi tutti';
|
@ -1,9 +0,0 @@
|
||||
<?php
|
||||
|
||||
/* /usr/share/nethesis/NethServer/Language/it/NethServer_Module_Doraemon_Hosts.php */
|
||||
|
||||
$L['Hosts_Title'] = 'Hosts';
|
||||
$L['Create_Host_Header'] = 'Crea un nuovo host';
|
||||
$L['Update_Host_Header'] = 'Modifica il nome host "${0}"';
|
||||
$L['Role_label'] = 'Ruolo';
|
||||
$L['Key_label'] = 'Hostname';
|
@ -1,17 +0,0 @@
|
||||
<?php
|
||||
namespace NethServer\Module;
|
||||
|
||||
class Doraemon extends \Nethgui\Controller\TabsController
|
||||
{
|
||||
protected function initializeAttributes(\Nethgui\Module\ModuleAttributesInterface $base)
|
||||
{
|
||||
return \Nethgui\Module\SimpleModuleAttributesProvider::extendModuleAttributes($base, 'Configuration', 50);
|
||||
}
|
||||
|
||||
public function initialize()
|
||||
{
|
||||
parent::initialize();
|
||||
$this->loadChildrenDirectory();
|
||||
}
|
||||
|
||||
}
|
@ -1,36 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace NethServer\Module\Doraemon;
|
||||
|
||||
|
||||
class Hosts extends \Nethgui\Controller\TableController
|
||||
{
|
||||
|
||||
public function initialize()
|
||||
{
|
||||
$columns = array(
|
||||
'Key',
|
||||
'MacAddress',
|
||||
'Role',
|
||||
'Actions',
|
||||
);
|
||||
|
||||
$this
|
||||
->setTableAdapter($this->getPlatform()->getTableAdapter('hosts', 'local'))
|
||||
->setColumns($columns)
|
||||
->addRowAction(new \NethServer\Module\Doraemon\Hosts\Modify('update'))
|
||||
->addRowAction(new \NethServer\Module\Doraemon\Hosts\TogglePower('wake'))
|
||||
->addRowAction(new \NethServer\Module\Doraemon\Hosts\TogglePower('reboot'))
|
||||
->addRowAction(new \NethServer\Module\Doraemon\Hosts\TogglePower('shutdown'))
|
||||
->addRowAction(new \NethServer\Module\Doraemon\Hosts\Modify('delete'))
|
||||
->addTableAction(new \NethServer\Module\Doraemon\Hosts\Modify('create'))
|
||||
->addTableAction(new \NethServer\Module\Doraemon\Hosts\TogglePowerAll('wake-all'))
|
||||
->addTableAction(new \NethServer\Module\Doraemon\Hosts\TogglePowerAll('reboot-all'))
|
||||
->addTableAction(new \NethServer\Module\Doraemon\Hosts\TogglePowerAll('shutdown-all'))
|
||||
->addTableAction(new \Nethgui\Controller\Table\Help('Help'))
|
||||
;
|
||||
|
||||
parent::initialize();
|
||||
}
|
||||
|
||||
}
|
@ -1,55 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace NethServer\Module\Doraemon\Hosts;
|
||||
|
||||
use Nethgui\System\PlatformInterface as Validate;
|
||||
|
||||
|
||||
class Modify extends \Nethgui\Controller\Table\Modify
|
||||
{
|
||||
|
||||
public function initialize()
|
||||
{
|
||||
$parameterSchema = array(
|
||||
// was: Validate::HOSTNAME_FQDN, but we need hostname
|
||||
array('hostname', Validate::HOSTNAME_SIMPLE, \Nethgui\Controller\Table\Modify::KEY),
|
||||
array('MacAddress', Validate::MACADDRESS, \Nethgui\Controller\Table\Modify::FIELD),
|
||||
array('Role', Validate::ANYTHING, \Nethgui\Controller\Table\Modify::FIELD),
|
||||
// array('Role', Validate::ROLES_COLLECTION ??? TODO!!!, \Nethgui\Controller\Table\Modify::FIELD),
|
||||
);
|
||||
$this->setSchema($parameterSchema);
|
||||
parent::initialize();
|
||||
}
|
||||
|
||||
public function validate(\Nethgui\Controller\ValidationReportInterface $report)
|
||||
{
|
||||
if ($this->getIdentifier() === 'delete') {
|
||||
$v = $this->createValidator()->platform('host-delete');
|
||||
if ( ! $v->evaluate($this->parameters['hostname'])) {
|
||||
$report->addValidationError($this, 'Key', $v);
|
||||
}
|
||||
}
|
||||
parent::validate($report);
|
||||
}
|
||||
|
||||
protected function onParametersSaved($parameters)
|
||||
{
|
||||
$actionName = $this->getIdentifier();
|
||||
if ($actionName === 'update') {
|
||||
$actionName = 'modify';
|
||||
}
|
||||
$this->getPlatform()->signalEvent(sprintf('host-%s &', $actionName));
|
||||
}
|
||||
|
||||
public function prepareView(\Nethgui\View\ViewInterface $view)
|
||||
{
|
||||
parent::prepareView($view);
|
||||
$templates = array(
|
||||
'create' => 'NethServer\Template\Doraemon\Hosts',
|
||||
'update' => 'NethServer\Template\Doraemon\Hosts',
|
||||
'delete' => 'Nethgui\Template\Table\Delete',
|
||||
);
|
||||
$view->setTemplate($templates[$this->getIdentifier()]);
|
||||
}
|
||||
|
||||
}
|
@ -1,48 +0,0 @@
|
||||
<?php
|
||||
namespace NethServer\Module\Doraemon\Hosts;
|
||||
|
||||
use Nethgui\System\PlatformInterface as Validate;
|
||||
|
||||
/**
|
||||
* Toggle host power status
|
||||
*
|
||||
* Fires events
|
||||
* - doraemon-wake
|
||||
* - doraemon-reboot
|
||||
* - doraemon-shutdown
|
||||
*/
|
||||
class TogglePower extends \Nethgui\Controller\Table\AbstractAction
|
||||
{
|
||||
|
||||
public function __construct($identifier = NULL)
|
||||
{
|
||||
if ($identifier !== 'wake' && $identifier !== 'reboot' && $identifier !== 'shutdown') {
|
||||
throw new \InvalidArgumentException(sprintf('%s: module identifier must be one of "wake" or "reboot" or "shutdown".', get_class($this)), 1325579395);
|
||||
}
|
||||
parent::__construct($identifier);
|
||||
}
|
||||
|
||||
public function bind(\Nethgui\Controller\RequestInterface $request)
|
||||
{
|
||||
$this->declareParameter('hostname', Validate::HOSTNAME_SIMPLE);
|
||||
|
||||
parent::bind($request);
|
||||
$hostname = \Nethgui\array_end($request->getPath());
|
||||
|
||||
if ( ! $hostname) {
|
||||
throw new \Nethgui\Exception\HttpException('Not found', 404, 1322148400);
|
||||
}
|
||||
|
||||
$this->parameters['hostname'] = $hostname;
|
||||
}
|
||||
|
||||
public function process()
|
||||
{
|
||||
if ( ! $this->getRequest()->isMutation()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->getPlatform()->signalEvent(sprintf('doraemon-%s@post', $this->getIdentifier()), array($this->parameters['hostname']));
|
||||
}
|
||||
|
||||
}
|
@ -1,34 +0,0 @@
|
||||
<?php
|
||||
namespace NethServer\Module\Doraemon\Hosts;
|
||||
|
||||
use Nethgui\System\PlatformInterface as Validate;
|
||||
|
||||
/**
|
||||
* Toggle host power status
|
||||
*
|
||||
* Fires events
|
||||
* - doraemon-wake-all
|
||||
* - doraemon-reboot-all
|
||||
* - doraemon-shutdown-all
|
||||
*/
|
||||
class TogglePowerAll extends \Nethgui\Controller\Table\AbstractAction
|
||||
{
|
||||
|
||||
public function __construct($identifier = NULL)
|
||||
{
|
||||
if ($identifier !== 'wake-all' && $identifier !== 'reboot-all' && $identifier !== 'shutdown-all') {
|
||||
throw new \InvalidArgumentException(sprintf('%s: module identifier must be one of "wake-all" or "reboot-all" or "shutdown-all".', get_class($this)), 1325579395);
|
||||
}
|
||||
parent::__construct($identifier);
|
||||
}
|
||||
|
||||
public function process()
|
||||
{
|
||||
if ( ! $this->getRequest()->isMutation()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->getPlatform()->signalEvent(sprintf('doraemon-%s@post', $this->getIdentifier()));
|
||||
}
|
||||
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
<?php
|
||||
/* @var $view \Nethgui\Renderer\Xhtml */
|
||||
|
||||
if ($view->getModule()->getIdentifier() == 'update') {
|
||||
// disable updating of hostname
|
||||
// the hostname is the key of the db item, if you change it, bad things happens
|
||||
$keyFlags = $view::STATE_DISABLED;
|
||||
$template = 'Update_Host_Header';
|
||||
} else {
|
||||
$keyFlags = 0;
|
||||
$template = 'Create_Host_Header';
|
||||
}
|
||||
|
||||
echo $view->header('hostname')->setAttribute('template', $T($template));
|
||||
|
||||
echo $view->panel()
|
||||
->insert($view->textInput('hostname', $keyFlags))
|
||||
->insert($view->textInput('MacAddress'))
|
||||
->insert($view->textInput('Role'))
|
||||
;
|
||||
|
||||
echo $view->buttonList($view::BUTTON_SUBMIT | $view::BUTTON_CANCEL | $view::BUTTON_HELP);
|
@ -1,23 +0,0 @@
|
||||
<?php
|
||||
$view->requireFlag($view::INSET_DIALOG);
|
||||
|
||||
if ($view->getModule()->getIdentifier() == 'shutdown') {
|
||||
$headerText = $T('Shutdown host `${0}`');
|
||||
$panelText = $T('Proceed with host `${0}` shutdown?');
|
||||
} elseif ($view->getModule()->getIdentifier() == 'reboot') {
|
||||
$headerText = $T('Reboot host `${0}`');
|
||||
$panelText = $T('Proceed with host `${0}` reboot?');
|
||||
} else {
|
||||
$headerText = $T('Wakeup host `${0}`');
|
||||
$panelText = $T('Proceed with host `${0}` wakeup?');
|
||||
}
|
||||
|
||||
echo $view->panel()
|
||||
->insert($view->header('hostname')->setAttribute('template', $headerText))
|
||||
->insert($view->textLabel('hostname')->setAttribute('template', $panelText))
|
||||
;
|
||||
|
||||
echo $view->buttonList()
|
||||
->insert($view->button('Yes', $view::BUTTON_SUBMIT))
|
||||
->insert($view->button('No', $view::BUTTON_CANCEL)->setAttribute('value', $view['Cancel']))
|
||||
;
|
@ -1,21 +0,0 @@
|
||||
<?php
|
||||
$view->requireFlag($view::INSET_DIALOG);
|
||||
|
||||
if ($view->getModule()->getIdentifier() == 'shutdown-all') {
|
||||
$headerText = $T('Shutdown all hosts');
|
||||
$panelText = $T('Proceed with all hosts shutdown?');
|
||||
} elseif ($view->getModule()->getIdentifier() == 'reboot-all') {
|
||||
$headerText = $T('Reboot all hosts');
|
||||
$panelText = $T('Proceed with all hosts reboot?');
|
||||
} else {
|
||||
$headerText = $T('Wakeup all hosts');
|
||||
$panelText = $T('Proceed with all hosts wakeup?');
|
||||
}
|
||||
|
||||
echo $view->header()->setAttribute('template', $headerText);
|
||||
// TODO: add a text label here
|
||||
// echo $view->textLabel()->setAttribute('template', $panelText);
|
||||
echo $view->buttonList()
|
||||
->insert($view->button('Yes', $view::BUTTON_SUBMIT))
|
||||
->insert($view->button('No', $view::BUTTON_CANCEL)->setAttribute('value', $view['Cancel']))
|
||||
;
|
Loading…
x
Reference in New Issue
Block a user