Beispiel #1
0
 def test_get_one_by_key(self):
     option_entity = OptionEntity()
     option = option_entity.insert_one({
         "key": "key7",
         "value": "value7",
         "autoload": True
     })
     self.assertEqual(option_entity.get_one_by_key("key7"), option)
     self.assertEqual(option_entity.get_one_by_key("key7").key, "key7")
     self.assertFalse(option_entity.get_one_by_key("not_found_key"))
Beispiel #2
0
class Metric():

    __metric_entity = None
    __option_entity = None
    __newrelic = None

    def __init__(self):
        self.__option_entity = OptionEntity()
        self.__metric_entity = MetricEntity()
        new_relic_api = self.__option_entity.get_one_by_key("newrelic_api_key")
        if new_relic_api:
            self.__newrelic = NewRelic_Provider(new_relic_api.value)

    def get_one_by_id(self, id):
        metric = self.__metric_entity.get_one_by_id(id)

        if not metric:
            return False

        return {
            "id": metric.id,
            "title": metric.title,
            "description": metric.description,
            "source": metric.source,
            "data": metric.data,
            "x_axis": metric.x_axis,
            "y_axis": metric.y_axis
        }

    def insert_one(self, metric):
        return self.__metric_entity.insert_one(metric)

    def update_one_by_id(self, id, metric_data):
        return self.__metric_entity.update_one_by_id(id, metric_data)

    def count_all(self):
        return self.__metric_entity.count_all()

    def get_all(self, offset=None, limit=None):
        return self.__metric_entity.get_all(offset, limit)

    def delete_one_by_id(self, id):
        return self.__metric_entity.delete_one_by_id(id)

    def get_new_relic_apps(self):
        result = []
        try:
            response = self.__newrelic.get_apps()
        except Exception as e:
            raise Exception(e)
        apps = json.loads(response)
        for app in apps["applications"]:
            result.append({"key": app["id"], "value": app["name"]})
        return result
Beispiel #3
0
class ForgotPassword():

    __reset_expire_option = 24
    __messages_count_option = 5

    def __init__(self):
        self.__reset_request_entity = ResetRequestEntity()
        self.__option_entity = OptionEntity()
        self.__user_entity = UserEntity()
        self.__task_core = TaskCore()

        messages_count_option = self.__option_entity.get_one_by_key(
            "reset_mails_messages_count")
        reset_expire_option = self.__option_entity.get_one_by_key(
            "reset_mails_expire_after")

        if messages_count_option:
            self.__messages_count_option = int(messages_count_option.value)

        if reset_expire_option:
            self.__reset_expire_option = int(reset_expire_option.value)

    def check_email(self, email):
        return True if self.__user_entity.get_one_by_email(
            email) is not False else False

    def reset_request_exists(self, email):
        return self.__reset_request_entity.get_one_by_email(email)

    def is_spam(self, request):
        if request.messages_count >= self.__messages_count_option and timezone.now(
        ) < request.expire_at:
            return True
        return False

    def update_request(self, request):

        # Delete Old Request
        self.__reset_request_entity.delete_one_by_id(request.id)

        # Create a Fresh Request
        if timezone.now() > request.expire_at:
            return self.create_request(request.email)

        # Create from the Old Request
        request = self.__reset_request_entity.insert_one({
            "email":
            request.email,
            "expire_at":
            request.expire_at,
            "messages_count":
            request.messages_count + 1
        })
        return request.token if request is not False else False

    def create_request(self, email):
        request = self.__reset_request_entity.insert_one({
            "email": email,
            "expire_after": self.__reset_expire_option,
            "messages_count": 0
        })
        return request.token if request is not False else False

    def send_message(self, email, token):

        app_name = self.__option_entity.get_value_by_key("app_name")
        app_email = self.__option_entity.get_value_by_key("app_email")
        app_url = self.__option_entity.get_value_by_key("app_url")
        user = self.__user_entity.get_one_by_email(email)

        return self.__task_core.delay(
            "forgot_password_email", {
                "app_name": app_name,
                "app_email": app_email,
                "app_url": app_url,
                "recipient_list": [email],
                "token": token,
                "subject": _("%s Password Reset") % (app_name),
                "template": "mails/reset_password.html",
                "fail_silently": False
            }, user.id)
Beispiel #4
0
class Install():

    __options = [{
        "key": "app_installed",
        "value": "true",
        "autoload": True
    }, {
        "key": "app_description",
        "value": "",
        "autoload": False
    }, {
        "key": "google_analytics_account",
        "value": "",
        "autoload": True
    }, {
        "key": "reset_mails_messages_count",
        "value": "5",
        "autoload": False
    }, {
        "key": "reset_mails_expire_after",
        "value": "24",
        "autoload": False
    }, {
        "key": "access_tokens_expire_after",
        "value": "48",
        "autoload": False
    }, {
        "key": "prometheus_token",
        "value": "",
        "autoload": False
    }, {
        "key": "newrelic_api_key",
        "value": "",
        "autoload": False
    }]
    __admin = {
        "username": "",
        "email": "",
        "password": "",
        "is_superuser": True,
        "is_active": True,
        "is_staff": False
    }

    def __init__(self):
        self.__option_entity = OptionEntity()
        self.__user_entity = UserEntity()
        self.__acl = ACL()

    def is_installed(self):
        return False if self.__option_entity.get_one_by_key(
            "app_installed") is False else True

    def set_app_data(self, name, email, url):
        self.__options.append({
            "key": "app_name",
            "value": name,
            "autoload": True
        })
        self.__options.append({
            "key": "app_email",
            "value": email,
            "autoload": True
        })
        self.__options.append({
            "key": "app_url",
            "value": url,
            "autoload": True
        })

    def set_admin_data(self, username, email, password):
        self.__admin["username"] = username
        self.__admin["email"] = email
        self.__admin["password"] = password

    def init_base_acl(self, user_id):
        self.__acl.truncate_default_permissions()
        self.__acl.new_role("super_admin")
        self.__acl.new_role("normal_user")
        self.__acl.new_permission(
            "Manage Settings", self.__acl.get_content_type_id("auth", "user"),
            "manage_settings")
        self.__acl.add_permission_to_role("super_admin", "manage_settings")
        self.__acl.add_role_to_user("super_admin", user_id)
        return True

    def install(self):
        execute_from_command_line(["manage.py", "migrate"])
        status = True
        status &= self.__option_entity.insert_many(self.__options)
        user = self.__user_entity.insert_one(self.__admin)
        status &= (user is not False)

        if user is not False:
            status &= self.init_base_acl(user.id)

        return user.id if status else False

    def uninstall(self):
        self.__option_entity.truncate()
        self.__user_entity.truncate()
Beispiel #5
0
class Notification():

    PENDING = "pending"
    FAILED = "failed"
    PASSED = "passed"
    ERROR = "error"
    MESSAGE = "message"

    __notification_entity = None
    __option_entity = None
    __humanize = None
    __app_name = None

    def __init__(self):
        self.__notification_entity = NotificationEntity()
        self.__option_entity = OptionEntity()
        self.__humanize = Humanize()
        option = self.__option_entity.get_one_by_key("app_name")
        self.__app_name = option.value if option is not False else ""

    def create_notification(self, data):
        return self.__notification_entity.insert_one(data)

    def user_latest_notifications(self, user_id, count=5):

        notifications = self.__notification_entity.get_many_by_user(user_id, "created_at", False, count)

        result = {
            "notifications": [],
            "status": "read"
        }

        for notification in notifications:
            if not notification.delivered:
                result["status"] = "unread"

            result["notifications"].append({
                "id": notification.id,
                "type": notification.type,
                "highlight": notification.highlight,
                "description": notification.notification,
                "url": notification.url,
                "delivered": notification.delivered,
                "time": self.__humanize.datetime(notification.created_at)
            })

        return result

    def update_task_notification(self, task_id, type, delivered=False):
        return self.__notification_entity.update_one_by_task_id(task_id, {
            "type": type,
            "delivered": delivered
        })

    def mark_notification(self, user_id, notification_id):
        if self.__notification_entity.get_one_by_id_and_user(notification_id, user_id):
            return self.__notification_entity.update_one_by_id(notification_id, {"delivered": True})

        return False

    def get(self, user_id, offset=None, limit=None):
        return self.__notification_entity.get(user_id, offset, limit)

    def count(self, user_id=None):
        return self.__notification_entity.count(user_id)
Beispiel #6
0
class StatusPage():

    def __init__(self):
        self.__option_entity = OptionEntity()
        self.__incident_entity = IncidentEntity()
        self.__incident_update_entity = IncidentUpdateEntity()
        self.__incident_update_component_entity = IncidentUpdateComponentEntity()
        self.__component_group_entity = ComponentGroupEntity()
        self.__component_entity = ComponentEntity()
        self.__metric_entity = MetricEntity()
        self.__load_system_status()

    def __load_system_status(self):
        open_incidents = self.__incident_entity.get_by_status("open")

        self.__system_status = {
            "affected_components_map": {},
            "affected_components_status": {},
            "affected_groups_map": {},
            "affected_groups_status": {},
            "overall_status": Constants.COMPONENT_STATUSES["operational"],
        }

        for open_incident in open_incidents:
            updates = self.__incident_update_entity.get_all(open_incident.id, 0, 1)
            for update in updates:
                update_components = self.__incident_update_component_entity.get_all(update.id)
                for update_component in update_components:
                    if update_component.component.name not in self.__system_status["affected_components_status"].keys():
                        self.__system_status["affected_components_status"][update_component.component.name] = update_component.type
                        if update_component.component.group:
                            self.__system_status["affected_groups_status"][update_component.component.group.name] = update_component.type
                    if update_component.component.name not in self.__system_status["affected_components_map"].keys():
                        self.__system_status["affected_components_map"][update_component.component.name] = update_component.component.id
                        if update_component.component.group:
                            self.__system_status["affected_groups_map"][update_component.component.group.name] = update_component.component.group.id

        if "major_outage" in self.__system_status["affected_components_status"].values():
            self.__system_status["overall_status"] = Constants.COMPONENT_STATUSES["major_outage"]

        elif "partial_outage" in self.__system_status["affected_components_status"].values():
            self.__system_status["overall_status"] = Constants.COMPONENT_STATUSES["partial_outage"]

        elif "degraded_performance" in self.__system_status["affected_components_status"].values():
            self.__system_status["overall_status"] = Constants.COMPONENT_STATUSES["degraded_performance"]

        elif "maintenance" in self.__system_status["affected_components_status"].values():
            self.__system_status["overall_status"] = Constants.COMPONENT_STATUSES["maintenance"]

    def get_system_status(self):

        affected_components = len(self.__system_status["affected_components_map"].keys())

        if affected_components == 0:
            return "normal"
        elif affected_components <= 2:
            return "medium"
        elif affected_components > 2:
            return "high"

    def get_about_site(self):
        option = self.__option_entity.get_one_by_key("builder_about")
        return option.value if option else ""

    def get_logo_url(self):
        option = self.__option_entity.get_one_by_key("builder_logo_url")
        return option.value if option else ""

    def get_favicon_url(self):
        option = self.__option_entity.get_one_by_key("builder_favicon_url")
        return option.value if option else ""

    def get_incident_by_uri(self, uri):
        incident = self.__incident_entity.get_one_by_uri(uri)
        app_name = self.__option_entity.get_one_by_key("app_name")

        if incident:
            incident_data = {
                "headline": incident.name,
                "status": incident.status,
                "sub_headline": _("Incident Report for %s") % (app_name.value),
                "affected_components": [],
                "updates": []
            }

            updates = self.__incident_update_entity.get_all(incident.id)

            for update in updates:
                incident_data["updates"].append({
                    "type": update.status.title(),
                    "body": update.message,
                    "date": "%(date)s %(tz)s" % {
                        "date": update.datetime.strftime("%B %d, %H:%M"),
                        "tz": os.getenv("APP_TIMEZONE", "UTC")
                    }
                })

                components = self.__incident_update_component_entity.get_all(update.id)

                for component in components:
                    if component.component.name not in incident_data["affected_components"]:
                        incident_data["affected_components"].append(component.component.name)

            incident_data["affected_components"] = ", ".join(incident_data["affected_components"])

            return incident_data

        return False

    def get_incidents_for_period(self, period):

        today = timezone.now()
        datem = datetime(today.year, today.month, 1)

        from_date = datem - relativedelta(months=+(period - 1) * 3)
        to_date = datem - relativedelta(months=+(period * 3))

        period = "%(from)s - %(to)s" % {
            "from": from_date.strftime("%B %Y"),
            "to": (to_date + relativedelta(months=+1)).strftime("%B %Y")
        }

        from_date = datetime(from_date.year, from_date.month, 1)
        to_date = datetime(to_date.year, to_date.month, 1)

        incidents = []
        while from_date > to_date:
            current_incidents = []

            incidents_list = self.__incident_entity.get_incident_on_month(DateTimeField().clean(from_date))

            for incident in incidents_list:
                current_incidents.append({
                    "uri": incident.uri,
                    "subject": incident.name,
                    "class": "text-danger",
                    "status": incident.status,
                    "final_update": _("This incident has been resolved.") if incident.status == "closed" else _("This incident is still open."),
                    "period": self.__get_incident_period(incident)
                })

            current_date = from_date.strftime("%B %Y")
            incidents.append({
                "date": current_date,
                "incidents": current_incidents
            })
            from_date -= relativedelta(months=+1)

        return {
            "period": period,
            "incidents": incidents
        }

    def __get_incident_period(self, incident):
        updates = self.__get_incident_updates(incident.id)
        if len(updates):
            return "%(from)s %(tz)s - %(to)s" % {
                "from": incident.datetime.strftime("%B %d, %H:%M"),
                "tz": os.getenv("APP_TIMEZONE", "UTC"),
                "to": updates[len(updates)-1]["date"]
            }
        return "%(from)s %(tz)s" % {
            "from": incident.datetime.strftime("%B %d, %H:%M"),
            "tz": os.getenv("APP_TIMEZONE", "UTC")
        }

    def get_past_incidents(self, days=7):
        i = 0
        past_incidents = []
        while days > i:
            date = (datetime.now() - timedelta(days=i))
            incidents_result = []
            incidents = self.__incident_entity.get_incident_from_days(i)
            for incident in incidents:
                incidents_result.append({
                    "uri": incident.uri,
                    "subject": incident.name,
                    "class": "text-danger",
                    "status": incident.status,
                    "updates": self.__get_incident_updates(incident.id)
                })

            past_incidents.append({
                "date": date.strftime("%B %d, %Y"),
                "incidents": incidents_result
            })
            i += 1
        return past_incidents

    def __get_incident_updates(self, incident_id):
        updates_result = []
        updates = self.__incident_update_entity.get_all(incident_id)
        for update in updates:
            updates_result.append({
                "type": update.status.title(),
                "date": "%(date)s %(tz)s" % {
                    "date": update.datetime.strftime("%B %d, %H:%M"),
                    "tz": os.getenv("APP_TIMEZONE", "UTC")
                },
                "body": update.message
            })
        return updates_result

    def get_system_metrics(self):
        metrics = []
        option = self.__option_entity.get_one_by_key("builder_metrics")
        if option:
            items = json.loads(option.value)
            for item in items:
                if "m-" in item:
                    item = int(item.replace("m-", ""))
                    if item:
                        metric = self.__metric_entity.get_one_by_id(item)
                        if metric:
                            metrics.append({
                                "id": "metric_container_%d" % (metric.id),
                                "title": metric.title,
                                "xtitle": metric.x_axis,
                                "ytitle": metric.y_axis,
                                "day_data": self.__get_metrics(metric, -1),
                                "week_data": self.__get_metrics(metric, -7),
                                "month_data": self.__get_metrics(metric, -30)
                            })
        return metrics

    def __get_metrics(self, metric, period):
        metric_values = []
        option = self.__option_entity.get_one_by_key("newrelic_api_key")

        if not option:
            raise Exception("Unable to find option with key newrelic_api_key")

        new_relic_client = NewRelic_Provider(option.value)

        if metric.source == "newrelic":
            data = json.loads(metric.data)

            if data["metric"] == "response_time":
                response = new_relic_client.get_metric(
                    data["application"],
                    ["WebTransaction"],
                    ["average_response_time"],
                    Datetime_Utils("UTC", period).iso(),
                    Datetime_Utils("UTC").iso(),
                    False
                )
                if len(response) > 0:
                    response = json.loads(response)

                    if "metric_data" not in response:
                        raise Exception(_("Error: Unable to find metric_data on NewRelic response!"))

                    if "WebTransaction" not in response["metric_data"]["metrics_found"]:
                        raise Exception(_("Error: Unable to find metric WebTransaction on NewRelic response!"))

                    if "metrics" not in response["metric_data"] or len(response["metric_data"]["metrics"]) < 1:
                        raise Exception(_("Error: Unable to find metric metrics on NewRelic response!"))

                    for item in response["metric_data"]["metrics"][0]["timeslices"]:
                        metric_values.append({
                            "timestamp": datetime.timestamp(parse(item["from"])),
                            "value": item["values"]["average_response_time"]
                        })
            elif data["metric"] == "apdex":
                raise Exception(_("Error: NewRelic apdex metric not implemented yet!"))

            elif data["metric"] == "error_rate":
                raise Exception(_("Error: NewRelic error_rate metric not implemented yet!"))

            elif data["metric"] == "throughput":
                raise Exception(_("Error: NewRelic throughput metric not implemented yet!"))

            elif data["metric"] == "errors":
                raise Exception(_("Error: NewRelic errors metric not implemented yet!"))

            elif data["metric"] == "real_user_response_time":
                raise Exception(_("Error: NewRelic real_user_response_time metric not implemented yet!"))

            elif data["metric"] == "real_user_apdex":
                raise Exception(_("Error: NewRelic real_user_apdex metric not implemented yet!"))

        return metric_values

    def get_services(self):
        services = []
        option = self.__option_entity.get_one_by_key("builder_components")
        if option:
            items = json.loads(option.value)
            for item in items:
                if "c-" in item:
                    component = self.__component_entity.get_one_by_id(item.replace("c-", ""))
                    if component:
                        services.append({
                            "name": component.name,
                            "description": component.description,
                            "current_status": self.get_status(component.name, "component"),
                            "uptime_chart": self.get_uptime_chart(component.id, "component"),
                            "sub_services": []
                        })
                elif "g-" in item:
                    group = self.__component_group_entity.get_one_by_id(item.replace("g-", ""))
                    services.append({
                        "name": group.name,
                        "description": group.description,
                        "current_status": self.get_status(group.name, "group"),
                        "uptime_chart": self.get_uptime_chart(group.id, "group"),
                        "sub_services": self.get_sub_services(group.id)
                    })

        return services

    def get_sub_services(self, group_id):
        services = []
        items = self.__component_entity.get_all_components_by_group(group_id)
        for item in items:
            services.append({
                "name": item.name,
                "description": item.description,
                "current_status": self.get_status(item.name, "component"),
                "uptime_chart": self.get_uptime_chart(item.id, "component"),
                "sub_services": []
            })
        return services

    def get_status(self, name, type):
        if type == "component" and name in self.__system_status["affected_components_status"].keys():
            return Constants.COMPONENT_STATUSES[self.__system_status["affected_components_status"][name]]

        elif type == "group" and name in self.__system_status["affected_groups_status"].keys():
            return Constants.COMPONENT_STATUSES[self.__system_status["affected_groups_status"][name]]

        return Constants.COMPONENT_STATUSES["operational"]

    def get_uptime_chart(self, id, type, period=90):
        return []