def add_role(session, role_name, role_password, role_email, is_active=True, is_admin=False): try: role = Roles( role_name=unicode(role_name), role_password=unicode(role_password), role_email=unicode(role_email), is_active=is_active, is_admin=is_admin) session.add(role) session.flush() return role except IntegrityError as e: if e.message.find('roles_role_email_key') > 0: raise TemboardUIError(400, "Email address '%s' already in use." % (role_email)) elif e.message.find('roles_pkey') > 0: raise TemboardUIError(400, "Role '%s' already exists." % (role_name)) else: raise TemboardUIError(e.message) except Exception as e: raise TemboardUIError(e.message)
def add_role_group_in_instance_group(session, role_group_name, instance_group_name): try: ari = AccessRoleInstance( role_group_name=unicode(role_group_name), instance_group_name=unicode(instance_group_name)) session.add(ari) session.flush() except IntegrityError as e: if e.message.find('access_role_instance_pkey') > 0: raise TemboardUIError( 400, "Group '%s' ('role') has already access to '%s'." % (role_group_name, instance_group_name)) elif e.message.find( 'access_role_instance_instance_group_name_fkey') > 0: raise TemboardUIError( 400, "Instance group '%s' does not exist." % (instance_group_name)) elif e.message.find('access_role_instance_role_group_name_fkey') > 0: raise TemboardUIError( 400, "Role group '%s' does not exist." % (role_group_name)) else: raise TemboardUIError(400, e.message) except Exception as e: raise TemboardUIError(400, e.message)
def update_group(session, group_name, group_kind, new_group_name=None, group_description=None): try: group = session.query(Groups) \ .filter_by( group_name=unicode(group_name), group_kind=unicode(group_kind)) \ .first() if new_group_name is not None: group.group_name = unicode(new_group_name) if group_description is not None: group.group_description = unicode(group_description) session.merge(group) session.flush() return group except IntegrityError as e: if e.message.find('groups_pkey') > 0: raise TemboardUIError(400, "Group name '%s' already in use." % (new_group_name)) else: raise TemboardUIError(400, e.message) except AttributeError as e: raise TemboardUIError(400, "Group '%s' ('%s') not found." % (group_name, group_kind)) except Exception as e: raise TemboardUIError(400, e.message)
def delete_instance(self): try: self.load_auth_cookie() self.start_db_session() self.check_admin() data = tornado.escape.json_decode(self.request.body) if 'agent_address' not in data or data['agent_address'] == '': raise TemboardUIError(400, "Agent address field is missing.") if 'agent_port' not in data or data['agent_port'] == '': raise TemboardUIError(400, "Agent port field is missing.") delete_instance(self.db_session, data['agent_address'], data['agent_port']) self.db_session.commit() self.db_session.close() return JSONAsyncResult(200, {'delete': True}) except (TemboardUIError, Exception) as e: self.logger.error(e.message) try: self.db_session.rollback() self.db_session.close() except Exception: pass if isinstance(e, TemboardUIError): return JSONAsyncResult(e.code, {'error': e.message}) else: return JSONAsyncResult(500, {'error': "Internal error."})
def add_instance_in_group(session, agent_address, agent_port, group_name): try: # Create instance group if not exists group = Groups(group_name=unicode(group_name), group_kind=u'instance') session.merge(group) session.flush() instance_group = InstanceGroups(agent_address=unicode(agent_address), agent_port=agent_port, group_name=unicode(group_name)) session.add(instance_group) session.flush() except IntegrityError as e: if e.message.find('instance_groups_group_name_fkey') > 0: raise TemboardUIError( 400, "Group '%s' ('instance') does not exist." % (group_name)) elif e.message.find('instance_groups_agent_address_fkey') > 0: raise TemboardUIError( 400, "Instance entry ('%s:%s') does not exist." % (agent_address, agent_port)) elif e.message.find('instance_groups_pkey') > 0: raise TemboardUIError( 400, "Instance entry ('%s:%s)' already in group '%s'." % (agent_address, agent_port, group_name)) else: raise TemboardUIError(400, e.message) except Exception as e: raise TemboardUIError(400, e.message)
def get_notifications(self, agent_address, agent_port): try: instance = None role = None self.load_auth_cookie() self.start_db_session() role = self.current_user if not role: raise TemboardUIError(302, "Current role unknown.") instance = get_instance(self.db_session, agent_address, agent_port) if not instance: raise TemboardUIError(404, "Instance not found.") self.db_session.expunge_all() self.db_session.commit() self.db_session.close() xsession = self.get_secure_cookie("temboard_%s_%s" % (instance.agent_address, instance.agent_port)) if not xsession: raise TemboardUIError(401, "Authentication cookie is missing.") # Load notifications. notifications = temboard_get_notifications(self.ssl_ca_cert_file, instance.agent_address, instance.agent_port, xsession) return HTMLAsyncResult( http_code = 200, template_file = 'notifications.html', data = { 'nav': True, 'role': role, 'instance': instance, 'notifications': notifications, 'xsession': xsession }) except (TemboardUIError, TemboardError, Exception) as e: self.logger.error(e.message) try: self.db_session.expunge_all() self.db_session.rollback() self.db_session.close() except Exception: pass if (isinstance(e, TemboardUIError) or isinstance(e, TemboardError)): if e.code == 401: return HTMLAsyncResult(http_code = 401, redirection = "/server/%s/%s/login" % (agent_address, agent_port)) elif e.code == 302: return HTMLAsyncResult(http_code = 401, redirection = "/login") code = e.code else: code = 500 return HTMLAsyncResult( http_code = code, template_file = 'error.html', data = { 'nav': True, 'role': role, 'instance': instance, 'code': e.code, 'error': e.message })
def update_instance(session, agent_address, agent_port, new_agent_address=None, new_agent_port=None, agent_key=None, hostname=None, cpu=None, memory_size=None, pg_port=None, pg_version=None, pg_version_summary=None, pg_data=None, notify=True): try: instance = session.query(Instances) \ .filter_by( agent_address=unicode(agent_address), agent_port=agent_port) \ .first() if new_agent_address is not None: instance.agent_address = unicode(new_agent_address) if new_agent_port is not None: instance.agent_port = int(new_agent_port) if cpu is not None and cpu != u'': instance.cpu = int(cpu) else: instance.cpu = None if memory_size is not None and memory_size != u'': instance.memory_size = int(memory_size) else: instance.memory_size = None if pg_port is not None and pg_port != u'': instance.pg_port = int(pg_port) else: instance.pg_port = None instance.notify = bool(notify) for prop in [ 'agent_key', 'hostname', 'pg_version', 'pg_version_summary', 'pg_data' ]: if locals().get(prop) is not None: setattr(instance, prop, unicode(locals().get(prop))) session.merge(instance) session.flush() return instance except IntegrityError as e: if e.message.find('instances_pkey') > 0: raise TemboardUIError( 400, "Instance entry ('%s:%s') already exists." % (agent_address, agent_port)) else: raise TemboardUIError(400, e.message) except AttributeError as e: raise TemboardUIError( 400, "Instance entry ('%s:%s') not found." % (agent_address, agent_port)) except Exception as e: raise TemboardUIError(400, e.message)
def get_role(session, role_name): try: return session.query(Roles).options(joinedload( Roles.groups)).filter_by(role_name=unicode(role_name)).first() except AttributeError as e: raise TemboardUIError(400, "Role '%s' not found." % (role_name)) except Exception as e: raise TemboardUIError(e.message)
def delete_role(session, role_name): try: role = session.query(Roles).filter( Roles.role_name == unicode(role_name)).one() session.delete(role) except NoResultFound as e: raise TemboardUIError(400, "Role '%s' not found." % (role_name)) except Exception as e: raise TemboardUIError(e.message)
def delete_group(session, group_name, group_kind): try: group = session.query(Groups).filter( Groups.group_name == unicode(group_name), Groups.group_kind == unicode(group_kind)).one() session.delete(group) except NoResultFound as e: raise TemboardUIError(400, "Group '%s' not found." % (group_name)) except Exception as e: raise TemboardUIError(400, e.message)
def get_activity_w_b(self, agent_address, agent_port, mode): try: self.logger.info("Getting waiting/blocking sessions (proxy).") role = None instance = None self.load_auth_cookie() self.start_db_session() role = self.current_user if not role: raise TemboardUIError(302, "Current role unknown.") instance = get_instance(self.db_session, agent_address, agent_port) if not instance: raise TemboardUIError(404, "Instance not found.") if __name__ not in [ plugin.plugin_name for plugin in instance.plugins ]: raise TemboardUIError(408, "Plugin not activated.") self.db_session.expunge_all() self.db_session.commit() self.db_session.close() xsession = self.request.headers.get('X-Session') if not xsession: raise TemboardUIError(401, 'X-Session header missing') # Load activity. if mode == 'waiting': data_activity = temboard_activity_waiting( self.ssl_ca_cert_file, instance.agent_address, instance.agent_port, xsession) elif mode == 'blocking': data_activity = temboard_activity_blocking( self.ssl_ca_cert_file, instance.agent_address, instance.agent_port, xsession) else: raise TemboardUIError(404, "Mode unknown.") self.logger.info("Done.") return JSONAsyncResult(http_code=200, data=data_activity) except (TemboardUIError, TemboardError, Exception) as e: self.logger.traceback(get_tb()) self.logger.error(str(e)) self.logger.info("Failed.") try: self.db_session.close() except Exception: pass if (isinstance(e, TemboardUIError) or isinstance(e, TemboardError)): return JSONAsyncResult(http_code=e.code, data={'error': e.message}) else: return JSONAsyncResult(http_code=500, data={'error': e.message})
def validate_user_data(data, role=None): # Submited attributes checking. if not data.get('new_username'): raise TemboardUIError(400, "Username is missing.") if data.get('email'): check_role_email(data['email']) if data.get('phone'): check_role_phone(data['phone']) if 'groups' not in data: raise TemboardUIError(400, "Groups field is missing.") if 'is_active' not in data: raise TemboardUIError(400, "Active field is missing.") if 'is_admin' not in data: raise TemboardUIError(400, "Administrator field is missing.") if role and role.role_name != data['new_username']: if not data.get('password'): raise TemboardUIError( 400, "Username will be changed, you need to change " "the password too.") if role is None: if not data.get('password'): raise TemboardUIError(400, "Password is missing.") if data.get('password') and not data.get('password2'): raise TemboardUIError(400, "Password confirmation is missing.") if 'password' in data and 'password2' in data: if data['password'] != data['password2']: raise TemboardUIError( 400, "Password confirmation can not be checked.") if data['groups'] is not None and type(data['groups']) != list: raise TemboardUIError(400, "Invalid group list.") check_role_name(data['new_username'])
def delete_role_from_group(session, role_name, group_name): try: role_group = session.query(RoleGroups).filter( RoleGroups.group_name == unicode(group_name), RoleGroups.role_name == unicode(role_name)).one() session.delete(role_group) except NoResultFound as e: raise TemboardUIError(400, "Role '%s' not found in group '%s'." % (role_name, group_name)) except Exception as e: raise TemboardUIError(400, e.message)
def delete_instance(session, agent_address, agent_port): try: instance = session.query(Instances).filter( Instances.agent_address == unicode(agent_address), Instances.agent_port == agent_port).one() session.delete(instance) except NoResultFound as e: raise TemboardUIError(400, "Instance entry ('%s:%s') not found." % (agent_address, agent_port)) except Exception as e: raise TemboardUIError(400, e.message)
def update_instance(session, agent_address, agent_port, new_agent_address=None, new_agent_port=None, agent_key=None, hostname=None, cpu=None, memory_size=None, pg_port=None, pg_version=None, pg_data=None): try: instance = session.query(Instances) \ .filter_by( agent_address=unicode(agent_address), agent_port=agent_port) \ .first() if new_agent_address is not None: instance.agent_address = unicode(new_agent_address) if new_agent_port is not None: instance.agent_port = int(new_agent_port) if cpu is not None and cpu is not u'': instance.cpu = int(cpu) else: instance.cpu = None if memory_size is not None and memory_size is not u'': instance.memory_size = int(memory_size) else: instance.memory_size = None if pg_port is not None and pg_port is not u'': instance.pg_port = int(pg_port) else: instance.pg_port = None instance.agent_key = unicode(agent_key) instance.hostname = unicode(hostname) instance.pg_version = unicode(pg_version) instance.pg_data = unicode(pg_data) session.merge(instance) session.flush() return instance except IntegrityError as e: if e.message.find('instances_pkey') > 0: raise TemboardUIError( 400, "Instance entry ('%s:%s') already exists." % (agent_address, agent_port)) else: raise TemboardUIError(400, e.message) except AttributeError as e: raise TemboardUIError( 400, "Instance entry ('%s:%s') not found." % (agent_address, agent_port)) except Exception as e: raise TemboardUIError(400, e.message)
def post_hba(self, agent_address, agent_port): try: self.logger.info("Posting HBA (proxy).") instance = None role = None self.load_auth_cookie() self.start_db_session() role = self.current_user if not role: raise TemboardUIError(302, "Current role unknown.") instance = get_instance(self.db_session, agent_address, agent_port) if not instance: raise TemboardUIError(404, "Instance not found.") if __name__ not in [ plugin.plugin_name for plugin in instance.plugins ]: raise TemboardUIError(408, "Plugin not active.") self.db_session.expunge_all() self.db_session.commit() self.db_session.close() xsession = self.get_secure_cookie( "temboard_%s_%s" % (instance.agent_address, instance.agent_port)) if not xsession: raise TemboardUIError(401, "Authentication cookie is missing.") data = temboard_post_conf_file( self.ssl_ca_cert_file, 'hba', instance.agent_address, instance.agent_port, xsession, tornado.escape.json_decode(self.request.body)) # And reload postgresql configuration. ret_reload = temboard_post_administration_control( self.ssl_ca_cert_file, instance.agent_address, instance.agent_port, xsession, {'action': 'reload'}) self.logger.info("Done.") return JSONAsyncResult(http_code=200, data=data) except (TemboardUIError, TemboardError, Exception) as e: self.logger.traceback(get_tb()) self.logger.error(str(e)) self.logger.info("Failed.") try: self.db_session.close() except Exception: pass if (isinstance(e, TemboardUIError) or isinstance(e, TemboardError)): return JSONAsyncResult(http_code=e.code, data={'error': e.message}) else: return JSONAsyncResult(http_code=500, data={'error': e.message})
def get_instance(session, agent_address, agent_port): try: return session.query(Instances).options(joinedload( Instances.groups), joinedload(Instances.plugins)).filter_by( agent_address=unicode(agent_address), agent_port=agent_port).first() except AttributeError as e: raise TemboardUIError( 400, "Instance entry '%s:%s' not found." % (agent_address, agent_port)) except Exception as e: raise TemboardUIError(e.message)
def get_check_changes(self, address, port, check_name): self.setUp(address, port) # Arguments start = self.get_argument('start', default=None) end = self.get_argument('end', default=None) if check_name not in check_specs: raise TemboardUIError(404, "Unknown check '%s'" % check_name) start_time = None end_time = None if start: try: start_time = dt_parser.parse(start) except ValueError as e: raise TemboardUIError(406, 'Datetime not valid.') if end: try: end_time = dt_parser.parse(end) except ValueError as e: raise TemboardUIError(406, 'Datetime not valid.') data_buffer = cStringIO.StringIO() cur = self.db_session.connection().connection.cursor() cur.execute("SET search_path TO monitoring") query = """ COPY ( SELECT array_to_json(array_agg(json_build_object( 'datetime', f.datetime, 'enabled', f.enabled, 'warning', f.warning, 'critical', f.critical, 'description', f.description ))) FROM get_check_changes(%s, %s, %s, %s, %s) f ) TO STDOUT """ # noqa # build the query query = cur.mogrify( query, (self.host_id, self.instance_id, check_name, start_time, end_time)) cur.copy_expert(query, data_buffer) cur.close() data = data_buffer.getvalue() data_buffer.close() try: data = json.loads(data) except Exception as e: logger.exception(str(e)) logger.debug(data) data = [] return JSONAsyncResult(http_code=200, data=data)
def delete_instance_from_group(session, agent_address, agent_port, group_name): try: instance_group = session.query(InstanceGroups).filter( InstanceGroups.agent_address == unicode(agent_address), InstanceGroups.agent_port == agent_port, InstanceGroups.group_name == unicode(group_name)).one() session.delete(instance_group) except NoResultFound as e: raise TemboardUIError( 400, "Instance entry ('%s:%s)' not found in group '%s'." % (agent_address, agent_port, group_name)) except Exception as e: raise TemboardUIError(400, e.message)
def get_role_by_auth(session, role_name, role_password): try: role = session.query(Roles).filter( Roles.role_name == unicode(role_name), Roles.is_active == True).one() if role.role_password != unicode(role_password): raise TemboardUIError( 400, "Wrong user/password: %s/%s" % (role_name, role_password)) return role except NoResultFound as e: raise TemboardUIError( 400, "Wrong user/password: %s/%s" % (role_name, role_password)) except Exception as e: raise TemboardUIError(400, e.message)
def delete_role_group_from_instance_group(session, role_group_name, instance_group_name): try: ari = session.query(AccessRoleInstance).filter( AccessRoleInstance.role_group_name == unicode(role_group_name), AccessRoleInstance.instance_group_name == unicode( instance_group_name)).one() session.delete(ari) except NoResultFound as e: raise TemboardUIError( 400, "Role group '%s' not found in instance group '%s'." % (role_role_name, instance_group_name)) except Exception as e: raise TemboardUIError(400, e.message)
def delete_hba(self, agent_address, agent_port): try: self.logger.info("Deleting HBA (proxy).") instance = None role = None self.load_auth_cookie() self.start_db_session() role = self.current_user if not role: raise TemboardUIError(302, "Current role unknown.") instance = get_instance(self.db_session, agent_address, agent_port) if not instance: raise TemboardUIError(404, "Instance not found.") if __name__ not in [ plugin.plugin_name for plugin in instance.plugins ]: raise TemboardUIError(408, "Plugin not active.") self.db_session.expunge_all() self.db_session.commit() self.db_session.close() xsession = self.get_secure_cookie( "temboard_%s_%s" % (instance.agent_address, instance.agent_port)) if not xsession: raise TemboardUIError(401, "Authentication cookie is missing.") res = temboard_delete_hba_version( self.ssl_ca_cert_file, instance.agent_address, instance.agent_port, xsession, self.get_argument('version', None)) self.logger.info("Done.") return JSONAsyncResult(http_code=200, data=res) except (TemboardUIError, TemboardError, Exception) as e: self.logger.traceback(get_tb()) self.logger.error(str(e)) self.logger.info("Failed.") try: self.db_session.close() except Exception: pass if (isinstance(e, TemboardUIError) or isinstance(e, TemboardError)): return JSONAsyncResult(http_code=e.code, data={'error': e.message}) else: return JSONAsyncResult(http_code=500, data={'error': e.message})
def delete_instance(session, agent_address, agent_port): from temboardui.plugins.monitoring.model.orm import ( Host as MonitoringHost, Instance as MonitoringInstance, ) try: instance = session.query(Instances).filter( Instances.agent_address == unicode(agent_address), Instances.agent_port == agent_port).one() session.delete(instance) except NoResultFound as e: raise TemboardUIError( 400, "Instance entry ('%s:%s') not found." % (agent_address, agent_port)) except Exception as e: raise TemboardUIError(400, e.message) # Also delete any monitoring data # First all instance data try: monitoring_instance = session.query(MonitoringInstance) \ .join(MonitoringHost) \ .filter( MonitoringHost.hostname == instance.hostname, MonitoringInstance.port == instance.pg_port).one() session.delete(monitoring_instance) except NoResultFound as e: pass except Exception as e: raise TemboardUIError(400, e.message) # Then delete host data if there's no instance left referenced for this # host count = session.query(MonitoringInstance.instance_id) \ .join(MonitoringHost) \ .filter(MonitoringHost.hostname == instance.hostname) \ .count() if count == 0: # Using bulk delete query here to prevent errors on not null constraint # on checks::host_id column (ON CASCADE DELETE not working) # when using session.delete(host) try: session.query(MonitoringHost) \ .filter(MonitoringHost.hostname == instance.hostname) \ .delete() except NoResultFound as e: pass except Exception as e: raise TemboardUIError(400, e.message)
def post_kill(self, agent_address, agent_port): try: self.logger.info("Posting terminate backend.") role = None instance = None self.load_auth_cookie() self.start_db_session() role = self.current_user if not role: raise TemboardUIError(302, "Current role unknown.") instance = get_instance(self.db_session, agent_address, agent_port) if not instance: raise TemboardUIError(404, "Instance not found.") if __name__ not in [ plugin.plugin_name for plugin in instance.plugins ]: raise TemboardUIError(408, "Plugin not activated.") self.db_session.expunge_all() self.db_session.commit() self.db_session.close() xsession = self.request.headers.get('X-Session') if not xsession: raise TemboardUIError(401, 'X-Session header missing') self.logger.debug(tornado.escape.json_decode(self.request.body)) data_kill = temboard_activity_kill( self.ssl_ca_cert_file, instance.agent_address, instance.agent_port, xsession, tornado.escape.json_decode(self.request.body)) self.logger.info("Done.") return JSONAsyncResult(http_code=200, data=data_kill) except (TemboardUIError, TemboardError, Exception) as e: self.logger.traceback(get_tb()) self.logger.error(str(e)) self.logger.info("Failed.") try: self.db_session.close() except Exception: pass if (isinstance(e, TemboardUIError) or isinstance(e, TemboardError)): return JSONAsyncResult(http_code=e.code, data={'error': e.message}) else: return JSONAsyncResult(http_code=500, data={'error': e.message})
def send_sms(config, content, phones): sid = config.twilio_account_sid token = config.twilio_auth_token from_ = config.twilio_from uri = 'https://api.twilio.com/2010-04-01/Accounts/%s/Messages.json' % sid s = base64.b64encode('%s:%s' % (sid, token)) errors = [] for recipient in phones: req = urllib2.Request(url=uri) req.add_header('Authorization', 'Basic %s' % s) data = {'From': from_, 'Body': content, 'To': recipient} req.add_data(urllib.urlencode(data)) try: urllib2.urlopen(req) except urllib2.HTTPError as e: response = json.loads(e.read()) logger.error("Could not send SMS; %s" % response.get('message')) errors.append(recipient) except Exception as e: logger.error("Could not send SMS; %s" % e) errors.append(recipient) if errors: raise TemboardUIError( 500, "Could not send SMS to %s; \n See logs for more information" % ', '.join(errors))
def delete_instance(self): self.logger.info("Deleting instance.") self.setUp() self.check_admin() data = tornado.escape.json_decode(self.request.body) self.logger.debug(data) if 'agent_address' not in data or data['agent_address'] == '': raise TemboardUIError(400, "Agent address field is missing.") if 'agent_port' not in data or data['agent_port'] == '': raise TemboardUIError(400, "Agent port field is missing.") delete_instance(self.db_session, data['agent_address'], data['agent_port']) self.tearDown() self.logger.info("Done.") return JSONAsyncResult(200, {'delete': True})
def check_group_description(group_description): if len(group_description) > 255: raise TemboardUIError( 400, "Invalid group description, must be a 256 char (max) length " "string." )
def delete_role(self): try: self.logger.info("Deleting role.") self.load_auth_cookie() self.start_db_session() self.check_admin() data = tornado.escape.json_decode(self.request.body) self.logger.debug(data) if 'username' not in data or data['username'] == '': raise TemboardUIError(400, "Username field is missing.") delete_role(self.db_session, data['username']) self.db_session.commit() self.db_session.close() self.logger.info("Done.") return JSONAsyncResult(200, {'delete': True}) except (TemboardUIError, Exception) as e: self.logger.exception(str(e)) self.logger.info("Failed.") try: self.db_session.rollback() self.db_session.close() except Exception: pass if isinstance(e, TemboardUIError): return JSONAsyncResult(e.code, {'error': e.message}) else: return JSONAsyncResult(500, {'error': "Internal error."})
def get_group(session, group_name, group_kind): try: if group_kind == 'role': return session.query(Groups).filter_by( group_name=unicode(group_name), group_kind=unicode(group_kind)).one() else: return session.query(Groups).options( joinedload(Groups.ari)).filter( Groups.group_name == unicode(group_name), Groups.group_kind == unicode(group_kind)).one() except AttributeError as e: raise TemboardUIError( 400, "Group '%s' (%s) not found." % (group_name, group_kind)) except Exception as e: raise TemboardUIError(e.message)
def check_group_name(group_name): p_group_name = r'^([a-z0-9_\-.]{3,16})$' r_group_name = re.compile(p_group_name) if not r_group_name.match(group_name): raise TemboardUIError( 400, "Invalid group name, must satisfy this regexp pattern: %s" % (p_group_name))