class Exports (SectionPlugin): config_path = '/etc/exports' def init(self): self.title = _('NFS Exports') self.icon = 'hdd' self.category = _('Software') self.append(self.ui.inflate('exports:main')) if not os.path.exists(self.config_path): open(self.config_path, 'w').close() self.config = ExportsConfig(path=self.config_path) self.binder = Binder(None, self) self.find('exports').new_item = lambda c: ExportData() self.find('clients').new_item = lambda c: ClientData() def on_page_load(self): self.config.load() self.binder.reset(self.config.tree).autodiscover().populate() @on('save', 'click') def save(self): self.binder.update() self.config.save() self.context.notify('info', _('Saved'))
class DHCPDPlugin (SectionPlugin): def init(self): self.title = _('DHCP Server') self.icon = 'sitemap' self.category = _('Software') self.append(self.ui.inflate('dhcpd:main')) self.config = DHCPDConfig(path='/etc/dhcp/dhcpd.conf') self.binder = Binder(None, self) for x in self.nearest(lambda x: x.bind == 'ranges'): x.new_item = lambda c: RangeData() for x in self.nearest(lambda x: x.bind == 'options'): x.new_item = lambda c: OptionData() self.find('subnets').new_item = lambda c: SubnetData() def on_page_load(self): self.config.load() self.binder.reset(self.config.tree).autodiscover().populate() @on('save', 'click') def save(self): self.binder.update() self.config.save()
class Netatalk (SectionPlugin): config_path = '/etc/afp.conf' def init(self): self.title = 'Netatalk' self.icon = 'folder-close' self.category = _('Software') self.append(self.ui.inflate('netatalk:main')) if not os.path.exists(self.config_path): open(self.config_path, 'w').close() self.binder = Binder(None, self.find('config')) self.find('shares').new_item = lambda c: ShareData() self.config = NetatalkConfig(path=self.config_path) def on_page_load(self): self.refresh() def refresh(self): self.config.load() self.binder.reset(self.config.tree).autodiscover().populate() @on('save', 'click') def on_save(self): self.binder.update() self.config.save() self.refresh()
class WonderShaper(SectionPlugin): # default config could be overwitten on main config.json default_classconfig = {'path': '/etc/conf.d/wondershaper.conf'} def init(self): self.title = 'WonderShaper' # Icons set: http://fortawesome.github.io/Font-Awesome/icons/ self.icon = 'download-alt' self.category = 'DXS' self.append(self.ui.inflate('wondershaper:main')) path = self.classconfig['path'] self.config = WonderShaperConfig(path=path) self.binder = Binder(None, self) def on_page_load(self): self.config.load() data = self.config.tree.wondershaper self.binder.reset(data).autodiscover().populate() @on('save', 'click') def on_save(self): self.binder.update() self.config.save() self.context.notify('info', 'Saved conf') ret = subprocess.call(['systemctl', 'restart', 'wondershaper.service']) if ret == 0: self.context.notify('info', 'Reload service') else: self.context.notify('error', 'Error on reload service')
class Resolv(SectionPlugin): def init(self): self.title = _('Nameservers') self.icon = 'globe' self.category = _('System') self.append(self.ui.inflate('resolv:main')) self.find('name-box').labels = [ _('DNS nameserver'), _('Local domain name'), _('Search list'), _('Sort list'), _('Options') ] self.find('name-box').values = [ 'nameserver', 'domain', 'search', 'sortlist', 'options' ] self.config = ResolvConfig(path='/etc/resolv.conf') self.binder = Binder(None, self.find('resolv-config')) self.find('items').new_item = lambda c: ItemData() def on_page_load(self): self.config.load() self.binder.reset(self.config.tree).autodiscover().populate() @on('save', 'click') def save(self): self.binder.update() self.config.save()
class VSFTPDExtension (BaseExtension): default_config = { 'created': False, 'user': None, 'password': None, } name = 'FTP' def init(self): self.append(self.ui.inflate('vh-vsftpd:ext')) self.binder = Binder(self, self) self.binder.autodiscover() if not self.config['created']: self.config['username'] = self.website.slug self.config['password'] = str(uuid.uuid4()) self.config['created'] = True self.refresh() def refresh(self): self.binder.reset().populate() def update(self): pass
class Squid(SectionPlugin): def init(self): self.title = 'Squid' self.icon = 'exchange' self.category = _('Software') self.append(self.ui.inflate('squid:main')) self.find('servicebar').name = platform_select( debian='squid3', centos='squid', default='squid', ) self.find('servicebar').reload() self.binder = Binder(None, self.find('config')) self.find('acl').new_item = lambda c: ACLData() self.find('http_access').new_item = lambda c: HTTPAccessData() self.find('http_port').new_item = lambda c: HTTPPortData() self.find('https_port').new_item = lambda c: HTTPSPortData() self.config = SquidConfig(path='/etc/squid3/squid.conf') def on_page_load(self): self.refresh() def refresh(self): self.config.load() self.binder.reset(self.config.tree).autodiscover().populate() @on('save', 'click') def on_save(self): self.binder.update() self.config.save() self.refresh()
class Squid(SectionPlugin): def init(self): self.title = 'Squid' self.icon = 'exchange' self.category = 'Software' self.append(self.ui.inflate('squid:main')) self.binder = Binder(None, self.find('config')) self.find('acl').new_item = lambda c: ACLData() self.find('http_access').new_item = lambda c: HTTPAccessData() self.find('http_port').new_item = lambda c: HTTPPortData() self.find('https_port').new_item = lambda c: HTTPSPortData() self.config = SquidConfig(path='/etc/squid3/squid.conf') #def post_item_bind(object, collection, item, ui): # ui.find('disconnect').on('click', self.on_disconnect, item) #self.find('connections').post_item_bind = post_item_bind def on_page_load(self): self.refresh() def refresh(self): self.config.load() self.binder.reset(self.config.tree).autodiscover().populate() @on('save', 'click') def on_save(self): self.binder.update() self.config.save() self.refresh()
class Netatalk(SectionPlugin): config_path = "/etc/afp.conf" def init(self): self.title = "Netatalk" self.icon = "folder-close" self.category = "Software" self.append(self.ui.inflate("netatalk:main")) if not os.path.exists(self.config_path): open(self.config_path, "w").close() self.binder = Binder(None, self.find("config")) self.find("shares").new_item = lambda c: ShareData() self.config = NetatalkConfig(path=self.config_path) def on_page_load(self): self.refresh() def refresh(self): self.config.load() self.binder.reset(self.config.tree).autodiscover().populate() @on("save", "click") def on_save(self): self.binder.update() self.config.save() self.refresh()
class PluginsPlugin (SectionPlugin): def init(self): self.title = 'Plugins' self.icon = 'cogs' self.category = '' self.order = 50 # In case you didn't notice it yet, this is the Plugins Plugin Plugin self.append(self.ui.inflate('plugins:main')) def post_plugin_bind(object, collection, item, ui): if not item.crash: ui.find('crash').visible = False def post_dep_bind(object, collection, item, ui): if not item.satisfied(): installer = ui.find('fix') if item.__class__ == ModuleDependency: installer.package = 'python-module-' + item.module_name if item.__class__ == BinaryDependency: installer.package = item.binary_name installer.recheck() self.find('plugins').post_item_bind = post_plugin_bind self.find('dependencies').post_item_bind = post_dep_bind self.binder = Binder(self, self.find('bind-root')) self.refresh() def refresh(self): self.plugins = sorted(manager.get_all().values()) self.binder.reset().autodiscover().populate()
class Filesystems(SectionPlugin): def init(self): self.title = _('Filesystems') self.icon = 'hdd' self.category = _('System') self.append(self.ui.inflate('fstab:main')) self.find('type').labels = [ 'Auto', 'EXT2', 'EXT3', 'EXT4', 'NTFS', 'FAT', 'ZFS', 'ReiserFS', 'Samba', 'None', 'Loop' ] self.find('type').values = [ 'auto', 'ext2', 'ext3', 'ext4', 'ntfs', 'vfat', 'zfs', 'reiser', 'smb', 'none', 'loop' ] self.fstab_config = FSTabConfig(path='/etc/fstab') self.mounts = MountsBackend.get() self.binder = Binder(None, self) self.find('fstab').find( 'filesystems').new_item = lambda c: FilesystemData() def post_mount_bind(object, collection, item, ui): ui.find('umount').on('click', self.on_umount, item) self.find('mounts').find( 'filesystems').post_item_bind = post_mount_bind def on_page_load(self): self.refresh() def on_umount(self, mount): subprocess.call(['umount', mount.mountpoint]) self.context.notify('info', _('Unmounted')) self.refresh() @on('mount-all', 'click') def on_mount_all(self): if subprocess.call(['mount', '-a']): self.context.notify('error', _('mount -a failed')) self.refresh() @on('refresh', 'click') def refresh(self): self.reload_disks() self.fstab_config.load() self.fstab = self.fstab_config.tree self.mounts.reload() self.binder.reset(self).autodiscover().populate() def reload_disks(self): lst = disks.list_devices(by_uuid=True, by_id=True, by_label=True) self.find('device').labels = [x[0] for x in lst] self.find('device').values = [x[1] for x in lst] @on('save', 'click') def save(self): self.binder.update() self.fstab_config.save()
class Exports(SectionPlugin): config_path = '/etc/exports' def init(self): self.title = 'NFS Exports' self.icon = 'hdd' self.category = 'System' self.append(self.ui.inflate('exports:main')) if not os.path.exists(self.config_path): open(self.config_path, 'w').close() self.config = ExportsConfig(path=self.config_path) self.binder = Binder(None, self) self.find('exports').new_item = lambda c: ExportData() self.find('clients').new_item = lambda c: ClientData() def on_page_load(self): self.config.load() self.binder.reset(self.config.tree).autodiscover().populate() @on('save', 'click') def save(self): self.binder.update() self.config.save() self.context.notify('info', 'Saved')
class Netatalk(SectionPlugin): config_path = '/etc/afp.conf' def init(self): self.title = 'Netatalk' self.icon = 'folder-close' self.category = _('Software') self.append(self.ui.inflate('netatalk:main')) if not os.path.exists(self.config_path): open(self.config_path, 'w').write("[Global]") self.binder = Binder(None, self.find('config')) self.find('shares').new_item = lambda c: ShareData() self.config = NetatalkConfig(path=self.config_path) def on_page_load(self): self.refresh() def refresh(self): self.config.load() self.binder.reset(self.config.tree).autodiscover().populate() @on('save', 'click') def on_save(self): self.binder.update() self.config.save() self.refresh()
class DHCPDPlugin(SectionPlugin): def init(self): self.title = _('DHCP Server') self.icon = 'sitemap' self.category = _('Software') self.append(self.ui.inflate('dhcpd:main')) self.config = DHCPDConfig(path='/etc/dhcp/dhcpd.conf') self.binder = Binder(None, self) for x in self.nearest(lambda x: x.bind == 'ranges'): x.new_item = lambda c: RangeData() for x in self.nearest(lambda x: x.bind == 'options'): x.new_item = lambda c: OptionData() self.find('subnets').new_item = lambda c: SubnetData() def on_page_load(self): self.config.load() self.binder.reset(self.config.tree).autodiscover().populate() @on('save', 'click') def save(self): self.binder.update() self.config.save()
class Squid (SectionPlugin): def init(self): self.title = _('Squid') self.icon = 'exchange' self.category = _('Software') self.append(self.ui.inflate('squid:main')) self.binder = Binder(None, self.find('config')) self.find('acl').new_item = lambda c: ACLData() self.find('http_access').new_item = lambda c: HTTPAccessData() self.find('http_port').new_item = lambda c: HTTPPortData() self.find('https_port').new_item = lambda c: HTTPSPortData() self.config = SquidConfig(path='/etc/squid3/squid.conf') def on_page_load(self): self.refresh() def refresh(self): self.config.load() self.binder.reset(self.config.tree).autodiscover().populate() @on('save', 'click') def on_save(self): self.binder.update() self.config.save() self.refresh()
class PluginsPlugin(SectionPlugin): def init(self): self.title = 'Plugins' self.icon = 'cogs' self.category = '' self.order = 50 # In case you didn't notice it yet, this is the Plugins Plugin Plugin self.append(self.ui.inflate('plugins:main')) def post_plugin_bind(object, collection, item, ui): if not item.crash: ui.find('crash').visible = False def post_dep_bind(object, collection, item, ui): if not item.satisfied(): installer = ui.find('fix') if item.__class__ == ModuleDependency: installer.package = 'python-module-' + item.module_name if item.__class__ == BinaryDependency: installer.package = item.binary_name installer.recheck() self.find('plugins').post_item_bind = post_plugin_bind self.find('dependencies').post_item_bind = post_dep_bind self.binder = Binder(self, self.find('bind-root')) self.refresh() def refresh(self): self.plugins = sorted(manager.get_all().values()) self.binder.reset().autodiscover().populate()
class NetworkPlugin(SectionPlugin): platforms = ['debian', 'centos'] def init(self): self.title = _('Network') self.icon = 'globe' self.category = _('System') self.net_config = INetworkConfig.get() self.append(self.ui.inflate('network:main')) def post_interface_bind(o, c, i, u): i.add_bits(self.ui) for bit in i.bits: u.find('bits').append( self.ui.create( 'tab', children=[bit], title=bit.title, )) u.find('up').on('click', self.on_up, i) u.find('down').on('click', self.on_down, i) def post_interface_update(o, c, i, u): for bit in i.bits: bit.apply() self.find('interfaces').post_item_bind = post_interface_bind self.find('interfaces').post_item_update = post_interface_update self.binder = Binder(self.net_config, self) def on_page_load(self): self.refresh() def refresh(self): self.net_config.rescan() sensor = Sensor.find('traffic') for i in self.net_config.interface_list: i.tx, i.rx = sensor.value(i.name) self.binder.reset().autodiscover().populate() return def on_up(self, iface=None): self.net_config.up(iface) self.refresh() def on_down(self, iface=None): self.net_config.down(iface) self.refresh() @on('save', 'click') def on_save(self): self.binder.update() self.net_config.save() self.refresh() self.context.notify('info', _('Saved'))
class Users (SectionPlugin): def init(self): self.title = 'Users' self.icon = 'group' self.category = 'System' self.append(self.ui.inflate('users:main')) def _sorter(x): u = int(x.uid) if u >= 1000: return u - 10000 return u self.find('users').sorting = _sorter self.config = PasswdConfig(path='/etc/passwd') self.config_g = GroupConfig(path='/etc/group') self.binder = Binder(None, self.find('passwd-config')) self.binder_g = Binder(None, self.find('group-config')) self.mgr = UsersBackend.get() def on_page_load(self): self.refresh() def refresh(self): self.config.load() self.config_g.load() self.binder.reset(self.config.tree).autodiscover().populate() self.binder_g.reset(self.config_g.tree).autodiscover().populate() @on('add-user', 'click') def on_add_user(self): self.find('input-username').visible = True @on('input-username', 'submit') def on_add_user_done(self, value): self.mgr.add_user(value) self.refresh() @on('add-group', 'click') def on_add_group(self): self.find('input-groupname').visible = True @on('input-groupname', 'submit') def on_add_group_done(self, value): self.mgr.add_group(value) self.refresh() @on('save-users', 'click') def save_users(self): self.binder.update() self.config.save() @on('save-groups', 'click') def save_groups(self): self.binder_g.update() self.config_g.save()
class NSDPlugin(SectionPlugin): def init(self): self.title = 'NSD' self.icon = 'globe' self.category = _('Software') self.append(self.ui.inflate('nsd:main')) self.config = NSDConfig(path='/etc/nsd3/nsd.conf') self.binder = Binder(None, self) self.find('zones').new_item = lambda c: ZoneData() def post_zone_bind(o, c, i, u): path = i.file if not path.startswith('/'): path = '/etc/nsd3/' + path exists = os.path.exists(path) u.find('no-file').visible = not exists u.find('file').visible = exists if exists: u.find('editor').value = open(path).read() def on_save_zone(): open(path, 'w').write(u.find('editor').value) self.context.notify('info', _('Zone saved')) def on_create_zone(): open(path, 'w').write("""$TTL 604800 @ IN SOA ns. root.ns. ( 1 ; Serial 604800 ; Refresh 86400 ; Retry 2419200 ; Expire 604800 ) ; Negative Cache TTL ; @ IN NS ns. example.com. IN A 127.0.0.1 example.com. IN AAAA ::1 """) post_zone_bind(o, c, i, u) u.find('save-zone').on('click', on_save_zone) u.find('create-zone').on('click', on_create_zone) self.find('zones').post_item_bind = post_zone_bind def on_page_load(self): self.refresh() def refresh(self): self.config.load() self.binder.reset(self.config.tree).autodiscover().populate() @on('save', 'click') def save(self): self.binder.update() self.config.save() self.refresh() self.context.notify('info', _('Saved'))
class WebserverPlugin(SectionPlugin): service_name = '' service_buttons = [] hosts_available_dir = '' hosts_enabled_dir = '' template = '' supports_host_activation = True def init(self): self.append(self.ui.inflate('webserver_common:main')) self.binder = Binder(None, self) self.find_type('servicebar').buttons = self.service_buttons self.hosts_dir = AvailabilitySymlinks(self.hosts_available_dir, self.hosts_enabled_dir, self.supports_host_activation) def delete_host(host, c): c.remove(host) self.hosts_dir.delete(host.name) def on_host_bind(o, c, host, u): host.__old_name = host.name def on_host_update(o, c, host, u): if host.__old_name != host.name: self.hosts_dir.rename(host.__old_name, host.name) host.save() def new_host(c): name = 'untitled' while os.path.exists(self.hosts_dir.get_path(name)): name += '_' self.hosts_dir.open(name, 'w').write(self.template) return WebserverHost(self, self.hosts_dir, name) self.find('hosts').delete_item = delete_host self.find('hosts').new_item = new_host self.find('hosts').post_item_bind = on_host_bind self.find('hosts').post_item_update = on_host_update self.find('header-active-checkbox').visible = \ self.find('body-active-line').visible = \ self.supports_host_activation def on_page_load(self): self.refresh() @on('save-button', 'click') def save(self): self.binder.update() self.refresh() self.context.notify('info', 'Saved') def refresh(self): self.hosts = [ WebserverHost(self, self.hosts_dir, x) for x in self.hosts_dir.list_available() ] self.binder.reset(self).autodiscover().populate() self.find_type('servicebar').reload()
class NetworkPlugin(SectionPlugin): platforms = ["debian", "centos"] def init(self): self.title = _("Network") self.icon = "globe" self.category = _("System") self.net_config = INetworkConfig.get() self.append(self.ui.inflate("network:main")) def post_interface_bind(o, c, i, u): i.add_bits(self.ui) for bit in i.bits: u.find("bits").append(self.ui.create("tab", children=[bit], title=bit.title)) u.find("up").on("click", self.on_up, i) u.find("down").on("click", self.on_down, i) u.find("restart").on("click", self.on_restart, i) def post_interface_update(o, c, i, u): for bit in i.bits: bit.apply() self.find("interfaces").post_item_bind = post_interface_bind self.find("interfaces").post_item_update = post_interface_update self.binder = Binder(self.net_config, self) def on_page_load(self): self.refresh() def refresh(self): self.net_config.rescan() sensor = Sensor.find("traffic") for i in self.net_config.interface_list: i.tx, i.rx = sensor.value(i.name) self.binder.reset().autodiscover().populate() return def on_up(self, iface=None): self.net_config.up(iface) self.refresh() def on_down(self, iface=None): self.net_config.down(iface) self.refresh() def on_restart(self, iface=None): self.on_down(iface) self.on_up(iface) @on("save", "click") def on_save(self): self.binder.update() self.net_config.save() self.refresh() self.context.notify("info", _("Saved"))
class NetworkPlugin (SectionPlugin): platforms = ['debian', 'centos'] def init(self): self.title = _('Network') self.icon = 'globe' self.category = _('System') self.net_config = INetworkConfig.get() self.append(self.ui.inflate('network:main')) def post_interface_bind(o, c, i, u): i.add_bits(self.ui) for bit in i.bits: u.find('bits').append(self.ui.create( 'tab', children=[bit], title=bit.title, )) u.find('up').on('click', self.on_up, i) u.find('down').on('click', self.on_down, i) def post_interface_update(o, c, i, u): for bit in i.bits: bit.apply() self.find('interfaces').post_item_bind = post_interface_bind self.find('interfaces').post_item_update = post_interface_update self.binder = Binder(self.net_config, self) def on_page_load(self): self.refresh() def refresh(self): self.net_config.rescan() sensor = Sensor.find('traffic') for i in self.net_config.interface_list: i.tx, i.rx = sensor.value(i.name) self.binder.reset().autodiscover().populate() return def on_up(self, iface=None): self.net_config.up(iface) self.refresh() def on_down(self, iface=None): self.net_config.down(iface) self.refresh() @on('save', 'click') def on_save(self): self.binder.update() self.net_config.save() self.refresh() self.context.notify('info', _('Saved'))
class WebserverPlugin (SectionPlugin): service_name = '' service_buttons = [] hosts_available_dir = '' hosts_enabled_dir = '' template = '' supports_host_activation = True def init(self): self.append(self.ui.inflate('webserver_common:main')) self.binder = Binder(None, self) self.find_type('servicebar').buttons = self.service_buttons self.hosts_dir = AvailabilitySymlinks( self.hosts_available_dir, self.hosts_enabled_dir, self.supports_host_activation ) def delete_host(host, c): c.remove(host) self.hosts_dir.delete(host.name) def on_host_bind(o, c, host, u): host.__old_name = host.name def on_host_update(o, c, host, u): if host.__old_name != host.name: self.hosts_dir.rename(host.__old_name, host.name) host.save() def new_host(c): name = 'untitled' while os.path.exists(self.hosts_dir.get_path(name)): name += '_' self.hosts_dir.open(name, 'w').write(self.template) return WebserverHost(self, self.hosts_dir, name) self.find('hosts').delete_item = delete_host self.find('hosts').new_item = new_host self.find('hosts').post_item_bind = on_host_bind self.find('hosts').post_item_update = on_host_update self.find('header-active-checkbox').visible = \ self.find('body-active-line').visible = \ self.supports_host_activation def on_page_load(self): self.refresh() @on('save-button', 'click') def save(self): self.binder.update() self.refresh() self.context.notify('info', 'Saved') def refresh(self): self.hosts = [WebserverHost(self, self.hosts_dir, x) for x in self.hosts_dir.list_available()] self.binder.reset(self).autodiscover().populate() self.find_type('servicebar').reload()
class BIND9Plugin (SectionPlugin): def init(self): self.title = 'BIND9' self.icon = 'globe' self.category = _('Software') self.append(self.ui.inflate('bind9:main')) self.config = BIND9Config(path='/etc/bind/named.conf') self.binder = Binder(None, self) self.find('zones').new_item = lambda c: ZoneData() def post_zone_bind(o, c, i, u): path = i.file if not path.startswith('/'): path = '/etc/bind/' + path exists = os.path.exists(path) u.find('no-file').visible = not exists u.find('file').visible = exists if exists: u.find('editor').value = open(path).read() def on_save_zone(): open(path, 'w').write(u.find('editor').value) self.context.notify('info', _('Zone saved')) def on_create_zone(): open(path, 'w').write("""$TTL 604800 @ IN SOA ns. root.ns. ( 1 ; Serial 604800 ; Refresh 86400 ; Retry 2419200 ; Expire 604800 ) ; Negative Cache TTL ; @ IN NS ns. example.com. IN A 127.0.0.1 example.com. IN AAAA ::1 """) post_zone_bind(o, c, i, u) u.find('save-zone').on('click', on_save_zone) u.find('create-zone').on('click', on_create_zone) self.find('zones').post_item_bind = post_zone_bind def on_page_load(self): self.refresh() def refresh(self): self.config.load() self.binder.reset(self.config.tree).autodiscover().populate() @on('save', 'click') def save(self): self.binder.update() self.config.save() self.refresh() self.context.notify('info', _('Saved'))
class TaskManager(SectionPlugin): def init(self): self.title = _('Processes') self.icon = 'th-list' self.category = _('System') self.append(self.ui.inflate('taskmgr:main')) def post_item_bind(object, collection, item, ui): ui.find('term').on('click', self.on_term, item) ui.find('kill').on('click', self.on_kill, item) self.find('processes').post_item_bind = post_item_bind self.binder = Binder(None, self) self.sorting = '_cpu' self.sorting_reverse = True for x in ['_cpu', 'pid', '_sort_ram', '_sort_name']: self.find('sort-by-' + x).on('click', self.sort, x) def on_page_load(self): self.refresh() def sort(self, by): if self.sorting == by: self.sorting_reverse = not self.sorting_reverse else: self.sorting_reverse = by in ['_cpu', '_ram'] self.sorting = by self.refresh() def refresh(self): self.processes = list(psutil.process_iter()) for p in self.processes: p._name = p.name p._cmd = ' '.join(p.cmdline) p._cpu = p.get_cpu_percent(interval=0) p._ram = '%i K' % int(p.get_memory_info()[0] / 1024) p._ppid = p.ppid p._sort_ram = p.get_memory_info()[0] p._sort_name = p.name.lower() try: p._username = p.username except: p._username = '******' self.processes = sorted(self.processes, key=lambda x: getattr(x, self.sorting), reverse=self.sorting_reverse) self.binder.reset(self).autodiscover().populate() def on_term(self, p): os.kill(p.pid, 15) self.refresh() def on_kill(self, p): os.kill(p.pid, 9) self.refresh()
class TaskManager (SectionPlugin): def init(self): self.title = _('Processes') self.icon = 'th-list' self.category = _('System') self.append(self.ui.inflate('taskmgr:main')) def post_item_bind(object, collection, item, ui): ui.find('term').on('click', self.on_term, item) ui.find('kill').on('click', self.on_kill, item) self.find('processes').post_item_bind = post_item_bind self.binder = Binder(None, self) self.sorting = '_cpu' self.sorting_reverse = True for x in ['_cpu', 'pid', '_sort_ram', '_sort_name']: self.find('sort-by-' + x).on('click', self.sort, x) def on_page_load(self): self.refresh() def sort(self, by): if self.sorting == by: self.sorting_reverse = not self.sorting_reverse else: self.sorting_reverse = by in ['_cpu', '_ram'] self.sorting = by self.refresh() def refresh(self): self.processes = list(psutil.process_iter()) for p in self.processes: p._name = p.name p._cmd = ' '.join(p.cmdline) p._cpu = p.get_cpu_percent(interval=0) p._ram = '%i K' % int(p.get_memory_info()[0] / 1024) p._ppid = p.ppid p._sort_ram = p.get_memory_info()[0] p._sort_name = p.name.lower() try: p._username = p.username except: p._username = '******' self.processes = sorted(self.processes, key=lambda x: getattr(x, self.sorting), reverse=self.sorting_reverse) self.binder.reset(self).autodiscover().populate() def on_term(self, p): os.kill(p.pid, 15) self.refresh() def on_kill(self, p): os.kill(p.pid, 9) self.refresh()
class Filesystems (SectionPlugin): def init(self): self.title = _('Filesystems') self.icon = 'hdd' self.category = _('System') self.append(self.ui.inflate('fstab:main')) self.find('type').labels = ['Auto', 'EXT2', 'EXT3', 'EXT4', 'NTFS', 'FAT', 'ZFS', 'ReiserFS', 'Samba', 'None', 'Loop'] self.find('type').values = ['auto', 'ext2', 'ext3', 'ext4', 'ntfs', 'vfat', 'zfs', 'reiser', 'smb', 'none', 'loop'] self.fstab_config = FSTabConfig(path='/etc/fstab') self.mounts = MountsBackend.get() self.binder = Binder(None, self) self.find('fstab').find('filesystems').new_item = lambda c: FilesystemData() def post_mount_bind(object, collection, item, ui): ui.find('umount').on('click', self.on_umount, item) self.find('mounts').find('filesystems').post_item_bind = post_mount_bind def on_page_load(self): self.refresh() def on_umount(self, mount): subprocess.call(['umount', mount.mountpoint]) self.context.notify('info', _('Unmounted')) self.refresh() @on('mount-all', 'click') def on_mount_all(self): self.save() if subprocess.call(['mount', '-a']): self.context.notify('error', _('mount -a failed')) self.refresh() @on('refresh', 'click') def refresh(self): self.reload_disks() self.fstab_config.load() self.fstab = self.fstab_config.tree self.mounts.reload() self.binder.reset(self).autodiscover().populate() def reload_disks(self): lst = disks.list_devices(by_uuid=True, by_id=True, by_label=True) self.find('device').labels = [x[0] for x in lst] self.find('device').values = [x[1] for x in lst] @on('save', 'click') def save(self): self.binder.update() self.fstab_config.save() self.context.notify('info', _('Saved'))
class LinuxBasicNetworkConfigSet (NetworkConfigBit): cls = 'linux-basic' title = 'Basic' def init(self): self.append(self.ui.inflate('network:bit-linux-basic')) self.binder = Binder(self.iface, self) def refresh(self): self.binder.reset(self.iface).autodiscover().populate() def apply(self): self.binder.update()
class LinuxDHCPNetworkConfigSet(NetworkConfigBit): cls = 'linux-dhcp' title = 'DHCP' def init(self): self.append(self.ui.inflate('network:bit-linux-dhcp')) self.binder = Binder(self.iface, self) def refresh(self): self.binder.reset(self.iface).autodiscover().populate() def apply(self): self.binder.update()
class LinuxIfUpDownNetworkConfigSet(NetworkConfigBit): cls = 'linux-ifupdown' title = 'Scripts' def init(self): self.append(self.ui.inflate('network:bit-linux-ifupdown')) self.binder = Binder(self.iface, self) def refresh(self): self.binder.reset(self.iface).autodiscover().populate() def apply(self): self.binder.update()
class LinuxIfUpDownNetworkConfigSet (NetworkConfigBit): cls = 'linux-ifupdown' title = 'Scripts' def init(self): self.append(self.ui.inflate('network:bit-linux-ifupdown')) self.binder = Binder(self.iface, self) def refresh(self): self.binder.reset(self.iface).autodiscover().populate() def apply(self): self.binder.update()
class WebserverPlugin(SectionPlugin): service_name = "" service_buttons = [] hosts_available_dir = "" hosts_enabled_dir = "" template = "" def init(self): self.append(self.ui.inflate("webserver_common:main")) self.binder = Binder(None, self) self.find_type("servicebar").buttons = self.service_buttons self.hosts_dir = AvailabilitySymlinks(self.hosts_available_dir, self.hosts_enabled_dir) def delete_host(host, c): c.remove(host) self.hosts_dir.delete(host.name) def on_host_bind(o, c, host, u): host.__old_name = host.name def on_host_update(o, c, host, u): if host.__old_name != host.name: self.hosts_dir.rename(host.__old_name, host.name) host.save() def new_host(c): name = "untitled" self.hosts_dir.open(name, "w").write(self.template) return WebserverHost(self.hosts_dir, name) self.find("hosts").delete_item = delete_host self.find("hosts").new_item = new_host self.find("hosts").post_item_bind = on_host_bind self.find("hosts").post_item_update = on_host_update def on_page_load(self): self.refresh() @on("save-button", "click") def save(self): self.binder.update() self.refresh() self.context.notify("info", "Saved") def refresh(self): self.hosts = [WebserverHost(self.hosts_dir, x) for x in self.hosts_dir.list_available()] self.binder.reset(self).autodiscover().populate() self.find_type("servicebar").reload()
class RAID (SectionPlugin): def init(self): self.title = 'LSI MegaRAID' self.icon = 'hdd' self.category = _('System') self.append(self.ui.inflate('megaraid:main')) self.mgr = RAIDManager.get() self.binder = Binder(self.mgr, self) def on_page_load(self): self.refresh() def refresh(self): self.mgr.refresh() self.binder.reset().autodiscover().populate()
class TaskManager (SectionPlugin): def init(self): self.title = 'Processes' self.icon = 'th-list' self.category = 'System' self.append(self.ui.inflate('taskmgr:main')) def post_item_bind(object, collection, item, ui): ui.find('term').on('click', self.on_term, item) ui.find('kill').on('click', self.on_kill, item) self.find('processes').post_item_bind = post_item_bind self.binder = Binder(None, self) def on_page_load(self): self.refresh() def refresh(self): profile('Process list') self.processes = list(psutil.process_iter()) for p in self.processes: p._name = p.name p._cmd = ' '.join(p.cmdline) p._cpu = p.get_cpu_percent(interval=0) p._ram = '%i K' % int(p.get_memory_info()[0] / 1024) p._ppid = p.ppid try: p._username = p.username except: p._username = '******' self.binder.reset(self).autodiscover().populate() profile_end('Process list') def on_term(self, p): os.kill(p.pid, 15) self.refresh() def on_kill(self, p): os.kill(p.pid, 9) self.refresh()
class TaskManager(SectionPlugin): def init(self): self.title = 'Processes' self.icon = 'th-list' self.category = 'System' self.append(self.ui.inflate('taskmgr:main')) def post_item_bind(object, collection, item, ui): ui.find('term').on('click', self.on_term, item) ui.find('kill').on('click', self.on_kill, item) self.find('processes').post_item_bind = post_item_bind self.binder = Binder(None, self) def on_page_load(self): self.refresh() def refresh(self): profile('Process list') self.processes = list(psutil.process_iter()) for p in self.processes: p._name = p.name p._cmd = ' '.join(p.cmdline) p._cpu = p.get_cpu_percent(interval=0) p._ram = '%i K' % int(p.get_memory_info()[0] / 1024) p._ppid = p.ppid try: p._username = p.username except: p._username = '******' self.binder.reset(self).autodiscover().populate() profile_end('Process list') def on_term(self, p): os.kill(p.pid, 15) self.refresh() def on_kill(self, p): os.kill(p.pid, 9) self.refresh()
class Cron(SectionPlugin): def init(self): self.title = 'Cron' self.icon = 'time' self.category = _('System') self.append(self.ui.inflate('cron:main')) self.binder = Binder(None, self.find('config')) self.find('normal_tasks').new_item = lambda c: CrontabNormalTaskData() self.find( 'special_tasks').new_item = lambda c: CrontabSpecialTaskData() self.find('env_settings').new_item = lambda c: CrontabEnvSettingData() self.current_user = '******' def on_page_load(self): self.refresh() @on('user-select', 'click') def on_user_select(self): self.current_user = self.find('users').value self.refresh() def refresh(self): users_select = self.find('users') users_select.value = self.current_user users = [ x.name for x in PasswdConfig(path='/etc/passwd').load().tree.users ] users_select.values = users_select.labels = users self.config = CronManager.get().load_tab(self.current_user) self.binder.reset(self.config.tree).autodiscover().populate() @on('save', 'click') def on_save(self): self.binder.update() try: CronManager.get().save_tab(self.current_user, self.config) self.refresh() except Exception, e: self.context.notify('error', e.message)
class VSFTPDExtension(BaseExtension): default_config = {"created": False, "user": None, "password": None} name = "FTP" def init(self): self.append(self.ui.inflate("vh-vsftpd:ext")) self.binder = Binder(self, self) self.binder.autodiscover() if not self.config["created"]: self.config["username"] = self.website.slug self.config["password"] = str(uuid.uuid4()) self.config["created"] = True self.refresh() def refresh(self): self.binder.reset().populate() def update(self): pass
class Exports (SectionPlugin): def init(self): self.title = 'NFS Exports' self.icon = 'hdd' self.category = 'System' self.append(self.ui.inflate('exports:main')) self.config = ExportsConfig(path='/etc/exports') self.binder = Binder(None, self) self.find('exports').new_item = lambda c: ExportData() self.find('clients').new_item = lambda c: ClientData() def on_page_load(self): self.config.load() self.binder.reset(self.config.tree).autodiscover().populate() @on('save', 'click') def save(self): self.binder.update() self.config.save() self.context.notify('info', 'Saved')
class Hosts (SectionPlugin): def init(self): self.title = _('Hosts') self.icon = 'sitemap' self.category = _('System') self.append(self.ui.inflate('hosts:main')) self.config = HostsConfig(path='/etc/hosts') self.binder = Binder(None, self.find('hosts-config')) self.find('aliases').new_item = lambda c: AliasData() self.find('hosts').new_item = lambda c: HostData() def on_page_load(self): self.config.load() self.binder.reset(self.config.tree).autodiscover().populate() @on('save', 'click') def save(self): self.binder.update() self.config.save()
class Services (SectionPlugin): def init(self): self.title = _('Services') self.icon = 'play' self.category = _('Software') self.append(self.ui.inflate('services:main')) self.mgr = ServiceMultiplexor.get() self.binder = Binder(None, self.find('main')) def post_item_bind(object, collection, item, ui): ui.find('stop').on('click', self.on_stop, item) ui.find('restart').on('click', self.on_restart, item) ui.find('start').on('click', self.on_start, item) ui.find('stop').visible = item.running ui.find('restart').visible = item.running ui.find('start').visible = not item.running self.find('services').post_item_bind = post_item_bind def on_page_load(self): self.refresh() def refresh(self): self.services = sorted(self.mgr.get_all(), key=lambda x: x.name) self.binder.reset(self).autodiscover().populate() def on_start(self, item): item.start() self.refresh() self.context.notify('info', _('%s started') % item.name) def on_stop(self, item): item.stop() self.refresh() self.context.notify('info', _('%s stopped') % item.name) def on_restart(self, item): item.restart() self.refresh() self.context.notify('info', _('%s restarted') % item.name)
class Services(SectionPlugin): def init(self): self.title = _('Services') self.icon = 'play' self.category = _('Software') self.append(self.ui.inflate('services:main')) self.mgr = ServiceMultiplexor.get() self.binder = Binder(None, self.find('main')) def post_item_bind(object, collection, item, ui): ui.find('stop').on('click', self.on_stop, item) ui.find('restart').on('click', self.on_restart, item) ui.find('start').on('click', self.on_start, item) ui.find('stop').visible = item.running ui.find('restart').visible = item.running ui.find('start').visible = not item.running self.find('services').post_item_bind = post_item_bind def on_page_load(self): self.refresh() def refresh(self): self.services = sorted(self.mgr.get_all(), key=lambda x: x.name) self.binder.reset(self).autodiscover().populate() def on_start(self, item): item.start() self.refresh() self.context.notify('info', _('%s started') % item.name) def on_stop(self, item): item.stop() self.refresh() self.context.notify('info', _('%s stopped') % item.name) def on_restart(self, item): item.restart() self.refresh() self.context.notify('info', _('%s restarted') % item.name)
class Cron (SectionPlugin): def init(self): self.title = 'Cron' self.icon = 'time' self.category = _('System') self.append(self.ui.inflate('cron:main')) self.binder = Binder(None, self.find('config')) self.find('normal_tasks').new_item = lambda c: CrontabNormalTaskData() self.find('special_tasks').new_item = lambda c: CrontabSpecialTaskData() self.find('env_settings').new_item = lambda c: CrontabEnvSettingData() self.current_user = '******' def on_page_load(self): self.refresh() @on('user-select', 'click') def on_user_select(self): self.current_user = self.find('users').value self.refresh() def refresh(self): users_select = self.find('users') users_select.value = self.current_user users = [x.name for x in PasswdConfig(path='/etc/passwd').load().tree.users] users_select.values = users_select.labels = users self.config = CronManager.get().load_tab(self.current_user) self.binder.reset(self.config.tree).autodiscover().populate() @on('save', 'click') def on_save(self): self.binder.update() try: CronManager.get().save_tab(self.current_user, self.config) self.refresh() except Exception, e: self.context.notify('error', e.message)
class Resolv (SectionPlugin): def init(self): self.title = 'Nameservers' self.icon = 'globe' self.category = 'System' self.append(self.ui.inflate('resolv:main')) self.find('name-box').labels = ['DNS nameserver', 'Local domain name', 'Search list', 'Sort list', 'Options'] self.find('name-box').values = ['nameserver', 'domain', 'search', 'sortlist', 'options'] self.config = ResolvConfig(path='/etc/resolv.conf') self.binder = Binder(None, self.find('resolv-config')) self.find('items').new_item = lambda c: ItemData() def on_page_load(self): self.config.load() self.binder.reset(self.config.tree).autodiscover().populate() @on('save', 'click') def save(self): self.binder.update() self.config.save()
class RAID(SectionPlugin): def init(self): self.title = _('RAID') self.icon = 'hdd' self.category = _('System') self.append(self.ui.inflate('raid:main')) def post_array_bind(o, c, i, u): u.find('recovery').visible = i.recovery self.find('arrays').post_item_bind = post_array_bind self.mgr = RAIDManager.get() self.binder = Binder(self.mgr, self) def on_page_load(self): self.refresh() def refresh(self): self.mgr.refresh() self.binder.reset().autodiscover().populate()
class RAID (SectionPlugin): def init(self): self.title = _('RAID') self.icon = 'hdd' self.category = _('System') self.append(self.ui.inflate('raid:main')) def post_array_bind(o, c, i, u): u.find('recovery').visible = i.recovery self.find('arrays').post_item_bind = post_array_bind self.mgr = RAIDManager.get() self.binder = Binder(self.mgr, self) def on_page_load(self): self.refresh() def refresh(self): self.mgr.refresh() self.binder.reset().autodiscover().populate()
class Supervisor (SectionPlugin): def init(self): self.title = 'Supervisor' self.icon = 'play' self.category = 'Software' self.append(self.ui.inflate('supervisor:main')) self.mgr = SupervisorServiceManager.get() self.binder = Binder(None, self.find('main')) self.find('programs').new_item = lambda c: ProgramData() self.config = SupervisorConfig(path='/etc/supervisor/supervisord.conf') def on_page_load(self): self.refresh() def refresh(self): self.config.load() self.mgr.fill(self.config.tree.programs) self.binder.reset(self.config.tree).autodiscover().populate() @on('save', 'click') def on_save(self): self.binder.update() self.config.save() self.refresh()
class Supervisor(SectionPlugin): def init(self): self.title = 'Supervisor' self.icon = 'play' self.category = 'Software' self.append(self.ui.inflate('supervisor:main')) self.mgr = SupervisorServiceManager.get() self.binder = Binder(None, self.find('main')) self.find('programs').new_item = lambda c: ProgramData() self.config = SupervisorConfig(path='/etc/supervisor/supervisord.conf') def on_page_load(self): self.refresh() def refresh(self): self.config.load() self.mgr.fill(self.config.tree.programs) self.binder.reset(self.config.tree).autodiscover().populate() @on('save', 'click') def on_save(self): self.binder.update() self.config.save() self.refresh()
class Samba(SectionPlugin): def init(self): self.title = 'Samba' self.icon = 'folder-close' self.category = _('Software') self.append(self.ui.inflate('samba:main')) self.find('servicebar').name = platform_select( debian='samba', ubuntu='smbd', centos='smb', default='samba', ) self.find('servicebar').reload() self.binder = Binder(None, self.find('config')) self.find('shares').new_item = lambda c: ShareData() self.config = SambaConfig(path='/etc/samba/smb.conf') def post_item_bind(object, collection, item, ui): ui.find('disconnect').on('click', self.on_disconnect, item) self.find('connections').post_item_bind = post_item_bind def post_user_bind(object, collection, item, ui): def delete_user(): self.usermgr.delete(item.username) self.refresh() ui.find('delete').on('click', delete_user) def set_password(): if self.usermgr.set_password(item.username, ui.find('password').value): self.context.notify('info', _('Password updated')) ui.find('password').value = '' else: self.context.notify('error', _('Password update failed')) ui.find('password-set').on('click', set_password) self.find('user-list').post_item_bind = post_user_bind self.usermgr = SambaUsers() self.binder_u = Binder(self.usermgr, self.find('users')) self.monitor = SambaMonitor() self.binder_m = Binder(self.monitor, self.find('status')) def on_page_load(self): self.refresh() def on_disconnect(self, connection): connection.disconnect() self.refresh() def refresh(self): self.config.load() self.monitor.refresh() self.usermgr.load() self.binder.reset(self.config.tree).autodiscover().populate() self.binder_m.reset(self.monitor).autodiscover().populate() self.binder_u.reset(self.usermgr).autodiscover().populate() users_dropdown = self.find('add-user-list') users = [ x.name for x in PasswdConfig(path='/etc/passwd').load().tree.users ] for u in self.usermgr.users: if u.username in users: users.remove(u.username) users_dropdown.values = users_dropdown.labels = users @on('add-user', 'click') def on_add_user(self): self.usermgr.create(self.find('add-user-list').value) self.refresh() @on('save', 'click') def on_save(self): self.binder.update() self.config.save() self.refresh()
class Users (SectionPlugin): def init(self): self.title = _('Users') self.icon = 'group' self.category = _('System') self.append(self.ui.inflate('users:main')) def _filterOnlyUsers(x): u = int(x.uid) if u >= 1000: return True return False def _filterOnlySystemUsers(x): u = int(x.uid) if u >= 1000: return False return True def _sorter(x): g = int(x.gid) if g >= 1000: return g - 10000 return g self.find('users').filter = _filterOnlyUsers self.find('system-users').filter = _filterOnlySystemUsers self.find('groups').sorting = _sorter self.config = PasswdConfig(path='/etc/passwd') self.config_g = GroupConfig(path='/etc/group') self.binder = Binder(None, self.find('passwd-config')) self.binder_system = Binder(None, self.find('passwd-config-system')) self.binder_g = Binder(None, self.find('group-config')) self.mgr = UsersBackend.get() def post_item_bind(object, collection, item, ui): ui.find('change-password').on('click', self.change_password, item, ui) ui.find('remove-password').on('click', self.remove_password, item) if not os.path.exists(item.home): ui.find('create-home-dir').on('click', self.create_home_dir, item, ui) ui.find('create-home-dir').visible = True self.find('users').post_item_bind = post_item_bind def on_page_load(self): self.refresh() def refresh(self): self.config.load() self.config_g.load() self.binder.reset(self.config.tree).autodiscover().populate() self.binder_system.reset(self.config.tree).autodiscover().populate() self.binder_g.reset(self.config_g.tree).autodiscover().populate() @on('add-user', 'click') def on_add_user(self): self.find('input-username').visible = True @on('input-username', 'submit') def on_add_user_done(self, value): self.mgr.add_user(value) self.refresh() @on('add-group', 'click') def on_add_group(self): self.find('input-groupname').visible = True @on('input-groupname', 'submit') def on_add_group_done(self, value): self.mgr.add_group(value) self.refresh() @on('save-users', 'click') @on('save-system-users', 'click') def save_users(self): self.binder.update() self.config.save() @on('save-groups', 'click') def save_groups(self): self.binder_g.update() self.config_g.save() def create_home_dir(self, user, ui): self.mgr.make_home_dir(user) self.context.notify('info', _('Home dir for %s was created') % user.name) ui.find('create-home-dir').visible = False def change_password(self, user, ui): new_password = ui.find('new-password').value if new_password: try: self.mgr.change_password(user, new_password) self.context.notify('info', _('Password for %s was changed') % user.name) ui.find('new-password').value = '' except Exception, e: self.context.notify('error', _('Error: "%s"') % e.message) else:
class Firewall(SectionPlugin): platforms = ['centos', 'debian'] def init(self): self.title = _('Firewall') self.icon = 'fire' self.category = _('System') self.append(self.ui.inflate('iptables:main')) self.fw_mgr = FirewallManager.get() self.config = IPTablesConfig(path=self.fw_mgr.config_path_ajenti) self.binder = Binder(None, self.find('config')) self.find('tables').new_item = lambda c: TableData() self.find('chains').new_item = lambda c: ChainData() self.find('rules').new_item = lambda c: RuleData() self.find('options').new_item = lambda c: OptionData() self.find('options').binding = OptionsBinding self.find('options').filter = lambda i: not i.name in ['j', 'jump'] def post_rule_bind(o, c, i, u): u.find('add-option').on('change', self.on_add_option, c, i, u) action = '' j_option = i.get_option('j', 'jump') if j_option: action = j_option.arguments[0].value u.find('action').text = action u.find('action').style = 'iptables-action iptables-%s' % action u.find('action-select').value = action u.find('title').text = i.comment if i.comment else i.summary def post_rule_update(o, c, i, u): action = u.find('action-select').value j_option = i.get_option('j', 'jump') if j_option: j_option.arguments[0].value = action else: if action: o = OptionData.create_destination() o.arguments[0].value = action i.options.append(o) self.find('rules').post_item_bind = post_rule_bind self.find('rules').post_item_update = post_rule_update self.find('add-option').values = self.find('add-option').labels = [ _('Add option') ] + sorted(OptionData.templates.keys()) def on_page_load(self): if not os.path.exists(self.fw_mgr.config_path_ajenti): if not os.path.exists(self.fw_mgr.config_path): open(self.fw_mgr.config_path, 'w').write(""" *mangle :PREROUTING ACCEPT [0:0] :INPUT ACCEPT [0:0] :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [0:0] :POSTROUTING ACCEPT [0:0] COMMIT *nat :PREROUTING ACCEPT [0:0] :INPUT ACCEPT [0:0] :OUTPUT ACCEPT [0:0] :POSTROUTING ACCEPT [0:0] COMMIT *filter :INPUT ACCEPT [0:0] :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [0:0] COMMIT """) open(self.fw_mgr.config_path_ajenti, 'w').write(open(self.fw_mgr.config_path).read()) self.config.load() self.refresh() @on('load-current', 'click') def on_load_current(self): subprocess.call('iptables-save > %s' % self.fw_mgr.config_path, shell=True) self.config.load() self.refresh() def refresh(self): self.find('autostart').text = (_('Disable') if self.fw_mgr.get_autostart_state() else _('Enable')) + _(' autostart') self.binder.reset(self.config.tree) actions = ['ACCEPT', 'DROP', 'REJECT', 'LOG', 'MASQUERADE', 'DNAT', 'SNAT'] + \ list(set(itertools.chain.from_iterable([[c.name for c in t.chains] for t in self.config.tree.tables]))) self.find('action-select').labels = actions self.find('action-select').values = actions self.find('chain-action-select').labels = actions self.find('chain-action-select').values = actions self.binder.autodiscover().populate() @on('autostart', 'click') def on_autostart_change(self): self.fw_mgr.set_autostart_state(not self.fw_mgr.get_autostart_state()) self.refresh() def on_add_option(self, options, rule, ui): o = OptionData.create(ui.find('add-option').value) ui.find('add-option').value = '' rule.options.append(o) self.binder.populate() @on('save', 'click') def save(self): self.binder.update() for t in self.config.tree.tables: for c in t.chains: for r in c.rules: r.verify() self.config.save() open(self.fw_mgr.config_path, 'w').write(''.join( l.split('#')[0] + '\n' for l in open(self.fw_mgr.config_path_ajenti).read().splitlines())) self.refresh() self.context.notify('info', _('Saved')) @on('edit', 'click') def raw_edit(self): self.context.launch('notepad', path='/etc/iptables.up.rules') @on('apply', 'click') def apply(self): self.save() cmd = 'cat %s | iptables-restore' % self.fw_mgr.config_path if subprocess.call(cmd, shell=True) != 0: self.context.launch('terminal', command=cmd) else: self.context.notify('info', _('Applied successfully'))
class Packages(SectionPlugin): def init(self): self.title = 'Packages' self.icon = 'gift' self.category = 'System' self.mgr = PackageManager.get() self.append(self.ui.inflate('packages:main')) def post_item_bind(object, collection, item, ui): ui.find('install').on('click', self.on_install, item) ui.find('remove').on('click', self.on_remove, item) ui.find('cancel').on('click', self.on_cancel, item) ui.find('install').visible = item.action == None ui.find( 'remove').visible = item.action == None and item.state == 'i' ui.find('cancel').visible = item.action != None self.find('upgradeable').post_item_bind = post_item_bind self.find('search').post_item_bind = post_item_bind self.find('pending').post_item_bind = post_item_bind self.binder = Binder(None, self.find('bind-root')) self.binder_p = Binder(self, self.find('bind-pending')) self.binder_s = CollectionAutoBinding([], None, self.find('search')).populate() self.pending = {} def refresh(self): self.fill(self.mgr.upgradeable) self.binder.reset(self.mgr).autodiscover().populate() self.binder_s.unpopulate().populate() self._pending = self.pending.values() self.binder_p.reset(self).autodiscover().populate() @intent('install-package') @restrict('packages:modify') def intent_install(self, package): self.activate() p = PackageInfo() p.name, p.action = package, 'i' self.mgr.do([p]) def on_page_load(self): self.mgr.refresh() self.refresh() @restrict('packages:modify') def on_install(self, package): package.action = 'i' self.pending[package.name] = package self.refresh() @restrict('packages:modify') def on_cancel(self, package): package.action = None if package.name in self.pending: del self.pending[package.name] self.refresh() @restrict('packages:modify') def on_remove(self, package): package.action = 'r' self.pending[package.name] = package self.refresh() @on('get-lists-button', 'click') @restrict('packages:refresh') def on_get_lists(self): self.mgr.get_lists() @on('apply-button', 'click') @restrict('packages:modify') def on_apply(self): self.mgr.do(self.pending.values()) self.pending = {} self.refresh() @on('upgrade-all-button', 'click') @restrict('packages:modify') def on_upgrade_all(self): for p in self.mgr.upgradeable: p.action = 'i' self.pending[p.name] = p self.refresh() @on('cancel-all-button', 'click') @restrict('packages:modify') def on_cancel_all(self): self.pending = {} self.refresh() def fill(self, packages): for p in packages: if p.name in self.pending: p.action = self.pending[p.name].action @on('search-button', 'click') def on_search(self): query = self.find('search-box').value results = self.mgr.search(query) if self.binder_s: self.binder_s.unpopulate() if len(results) > 100: self.find( 'search-counter').text = '%i found, 100 shown' % len(results) results = results[:100] else: self.find('search-counter').text = '%i found' % len(results) self.fill(results) self.binder_s = CollectionAutoBinding(results, None, self.find('search')).populate()
class FileManager(SectionPlugin): default_classconfig = {'root': '/'} classconfig_editor = FileManagerConfigEditor classconfig_root = True def init(self): self.title = _('File Manager') self.category = _('Tools') self.icon = 'folder-open' self.backend = FMBackend().get() self.append(self.ui.inflate('fm:main')) self.controller = Controller() def post_item_bind(object, collection, item, ui): ui.find('name').on('click', self.on_item_click, object, item) ui.find('edit').on('click', self.edit, item.fullpath) self.find('items').post_item_bind = post_item_bind def post_bc_bind(object, collection, item, ui): ui.find('name').on('click', self.on_bc_click, object, item) self.find('breadcrumbs').post_item_bind = post_bc_bind self.clipboard = [] self.tabs = self.find('tabs') self.find('dialog').buttons = [ { 'id': 'save', 'text': _('Save') }, { 'id': 'cancel', 'text': _('Cancel') }, ] def on_first_page_load(self): self.controller.new_tab(self.classconfig['root']) self.binder = Binder( self.controller, self.find('filemanager')).autodiscover().populate() self.binder_c = Binder( self, self.find('bind-clipboard')).autodiscover().populate() def refresh_clipboard(self): self.binder_c.reset().autodiscover().populate() @on('tabs', 'switch') def on_tab_switch(self): if self.tabs.active == (len(self.controller.tabs) - 1): self.controller.new_tab(self.classconfig['root']) self.refresh() @on('close', 'click') def on_tab_close(self): if len(self.controller.tabs) > 2: self.controller.tabs.pop(self.tabs.active) self.tabs.active = 0 self.refresh() @on('new-file', 'click') def on_new_file(self): open( os.path.join(self.controller.tabs[self.tabs.active].path, 'new file'), 'w').close() self.refresh() def upload(self, name, file): open(os.path.join(self.controller.tabs[self.tabs.active].path, name), 'w').write(file.read()) self.refresh() @on('new-dir', 'click') def on_new_directory(self): os.mkdir( os.path.join(self.controller.tabs[self.tabs.active].path, 'new directory')) self.refresh() @on('mass-cut', 'click') def on_cut(self): l = self._get_checked() for i in l: i.action = 'cut' self.clipboard += l self.refresh_clipboard() @on('mass-copy', 'click') def on_copy(self): l = self._get_checked() for i in l: i.action = 'copy' self.clipboard += l self.refresh_clipboard() @on('mass-delete', 'click') def on_delete(self): self.backend.remove(self._get_checked()) self.refresh() @on('paste', 'click') def on_paste(self): tab = self.controller.tabs[self.tabs.active] for_move = [] for_copy = [] for i in self.clipboard: if i.action == 'cut': for_move.append(i) else: for_copy.append(i) if for_move: self.backend.move(for_move, tab.path) if for_copy: self.backend.copy(for_copy, tab.path) self.clipboard = [] self.refresh_clipboard() self.refresh() def _get_checked(self): self.binder.update() tab = self.controller.tabs[self.tabs.active] r = [] for item in tab.items: if item.checked: r.append(item) item.checked = False self.refresh() return r @on('clear-clipboard', 'click') def on_clear_clipboard(self): self.clipboard = [] self.refresh_clipboard() def on_item_click(self, tab, item): path = os.path.join(tab.path, item.name) if not os.path.isdir(path): self.edit(path) if not path.startswith(self.classconfig['root']): return tab.navigate(path) self.refresh() def edit(self, path): self.find('dialog').visible = True self.item = Item(path) self.item.read() self.binder_d = Binder(self.item, self.find('dialog')).autodiscover().populate() @on('dialog', 'button') def on_close_dialog(self, button): self.find('dialog').visible = False if button == 'save': self.binder_d.update() self.item.write() self.refresh() def on_bc_click(self, tab, item): if not item.path.startswith(self.classconfig['root']): return tab.navigate(item.path) self.refresh() def refresh(self): for tab in self.controller.tabs: tab.refresh() self.binder.populate()
class Firewall (SectionPlugin): def init(self): self.title = 'Firewall' self.icon = 'fire' self.category = 'System' self.append(self.ui.inflate('iptables:main')) self.fw_mgr = FirewallManager.get() self.config = IPTablesConfig(path=self.fw_mgr.config_path) self.binder = Binder(None, self.find('config')) self.find('tables').new_item = lambda c: TableData() self.find('chains').new_item = lambda c: ChainData() self.find('rules').new_item = lambda c: RuleData() self.find('options').new_item = lambda c: OptionData() self.find('options').binding = OptionsBinding self.find('options').filter = lambda i: not i.name in ['j', 'jump'] def post_rule_bind(o, c, i, u): u.find('add-option').on('change', self.on_add_option, c, i, u) actions = ['ACCEPT', 'DROP', 'REJECT', 'LOG', 'MASQUERADE', 'DNAT', 'SNAT'] + \ list(set(itertools.chain.from_iterable([[c.name for c in t.chains] for t in self.config.tree.tables]))) u.find('action-select').labels = actions u.find('action-select').values = actions action = '' j_option = i.get_option('j', 'jump') if j_option: action = j_option.arguments[0].value u.find('action').text = action u.find('action').style = 'iptables-action iptables-%s' % action u.find('action-select').value = action def post_rule_update(o, c, i, u): action = u.find('action-select').value j_option = i.get_option('j', 'jump') if j_option: j_option.arguments[0].value = action else: o = OptionData.create_destination() o.arguments[0].value = action i.options.append(o) self.find('rules').post_item_bind = post_rule_bind self.find('rules').post_item_update = post_rule_update self.find('add-option').values = self.find('add-option').labels = ['Add option'] + sorted(OptionData.templates.keys()) def on_page_load(self): if not os.path.exists(self.fw_mgr.config_path): subprocess.call('iptables-save > %s' % self.fw_mgr.config_path, shell=True) self.config.load() self.refresh() def refresh(self): self.binder.reset(self.config.tree).autodiscover().populate() self.find('autostart').text = ('Disable' if self.fw_mgr.get_autostart_state() else 'Enable') + ' autostart' @on('autostart', 'click') def on_autostart_change(self): self.fw_mgr.set_autostart_state(not self.fw_mgr.get_autostart_state()) self.refresh() def on_add_option(self, options, rule, ui): o = OptionData.create(ui.find('add-option').value) ui.find('add-option').value = '' rule.options.append(o) self.binder.populate() @on('save', 'click') def save(self): self.binder.update() self.config.save() self.refresh() @on('edit', 'click') def raw_edit(self): self.context.launch('notepad', path='/etc/iptables.up.rules') @on('apply', 'click') def apply(self): self.save() cmd = 'cat /etc/iptables.up.rules | iptables-restore' if subprocess.call(cmd, shell=True) != 0: self.context.launch('terminal', command=cmd) else: self.context.notify('info', 'Saved')
class Configurator (SectionPlugin): def init(self): self.title = _('Configure') self.icon = 'wrench' self.category = '' self.order = 50 self.append(self.ui.inflate('configurator:main')) self.binder = Binder(ajenti.config.tree, self.find('ajenti-config')) self.ccmgr = ClassConfigManager.get() self.classconfig_binding = Binder(self.ccmgr, self.find('classconfigs')) self.classconfig_rows = {} def post_classconfig_bind(object, collection, item, ui): self.classconfig_rows[item] = ui editor = item.classconfig_editor.new(self.ui) ui.find('container').append(editor) binder = DictAutoBinding(item, 'classconfig', editor.find('bind')) binder.populate() def save(): binder.update() item.save_classconfig() self.context.notify('info', _('Saved')) ui.find('save').on('click', save) self.find('classconfigs').find('classes').post_item_bind = post_classconfig_bind self.find('users').new_item = lambda c: UserData() def post_user_bind(object, collection, item, ui): box = ui.find('permissions') box.empty() ui.find('name-edit').visible = item.name != 'root' ui.find('name-label').visible = item.name == 'root' for prov in PermissionProvider.get_all(): line = self.ui.create('tab', title=prov.get_name()) box.append(line) for perm in prov.get_permissions(): line.append( self.ui.create('checkbox', id=perm[0], text=perm[1], value=(perm[0] in item.permissions)) ) self.find('users').post_item_bind = post_user_bind def post_user_update(object, collection, item, ui): box = ui.find('permissions') for prov in PermissionProvider.get_all(): for perm in prov.get_permissions(): has = box.find(perm[0]).value if has and not perm[0] in item.permissions: item.permissions.append(perm[0]) if not has and perm[0] in item.permissions: item.permissions.remove(perm[0]) if ui.find('password').value: item.password = ui.find('password').value self.find('users').post_item_update = post_user_update def on_page_load(self): self.refresh() def refresh(self): self.binder.reset().autodiscover().populate() self.ccmgr.reload() self.classconfig_binding.reset().autodiscover().populate() @on('save-button', 'click') @restrict('configurator:configure') def save(self): self.binder.update() for user in ajenti.config.tree.users.values(): if not '|' in user.password: user.password = UserManager.get().hash_password(user.password) self.binder.populate() ajenti.config.save() self.context.notify('info', _('Saved. Please restart Ajenti for changes to take effect.')) @on('fake-ssl', 'click') def on_gen_ssl(self): host = self.find('fake-ssl-host').value if host == '': self.context.notify('error', _('Please supply hostname')) else: self.gen_ssl(host) @on('restart-button', 'click') def on_restart(self): ajenti.restart() @intent('configure-plugin') def configure_plugin(self, plugin=None): self.find('tabs').active = 1 self.refresh() #if plugin in self.classconfig_rows: # self.classconfig_rows[plugin].children[0].expanded = True # print self.classconfig_rows[plugin].children[0] if plugin: self.context.notify('info', _('Please configure %s plugin!') % plugin.classconfig_editor.title) self.activate() @intent('setup-fake-ssl') def gen_ssl(self, host): self.save() subprocess.call(['ajenti-ssl-gen', host, '-f']) ajenti.config.load() self.refresh()
class Users(SectionPlugin): def init(self): self.title = _('Users') self.icon = 'group' self.category = _('System') self.append(self.ui.inflate('users:main')) def _filterOnlyUsers(x): u = int(x.uid) return u >= 500 def _filterOnlySystemUsers(x): u = int(x.uid) return u < 500 def _sorter(x): g = int(x.gid) if g >= 500: return g - 10000 return g self.find('users').filter = _filterOnlyUsers self.find('system-users').filter = _filterOnlySystemUsers self.find('groups').sorting = _sorter self.config = PasswdConfig(path='/etc/passwd') self.config_g = GroupConfig(path='/etc/group') self.binder = Binder(None, self.find('passwd-config')) self.binder_system = Binder(None, self.find('passwd-config-system')) self.binder_g = Binder(None, self.find('group-config')) self.mgr = UsersBackend.get() def post_item_bind(object, collection, item, ui): ui.find('change-password').on('click', self.change_password, item, ui) ui.find('remove-password').on('click', self.remove_password, item) if not os.path.exists(item.home): ui.find('create-home-dir').on('click', self.create_home_dir, item, ui) ui.find('create-home-dir').visible = True self.find('users').post_item_bind = post_item_bind self.find('system-users').post_item_bind = post_item_bind def on_page_load(self): self.refresh() def refresh(self): self.config.load() self.config_g.load() self.binder.reset(self.config.tree).autodiscover().populate() self.binder_system.reset(self.config.tree).autodiscover().populate() self.binder_g.reset(self.config_g.tree).autodiscover().populate() @on('add-user', 'click') def on_add_user(self): self.find('input-username').visible = True @on('input-username', 'submit') def on_add_user_done(self, value): self.mgr.add_user(value) self.refresh() @on('add-group', 'click') def on_add_group(self): self.find('input-groupname').visible = True @on('input-groupname', 'submit') def on_add_group_done(self, value): self.mgr.add_group(value) self.refresh() @on('save-users', 'click') @on('save-system-users', 'click') def save_users(self): self.binder.update() self.binder_system.update() self.config.save() @on('save-groups', 'click') def save_groups(self): self.binder_g.update() self.config_g.save() def create_home_dir(self, user, ui): self.mgr.make_home_dir(user) self.context.notify('info', _('Home dir for %s was created') % user.name) ui.find('create-home-dir').visible = False def change_password(self, user, ui): new_password = ui.find('new-password').value if new_password: try: self.mgr.change_password(user, new_password) self.context.notify( 'info', _('Password for %s was changed') % user.name) ui.find('new-password').value = '' except Exception, e: self.context.notify('error', _('Error: "%s"') % e.message) else:
class Configurator(SectionPlugin): def init(self): self.title = 'Configure' self.icon = 'wrench' self.category = '' self.order = 50 self.append(self.ui.inflate('configurator:main')) self.binder = Binder(ajenti.config.tree, self.find('ajenti-config')) self.ccmgr = ClassConfigManager.get() self.classconfig_binding = Binder(self.ccmgr, self.find('classconfigs')) self.classconfig_rows = {} def post_classconfig_bind(object, collection, item, ui): self.classconfig_rows[item] = ui editor = item.classconfig_editor.new(self.ui) ui.find('container').append(editor) binder = DictAutoBinding(item, 'classconfig', editor.find('bind')) binder.populate() def save(): binder.update() item.save_classconfig() self.context.notify('info', 'Saved') ui.find('save').on('click', save) self.find('classconfigs').find( 'classes').post_item_bind = post_classconfig_bind self.find('users').new_item = lambda c: UserData() def post_user_bind(object, collection, item, ui): box = ui.find('permissions') box.empty() for prov in PermissionProvider.get_all(): line = self.ui.create('tab', title=prov.get_name()) box.append(line) for perm in prov.get_permissions(): line.append(self.ui.create('checkbox', id=perm[0], text=perm[1], \ value=(perm[0] in item.permissions))) self.find('users').post_item_bind = post_user_bind def post_user_update(object, collection, item, ui): box = ui.find('permissions') for prov in PermissionProvider.get_all(): for perm in prov.get_permissions(): has = box.find(perm[0]).value if has and not perm[0] in item.permissions: item.permissions.append(perm[0]) if not has and perm[0] in item.permissions: item.permissions.remove(perm[0]) if ui.find('password').value: item.password = ui.find('password').value self.find('users').post_item_update = post_user_update self.refresh() def on_page_load(self): self.refresh() def refresh(self): self.binder.reset().autodiscover().populate() self.ccmgr.reload() self.classconfig_binding.reset().autodiscover().populate() @on('save-button', 'click') @restrict('configurator:configure') def save(self): self.binder.update() for user in ajenti.config.tree.users.values(): if not '|' in user.password: user.password = UserManager.get().hash_password(user.password) self.binder.populate() ajenti.config.save() self.context.notify( 'info', 'Saved. Please restart Ajenti for changes to take effect.') @on('fake-ssl', 'click') def on_gen_ssl(self): host = self.find('fake-ssl-host').value if host == '': self.context.notify('error', 'Please supply hostname') else: self.gen_ssl(host) @on('restart-button', 'click') def on_restart(self): ajenti.restart() @intent('configure-plugin') def configure_plugin(self, plugin=None): self.find('tabs').active = 1 self.refresh() #if plugin in self.classconfig_rows: # self.classconfig_rows[plugin].children[0].expanded = True # print self.classconfig_rows[plugin].children[0] if plugin: self.context.notify( 'info', 'Please configure %s plugin!' % plugin.classconfig_editor.title) self.activate() @intent('setup-fake-ssl') def gen_ssl(self, host): self.save() subprocess.call(['ajenti-ssl-gen', host, '-f']) ajenti.config.load() self.refresh()