Esempio n. 1
0
 def on_init(self):
     if self._relsec != None:
         if self._relsec[0] == 'add':
             apis.networkcontrol(self.app).add_webapp(self._relsec[1])
             self._relsec = None
         elif self._relsec[0] == 'del':
             apis.networkcontrol(self.app).remove_webapp(self._relsec[1])
         self._relsec = None
     self.services = []
     self.apiops = apis.webapps(self.app)
     self.mgr = WebappControl(self.app)
     self.sites = sorted(self.apiops.get_sites(), key=lambda st: st['name'])
     ats = sorted(self.apiops.get_apptypes(), key=lambda x: x.name.lower())
     self.apptypes = sorted(ats, key=lambda x: (hasattr(x, 'sort')))
     if len(self.sites) != 0:
         self.services.append(('Web Server', 'nginx'))
     if not self._current:
         self._current = self.apptypes[0]
     for apptype in self.apptypes:
         ok = False
         for site in self.sites:
             if site['type'] == apptype.name:
                 ok = True
         if ok == False:
             continue
         if hasattr(apptype, 'services'):
             for dep in apptype.services:
                 post = True
                 for svc in self.services:
                     if svc[1] == dep[1]:
                         post = False
                 if post == True:
                     self.services.append((dep[0], dep[1]))
Esempio n. 2
0
File: main.py Progetto: tewe/genesis
 def on_init(self):
     if self._relsec != None:
         if self._relsec[0] == 'add':
             apis.networkcontrol(self.app).add_webapp(self._relsec[1])
             self._relsec = None
         elif self._relsec[0] == 'del':
             apis.networkcontrol(self.app).remove_webapp(self._relsec[1])
         self._relsec = None
     self.services = []
     self.apiops = apis.webapps(self.app)
     self.dbops = apis.databases(self.app)
     self.mgr = WebappControl(self.app)
     self.sites = sorted(self.apiops.get_sites(), key=lambda st: st.name)
     ats = sorted([x.plugin_info for x in self.apiops.get_apptypes()],
                  key=lambda x: x.name.lower())
     self.apptypes = sorted(ats, key=lambda x: (hasattr(x, 'sort')))
     if len(self.sites) != 0:
         self.services.append({
             "name": 'Web Server',
             "binary": 'nginx',
             "ports": []
         })
         for x in self.sites:
             if x.php:
                 self.services.append({
                     "name": 'PHP FastCGI',
                     "binary": 'php-fpm',
                     "ports": []
                 })
                 break
     if not self._current:
         self._current = self.apptypes[0] if len(self.apptypes) else None
     for apptype in self.apptypes:
         ok = False
         for site in self.sites:
             if site.stype == apptype.wa_plugin:
                 ok = True
         if ok == False:
             continue
         if hasattr(apptype, 'services'):
             for dep in apptype.services:
                 post = True
                 for svc in self.services:
                     if svc['binary'] == dep['binary']:
                         post = False
                 if post == True:
                     self.services.append({
                         "name": dep['name'],
                         "binary": dep['binary'],
                         "ports": []
                     })
Esempio n. 3
0
File: main.py Progetto: ajvb/genesis
	def on_init(self):
		if self._relsec != None:
			if self._relsec[0] == 'add':
				apis.networkcontrol(self.app).add_webapp(self._relsec[1])
				self._relsec = None
			elif self._relsec[0] == 'del':
				apis.networkcontrol(self.app).remove_webapp(self._relsec[1])
			self._relsec = None
		self.services = []
		self.apiops = apis.webapps(self.app)
		self.mgr = WebappControl(self.app)
		self.sites = sorted(self.apiops.get_sites(), 
			key=lambda st: st['name'])
		ats = sorted(self.apiops.get_apptypes(), key=lambda x: x.name.lower())
		self.apptypes = sorted(ats, key=lambda x: (hasattr(x, 'sort')))
		if len(self.sites) != 0:
			self.services.append(('Web Server', 'nginx'))
		if not self._current:
			self._current = self.apptypes[0]
		for apptype in self.apptypes:
			ok = False
			for site in self.sites:
				if site['type'] == apptype.name:
					ok = True
			if ok == False:
				continue
			if hasattr(apptype, 'services'):
				for dep in apptype.services:
					post = True
					for svc in self.services:
						if svc[1] == dep[1]:
							post = False
					if post == True:
						self.services.append((dep[0], dep[1]))
Esempio n. 4
0
File: main.py Progetto: tewe/genesis
	def on_init(self):
		if self._relsec != None:
			if self._relsec[0] == 'add':
				apis.networkcontrol(self.app).add_webapp(self._relsec[1])
				self._relsec = None
			elif self._relsec[0] == 'del':
				apis.networkcontrol(self.app).remove_webapp(self._relsec[1])
			self._relsec = None
		self.services = []
		self.apiops = apis.webapps(self.app)
		self.dbops = apis.databases(self.app)
		self.mgr = WebappControl(self.app)
		self.sites = sorted(self.apiops.get_sites(), 
			key=lambda st: st.name)
		ats = sorted([x.plugin_info for x in self.apiops.get_apptypes()], key=lambda x: x.name.lower())
		self.apptypes = sorted(ats, key=lambda x: (hasattr(x, 'sort')))
		if len(self.sites) != 0:
			self.services.append(
				{
					"name": 'Web Server',
					"binary": 'nginx',
					"ports": []
				}
			)
			for x in self.sites:
				if x.php:
					self.services.append(
						{
							"name": 'PHP FastCGI',
							"binary": 'php-fpm',
							"ports": []
						}
					)
					break
		if not self._current:
			self._current = self.apptypes[0] if len(self.apptypes) else None
		for apptype in self.apptypes:
			ok = False
			for site in self.sites:
				if site.stype == apptype.wa_plugin:
					ok = True
			if ok == False:
				continue
			if hasattr(apptype, 'services'):
				for dep in apptype.services:
					post = True
					for svc in self.services:
						if svc['binary'] == dep['binary']:
							post = False
					if post == True:
						self.services.append({"name": dep['name'], "binary": dep['binary'], "ports": []})
Esempio n. 5
0
 def run(self, cat, action, name, current='', vars=None):
     if action == 'add':
         try:
             spmsg = WebappControl(cat.app).add(cat, name, current, vars,
                                                True)
         except Exception, e:
             cat.clr_statusmsg()
             cat.put_message('err', str(e))
             cat.app.log.error(str(e))
         else:
             cat.put_message('info', '%s added sucessfully' % name)
             cat._relsec = ('add', (name, current, vars))
             if spmsg:
                 cat.put_message('info', spmsg)
Esempio n. 6
0
class WAWorker(BackgroundWorker):
    def run(self, cat, action, name, current='', vars=None):
        if action == 'add':
            try:
                spmsg = WebappControl(cat.app).add(cat, name, current, vars,
                                                   True)
            except Exception, e:
                cat.clr_statusmsg()
                cat.put_message('err', str(e))
                cat.app.log.error(str(e))
            else:
                cat.put_message('info', '%s added sucessfully' % name)
                cat._relsec = ('add', (name, current, vars))
                if spmsg:
                    cat.put_message('info', spmsg)
        elif action == 'drop':
            try:
                WebappControl(cat.app).remove(cat, name)
            except Exception, e:
                cat.clr_statusmsg()
                cat.put_message('err', 'Website removal failed: ' + str(e))
                cat.app.log.error('Website removal failed: ' + str(e))
Esempio n. 7
0
class WebAppsPlugin(apis.services.ServiceControlPlugin):
    text = 'Websites'
    iconfont = 'gen-earth'
    folder = None
    services = []

    def on_init(self):
        self.services = []
        self.ncops = apis.networkcontrol(self.app)
        self.apiops = apis.webapps(self.app)
        self.dbops = apis.databases(self.app)
        self.mgr = WebappControl(self.app)
        self.sites = sorted(self.apiops.get_sites(), 
            key=lambda st: st.name)
        ats = sorted([x.plugin_info for x in self.apiops.get_apptypes()], key=lambda x: x.name.lower())
        self.apptypes = sorted(ats, key=lambda x: (hasattr(x, 'sort')))
        if len(self.sites) != 0:
            self.services.append(
                {
                    "name": 'Web Server',
                    "binary": 'nginx',
                    "ports": []
                }
            )
            for x in self.sites:
                if x.php:
                    self.services.append(
                        {
                            "name": 'PHP FastCGI',
                            "binary": 'php-fpm',
                            "ports": []
                        }
                    )
                    break
        if not self._current:
            self._current = self.apptypes[0] if len(self.apptypes) else None
        for apptype in self.apptypes:
            ok = False
            for site in self.sites:
                if site.stype == apptype.wa_plugin:
                    ok = True
            if ok == False:
                continue
            if hasattr(apptype, 'services'):
                for dep in apptype.services:
                    post = True
                    for svc in self.services:
                        if svc['binary'] == dep['binary']:
                            post = False
                    if post == True:
                        self.services.append({"name": dep['name'], "binary": dep['binary'], "ports": []})

    def on_session_start(self):
        self._add = None
        self._edit = None
        self._setup = None
        self._dbauth = ('','','')

    def get_main_ui(self):
        ui = self.app.inflate('webapps:main')

        for s in self.sites:
            if s.addr and s.ssl:
                addr = 'https://' + s.addr + (':'+s.port if s.port != '443' else '')
            elif s.addr:
                addr = 'http://' + s.addr + (':'+s.port if s.port != '80' else '')
            else:
                addr = False

            update = False
            if s.version and (s.version != 'None' or (hasattr(s.sclass, 'plugin_info') and s.sclass.plugin_info.website_updates)) \
            and s.version != s.sclass.plugin_info.version.rsplit('-', 1)[0]:
                update = True

            ui.find('main').append(
                UI.TblBtn(
                    UI.TipIcon(
                        iconfont='gen-download',
                        id=('update/') + str(self.sites.index(s)),
                        text='Update Site'
                    ) if update else None,
                    UI.TipIcon(
                        iconfont='gen-minus-circle' if s.enabled else 'gen-checkmark-circle',
                        id=('disable/' if s.enabled else 'enable/') + str(self.sites.index(s)),
                        text='Disable' if s.enabled else 'Enable'
                    ),
                    UI.TipIcon(
                        iconfont='gen-tools',
                        id='config/' + str(self.sites.index(s)),
                        text='Configure'
                    ),
                    UI.TipIcon(
                        iconfont='gen-cancel-circle',
                        id='drop/' + str(self.sites.index(s)),
                        text='Delete',
                        warning='Are you sure you wish to delete site %s? This action is irreversible.%s'%(s.name,
                            ' If this Reverse Proxy was set up automatically by Genesis, this may cause the associated plugin to stop functioning.' if s.stype == 'ReverseProxy' else '')
                    ),
                    id=s.name,
                    outlink=addr,
                    icon=s.sclass.plugin_info.icon if s.sclass and hasattr(s.sclass.plugin_info, 'icon') else 'gen-earth',
                    name=s.name,
                    subtext=s.stype
                    )
                )
        ui.find('main').append(
            UI.TblBtn(
                id='add',
                icon='gen-plus-circle',
                name='Add new site'
                )
            )

        provs = ui.find('provs')

        for apptype in self.apptypes:
            provs.append(
                    UI.ListItem(
                        UI.Label(text=apptype.name),
                        iconfont=apptype.icon,
                        id=apptype.name,
                        active=apptype.name==self._current.name
                    )
                )

        info = self._current
        if info:
            if info.logo:
                ui.find('logo').append(UI.Image(file='/dl/'+self._current.id+'/logo.png'))
            ui.find('appname').set('text', info.name)
            ui.find('short').set('text', info.desc)
            if info.app_homepage is None:
                ui.find('website').set('text', 'None')
                ui.find('website').set('url', 'http://localhost')
            else:
                ui.find('website').set('text', info.app_homepage)
                ui.find('website').set('url', info.app_homepage)
            ui.find('desc').set('text', info.longdesc)

        if self._add is None:
            ui.remove('dlgAdd')

        if self._setup is not None:
            ui.find('addr').set('value', self.app.get_backend(IHostnameManager).gethostname().lower())
            if len(self._setup.dbengines) > 1:
                ui.append('app-config', UI.Formline(
                    UI.SelectInput(
                        *list(UI.SelectOption(text=x if x else 'None', value=x if x else 'None') for x in self._setup.dbengines), 
                        name="dbtype", id="dbtype"), 
                    text="Database Type", 
                    help="This application supports multiple types of databases. Please choose the one you would like to use.")
                )
            if self._setup.dbengines:
                ui.append('app-config', UI.Formline(UI.TextInput(name="dbname", id="dbname"), text="Database Name (Optional)"))
                ui.append('app-config', UI.Formline(UI.TextInput(name="dbpass", id="dbpass", password=True), text="Database User Password (Optional)"))
            try:
                cfgui = self.app.inflate(self._setup.id + ':conf')
                ui.append('app-config', UI.Label(size=3, text="App Settings"))
                if hasattr(self.apiops.get_interface(self._setup.wa_plugin), 'show_opts_add'):
                    self.apiops.get_interface(self._setup.wa_plugin).show_opts_add(cfgui)
                ui.append('app-config', cfgui)
            except:
                pass
        else:
            ui.remove('dlgSetup')

        if self._edit is not None:
            try:
                edgui = self.app.inflate(self._edit.stype.lower() + ':edit')
                ui.append('dlgEdit', edgui)
            except:
                pass
            ui.find('cfgname').set('value', self._edit.name)
            ui.find('cfgaddr').set('value', self._edit.addr)
            ui.find('cfgport').set('value', self._edit.port)
        else:
            ui.remove('dlgEdit')

        if self._dbauth[0] and not self.dbops.get_interface(self._dbauth[1]).checkpwstat():
            self.put_message('err', '%s does not have a root password set. '
                'Please add this via the Databases screen.' % self._dbauth[1])
            self._dbauth = ('','','')
        if self._dbauth[0]:
            ui.append('main', 
                UI.Authorization(
                    app='Webapps',
                    reason='%s a website'%('Adding' if self._dbauth[0] == 'add' else 'Removing'),
                    label='Please enter your %s root password'%self._dbauth[1])
                )

        return ui

    @event('button/click')
    def on_click(self, event, params, vars = None):
        if params[0] == 'add':
            if self.apptypes == []:
                self.put_message('err', 'No webapp types installed. Check the Applications tab to find some')
            else:
                self._add = len(self.sites)
        elif params[0] == 'config':
            self._edit = self.sites[int(params[1])]
        elif params[0] == 'drop':
            site = self.sites[int(params[1])]
            if hasattr(site, 'dbengine') and site.dbengine and \
            self.dbops.get_info(site.dbengine).requires_conn and \
            not self.dbops.get_dbconn(site.dbengine):
                self._dbauth = ('drop', site.dbengine, site)
            else:
                try:
                    self.mgr.remove(self, site)
                except Exception, e:
                    self.put_message('err', 'Website removal failed: ' + str(e))
                    self.app.log.error('Website removal failed: ' + str(e))
                else:
                    self.put_message('success', 'Website successfully removed')
                    self.ncops.remove_webapp(site.name)
Esempio n. 8
0
File: main.py Progetto: tewe/genesis
class WebAppsPlugin(apis.services.ServiceControlPlugin):
    text = 'Websites'
    iconfont = 'gen-earth'
    folder = 'servers'
    services = []

    def on_init(self):
        if self._relsec != None:
            if self._relsec[0] == 'add':
                apis.networkcontrol(self.app).add_webapp(self._relsec[1])
                self._relsec = None
            elif self._relsec[0] == 'del':
                apis.networkcontrol(self.app).remove_webapp(self._relsec[1])
            self._relsec = None
        self.services = []
        self.apiops = apis.webapps(self.app)
        self.dbops = apis.databases(self.app)
        self.mgr = WebappControl(self.app)
        self.sites = sorted(self.apiops.get_sites(), key=lambda st: st.name)
        ats = sorted([x.plugin_info for x in self.apiops.get_apptypes()],
                     key=lambda x: x.name.lower())
        self.apptypes = sorted(ats, key=lambda x: (hasattr(x, 'sort')))
        if len(self.sites) != 0:
            self.services.append({
                "name": 'Web Server',
                "binary": 'nginx',
                "ports": []
            })
            for x in self.sites:
                if x.php:
                    self.services.append({
                        "name": 'PHP FastCGI',
                        "binary": 'php-fpm',
                        "ports": []
                    })
                    break
        if not self._current:
            self._current = self.apptypes[0] if len(self.apptypes) else None
        for apptype in self.apptypes:
            ok = False
            for site in self.sites:
                if site.stype == apptype.wa_plugin:
                    ok = True
            if ok == False:
                continue
            if hasattr(apptype, 'services'):
                for dep in apptype.services:
                    post = True
                    for svc in self.services:
                        if svc['binary'] == dep['binary']:
                            post = False
                    if post == True:
                        self.services.append({
                            "name": dep['name'],
                            "binary": dep['binary'],
                            "ports": []
                        })

    def on_session_start(self):
        self._add = None
        self._edit = None
        self._setup = None
        self._relsec = None
        self._dbauth = ('', '', '')

    def get_main_ui(self):
        ui = self.app.inflate('webapps:main')
        t = ui.find('list')

        for s in self.sites:
            if s.addr and s.ssl:
                addr = 'https://' + s.addr + (':' + s.port
                                              if s.port != '443' else '')
            elif s.addr:
                addr = 'http://' + s.addr + (':' +
                                             s.port if s.port != '80' else '')
            else:
                addr = False

            t.append(
                UI.DTR(
                    UI.Iconfont(
                        iconfont=s.sclass.plugin_info.iconfont if s.sclass
                        and hasattr(s.sclass.plugin_info, 'iconfont') else
                        'gen-earth'),
                    (UI.OutLinkLabel(text=s.name, url=addr)
                     if s.addr is not False else UI.Label(text=s.name)),
                    UI.Label(text=s.stype),
                    UI.HContainer(
                        UI.TipIcon(
                            iconfont='gen-minus-circle'
                            if s.enabled else 'gen-checkmark-circle',
                            id=('disable/' if s.enabled else 'enable/') +
                            str(self.sites.index(s)),
                            text='Disable' if s.enabled else 'Enable'),
                        UI.TipIcon(iconfont='gen-tools',
                                   id='config/' + str(self.sites.index(s)),
                                   text='Configure'),
                        UI.TipIcon(
                            iconfont='gen-cancel-circle',
                            id='drop/' + str(self.sites.index(s)),
                            text='Delete',
                            warning=
                            'Are you sure you wish to delete site %s? This action is irreversible.%s'
                            %
                            (s.name,
                             ' If this Reverse Proxy was set up automatically by Genesis, this may cause the associated plugin to stop functioning.'
                             if s.stype == 'ReverseProxy' else ''))),
                ))

        provs = ui.find('provs')

        for apptype in self.apptypes:
            provs.append(
                UI.ListItem(UI.Label(text=apptype.name),
                            id=apptype.name,
                            active=apptype.name == self._current.name))

        info = self._current
        if info:
            if info.logo:
                ui.find('logo').append(
                    UI.Image(file='/dl/' + self._current.id + '/logo.png'))
            ui.find('appname').set('text', info.name)
            ui.find('short').set('text', info.desc)
            if info.app_homepage is None:
                ui.find('website').set('text', 'None')
                ui.find('website').set('url', 'http://localhost')
            else:
                ui.find('website').set('text', info.app_homepage)
                ui.find('website').set('url', info.app_homepage)
            ui.find('desc').set('text', info.longdesc)

        if self._add is None:
            ui.remove('dlgAdd')

        if self._setup is not None:
            ui.find('addr').set(
                'value',
                self.app.get_backend(IHostnameManager).gethostname())
            if self._setup.nomulti is True:
                for site in self.sites:
                    if self._setup.wa_plugin in site.stype:
                        ui.remove('dlgSetup')
                        ui.remove('dlgEdit')
                        self.put_message(
                            'err',
                            'Only one site of this type at any given time')
                        self._setup = None
                        return ui
            try:
                cfgui = self.app.inflate(self._setup.id + ':conf')
                if hasattr(self.apiops.get_interface(self._setup.wa_plugin),
                           'show_opts_add'):
                    self.apiops.get_interface(
                        self._setup.wa_plugin).show_opts_add(cfgui)
                ui.append('app-config', cfgui)
            except:
                ui.find('app-config').append(
                    UI.Label(text="No config options available for this app"))
        else:
            ui.remove('dlgSetup')

        if self._edit is not None:
            try:
                edgui = self.app.inflate(self._edit.stype.lower() + ':edit')
                ui.append('dlgEdit', edgui)
            except:
                pass
            ui.find('cfgname').set('value', self._edit.name)
            ui.find('cfgaddr').set('value', self._edit.addr)
            ui.find('cfgport').set('value', self._edit.port)
        else:
            ui.remove('dlgEdit')

        if self._dbauth[0] and not self.dbops.get_interface(
                self._dbauth[0]).checkpwstat():
            self.put_message(
                'err', '%s does not have a root password set. '
                'Please add this via the Databases screen.' % self._dbauth[0])
            self._dbauth = ('', '', '')
        if self._dbauth[0]:
            ui.append(
                'main',
                UI.InputBox(id='dlgAuth%s' % self._dbauth[0],
                            text='Enter the database password for %s' %
                            self._dbauth[0],
                            password=True))

        return ui

    @event('button/click')
    def on_click(self, event, params, vars=None):
        if params[0] == 'add':
            if self.apptypes == []:
                self.put_message(
                    'err',
                    'No webapp types installed. Check the Applications tab to find some'
                )
            else:
                self._add = len(self.sites)
        elif params[0] == 'config':
            self._edit = self.sites[int(params[1])]
        elif params[0] == 'drop':
            if hasattr(self.sites[int(params[1])], 'dbengine') and \
            self.sites[int(params[1])].dbengine and \
            self.dbops.get_info(self.sites[int(params[1])].dbengine).requires_conn and \
            not self.dbops.get_dbconn(self.sites[int(params[1])].dbengine):
                self._dbauth = (self.sites[int(params[1])].dbengine,
                                self.sites[int(params[1])], 'drop')
            else:
                w = WAWorker(self, 'drop', self.sites[int(params[1])])
                w.start()
        elif params[0] == 'enable':
            self.mgr.nginx_enable(self.sites[int(params[1])])
        elif params[0] == 'disable':
            self.mgr.nginx_disable(self.sites[int(params[1])])
        else:
            for x in self.apptypes:
                if x.name.lower() == params[0]:
                    speccall = getattr(self.apiops.get_interface(x.wa_plugin),
                                       params[1])
                    speccall(self._edit)

    @event('dialog/submit')
    def on_submit(self, event, params, vars=None):
        if params[0] == 'dlgAdd':
            if vars.getvalue('action', '') == 'OK':
                if hasattr(self._current,
                           'dbengine') and self._current.dbengine:
                    on = False
                    for dbtype in self.dbops.get_dbtypes():
                        if self._current.dbengine == dbtype[0] and dbtype[
                                2] == True:
                            on = True
                        elif self._current.dbengine == dbtype[0] and dbtype[
                                2] == None:
                            on = True
                    if on:
                        if self.dbops.get_info(self._current.dbengine).requires_conn and \
                        not self.dbops.get_dbconn(self._current.dbengine):
                            self._dbauth = (self._current.dbengine, '', 'add')
                        else:
                            self._setup = self._current
                    else:
                        self.put_message(
                            'err',
                            'The database engine for %s is not running. Please start it via the Status button.'
                            % self._current.dbengine)
                else:
                    self._setup = self._current
            self._add = None
        if params[0] == 'dlgEdit':
            if vars.getvalue('action', '') == 'OK':
                name = vars.getvalue('cfgname', '')
                addr = vars.getvalue('cfgaddr', '')
                port = vars.getvalue('cfgport', '')
                vaddr = True
                for site in self.sites:
                    if addr == site.addr and port == site.port:
                        vaddr = False
                if name == '':
                    self.put_message('err', 'Must choose a name')
                elif re.search('\.|-|`|\\\\|\/|^test$|[ ]', name):
                    self.put_message(
                        'err',
                        'Site name must not contain spaces, dots, dashes or special characters'
                    )
                elif addr == '':
                    self.put_message('err', 'Must choose an address')
                elif port == '':
                    self.put_message('err', 'Must choose a port (default 80)')
                elif port == self.app.gconfig.get('genesis', 'bind_port', ''):
                    self.put_message(
                        'err', 'Can\'t use the same port number as Genesis')
                elif not vaddr:
                    self.put_message(
                        'err',
                        'Site must have either a different domain/subdomain or a different port'
                    )
                else:
                    w = Webapp()
                    w.name = name
                    w.stype = self._edit.stype
                    w.path = self._edit.path
                    w.addr = addr
                    w.port = port
                    w.ssl = self._edit.ssl
                    w.php = self._edit.php
                    self.mgr.nginx_edit(self._edit, w)
                    apis.networkcontrol(self.app).change_webapp(self._edit, w)
            self._edit = None
        if params[0] == 'dlgSetup':
            if vars.getvalue('action', '') == 'OK':
                name = vars.getvalue('name', '').lower()
                addr = vars.getvalue('addr', '')
                port = vars.getvalue('port', '80')
                vname, vaddr = True, True
                for site in self.sites:
                    if name == site.name:
                        vname = False
                    if addr == site.addr and port == site.port:
                        vaddr = False
                if not name or not self._setup:
                    self.put_message('err', 'Name or type not selected')
                elif re.search('\.|-|`|\\\\|\/|^test$|[ ]', name):
                    self.put_message(
                        'err',
                        'Site name must not contain spaces, dots, dashes or special characters'
                    )
                elif addr == '':
                    self.put_message('err', 'Must choose an address')
                elif port == '':
                    self.put_message('err', 'Must choose a port (default 80)')
                elif port == self.app.gconfig.get('genesis', 'bind_port', ''):
                    self.put_message(
                        'err', 'Can\'t use the same port number as Genesis')
                elif not vaddr:
                    self.put_message(
                        'err',
                        'Site must have either a different domain/subdomain or a different port'
                    )
                elif not vname:
                    self.put_message('err',
                                     'A site with this name already exists')
                else:
                    w = WAWorker(self, 'add', name, self._current, vars)
                    w.start()
            self._setup = None
        if params[0].startswith('dlgAuth'):
            dbtype = params[0].split('dlgAuth')[1]
            if vars.getvalue('action', '') == 'OK':
                login = vars.getvalue('value', '')
                try:
                    dbauth = self._dbauth
                    self._dbauth = ('', '', '')
                    self.dbops.get_interface(dbtype).connect(
                        store=self.app.session['dbconns'], passwd=login)
                    if dbauth[2] == 'drop':
                        w = WAWorker(self, 'drop', dbauth[1])
                        w.start()
                    elif dbauth[2] == 'add':
                        self._setup = self._current
                except DBAuthFail, e:
                    self.put_message('err', str(e))
            else:
                self.put_message('info',
                                 'Website %s cancelled' % self._dbauth[2])
                self._dbauth = ('', '', '')
Esempio n. 9
0
class WebAppsPlugin(apis.services.ServiceControlPlugin):
    text = 'Websites'
    iconfont = 'gen-earth'
    folder = None
    services = []

    def on_init(self):
        self.services = []
        self.ncops = apis.networkcontrol(self.app)
        self.apiops = apis.webapps(self.app)
        self.dbops = apis.databases(self.app)
        self.mgr = WebappControl(self.app)
        self.sites = sorted(self.apiops.get_sites(), 
            key=lambda st: st.name)
        ats = sorted([x.plugin_info for x in self.apiops.get_apptypes()], key=lambda x: x.name.lower())
        self.apptypes = sorted(ats, key=lambda x: (hasattr(x, 'sort')))
        if len(self.sites) != 0:
            self.services.append(
                {
                    "name": 'Web Server',
                    "binary": 'nginx',
                    "ports": []
                }
            )
            for x in self.sites:
                if x.php:
                    self.services.append(
                        {
                            "name": 'PHP FastCGI',
                            "binary": 'php-fpm',
                            "ports": []
                        }
                    )
                    break
        if not self._current:
            self._current = self.apptypes[0] if len(self.apptypes) else None
        for apptype in self.apptypes:
            ok = False
            for site in self.sites:
                if site.stype == apptype.wa_plugin:
                    ok = True
            if ok == False:
                continue
            if hasattr(apptype, 'services'):
                for dep in apptype.services:
                    post = True
                    for svc in self.services:
                        if svc['binary'] == dep['binary']:
                            post = False
                    if post == True:
                        self.services.append({"name": dep['name'], "binary": dep['binary'], "ports": []})

    def on_session_start(self):
        self._add = None
        self._edit = None
        self._setup = None
        self._settings = None
        self._dbauth = ('','','')

    def get_main_ui(self):
        ui = self.app.inflate('webapps:main')

        for s in self.sites:
            if s.addr and s.ssl:
                addr = 'https://' + s.addr + (':'+s.port if s.port != '443' else '')
            elif s.addr:
                addr = 'http://' + s.addr + (':'+s.port if s.port != '80' else '')
            else:
                addr = False

            update = False
            if s.version and (s.version != 'None' or (hasattr(s.sclass, 'plugin_info') and s.sclass.plugin_info.website_updates)) \
            and s.version != s.sclass.plugin_info.version.rsplit('-', 1)[0]:
                update = True

            ui.find('main').append(
                UI.TblBtn(
                    UI.TipIcon(
                        iconfont='gen-download',
                        id=('update/') + str(self.sites.index(s)),
                        text='Update Site'
                    ) if update else None,
                    UI.TipIcon(
                        iconfont='gen-minus-circle' if s.enabled else 'gen-checkmark-circle',
                        id=('disable/' if s.enabled else 'enable/') + str(self.sites.index(s)),
                        text='Disable' if s.enabled else 'Enable'
                    ),
                    UI.TipIcon(
                        iconfont='gen-tools',
                        id='config/' + str(self.sites.index(s)),
                        text='Configure'
                    ),
                    UI.TipIcon(
                        iconfont='gen-cancel-circle',
                        id='drop/' + str(self.sites.index(s)),
                        text='Delete',
                        warning='Are you sure you wish to delete site %s? This action is irreversible.%s'%(s.name,
                            ' If this Reverse Proxy was set up automatically by Genesis, this may cause the associated plugin to stop functioning.' if s.stype == 'ReverseProxy' else '')
                    ),
                    id=s.name,
                    outlink=addr,
                    icon=s.sclass.plugin_info.icon if s.sclass and hasattr(s.sclass.plugin_info, 'icon') else 'gen-earth',
                    name=s.name,
                    subtext=s.stype
                    )
                )
        ui.find('main').append(
            UI.TblBtn(
                id='add',
                icon='gen-plus-circle',
                name='Add new site'
                )
            )

        provs = ui.find('provs')

        for apptype in self.apptypes:
            provs.append(
                    UI.ListItem(
                        UI.Label(text=apptype.name),
                        iconfont=apptype.icon,
                        id=apptype.name,
                        active=apptype.name==self._current.name
                    )
                )

        info = self._current
        if info:
            if info.logo:
                ui.find('logo').append(UI.Image(file='/dl/'+self._current.id+'/logo.png'))
            ui.find('appname').set('text', info.name)
            ui.find('short').set('text', info.desc)
            if info.app_homepage is None:
                ui.find('website').set('text', 'None')
                ui.find('website').set('url', 'http://localhost')
            else:
                ui.find('website').set('text', info.app_homepage)
                ui.find('website').set('url', info.app_homepage)
            ui.find('desc').set('text', info.longdesc)

        if self._add is None:
            ui.remove('dlgAdd')

        if self._setup is not None:
            ui.find('addr').set('value', self.app.get_backend(IHostnameManager).gethostname().lower())
            if len(self._setup.dbengines) > 1:
                ui.append('app-config', UI.Formline(
                    UI.SelectInput(
                        *list(UI.SelectOption(text=x if x else 'None', value=x if x else 'None') for x in self._setup.dbengines), 
                        name="dbtype", id="dbtype"), 
                    text="Database Type", 
                    help="This application supports multiple types of databases. Please choose the one you would like to use.")
                )
            if self._setup.dbengines:
                ui.append('app-config', UI.Formline(UI.TextInput(name="dbname", id="dbname"), text="Database Name (Optional)"))
                ui.append('app-config', UI.Formline(UI.TextInput(name="dbpass", id="dbpass", password=True), text="Database User Password (Optional)"))
            try:
                cfgui = self.app.inflate(self._setup.id + ':conf')
                ui.append('app-config', UI.Label(size=3, text="App Settings"))
                if hasattr(self.apiops.get_interface(self._setup.wa_plugin), 'show_opts_add'):
                    self.apiops.get_interface(self._setup.wa_plugin).show_opts_add(cfgui)
                ui.append('app-config', cfgui)
            except:
                pass
        else:
            ui.remove('dlgSetup')

        if self._edit is not None:
            try:
                edgui = self.app.inflate(self._edit.stype.lower() + ':edit')
                ui.append('dlgEdit', edgui)
            except:
                pass
            ui.find('cfgname').set('value', self._edit.name)
            ui.find('cfgaddr').set('value', self._edit.addr)
            ui.find('cfgport').set('value', self._edit.port)
        else:
            ui.remove('dlgEdit')

        if self._dbauth[0] and not self.dbops.get_interface(self._dbauth[1]).checkpwstat():
            self.put_message('err', '%s does not have a root password set. '
                'Please add this via the Databases screen.' % self._dbauth[1])
            self._dbauth = ('','','')
        if self._dbauth[0]:
            ui.append('main', 
                UI.Authorization(
                    app='Webapps',
                    reason='%s a website'%('Adding' if self._dbauth[0] == 'add' else 'Removing'),
                    label='Please enter your %s root password'%self._dbauth[1])
                )

        if self._settings:
            size = re.search("client_max_body_size\s*([^\s]+)[mM];", open('/etc/nginx/nginx.conf', 'r').read())
            size = size.group(1) if size else "1"
            ui.append('main',
                UI.DialogBox(
                    UI.Formline(UI.TextInput(id="uplsize", name="uplsize", value=size), 
                        text="Max file upload size (MB)"),
                    id="dlgSettings")
                )

        return ui

    @event('button/click')
    def on_click(self, event, params, vars = None):
        if params[0] == 'add':
            if self.apptypes == []:
                self.put_message('err', 'No webapp types installed. Check the Applications tab to find some')
            else:
                self._add = len(self.sites)
        elif params[0] == 'config':
            self._edit = self.sites[int(params[1])]
        elif params[0] == 'drop':
            site = self.sites[int(params[1])]
            if hasattr(site, 'dbengine') and site.dbengine and \
            self.dbops.get_info(site.dbengine).requires_conn and \
            not self.dbops.get_dbconn(site.dbengine):
                self._dbauth = ('drop', site.dbengine, site)
            else:
                try:
                    self.mgr.remove(self, site)
                except Exception, e:
                    self.put_message('err', 'Website removal failed: ' + str(e))
                    self.app.log.error('Website removal failed: ' + str(e))
                else:
                    self.put_message('success', 'Website successfully removed')
                    self.ncops.remove_webapp(site.name)
Esempio n. 10
0
File: main.py Progetto: ajvb/genesis
class WebAppsPlugin(apis.services.ServiceControlPlugin):
	text = 'Websites'
	iconfont = 'gen-earth'
	folder = 'servers'
	services = []

	def on_init(self):
		if self._relsec != None:
			if self._relsec[0] == 'add':
				apis.networkcontrol(self.app).add_webapp(self._relsec[1])
				self._relsec = None
			elif self._relsec[0] == 'del':
				apis.networkcontrol(self.app).remove_webapp(self._relsec[1])
			self._relsec = None
		self.services = []
		self.apiops = apis.webapps(self.app)
		self.mgr = WebappControl(self.app)
		self.sites = sorted(self.apiops.get_sites(), 
			key=lambda st: st['name'])
		ats = sorted(self.apiops.get_apptypes(), key=lambda x: x.name.lower())
		self.apptypes = sorted(ats, key=lambda x: (hasattr(x, 'sort')))
		if len(self.sites) != 0:
			self.services.append(('Web Server', 'nginx'))
		if not self._current:
			self._current = self.apptypes[0]
		for apptype in self.apptypes:
			ok = False
			for site in self.sites:
				if site['type'] == apptype.name:
					ok = True
			if ok == False:
				continue
			if hasattr(apptype, 'services'):
				for dep in apptype.services:
					post = True
					for svc in self.services:
						if svc[1] == dep[1]:
							post = False
					if post == True:
						self.services.append((dep[0], dep[1]))

	def on_session_start(self):
		self._add = None
		self._edit = None
		self._setup = None
		self._relsec = None

	def get_main_ui(self):
		ui = self.app.inflate('webapps:main')
		t = ui.find('list')

		for s in self.sites:
			if s['addr'] is not False and s['ssl']:
				addr = 'https://' + s['addr'] + (':'+s['port'] if s['port'] is not '443' else '')
			elif s['addr'] is not False:
				addr = 'http://' + s['addr'] + (':'+s['port'] if s['port'] is not '80' else '')
			else:
				addr = False

			t.append(UI.DTR(
				UI.Iconfont(iconfont="gen-earth"),
				(UI.OutLinkLabel(
					text=s['name'],
					url=addr
					) if s['addr'] is not False else UI.Label(text=s['name'])
				),
				UI.Label(text=s['type']),
				UI.HContainer(
					UI.TipIcon(
						iconfont='gen-minus-circle' if s['enabled'] else 'gen-checkmark-circle',
						id=('disable/' if s['enabled'] else 'enable/') + str(self.sites.index(s)),
						text='Disable' if s['enabled'] else 'Enable'
					),
					UI.TipIcon(
						iconfont='gen-tools',
						id='config/' + str(self.sites.index(s)),
						text='Configure'
					),
					UI.TipIcon(
						iconfont='gen-cancel-circle',
						id='drop/' + str(self.sites.index(s)),
						text='Delete',
						warning='Are you sure you wish to delete site %s? This action is irreversible.'%s['name']
						)
					),
				))

		provs = ui.find('provs')

		for apptype in self.apptypes:
			provs.append(
					UI.ListItem(
						UI.Label(text=apptype.name),
						id=apptype.name,
						active=apptype.name==self._current.name
					)
				)

		info = self._current.get_info()
		if info['logo'] is True:
			ui.find('logo').set('file', '/dl/'+self._current.__class__.__name__.lower()+'/logo.png')
		ui.find('appname').set('text', info['name'])
		ui.find('short').set('text', info['short'])
		if info['site'] is None:
			ui.find('website').set('text', 'None')
			ui.find('website').set('url', 'http://localhost')
		else:
			ui.find('website').set('text', info['site'])
			ui.find('website').set('url', info['site'])
		ui.find('desc').set('text', info['long'])

		if self._add is None:
			ui.remove('dlgAdd')

		if self._setup is not None:
			if self._setup.nomulti is True:
				for site in self.sites:
					if self._setup.name in site['type']:
						ui.remove('dlgSetup')
						ui.remove('dlgEdit')
						self.put_message('err', 'Only one site of this type at any given time')
						self._setup = None
						return ui
			try:
				if self._setup.name == 'Website':
					cfgui = self.app.inflate('webapps:conf')
					type_sel = [UI.SelectOption(text='None', value='None')]
					for x in sorted(apis.databases(self.app).get_dbtypes()):
						type_sel.append(UI.SelectOption(text=x[0], value=x[0]))
					cfgui.appendAll('ws-dbsel', *type_sel)
				else:
					cfgui = self.app.inflate(self._setup.__class__.__name__.lower() + ':conf')
				ui.append('app-config', cfgui)
			except:
				raise
				ui.find('app-config').append(UI.Label(text="No config options available for this app"))
		else:
			ui.remove('dlgSetup')

		if self._edit is not None:
			try:
				edgui = self.app.inflate(self._edit['type'].lower() + ':edit')
				ui.append('dlgEdit', edgui)
			except:
				pass
			ui.find('cfgname').set('value', self._edit['name'])
			ui.find('cfgaddr').set('value', self._edit['addr'])
			ui.find('cfgport').set('value', self._edit['port'])
		else:
			ui.remove('dlgEdit')

		return ui

	@event('button/click')
	def on_click(self, event, params, vars = None):
		if params[0] == 'add':
			if self.apptypes == []:
				self.put_message('err', 'No webapp types installed. Check the Applications tab to find some')
			else:
				self._add = len(self.sites)
		elif params[0] == 'config':
			self._edit = self.sites[int(params[1])]
		elif params[0] == 'drop':
			w = WAWorker(self, 'drop', self.sites[int(params[1])])
			w.start()
		elif params[0] == 'enable':
			dt = self.sites[int(params[1])]
			self.mgr.nginx_enable(dt['name'])
		elif params[0] == 'disable':
			dt = self.sites[int(params[1])]
			self.mgr.nginx_disable(dt['name'])
		else: 
			for x in self.apptypes:
				if x.name.lower() == params[0]:
					speccall = getattr(x, params[1])
					speccall(self._edit)

	@event('dialog/submit')
	def on_submit(self, event, params, vars = None):
		if params[0] == 'dlgAdd':
			if vars.getvalue('action', '') == 'OK':
				if hasattr(self._current, 'dbengine'):
					on = False
					for dbtype in apis.databases(self.app).get_dbtypes():
						if self._current.dbengine == dbtype[0] and dbtype[2] == True:
							on = True
						elif self._current.dbengine == dbtype[0] and dbtype[2] == None:
							on = True
					if on:
						self._setup = self._current
					else:
						self.put_message('err', 'The database engine for %s is not running. Please start it via the Status button.' % self._current.dbengine)
				else:
					self._setup = self._current
			self._add = None
		if params[0] == 'dlgEdit':
			if vars.getvalue('action', '') == 'OK':
				name = vars.getvalue('cfgname', '')
				if name == '':
					self.put_message('err', 'Must choose a name')
				elif re.search('\.|-|[ ]', name):
					self.put_message('err', 'Site name must not contain spaces, dots or dashes')
				elif vars.getvalue('cfgaddr', '') == '':
					self.put_message('err', 'Must choose an address')
				elif vars.getvalue('cfgport', '') == '':
					self.put_message('err', 'Must choose a port (default 80)')
				elif vars.getvalue('cfgport') == self.app.gconfig.get('genesis', 'bind_port', ''):
					self.put_message('err', 'Can\'t use the same port number as Genesis')
				else:
					self.mgr.nginx_edit(
						origname=self._edit['name'], 
						name=vars.getvalue('cfgname'), 
						stype=self._edit['type'], 
						path=self._edit['path'], 
						addr=vars.getvalue('cfgaddr'), 
						port=vars.getvalue('cfgport'),
						ssl=self._edit['ssl'],
						php=self._edit['php']
						)
					apis.networkcontrol(self.app).change_webapp(
						self._edit['name'], vars.getvalue('cfgname'), 
						self._edit['type'], vars.getvalue('cfgport'))
			self._edit = None
		if params[0] == 'dlgSetup':
			if vars.getvalue('action', '') == 'OK':
				name = vars.getvalue('name', '').lower()
				port = vars.getvalue('port', '80')
				samename = False
				for site in self.sites:
					if name == site['name']:
						samename = True
				if not name or not self._setup:
					self.put_message('err', 'Name or type not selected')
				elif samename is True:
					self.put_message('err', 'A site with this name already exists')
				elif port == self.app.gconfig.get('genesis', 'bind_port', ''):
					self.put_message('err', 'Can\'t use the same port number as Genesis')
				elif re.search('\.|-|[ ]', name):
					self.put_message('err', 'Site name must not contain spaces, dots or dashes')
				else:
					w = WAWorker(self, 'add', name, self._current, vars)
					w.start()
					
			self._setup = None

	@event('listitem/click')
	def on_list_click(self, event, params, vars=None):
		for p in self.apptypes:
			if p.name == params[0]:
				self._current = p
Esempio n. 11
0
File: main.py Progetto: tewe/genesis
class WebAppsPlugin(apis.services.ServiceControlPlugin):
	text = 'Websites'
	iconfont = 'gen-earth'
	folder = 'servers'
	services = []

	def on_init(self):
		if self._relsec != None:
			if self._relsec[0] == 'add':
				apis.networkcontrol(self.app).add_webapp(self._relsec[1])
				self._relsec = None
			elif self._relsec[0] == 'del':
				apis.networkcontrol(self.app).remove_webapp(self._relsec[1])
			self._relsec = None
		self.services = []
		self.apiops = apis.webapps(self.app)
		self.dbops = apis.databases(self.app)
		self.mgr = WebappControl(self.app)
		self.sites = sorted(self.apiops.get_sites(), 
			key=lambda st: st.name)
		ats = sorted([x.plugin_info for x in self.apiops.get_apptypes()], key=lambda x: x.name.lower())
		self.apptypes = sorted(ats, key=lambda x: (hasattr(x, 'sort')))
		if len(self.sites) != 0:
			self.services.append(
				{
					"name": 'Web Server',
					"binary": 'nginx',
					"ports": []
				}
			)
			for x in self.sites:
				if x.php:
					self.services.append(
						{
							"name": 'PHP FastCGI',
							"binary": 'php-fpm',
							"ports": []
						}
					)
					break
		if not self._current:
			self._current = self.apptypes[0] if len(self.apptypes) else None
		for apptype in self.apptypes:
			ok = False
			for site in self.sites:
				if site.stype == apptype.wa_plugin:
					ok = True
			if ok == False:
				continue
			if hasattr(apptype, 'services'):
				for dep in apptype.services:
					post = True
					for svc in self.services:
						if svc['binary'] == dep['binary']:
							post = False
					if post == True:
						self.services.append({"name": dep['name'], "binary": dep['binary'], "ports": []})

	def on_session_start(self):
		self._add = None
		self._edit = None
		self._setup = None
		self._relsec = None
		self._dbauth = ('','','')

	def get_main_ui(self):
		ui = self.app.inflate('webapps:main')
		t = ui.find('list')

		for s in self.sites:
			if s.addr and s.ssl:
				addr = 'https://' + s.addr + (':'+s.port if s.port != '443' else '')
			elif s.addr:
				addr = 'http://' + s.addr + (':'+s.port if s.port != '80' else '')
			else:
				addr = False

			t.append(UI.DTR(
				UI.Iconfont(iconfont=s.sclass.plugin_info.iconfont if s.sclass and hasattr(s.sclass.plugin_info, 'iconfont') else 'gen-earth'),
				(UI.OutLinkLabel(
					text=s.name,
					url=addr
					) if s.addr is not False else UI.Label(text=s.name)
				),
				UI.Label(text=s.stype),
				UI.HContainer(
					UI.TipIcon(
						iconfont='gen-minus-circle' if s.enabled else 'gen-checkmark-circle',
						id=('disable/' if s.enabled else 'enable/') + str(self.sites.index(s)),
						text='Disable' if s.enabled else 'Enable'
					),
					UI.TipIcon(
						iconfont='gen-tools',
						id='config/' + str(self.sites.index(s)),
						text='Configure'
					),
					UI.TipIcon(
						iconfont='gen-cancel-circle',
						id='drop/' + str(self.sites.index(s)),
						text='Delete',
						warning='Are you sure you wish to delete site %s? This action is irreversible.%s'%(s.name,
							' If this Reverse Proxy was set up automatically by Genesis, this may cause the associated plugin to stop functioning.' if s.stype == 'ReverseProxy' else '')
						)
					),
				))

		provs = ui.find('provs')

		for apptype in self.apptypes:
			provs.append(
					UI.ListItem(
						UI.Label(text=apptype.name),
						id=apptype.name,
						active=apptype.name==self._current.name
					)
				)

		info = self._current
		if info:
			if info.logo:
				ui.find('logo').append(UI.Image(file='/dl/'+self._current.id+'/logo.png'))
			ui.find('appname').set('text', info.name)
			ui.find('short').set('text', info.desc)
			if info.app_homepage is None:
				ui.find('website').set('text', 'None')
				ui.find('website').set('url', 'http://localhost')
			else:
				ui.find('website').set('text', info.app_homepage)
				ui.find('website').set('url', info.app_homepage)
			ui.find('desc').set('text', info.longdesc)

		if self._add is None:
			ui.remove('dlgAdd')

		if self._setup is not None:
			ui.find('addr').set('value', self.app.get_backend(IHostnameManager).gethostname())
			if self._setup.nomulti is True:
				for site in self.sites:
					if self._setup.wa_plugin in site.stype:
						ui.remove('dlgSetup')
						ui.remove('dlgEdit')
						self.put_message('err', 'Only one site of this type at any given time')
						self._setup = None
						return ui
			try:
				cfgui = self.app.inflate(self._setup.id + ':conf')
				if hasattr(self.apiops.get_interface(self._setup.wa_plugin), 'show_opts_add'):
					self.apiops.get_interface(self._setup.wa_plugin).show_opts_add(cfgui)
				ui.append('app-config', cfgui)
			except:
				ui.find('app-config').append(UI.Label(text="No config options available for this app"))
		else:
			ui.remove('dlgSetup')

		if self._edit is not None:
			try:
				edgui = self.app.inflate(self._edit.stype.lower() + ':edit')
				ui.append('dlgEdit', edgui)
			except:
				pass
			ui.find('cfgname').set('value', self._edit.name)
			ui.find('cfgaddr').set('value', self._edit.addr)
			ui.find('cfgport').set('value', self._edit.port)
		else:
			ui.remove('dlgEdit')

		if self._dbauth[0] and not self.dbops.get_interface(self._dbauth[0]).checkpwstat():
			self.put_message('err', '%s does not have a root password set. '
				'Please add this via the Databases screen.' % self._dbauth[0])
			self._dbauth = ('','','')
		if self._dbauth[0]:
			ui.append('main', UI.InputBox(id='dlgAuth%s' % self._dbauth[0], 
				text='Enter the database password for %s' 
				% self._dbauth[0], password=True))

		return ui

	@event('button/click')
	def on_click(self, event, params, vars = None):
		if params[0] == 'add':
			if self.apptypes == []:
				self.put_message('err', 'No webapp types installed. Check the Applications tab to find some')
			else:
				self._add = len(self.sites)
		elif params[0] == 'config':
			self._edit = self.sites[int(params[1])]
		elif params[0] == 'drop':
			if hasattr(self.sites[int(params[1])], 'dbengine') and \
			self.sites[int(params[1])].dbengine and \
			self.dbops.get_info(self.sites[int(params[1])].dbengine).requires_conn and \
			not self.dbops.get_dbconn(self.sites[int(params[1])].dbengine):
				self._dbauth = (self.sites[int(params[1])].dbengine, 
					self.sites[int(params[1])], 'drop')
			else:
				w = WAWorker(self, 'drop', self.sites[int(params[1])])
				w.start()
		elif params[0] == 'enable':
			self.mgr.nginx_enable(self.sites[int(params[1])])
		elif params[0] == 'disable':
			self.mgr.nginx_disable(self.sites[int(params[1])])
		else: 
			for x in self.apptypes:
				if x.name.lower() == params[0]:
					speccall = getattr(self.apiops.get_interface(x.wa_plugin), params[1])
					speccall(self._edit)

	@event('dialog/submit')
	def on_submit(self, event, params, vars = None):
		if params[0] == 'dlgAdd':
			if vars.getvalue('action', '') == 'OK':
				if hasattr(self._current, 'dbengine') and self._current.dbengine:
					on = False
					for dbtype in self.dbops.get_dbtypes():
						if self._current.dbengine == dbtype[0] and dbtype[2] == True:
							on = True
						elif self._current.dbengine == dbtype[0] and dbtype[2] == None:
							on = True
					if on:
						if self.dbops.get_info(self._current.dbengine).requires_conn and \
						not self.dbops.get_dbconn(self._current.dbengine):
							self._dbauth = (self._current.dbengine, '', 'add')
						else:
							self._setup = self._current
					else:
						self.put_message('err', 'The database engine for %s is not running. Please start it via the Status button.' % self._current.dbengine)
				else:
					self._setup = self._current
			self._add = None
		if params[0] == 'dlgEdit':
			if vars.getvalue('action', '') == 'OK':
				name = vars.getvalue('cfgname', '')
				addr = vars.getvalue('cfgaddr', '')
				port = vars.getvalue('cfgport', '')
				vaddr = True
				for site in self.sites:
					if addr == site.addr and port == site.port:
						vaddr = False
				if name == '':
					self.put_message('err', 'Must choose a name')
				elif re.search('\.|-|`|\\\\|\/|^test$|[ ]', name):
					self.put_message('err', 'Site name must not contain spaces, dots, dashes or special characters')
				elif addr == '':
					self.put_message('err', 'Must choose an address')
				elif port == '':
					self.put_message('err', 'Must choose a port (default 80)')
				elif port == self.app.gconfig.get('genesis', 'bind_port', ''):
					self.put_message('err', 'Can\'t use the same port number as Genesis')
				elif not vaddr:
					self.put_message('err', 'Site must have either a different domain/subdomain or a different port')
				else:
					w = Webapp()
					w.name = name
					w.stype = self._edit.stype
					w.path = self._edit.path
					w.addr = addr
					w.port = port
					w.ssl = self._edit.ssl
					w.php = self._edit.php
					self.mgr.nginx_edit(self._edit, w)
					apis.networkcontrol(self.app).change_webapp(self._edit, w)
			self._edit = None
		if params[0] == 'dlgSetup':
			if vars.getvalue('action', '') == 'OK':
				name = vars.getvalue('name', '').lower()
				addr = vars.getvalue('addr', '')
				port = vars.getvalue('port', '80')
				vname, vaddr = True, True
				for site in self.sites:
					if name == site.name:
						vname = False
					if addr == site.addr and port == site.port:
						vaddr = False
				if not name or not self._setup:
					self.put_message('err', 'Name or type not selected')
				elif re.search('\.|-|`|\\\\|\/|^test$|[ ]', name):
					self.put_message('err', 'Site name must not contain spaces, dots, dashes or special characters')
				elif addr == '':
					self.put_message('err', 'Must choose an address')
				elif port == '':
					self.put_message('err', 'Must choose a port (default 80)')
				elif port == self.app.gconfig.get('genesis', 'bind_port', ''):
					self.put_message('err', 'Can\'t use the same port number as Genesis')
				elif not vaddr:
					self.put_message('err', 'Site must have either a different domain/subdomain or a different port')
				elif not vname:
					self.put_message('err', 'A site with this name already exists')
				else:
					w = WAWorker(self, 'add', name, self._current, vars)
					w.start()
			self._setup = None
		if params[0].startswith('dlgAuth'):
			dbtype = params[0].split('dlgAuth')[1]
			if vars.getvalue('action', '') == 'OK':
				login = vars.getvalue('value', '')
				try:
					dbauth = self._dbauth
					self._dbauth = ('','','')
					self.dbops.get_interface(dbtype).connect(
						store=self.app.session['dbconns'],
						passwd=login)
					if dbauth[2] == 'drop':
						w = WAWorker(self, 'drop', dbauth[1])
						w.start()
					elif dbauth[2] == 'add':
						self._setup = self._current
				except DBAuthFail, e:
					self.put_message('err', str(e))
			else:
				self.put_message('info', 'Website %s cancelled' % self._dbauth[2])
				self._dbauth = ('','','')
Esempio n. 12
0
class WebAppsPlugin(apis.services.ServiceControlPlugin):
    text = 'Websites'
    iconfont = 'gen-earth'
    folder = 'servers'
    services = []

    def on_init(self):
        if self._relsec != None:
            if self._relsec[0] == 'add':
                apis.networkcontrol(self.app).add_webapp(self._relsec[1])
                self._relsec = None
            elif self._relsec[0] == 'del':
                apis.networkcontrol(self.app).remove_webapp(self._relsec[1])
            self._relsec = None
        self.services = []
        self.apiops = apis.webapps(self.app)
        self.mgr = WebappControl(self.app)
        self.sites = sorted(self.apiops.get_sites(), key=lambda st: st['name'])
        ats = sorted(self.apiops.get_apptypes(), key=lambda x: x.name.lower())
        self.apptypes = sorted(ats, key=lambda x: (hasattr(x, 'sort')))
        if len(self.sites) != 0:
            self.services.append(('Web Server', 'nginx'))
        if not self._current:
            self._current = self.apptypes[0]
        for apptype in self.apptypes:
            ok = False
            for site in self.sites:
                if site['type'] == apptype.name:
                    ok = True
            if ok == False:
                continue
            if hasattr(apptype, 'services'):
                for dep in apptype.services:
                    post = True
                    for svc in self.services:
                        if svc[1] == dep[1]:
                            post = False
                    if post == True:
                        self.services.append((dep[0], dep[1]))

    def on_session_start(self):
        self._add = None
        self._edit = None
        self._setup = None
        self._relsec = None

    def get_main_ui(self):
        ui = self.app.inflate('webapps:main')
        t = ui.find('list')

        for s in self.sites:
            if s['addr'] is not False and s['ssl']:
                addr = 'https://' + s['addr'] + (':' + s['port'] if s['port']
                                                 is not '443' else '')
            elif s['addr'] is not False:
                addr = 'http://' + s['addr'] + (':' + s['port'] if s['port']
                                                is not '80' else '')
            else:
                addr = False

            t.append(
                UI.DTR(
                    UI.Iconfont(iconfont="gen-earth"),
                    (UI.OutLinkLabel(text=s['name'], url=addr)
                     if s['addr'] is not False else UI.Label(text=s['name'])),
                    UI.Label(text=s['type']),
                    UI.HContainer(
                        UI.TipIcon(
                            iconfont='gen-minus-circle'
                            if s['enabled'] else 'gen-checkmark-circle',
                            id=('disable/' if s['enabled'] else 'enable/') +
                            str(self.sites.index(s)),
                            text='Disable' if s['enabled'] else 'Enable'),
                        UI.TipIcon(iconfont='gen-tools',
                                   id='config/' + str(self.sites.index(s)),
                                   text='Configure'),
                        UI.TipIcon(
                            iconfont='gen-cancel-circle',
                            id='drop/' + str(self.sites.index(s)),
                            text='Delete',
                            warning=
                            'Are you sure you wish to delete site %s? This action is irreversible.'
                            % s['name'])),
                ))

        provs = ui.find('provs')

        for apptype in self.apptypes:
            provs.append(
                UI.ListItem(UI.Label(text=apptype.name),
                            id=apptype.name,
                            active=apptype.name == self._current.name))

        info = self._current.get_info()
        if info['logo'] is True:
            ui.find('logo').set(
                'file', '/dl/' + self._current.__class__.__name__.lower() +
                '/logo.png')
        ui.find('appname').set('text', info['name'])
        ui.find('short').set('text', info['short'])
        if info['site'] is None:
            ui.find('website').set('text', 'None')
            ui.find('website').set('url', 'http://localhost')
        else:
            ui.find('website').set('text', info['site'])
            ui.find('website').set('url', info['site'])
        ui.find('desc').set('text', info['long'])

        if self._add is None:
            ui.remove('dlgAdd')

        if self._setup is not None:
            if self._setup.nomulti is True:
                for site in self.sites:
                    if self._setup.name in site['type']:
                        ui.remove('dlgSetup')
                        ui.remove('dlgEdit')
                        self.put_message(
                            'err',
                            'Only one site of this type at any given time')
                        self._setup = None
                        return ui
            try:
                if self._setup.name == 'Website':
                    cfgui = self.app.inflate('webapps:conf')
                    type_sel = [UI.SelectOption(text='None', value='None')]
                    for x in sorted(apis.databases(self.app).get_dbtypes()):
                        type_sel.append(UI.SelectOption(text=x[0], value=x[0]))
                    cfgui.appendAll('ws-dbsel', *type_sel)
                else:
                    cfgui = self.app.inflate(
                        self._setup.__class__.__name__.lower() + ':conf')
                ui.append('app-config', cfgui)
            except:
                raise
                ui.find('app-config').append(
                    UI.Label(text="No config options available for this app"))
        else:
            ui.remove('dlgSetup')

        if self._edit is not None:
            try:
                edgui = self.app.inflate(self._edit['type'].lower() + ':edit')
                ui.append('dlgEdit', edgui)
            except:
                pass
            ui.find('cfgname').set('value', self._edit['name'])
            ui.find('cfgaddr').set('value', self._edit['addr'])
            ui.find('cfgport').set('value', self._edit['port'])
        else:
            ui.remove('dlgEdit')

        return ui

    @event('button/click')
    def on_click(self, event, params, vars=None):
        if params[0] == 'add':
            if self.apptypes == []:
                self.put_message(
                    'err',
                    'No webapp types installed. Check the Applications tab to find some'
                )
            else:
                self._add = len(self.sites)
        elif params[0] == 'config':
            self._edit = self.sites[int(params[1])]
        elif params[0] == 'drop':
            w = WAWorker(self, 'drop', self.sites[int(params[1])])
            w.start()
        elif params[0] == 'enable':
            dt = self.sites[int(params[1])]
            self.mgr.nginx_enable(dt['name'])
        elif params[0] == 'disable':
            dt = self.sites[int(params[1])]
            self.mgr.nginx_disable(dt['name'])
        else:
            for x in self.apptypes:
                if x.name.lower() == params[0]:
                    speccall = getattr(x, params[1])
                    speccall(self._edit)

    @event('dialog/submit')
    def on_submit(self, event, params, vars=None):
        if params[0] == 'dlgAdd':
            if vars.getvalue('action', '') == 'OK':
                if hasattr(self._current, 'dbengine'):
                    on = False
                    for dbtype in apis.databases(self.app).get_dbtypes():
                        if self._current.dbengine == dbtype[0] and dbtype[
                                2] == True:
                            on = True
                        elif self._current.dbengine == dbtype[0] and dbtype[
                                2] == None:
                            on = True
                    if on:
                        self._setup = self._current
                    else:
                        self.put_message(
                            'err',
                            'The database engine for %s is not running. Please start it via the Status button.'
                            % self._current.dbengine)
                else:
                    self._setup = self._current
            self._add = None
        if params[0] == 'dlgEdit':
            if vars.getvalue('action', '') == 'OK':
                name = vars.getvalue('cfgname', '')
                if name == '':
                    self.put_message('err', 'Must choose a name')
                elif re.search('\.|-|[ ]', name):
                    self.put_message(
                        'err',
                        'Site name must not contain spaces, dots or dashes')
                elif vars.getvalue('cfgaddr', '') == '':
                    self.put_message('err', 'Must choose an address')
                elif vars.getvalue('cfgport', '') == '':
                    self.put_message('err', 'Must choose a port (default 80)')
                elif vars.getvalue('cfgport') == self.app.gconfig.get(
                        'genesis', 'bind_port', ''):
                    self.put_message(
                        'err', 'Can\'t use the same port number as Genesis')
                else:
                    self.mgr.nginx_edit(origname=self._edit['name'],
                                        name=vars.getvalue('cfgname'),
                                        stype=self._edit['type'],
                                        path=self._edit['path'],
                                        addr=vars.getvalue('cfgaddr'),
                                        port=vars.getvalue('cfgport'),
                                        ssl=self._edit['ssl'],
                                        php=self._edit['php'])
                    apis.networkcontrol(self.app).change_webapp(
                        self._edit['name'], vars.getvalue('cfgname'),
                        self._edit['type'], vars.getvalue('cfgport'))
            self._edit = None
        if params[0] == 'dlgSetup':
            if vars.getvalue('action', '') == 'OK':
                name = vars.getvalue('name', '').lower()
                port = vars.getvalue('port', '80')
                samename = False
                for site in self.sites:
                    if name == site['name']:
                        samename = True
                if not name or not self._setup:
                    self.put_message('err', 'Name or type not selected')
                elif samename is True:
                    self.put_message('err',
                                     'A site with this name already exists')
                elif port == self.app.gconfig.get('genesis', 'bind_port', ''):
                    self.put_message(
                        'err', 'Can\'t use the same port number as Genesis')
                elif re.search('\.|-|[ ]', name):
                    self.put_message(
                        'err',
                        'Site name must not contain spaces, dots or dashes')
                else:
                    w = WAWorker(self, 'add', name, self._current, vars)
                    w.start()

            self._setup = None

    @event('listitem/click')
    def on_list_click(self, event, params, vars=None):
        for p in self.apptypes:
            if p.name == params[0]:
                self._current = p