Source code for smc.administration.monitoring_status

#  Licensed under the Apache License, Version 2.0 (the "License"); you may
#  not use this file except in compliance with the License. You may obtain
#  a copy of the License at
#
#       http://www.apache.org/licenses/LICENSE-2.0
#
#  Unless required by applicable law or agreed to in writing, software
#  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
#  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
#  License for the specific language governing permissions and limitations
#  under the License.
"""
Module that controls aspects of the getting Monitoring Status
To get Monitoring Status for VPN and tunnels, do::

    >>> vpn = PolicyVPN("Corporate VPN")
    >>> status = MonitoringStatus.get_status(href=vpn.href)
    >>> print("vpn status monitoring={}".format(status))
    vpn status monitoring=VPNStatus=>_health_in_percent = 69, _jitter_in_ms = 3, _latency_in_ms = 71

    >>> # get tunnel status in result
    >>> for sub_status in status.result:
    >>>     sub_status = MonitoringStatus.get_status(href=sub_status.get("href"))
    >>>     print("tunnel status monitoring={}".format(sub_status))
    ...
    tunnel status monitoring=VPNGatewayTunnelStatus=>_gatewayA = Helsinki VPN Gateway, _gatewayB =..
    ...
"""
import logging
from smc.api.common import fetch_entry_point, SMCRequest
from smc.api.exceptions import NotMonitored
from smc.base.model import Element
from smc.compat import min_smc_version
from smc.core.resource import History

logger = logging.getLogger(__name__)


[docs] class MonitoringStatus(object): """ MonitoringStatus represents the base class for all statuses returned by get_monitoring_status(href) for the element href Valid attributes (read-only) are: :ivar name: name of the element described by href :ivar monitoring_state: INITIAL For an Engine Node: Status not yet received. For a Composite Status: Composite Status value is not yet computed. READY For an Engine Node: Status is received. For a Composite Status: Composite Status value is computed. NO_STATUS For an Engine Node: No status received for the node during initial timeout. TIMEOUT For an Engine Node: Status was not received in time. ERROR Not used. SERVER_ERROR For an Engine Node: Status poll from log server failed. DELETED Status is deleted DUMMY For an Engine Node: Status is a dummy Status for Demo mode. For a Composite Status: Status is a dummy Status for Demo mode. :ivar monitoring_status: ANY Refers to any Status. NOT_MONITORED Indicates that Status element has currently Not Monitored Status. UNKNOWN For an Engine Node: Node has not sent status (or timeout). For a Composite Status: All children are unknown. OK For an Engine Node: Status is OK. For a Composite Status: All children are OK. PARTIAL_OK For a Composite Status: Some children are OK and others are unknown. WARNING For a Composite Status: Some children have warning. ERROR For an Engine Node: Status is KO. For a Composite Status: Some children are KO. IDLE For a VPN Node: Status is STANDBY. Composite: All children are STANDBY. :ivar result: The API's links of the children or SDWAN Branch Status if exists """ def __init__(self, **data): for d, v in data.items(): # Made the code SMC 7.1 compatible if min_smc_version('7.1') and d == 'child': setattr(self, 'result', v) setattr(self, d, v) @property def name(self): """ name of the element described by href """ return self._name @name.setter def name(self, value): self._name = value @property def monitoring_state(self): """ The monitoring state: ***INITIAL*** For an Engine Node: Status not yet received. For a Composite Status: Composite Status value is not yet computed. ***READY*** For an Engine Node: Status is received. For a Composite Status: Composite Status value is computed. ***NO_STATUS*** For an Engine Node: No status received for the node during initial timeout. ***TIMEOUT*** For an Engine Node: Status was not received in time. ***ERROR*** Not used. ***SERVER_ERROR*** For an Engine Node: Status poll from log server failed. ***DELETED*** Status is deleted. ***DUMMY*** For an Engine Node: Status is a dummy Status for Demo mode. For a Composite Status: Status is a dummy Status for Demo mode. :return: The monitoring state. :rtype: str """ return self._monitoring_state @monitoring_state.setter def monitoring_state(self, value): self._monitoring_state = value @property def monitoring_status(self): """ The monitoring status: ***ANY*** Refers to any Status. ***NOT_MONITORED*** Indicates that Status element has currently Not Monitored Status. ***UNKNOWN*** For an Engine Node: Node has not sent status (or timeout). For a Composite Status: All children are unknown. ***OK*** For an Engine Node: Status is OK. For a Composite Status: All children are OK. ***PARTIAL_OK*** For a Composite Status: Some children are OK and others are unknown. ***WARNING*** For a Composite Status: Some children have warning. ***ERROR*** For an Engine Node: Status is KO. For a Composite Status: Some children are KO. ***IDLE*** For a VPN Node: Status is STANDBY. Composite: All children are STANDBY. :return: The monitoring status. :rtype: str """ return self._monitoring_status @monitoring_status.setter def monitoring_status(self, value): self._monitoring_status = value @property def result(self): """ :return: The API's links of the children or SDWAN Branch Status if exists :rtype: list str """ return self._result @property def history(self): """ This function returns a history object. :return: history object. :rtype: History """ if min_smc_version('7.1'): for link_dict in self.link: if link_dict['rel'] == 'history': history_link = link_dict['href'] result = SMCRequest(method="create", href=history_link).create() return History(**result.json) @result.setter def result(self, value): self._result = value @staticmethod def __get_status_type(data): """ :return: status class related to data :rtype: MonitoringStatus """ # status by default result = MonitoringStatus for st in status_type: find = True nb_found = 0 for attr in data: # don't check attributes from superclass if hasattr(MonitoringStatus, attr): continue # if attribute from data not in status type, we continue to next type if not hasattr(st, attr): find = False break nb_found += 1 if find and nb_found > 0: result = st break return result
[docs] @staticmethod def get_status(href): """ Return Monitoring Status for the given href element :param str href: the uri of the element to retrieve the status :raises NotMonitored: the element is not monitored :rtype: MonitoringStatus """ if min_smc_version('7.1') and 'monitoring_status' in href: result = SMCRequest(method="read", href=href).read() else: monitoring_json = {"value": href} result = SMCRequest(method="create", json=monitoring_json, href=fetch_entry_point("monitoring_status")).create() if result.code == 400: raise NotMonitored(result.msg) status = MonitoringStatus.__get_status_type(result.json) return status(**result.json)
def __str__(self): result = "{}=>".format(self.__class__.__name__) for attr in vars(self): result += "{} = {}, ".format(attr, getattr(self, attr)) return result
[docs] class ServerStatus(MonitoringStatus): """ This represents an SMC Server Status (Class ServerStatus).<br/> Field from the StatusDTO map the normal server status. For an SMC Server, additionnal information is provided about: - replication states ( detailed content depend on server role ) - resource monitoring common to all servers ( memory only currenlty ) """ @property def replication_status(self): return self._replication_status @replication_status.setter def replication_status(self, value): self._replication_status = value @property def replication_info(self): return self._replication_info @replication_info.setter def replication_info(self, value): self._replication_info = value @property def memory_used(self): return self._memory_used @memory_used.setter def memory_used(self, value): self._memory_used = value @property def memory_info(self): return self._memory_info @memory_info.setter def memory_info(self, value): self._memory_info = value
[docs] class EngineNodeStatus(MonitoringStatus): """ This represents the Node Status. For a node, this structure describes the state, version, current policy, ... of the specified Node. """ @property def installed_policy(self): """ :return: The Last Uploaded Policy. :rtype: str """ return self._installed_policy def installed_policy(self, value): self._installed_policy = value @property def installed_policy_ref(self): """ :return: The reference to Last Uploaded Policy. :rtype: Policy """ return Element.from_href(self._installed_policy_ref) @installed_policy_ref.setter def installed_policy_ref(self, value): self._installed_policy_ref = value @property def last_upload_time(self): """ :return: The Upload Time of the Last Uploaded Policy. :rtype: str """ return self._last_upload_time @last_upload_time.setter def last_upload_time(self, value): self._last_upload_time = value @property def active_policy(self): """ :return: The Currently Active Policy. :rtype: str """ return self._active_policy @active_policy.setter def active_policy(self, value): self._active_policy = value @property def active_policy_ref(self): """ :return: The reference to Currently Active Policy. :rtype: Policy """ return Element.from_href(self._active_policy_ref) @active_policy_ref.setter def active_policy_ref(self, value): self._active_policy_ref = value @property def local_alternative_policy_activation_time(self): """ :return: The timestamp when Active Policy was activated, if it is a Local Alternative Policy. :rtype: long """ return self._local_alternative_policy_activation_time @local_alternative_policy_activation_time.setter def local_alternative_policy_activation_time(self, value): self._local_alternative_policy_activation_time = value @property def configuration_status(self): """ :return: The Configuration status: -*Initial* no initial configuration file is yet generated. -*Declared* initial configuration file is generated. -*Configured* initial configuration is done with the engine. -*Installed* policy is installed on the engine. :rtype: str """ return self._configuration_status @configuration_status.setter def configuration_status(self, value): self._configuration_status = value @property def hw_info(self): """ :return: The information about the hardware. :rtype: str """ return self._hw_info @hw_info.setter def hw_info(self, value): self._hw_info = value @property def engine_node_status(self): """ :return: The engine status ("Not Monitored"/"Unknown"/"Online"/"Going Online"/ "Locked Online"/"Going Locked Online"/"Offline"/"Going Offline"/"Locked Offline"/ "Going Locked Offline"/"Standby"/"Going Standby"/"No Policy Installed" :rtype: str """ return self._engine_node_status @engine_node_status.setter def engine_node_status(self, value): self._engine_node_status = value @property def dyn_up(self): """ :return: The dynamic update package received. :rtype: str """ return self._dyn_up @dyn_up.setter def dyn_up(self, value): self._dyn_up = value @property def platform(self): """ :return: The engine platform. :rtype: str """ return self._platform @platform.setter def platform(self, value): self._platform = value @property def version(self): """ :return: The engine version. :rtype: str """ return self._version @version.setter def version(self, value): self._version = value @property def local_alternative_policies(self): """ :return: The Local Alternative Policies. :rtype: list str """ return self._local_alternative_policies @local_alternative_policies.setter def local_alternative_policies(self, value): self._local_alternative_policies = value @property def master_node(self): """ Used by Virtual Firewall Node :return: master node. :rtype: MasterNode """ return Element.from_href(self._master_node) @master_node.setter def master_node(self, master_node): self._master_node = master_node
[docs] class SDWANBranchStatus(MonitoringStatus): """ This represents the SDWAN branch Status. """ @property def health_in_percent(self): """ :return: SDWAN Branch Health in percent :rtype: int """ return self._health_in_percent @health_in_percent.setter def health_in_percent(self, value): self._health_in_percent = value
[docs] class SDWANBranchToBranchStatus(MonitoringStatus): """ This represents the SDWAN branch to branch Status. """ @property def health_in_percent(self): """ :return: SDWAN Branch Health in percent :rtype: int """ return self._health_in_percent @health_in_percent.setter def health_in_percent(self, value): self._health_in_percent = value @property def traffic_in_bits_per_sec(self): """ :return: SDWAN Branch to Branch Traffic in bits per second :rtype: long """ return self._traffic_in_bits_per_sec @traffic_in_bits_per_sec.setter def traffic_in_bits_per_sec(self, value): self._traffic_in_bits_per_sec = value @property def packet_loss_in_permyriad(self): """ :return: SDWAN Branch to Branch Packet loss in permyriad (per ten thousands) :rtype: int """ return self._packet_loss_in_permyriad @packet_loss_in_permyriad.setter def packet_loss_in_permyriad(self, value): self._packet_loss_in_permyriad = value @property def latency_in_ms(self): """ :return: SDWAN Branch to Branch Latency in milliseconds :rtype: int """ return self._latency_in_ms @latency_in_ms.setter def latency_in_ms(self, value): self._latency_in_ms = value @property def jitter_in_ms(self): """ :return: SDWAN Branch to Branch Jitter in milliseconds :rtype: int """ return self._jitter_in_ms @jitter_in_ms.setter def jitter_in_ms(self, value): self._jitter_in_ms = value
[docs] class SDWANNetlinkElementStatus(MonitoringStatus): """ This represents the SDWAN Netlink element Status. """ @property def inbound_traffic_in_bits_per_sec(self): """ :return: Inbound traffic in bits per second :rtype: long """ return self._inbound_traffic_in_bits_per_sec @inbound_traffic_in_bits_per_sec.setter def inbound_traffic_in_bits_per_sec(self, value): self._inbound_traffic_in_bits_per_sec = value @property def outbound_traffic_in_bits_per_sec(self): """ :return: Outbound traffic in bits per second :rtype: long """ return self._outbound_traffic_in_bits_per_sec @outbound_traffic_in_bits_per_sec.setter def outbound_traffic_in_bits_per_sec(self, value): self._outbound_traffic_in_bits_per_sec = value @property def connection_count(self): """ :return: Connection Count :rtype: long """ return self._connection_count @connection_count.setter def connection_count(self, value): self._connection_count = value @property def packet_loss_in_permyriad(self): """ :return: Packet loss in permyriad (per ten thousands) :rtype: long """ return self._packet_loss_in_permyriad @packet_loss_in_permyriad.setter def packet_loss_in_permyriad(self, value): self._packet_loss_in_permyriad = value
[docs] class VPNStatus(MonitoringStatus): """ This represents the VPN Status """ @property def vpn_status_code(self): """ :return: The Monitoring VPN Status Code. :rtype: str """ return self._vpn_status_code @vpn_status_code.setter def vpn_status_code(self, value): self._vpn_status_code = value @property def health_in_percent(self): """ :return: VPN Health in percent. :rtype: str """ return self._health_in_percent @health_in_percent.setter def health_in_percent(self, value): self._health_in_percent = value @property def traffic_in_bits_per_sec(self): """ :return: VPN Traffic in bits per second :rtype: long """ return self._traffic_in_bits_per_sec @traffic_in_bits_per_sec.setter def traffic_in_bits_per_sec(self, value): self._traffic_in_bits_per_sec = value @property def packet_loss_in_permyriad(self): """ :return: VPN Packet loss in permyriad (per ten thousands) :rtype: int """ return self._packet_loss_in_permyriad @packet_loss_in_permyriad.setter def packet_loss_in_permyriad(self, value): self._packet_loss_in_permyriad = value @property def latency_in_ms(self): """ :return: VPN Latency in milliseconds :rtype: int """ return self._latency_in_ms @latency_in_ms.setter def latency_in_ms(self, value): self._latency_in_ms = value @property def jitter_in_ms(self): """ :return: VPN Jitter in milliseconds :rtype: int """ return self._jitter_in_ms @jitter_in_ms.setter def jitter_in_ms(self, value): self._jitter_in_ms = value
[docs] class VPNGatewayTunnelStatus(VPNStatus): """ This represents the Monitoring Status for a Gateway Tunnel. """ @property def gatewayA(self): """ :return: Name of Gateway A :rtype: str """ return self._gatewayA @gatewayA.setter def gatewayA(self, value): self._gatewayA = value @property def gatewayB(self): """ :return: Name of Gateway B :rtype: str """ return self._gatewayB @gatewayB.setter def gatewayB(self, value): self._gatewayB = value
[docs] class VPNEndpointTunnelStatus(VPNGatewayTunnelStatus): """ This represents the Monitoring Status for an endpoint tunnel. """ @property def endpointA(self): """ :return: Name of Endpoint A :rtype: str """ return self._endpointA @endpointA.setter def endpointA(self, value): self._endpointA = value @property def endpointB(self): """ :return: Name of Endpoint B :rtype: str """ return self._endpointB @endpointB.setter def endpointB(self, value): self._endpointB = value
# order is important, set at first Status with the commons fields # first status with all data fields matching will be returned status_type = [ServerStatus, EngineNodeStatus, SDWANBranchStatus, SDWANBranchToBranchStatus, SDWANNetlinkElementStatus, VPNStatus, VPNGatewayTunnelStatus, VPNEndpointTunnelStatus]