Viewing File: /usr/local/cpanel/base/frontend/jupiter/site-monitor/models/monitor.js

/*
 * site-monitor/models/monitor.js                   Copyright 2021 cPanel, L.L.C.
 *                                                           All rights reserved.
 * copyright@cpanel.net                                         http://cpanel.net
 * This code is subject to the cPanel license. Unauthorized copying is prohibited
 */

/* global define, PAGE */

/** @namespace cpanel.siteMoniter.models.monitor */

define([
        "app/models/monitor-status.enum",
        "app/models/monitor-type.enum",
        "app/models/uptime-window.enum",
        "app/models/monitor-state.enum",
    ],
    function(MonitorStatus, MonitorType, UptimeWindow, MonitorState) {

        "use strict";

        var DEFAULT_CHECK_INTERVAL = 1800;  // 30 min

        /**
         * @typedef Monitor
         * @property {string} id - The unique id for the monitor provided by the backend.
         * @property {string} name - The user given name for the monitor.
         * @property {MonitorType} protocol - The protocal to access the site with.
         * @property {string} domain - The domain to monitor.
         * @property {number} port - Port the site is hosted on if any.
         * @property {string} path - Path under the domain if any.
         * @property {string} search  - The querystring associated with the site url.
         * @property {boolean} enabled - Weather the monitor is enabled or not, NOTE: not supported yet by nixstats
         * @property {ISiteCheck2[]} data - average response time by hour for last 24 hours.
         * @property {Contact} contact - The contact information for the monitor.
         * @property {Date} firstUpdate - The date/time of the first check.
         * @property {Date} lastUpdate -  The date/time of the most recent check.
         * @property {string} fromLocation - The location monitors check from.
         * @property {number} interval - The interval that the site is check in seconds. NOTE: We don't know how to retrive this right now.
         * @property {Date} sslExpiration - When HTTPS, the expiration date for the SSL certificate. Only present when retrieving the list of monitors.
         * @property {MonitorState} [state] - optional, default to MonitorState.Ready.
         */

        /**
         *
         * @param {Monitor} monitor
         */
        function Monitor(monitor) {
            if (monitor) {
                this.id = monitor.id;
                this.name = monitor.name;

                this.protocol = monitor.protocol || MonitorType.HTTPS;
                this.domain = monitor.domain;
                this.port = monitor.port || _getDefaultPort(this.protocol);
                this.path = monitor.path || '';
                this.search = monitor.search || '';

                this.enabled  = monitor.enabled || true;

                this.data = monitor.data || [];

                this.contact = monitor.contact;

                this.firstUpdate = monitor.firstUpdate;
                this.lastUpdate  = monitor.lastUpdate;
                this.fromLocation = monitor.fromLocation;

                this.interval = monitor.interval || DEFAULT_CHECK_INTERVAL;
                this.sslExpiration = monitor.sslExpiration;
                this.state = monitor.state || MonitorState.Ready;
            }
        }

        /**
         * Getter for the full URL for the monitor.
         */
        Monitor.prototype.url = function() {
            return (/^http/.test(this.protocol) ? this.protocol + "://" : "") +
                   this.domain +
                   (this.port !== _getDefaultPort(this.protocol) ? ":" + this.port : "") +
                   "/" + this.path +
                   (this.search !== '' ? "?" + this.search : "");
        }

        /**
         * Clone the monitor.
         *
         * @returns {Monitor}
         */
        Monitor.prototype.clone = function() {
            return new Monitor(_.cloneDeep(this));
        }

        /**
         * Calculate the default port number to be used with the given protocol.
         *
         * @param {MonitorType} protocol
         * @returns {Number} the default port number.
         */
        function _getDefaultPort(protocol) {
            switch(protocol) {
                case MonitorType.ICMP:
                    return; // ICMP does not use ports as it is neither TCP or UDP, it is a lower level IP protocol.
                case MonitorType.TCP:
                    return 23; // Described as telnet, so uses the default telnet port.
                case MonitorType.HTTP:
                    return 80;
                case MonitorType.HTTPS:
                default:
                    return 443;
            }
        }

        /**
         * @typedef {number} Timestamp
         */

        /**
         * @typedef ISiteCheck
         * @property {number} t - Total time
         * @property {numbrer} c - Time to connect to the server
         * @property {string} status - The status message returned by the site check
         * @property {Timestamp} time - The time the last site check was processed.
         * @property {number} code - Status code returned by the site check
         * @property {number} dns - Time for dns resolution
         * @property {number} ttfb - Time to first byte
         */

        /**
         * @typedef ICheckFrom
         * @property {string} name - The location the site was checked from.
         * @property {string} ip_address_v6 - optional the locations ipv6 address.
         * @property {string} ip_address - the locations ipv4 address.
         */

        /**
         * @typedef IMonitorItem
         * @property {number} downtime_seconds - number of seconds the site was down.
         * @property {Timestamp} first_update - the first time the monitore was updated.
         * @property {string} id - unique idenfier for the monitor
         * @property {string|null} ip_address - ???
         * @property {ISiteCheck} last_check - statistics from the last site check.
         * @property {Timestamp} last_update - the last time the monitor was updated.
         * @property {ICheckFrom} monitor - the location the site was checked from.
         * @property {string} name - the human readable name for the monitor.
         * @property {Timestamp} ssl_expiration_timestamp - expiration date for the certificate. Only pressent on https requests.
         * @property {MonitorStatus} status - the last status for the site.
         * @property {string} status_message - the status message from the last check.
         * @property {MonitorType} type - the monitor type.
         * @property {number} uptime_percentage - the percentage of uptime
         * @property {string} url - the full url without the protocol.
         */

        /**
         * Parse the raw monitor data from the apis into a Monitor object.
         *
         * @param {IMonitorItem} item
         * @returns {Monitor}
         */
        Monitor.parseListItem = function parseListItem(item) {
            var fullUrl = "https://" + item.url;
            var url = new URL(fullUrl);

            return new Monitor({
                id: item.id,
                name: item.name,

                protocol: item.type,
                domain: url.hostname,
                port: Number(url.port),
                path: url.pathname.replace(/^\//, ""),
                search: url.search.replace(/^\?/, ""),

                type: item.type,

                // UNIX timestamps are in sec, javascript timestamps are in ms
                firstUpdate: new Date(item.first_update * 1000),
                lastUpdate: new Date(item.last_update * 1000),
                sslExpiration: new Date(item.ssl_expiration_timestamp * 1000), // UNIX timestamps are in sec, javascript timestamps are in ms

                fromLocation: item.monitor.name,

                // TODO: parse more data
            });
        }

        /**
         * @typedef {object} Contact
         * @property {object} email - the contact is an email address
         *   @property {number} delay - number of seconds to delay before sending the alert.
         */

        /**
         * @typedef ISiteCheck2
         * @property {number} time_total - Total time
         * @property {number} time_connect - Time to connect to the server
         * @property {string} status - The status message returned by the site check
         * @property {number} time_dns - Time for dns resolution
         * @property {number} time_to_first_byte - Time to first byte
         */

        /**
         * @typedef IUptimeWindow
         * @property {UptimeWindow} date - the kind of uptime window.
         * @property {number} events - number of events seen during the window.
         * @property {number} downtime_seconds - number of seconds the site was down.
         * @property {number} uptime_percentage - the percentage of time the site was down.
         * @property {Timestamp} start - the start date/time for the window
         * @property {Timestamp} end - the start date/time for the window
         */

        /**
         * @typedef {object} IMonitorDetails
         * @property {Object.<string, Contact>} contacts - list of contact to alert when the site is down
         * @property {number} code
         * @property {Timestamp} first_update - the date/time of the first update
         * @property {string} id - uniquie id for the monitor.
         * @property {string|null} ip_address - ???
         * @property {boolean} password - ???
         * @property {Timestamp} last_update - the date/time of the last update
         * @property {ISiteCheck2} last_check - the times for the most recent check.
         * @property {ICheckFrom} monitor - the location the monitor was checked from.
         * @property {string} name - the user friendly name of the monitor
         * @property {MonitorType} type - the protocol for the monitor.
         * @property {MonitorStatus} status - the current status for the monitor.
         * @property {string} url - the full url including the protocol.
         * @property {IUptimeWindow[]} uptimes - summaries of various uptime windows.
         * @property {boolean} username - ???
         */

        /**
         * Parser for data returned by get_domain_monitor
         *
         * @param {IMonitorDetails} item
         * @returns {Monitor}
         */
        Monitor.parseItem = function parseItem(item) {
            var url = new URL(item.url);

            return new Monitor({
                id: angular.isDefined(item.id) ? item.id: null,
                name: angular.isDefined(item.name) ? item.name: null,

                protocol: item.type,
                domain: url.hostname,
                port: url.port,
                path: url.pathname.replace(/^\//, ""),
                search: url.search.replace(/^\?/, ""),

                firstUpdate: angular.isDefined(item.first_update) ? new Date(item.first_update * 1000) : null,
                lastUpdate: angular.isDefined(item.last_update) ? new Date(item.last_update * 1000) : null,
                fromLocation: angular.isDefined(item.monitor) ? item.monitor.name : null,

                interval: angular.isDefined(item.interval) ? item.interval: null,

                state: angular.isDefined(item.state) ? item.state: null,

                // TODO: parse more data
            });
        }

        /**
         * The default interval that monitors check the site/page being monitored in ms.
         *
         * @type Number
         */
        Monitor.DEFAULT_CHECK_INTERVAL = DEFAULT_CHECK_INTERVAL;

        return Monitor;
    }
);
Back to Directory File Manager