def __init__(self, request, response): """ Constructor. Args: request: The webapp2.Request object that contains information about the current web request. response: The webapp2.Response object that contains the response to be sent back to the browser. """ self.initialize(request, response) self.helper = AppDashboardHelper() self.dstore = AppDashboardData(self.helper)
def get(self): """ Retrieves the cached information about applications running in this AppScale deployment as a JSON-encoded dict. """ is_cloud_admin = AppDashboardHelper().is_user_cloud_admin() apps_user_is_admin_on = AppDashboardHelper().get_application_info() if not is_cloud_admin: apps_user_owns = AppDashboardHelper().get_owned_apps() new_app_dict = {} for app_name in apps_user_owns: if app_name in apps_user_is_admin_on: new_app_dict[app_name] = apps_user_is_admin_on.get(app_name) apps_user_is_admin_on = new_app_dict self.response.out.write(json.dumps(apps_user_is_admin_on))
def test_update_cookie_app_list(self): fake_user = flexmock() fake_user.should_receive('email').and_return('*****@*****.**') flexmock(users).should_receive('get_current_user') \ .and_return(fake_user) flexmock(AppDashboardHelper).should_receive('get_cookie_app_list') \ .and_return(['app1', 'app2']) flexmock(AppDashboardHelper).should_receive('set_appserver_cookie') \ .once() self.assertTrue(AppDashboardHelper().update_cookie_app_list( ['app1', 'app2', 'app3'], flexmock(), flexmock())) self.assertFalse(AppDashboardHelper().update_cookie_app_list( ['app1', 'app2'], flexmock(), flexmock()))
def get(self): """ Retrieves the cached information about applications running in this AppScale deployment as a JSON-encoded dict. """ is_cloud_admin = AppDashboardHelper().is_user_cloud_admin() all_versions = AppDashboardHelper().get_version_info() if is_cloud_admin: apps_user_owns = {version.split('_')[0] for version in all_versions} else: apps_user_owns = AppDashboardHelper().get_owned_apps() versions_user_is_admin_on = { version: all_versions[version] for version in all_versions if version.split('_')[0] in apps_user_owns} self.response.out.write(json.dumps(versions_user_is_admin_on))
def get_status_info(self): """ Queries our local AppController to get server-level information about every server running in this AppScale deployment. Returns: A list of dicts, where each dict contains VM-level info (e.g., CPU, memory, disk usage) about that machine. The empty list is returned if there was a problem retrieving this information. """ cluster_stats = self.setUpClusterStats() statuses = AppDashboardHelper().get_status_info() test_statuses = [] for node in cluster_stats: cpu_usage = 100.0 - node['cpu']['idle'] total_memory = node['memory']['available'] + node['memory']['used'] memory_usage = round(100.0 * node['memory']['used'] / total_memory, 1) total_disk = 0 total_used = 0 for disk in node['disk']: for _, disk_info in disk.iteritems(): total_disk += disk_info['free'] + disk_info['used'] total_used += disk_info['used'] disk_usage = round(100.0 * total_used / total_disk, 1) test_statuses.append({'ip': node['public_ip'], 'cpu': str(cpu_usage), 'memory': str(memory_usage), 'disk': str(disk_usage), 'roles': node['roles'], 'key': str(node['public_ip']).translate(None, '.')}) self.assertEqual(statuses, test_statuses)
def test_get_user_app_list(self): flexmock(AppDashboardHelper).should_receive('query_user_data') \ .and_return('\napplications:app1:app2\n') output = AppDashboardHelper().get_user_app_list('*****@*****.**') self.assertTrue(len(output) == 2) self.assertEquals('app1', output[0]) self.assertEquals('app2', output[1])
def test_get_cookie_app_list(self): request = flexmock() request.cookies = { AppDashboardHelper.DEV_APPSERVER_LOGIN_COOKIE : urllib.quote('[email protected]:a:app1,app2:FAKEHASH') } output = AppDashboardHelper().get_cookie_app_list(request) self.assertTrue( len(output) == 2 ) self.assertEquals('app1', output[0] ) self.assertEquals('app2', output[1] )
def get_version_info(self): """ Queries the AppController for information about active versions. Returns: A dictionary mapping version keys to serving URLs. A None value indicates that the version is still loading. """ version_info = { 'test1_default_v1': ['http://1.1.1.1:1', 'https://1.1.1.1:1'], 'test2_default_v1': ['http://1.1.1.1:2', 'https://1.1.1.1:2'] } flexmock(AppDashboardHelper) AppDashboardHelper.should_receive('get_login_host').and_return('1.1.1.1') AppDashboardHelper.should_receive('get_version_ports').and_return([1, 1])\ .and_return([2, 2]) self.setUpClusterStats() app_info = AppDashboardHelper().get_version_info() self.assertEqual(app_info, version_info)
def __init__(self, helper=None): """ Creates a new AppDashboard, which will cache SOAP-exposed information provided to us by the AppDashboardHelper. Args: helper: An AppDashboardHelper, which will perform SOAP calls to the AppController whenever the AppDashboardData needs to update its caches. If None is provided here, then the AppDashboardData will create a new AppDashboardHelper to talk to the AppController. """ self.helper = helper or AppDashboardHelper()
def get_application_info(self): """ Queries the AppController for information about which Google App Engine applications are currently running, and if they are done loading, the URL that they can be accessed at. Returns: A dict, where each key is a str indicating the name of a Google App Engine application running in this deployment, and each value is either a str indicating the URL that the app can be found at, or None, if the application is still loading. """ application_info = { "test1": ["http://1.1.1.1:1", "https://1.1.1.1:1"], "test2": ["http://1.1.1.1:2", "https://1.1.1.1:2"] } flexmock(AppDashboardHelper) AppDashboardHelper.should_receive('get_login_host').and_return( '1.1.1.1') AppDashboardHelper.should_receive('get_version_ports').and_return([1, 1])\ .and_return([2, 2]) self.setUpClusterStats() app_info = AppDashboardHelper().get_application_info() self.assertEqual(app_info, application_info)
def get_instance_info(self, app_id): """ Queries the AppController to get instance information for a given app_id """ self.setUpInstanceStats() instance_info = AppDashboardHelper().get_instance_info('test1') test1_instance_stats = [{ 'host': '1.1.1.1', 'port': 0000, 'language': 'python' }, { 'host': '1.1.1.1', 'port': 0001, 'language': 'python' }, { 'host': '1.1.1.1', 'port': 0002, 'language': 'python' }]
class AppDashboard(webapp2.RequestHandler): """ Class that all pages in the Dashboard must inherit from. """ # Regular expression to capture the continue url. CONTINUE_URL_REGEX = 'continue=(.*)$' # The dashboard's project ID. PROJECT_ID = 'appscaledashboard' # Regular expression for updating user permissions. USER_PERMISSION_REGEX = '^user_permission_' # Regular expression that matches email addresses. USER_EMAIL_REGEX = '^\w[^@\s]*@[^@\s]{2,}$' # The frequency, in seconds, that defines how often Task Queue tasks are fired # to update the Dashboard's Datastore cache. REFRESH_WAIT_TIME = 10 def __init__(self, request, response): """ Constructor. Args: request: The webapp2.Request object that contains information about the current web request. response: The webapp2.Response object that contains the response to be sent back to the browser. """ self.initialize(request, response) self.helper = AppDashboardHelper() self.dstore = AppDashboardData(self.helper) def render_template(self, template_file, values=None): """ Renders a template file with all variables loaded. Args: template_file: A str with the relative path to template file. values: A dict with key/value pairs used as variables in the jinja template files. Returns: A str with the rendered template. """ if values is None: values = {} is_cloud_admin = self.helper.is_user_cloud_admin() all_versions = self.helper.get_version_info() if is_cloud_admin: apps_user_owns = list( {version.split('_')[0] for version in all_versions}) else: apps_user_owns = self.helper.get_owned_apps() versions_user_is_admin_on = { version: all_versions[version] for version in all_versions if version.split('_')[0] in apps_user_owns } self.helper.update_cookie_app_list(apps_user_owns, self.request, self.response) template = jinja_environment.get_template(template_file) sub_vars = { 'logged_in': self.helper.is_user_logged_in(), 'user_email': self.helper.get_user_email(), 'is_user_cloud_admin': self.dstore.is_user_cloud_admin(), 'can_upload_apps': self.dstore.can_upload_apps(), 'versions_user_is_admin_on': versions_user_is_admin_on, 'user_layout_pref': self.dstore.get_dash_layout_settings(), 'flower_url': self.dstore.get_flower_url(), 'monit_url': self.dstore.get_monit_url() } for key in values.keys(): sub_vars[key] = values[key] return template.render(sub_vars) def get_shared_navigation(self, page): """ Renders the shared navigation. Args: page: A string specifying the page ID. Returns: A str with the navigation bar rendered. """ show_create_account = True if AppDashboardHelper.USE_SHIBBOLETH: show_create_account = False # These sections do not lend themselves well to having panels. panel_blacklist = ['monit', 'taskqueue', 'datastore_viewer'] return self.render_template(template_file='shared/navigation.html', values={ 'show_create_account': show_create_account, 'page_name': page, 'panel_blacklist': panel_blacklist }) def render_page(self, page, template_file, values=None): """ Renders a template with the main layout and nav bar. Args: page: A string specifying the page ID. template_file: A string specifying the template to use. values: A dictionary containing template variables. """ if values is None: values = {} self.response.headers['Content-Type'] = 'text/html' template = jinja_environment.get_template('layouts/main.html') self.response.out.write( template.render( page_name=page, page_body=self.render_template(template_file, values), shared_navigation=self.get_shared_navigation(page))) def render_app_page(self, page, values=None): """ Render a typical page using the app_page template. Args: page: A string specifying the page ID. values: A dictionary containing template variables. """ self.render_page(page=page, template_file="layouts/app_page.html", values=values)
class AppDashboard(webapp2.RequestHandler): """ Class that all pages in the Dashboard must inherit from. """ # Regular expression to capture the continue url. CONTINUE_URL_REGEX = 'continue=(.*)$' # Regular expression for updating user permissions. USER_PERMISSION_REGEX = '^user_permission_' # Regular expression that matches email addresses. USER_EMAIL_REGEX = '^\w[^@\s]*@[^@\s]{2,}$' # The frequency, in seconds, that defines how often Task Queue tasks are fired # to update the Dashboard's Datastore cache. REFRESH_WAIT_TIME = 10 def __init__(self, request, response): """ Constructor. Args: request: The webapp2.Request object that contains information about the current web request. response: The webapp2.Response object that contains the response to be sent back to the browser. """ self.initialize(request, response) self.helper = AppDashboardHelper() self.dstore = AppDashboardData(self.helper) def render_template(self, template_file, values=None): """ Renders a template file with all variables loaded. Args: template_file: A str with the relative path to template file. values: A dict with key/value pairs used as variables in the jinja template files. Returns: A str with the rendered template. """ if values is None: values = {} owned_apps = self.dstore.get_owned_apps() self.helper.update_cookie_app_list(owned_apps, self.request, self.response) template = jinja_environment.get_template(template_file) sub_vars = { 'logged_in' : self.helper.is_user_logged_in(), 'user_email' : self.helper.get_user_email(), 'is_user_cloud_admin' : self.dstore.is_user_cloud_admin(), 'can_upload_apps' : self.dstore.can_upload_apps(), 'apps_user_is_admin_on' : owned_apps, 'flower_url' : self.dstore.get_flower_url(), } for key in values.keys(): sub_vars[key] = values[key] return template.render(sub_vars) def get_shared_navigation(self): """ Renders the shared navigation. Returns: A str with the navigation bar rendered. """ return self.render_template(template_file='shared/navigation.html') def render_page(self, page, template_file, values=None ): """ Renders a template with the main layout and nav bar. """ if values is None: values = {} self.response.headers['Content-Type'] = 'text/html' template = jinja_environment.get_template('layouts/main.html') self.response.out.write(template.render( page_name=page, page_body=self.render_template(template_file, values), shared_navigation=self.get_shared_navigation() ))
class AppDashboard(webapp2.RequestHandler): """ Class that all pages in the Dashboard must inherit from. """ # Regular expression to capture the continue url. CONTINUE_URL_REGEX = 'continue=(.*)$' # The dashboard's project ID. PROJECT_ID = 'appscaledashboard' # Regular expression for updating user permissions. USER_PERMISSION_REGEX = '^user_permission_' # Regular expression that matches email addresses. USER_EMAIL_REGEX = '^\w[^@\s]*@[^@\s]{2,}$' # The frequency, in seconds, that defines how often Task Queue tasks are fired # to update the Dashboard's Datastore cache. REFRESH_WAIT_TIME = 10 def __init__(self, request, response): """ Constructor. Args: request: The webapp2.Request object that contains information about the current web request. response: The webapp2.Response object that contains the response to be sent back to the browser. """ self.initialize(request, response) self.helper = AppDashboardHelper() self.dstore = AppDashboardData(self.helper) def render_template(self, template_file, values=None): """ Renders a template file with all variables loaded. Args: template_file: A str with the relative path to template file. values: A dict with key/value pairs used as variables in the jinja template files. Returns: A str with the rendered template. """ if values is None: values = {} is_cloud_admin = self.helper.is_user_cloud_admin() all_versions = self.helper.get_version_info() if is_cloud_admin: apps_user_owns = list({version.split('_')[0] for version in all_versions}) else: apps_user_owns = self.helper.get_owned_apps() versions_user_is_admin_on = { version: all_versions[version] for version in all_versions if version.split('_')[0] in apps_user_owns} self.helper.update_cookie_app_list(apps_user_owns, self.request, self.response) template = jinja_environment.get_template(template_file) sub_vars = { 'logged_in': self.helper.is_user_logged_in(), 'user_email': self.helper.get_user_email(), 'is_user_cloud_admin': self.dstore.is_user_cloud_admin(), 'can_upload_apps': self.dstore.can_upload_apps(), 'versions_user_is_admin_on': versions_user_is_admin_on, 'user_layout_pref': self.dstore.get_dash_layout_settings(), 'flower_url': self.dstore.get_flower_url(), 'monit_url': self.dstore.get_monit_url() } for key in values.keys(): sub_vars[key] = values[key] return template.render(sub_vars) def get_shared_navigation(self, page): """ Renders the shared navigation. Args: page: A string specifying the page ID. Returns: A str with the navigation bar rendered. """ show_create_account = True if AppDashboardHelper.USE_SHIBBOLETH: show_create_account = False # These sections do not lend themselves well to having panels. panel_blacklist = ['monit', 'taskqueue', 'datastore_viewer'] return self.render_template(template_file='shared/navigation.html', values={'show_create_account': show_create_account, 'page_name': page, 'panel_blacklist': panel_blacklist}) def render_page(self, page, template_file, values=None): """ Renders a template with the main layout and nav bar. Args: page: A string specifying the page ID. template_file: A string specifying the template to use. values: A dictionary containing template variables. """ if values is None: values = {} self.response.headers['Content-Type'] = 'text/html' template = jinja_environment.get_template('layouts/main.html') self.response.out.write(template.render( page_name=page, page_body=self.render_template(template_file, values), shared_navigation=self.get_shared_navigation(page) )) def render_app_page(self, page, values=None): """ Render a typical page using the app_page template. Args: page: A string specifying the page ID. values: A dictionary containing template variables. """ self.render_page(page=page, template_file="layouts/app_page.html", values=values)
class AppDashboard(webapp2.RequestHandler): """ Class that all pages in the Dashboard must inherit from. """ # Regular expression to capture the continue url. CONTINUE_URL_REGEX = 'continue=(.*)$' # Regular expression for updating user permissions. USER_PERMISSION_REGEX = '^user_permission_' # Regular expression that matches email addresses. USER_EMAIL_REGEX = '^\w[^@\s]*@[^@\s]{2,}$' # The frequency, in seconds, that defines how often Task Queue tasks are fired # to update the Dashboard's Datastore cache. REFRESH_WAIT_TIME = 10 def __init__(self, request, response): """ Constructor. Args: request: The webapp2.Request object that contains information about the current web request. response: The webapp2.Response object that contains the response to be sent back to the browser. """ self.initialize(request, response) self.helper = AppDashboardHelper() self.dstore = AppDashboardData(self.helper) def render_template(self, template_file, values=None): """ Renders a template file with all variables loaded. Args: template_file: A str with the relative path to template file. values: A dict with key/value pairs used as variables in the jinja template files. Returns: A str with the rendered template. """ if values is None: values = {} owned_apps = self.dstore.get_owned_apps() self.helper.update_cookie_app_list(owned_apps, self.request, self.response) template = jinja_environment.get_template(template_file) sub_vars = { 'logged_in': self.helper.is_user_logged_in(), 'user_email': self.helper.get_user_email(), 'is_user_cloud_admin': self.dstore.is_user_cloud_admin(), 'can_upload_apps': self.dstore.can_upload_apps(), 'apps_user_is_admin_on': owned_apps, 'flower_url': self.dstore.get_flower_url(), 'monit_url': self.dstore.get_monit_url() } for key in values.keys(): sub_vars[key] = values[key] return template.render(sub_vars) def get_shared_navigation(self): """ Renders the shared navigation. Returns: A str with the navigation bar rendered. """ show_create_account = True if AppDashboardHelper.USE_SHIBBOLETH: show_create_account = False return self.render_template( template_file='shared/navigation.html', values={'show_create_account': show_create_account}) def render_page(self, page, template_file, values=None): """ Renders a template with the main layout and nav bar. """ if values is None: values = {} self.response.headers['Content-Type'] = 'text/html' template = jinja_environment.get_template('layouts/main.html') self.response.out.write( template.render(page_name=page, page_body=self.render_template( template_file, values), shared_navigation=self.get_shared_navigation()))
def get(self): """ Retrieves the cached information about machine-level statistics as a JSON-encoded dict. """ self.response.out.write(json.dumps(AppDashboardHelper().get_status_info()))