Skip to content

Commit

Permalink
Merge pull request #19 from mmahacek/develop
Browse files Browse the repository at this point in the history
v0.0.6 release
  • Loading branch information
mmahacek authored Feb 24, 2023
2 parents d2768a0 + 27af500 commit ba4a39d
Show file tree
Hide file tree
Showing 27 changed files with 537 additions and 174 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@ name: "CodeQL"

on:
push:
branches: [ "main" ]
branches: [ "main", "develop" ]
pull_request:
# The branches below must be a subset of the branches above
branches: [ "main" ]
schedule:
- cron: '19 22 * * 4'
#schedule:
# - cron: '19 22 * * 4'

jobs:
analyze:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ jobs:
- run: pip install -e . pdoc
# ADJUST THIS: build your documentation into docs/.
# We use a custom build script for pdoc itself, ideally you just run `pdoc -o docs/ ...` here.
- run: pdoc -o html pyonms --docformat google
- run: pdoc -o html pyonms --docformat google -e pyonms=https://github.com/mmahacek/PyONMS/tree/main/pyonms/

- uses: actions/upload-pages-artifact@v1
with:
Expand Down
2 changes: 1 addition & 1 deletion LICENSE.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2020 mmahacek
Copyright (c) 2023 mmahacek

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

A Python library for accessing the OpenNMS REST API.

This is being developed with Python 3.10 and OpenNMS 30.
This is being developed with Python 3.10 and OpenNMS 31.
It may work on older versions, but they haven't been tested yet.

- [OpenNMS REST API documentation](https://docs.opennms.com/horizon/30/development/rest/rest-api.html)
Expand Down
2 changes: 1 addition & 1 deletion antora-playbook-local.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ ui:
- path: .nojekyll
- path: index.html
contents: |
<html><head><meta http-equiv="refresh" content="0; url='opennms.py/0.0.5/index.html'" /></head></html>
<html><head><meta http-equiv="refresh" content="0; url='opennms.py/0.0.6/index.html'" /></head></html>
asciidoc:
attributes:
experimental: true
Expand Down
4 changes: 2 additions & 2 deletions docs/antora.yml
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
name: opennms.py
version: '0.0.5'
version: '0.0.6'
prerelease: true
title: OpenNMS.py
asciidoc:
attributes:
full-display-version: '0.0.5'
full-display-version: '0.0.6'
experimental: true
source-language: asciidoc@
xrefstyle: short@
Expand Down
20 changes: 14 additions & 6 deletions pyonms/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
.. include:: ../README.md
"""

from multiprocessing import current_process
from urllib.parse import urlsplit

import pyonms.dao.alarms
Expand Down Expand Up @@ -40,6 +41,18 @@ def __init__(self, hostname: str, username: str, password: str, name: str = None
else:
self.name = urlsplit(hostname).netloc.split(":")[0]
args["name"] = self.name

self.health = pyonms.dao.health.HealthAPI(args)
"""`pyonms.dao.health.HealthAPI` endpoint"""
self.info = pyonms.dao.info.InfoAPI(args)
"""`pyonms.dao.info.InfoAPI` endpoint"""

if current_process().name == "MainProcess":
self.health_status = self.health.get_health()

self.server_status = self.info.get_info()
args["version"] = self.server_status.version

self.alarms = pyonms.dao.alarms.AlarmAPI(args)
"""`pyonms.dao.alarms.AlarmAPI` endpoint"""
self.bsm = pyonms.dao.business_services.BSMAPI(args)
Expand All @@ -48,17 +61,11 @@ def __init__(self, hostname: str, username: str, password: str, name: str = None
"""`pyonms.dao.events.EventAPI` endpoint"""
self.fs = pyonms.dao.foreign_sources.ForeignSourceAPI(args)
"""`pyonms.dao.foreign_sources.ForeignSourceAPI` endpoint"""
self.health = pyonms.dao.health.HealthAPI(args)
"""`pyonms.dao.health.HealthAPI` endpoint"""
self.info = pyonms.dao.info.InfoAPI(args)
"""`pyonms.dao.info.InfoAPI` endpoint"""
self.nodes = pyonms.dao.nodes.NodeAPI(args)
"""`pyonms.dao.nodes.NodeAPI` endpoint"""
self.requisitions = pyonms.dao.requisitions.RequisitionsAPI(args)
"""`pyonms.dao.requisitions.RequisitionsAPI` endpoint"""

self.status = self.info.get_info()

def __repr__(self):
return self.hostname

Expand All @@ -74,3 +81,4 @@ def reload_daemon(self, name: str):
EventParameter(name="daemonName", value=name, type="string")
)
self.events.send_event(reload_event)
print(f"Sending event to trigger reload of the {name} daemon.")
16 changes: 10 additions & 6 deletions pyonms/dao/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,9 @@ def _get_batch(
params["limit"] = batch_size
else:
params["limit"] = limit
records = self._get(uri=url, params=params, endpoint=endpoint)
records = self._get(
uri=url, params=params, endpoint=endpoint, headers=self.headers
)
if records.get(endpoint, [None]) in [[None], []]:
return [None]
if limit == 0 or records["totalCount"] < limit:
Expand All @@ -70,11 +72,13 @@ def _get_batch(
def _get(
self, uri: str, headers: dict = {}, params: dict = {}, endpoint: str = None
) -> dict:
if self.base_v1 in uri:
return self._get_v1(
uri=uri, headers=headers, params=params, endpoint=endpoint
)
headers["Accept"] = "application/json"
# if self.base_v1 in uri:
# return self._get_v1(
# uri=uri, headers=headers, params=params, endpoint=endpoint
# )
if endpoint != "raw":
for key, value in self.headers.items():
headers[key] = value
response = requests.get(uri, auth=self.auth, headers=headers, params=params)
if response.status_code == 200:
if "was not found" not in response.text:
Expand Down
2 changes: 1 addition & 1 deletion pyonms/dao/business_services.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
from tqdm import tqdm

from pyonms.dao import Endpoint

import pyonms.models.business_service
import pyonms.models.exceptions


class BSMAPI(Endpoint):
Expand Down
8 changes: 8 additions & 0 deletions pyonms/dao/foreign_sources.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,11 @@ def _get(
if "was not found" not in response.text:
return response.json()
return {}

def update_foreign_source(
self, foreign_source: pyonms.models.foreign_source.ForeignSource
):
response = self._post(
uri=self.url, headers=self.headers, json=foreign_source._to_dict()
)
return response
3 changes: 0 additions & 3 deletions pyonms/dao/health.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
# dao.health.py

import json

from pyonms.dao import Endpoint

import pyonms.models.health
Expand All @@ -15,7 +13,6 @@ def __init__(self, kwargs):
def get_health(self) -> pyonms.models.health.Health:
record = self._get(uri=f"{self.url}", endpoint="raw")
if record is not None:
record = json.loads(record)
health = self._process_health(record)
if health.healthy:
print(f"Connected to {self.name}")
Expand Down
3 changes: 0 additions & 3 deletions pyonms/dao/info.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
# dao.info.py

import json

from pyonms.dao import Endpoint

import pyonms.models.info
Expand All @@ -15,7 +13,6 @@ def __init__(self, kwargs):
def get_info(self) -> pyonms.models.info.Info:
record = self._get(uri=f"{self.url}", endpoint="raw")
if record is not None:
record = json.loads(record)
return self._process_info(record)
else:
return None
Expand Down
44 changes: 39 additions & 5 deletions pyonms/dao/requisitions.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
# dao.requisitions.py

import requests

from typing import List, Union

from pyonms.dao import Endpoint
from pyonms.utils import normalize_dict

import pyonms.models.requisition


Expand All @@ -14,7 +18,9 @@ def __init__(self, kwargs):
def get_requisition(
self, name: str
) -> Union[pyonms.models.requisition.Requisition, None]:
record = self._get(uri=f"{self.url}/{name}", endpoint="requisitions")
record = self._get(
uri=f"{self.url}/{name}", endpoint="requisitions", headers=self.headers
)
if record is not None:
return self._process_requisition(record)
else:
Expand All @@ -29,7 +35,7 @@ def get_requisitions(
params = {}
records = self._get_batch(
url=self.url,
endpoint="requisitions",
endpoint="model-import",
limit=limit,
batch_size=batch_size,
params=params,
Expand All @@ -41,6 +47,16 @@ def get_requisitions(
return requisitions

def _process_requisition(self, data: dict) -> pyonms.models.requisition.Requisition:
# if data.get("foreign-source"):
# data["foreign_source"] = data["foreign-source"]
# del data["foreign-source"]
# if data.get("date-stamp"):
# data["date_stamp"] = data["date-stamp"]
# del data["date-stamp"]
# if data.get("last-import") or data["last-import"] is None:
# data["last_import"] = data["last-import"]
# del data["last-import"]
data = normalize_dict(data)
return pyonms.models.requisition.Requisition(**data)

def get_requisition_active_count(self) -> int:
Expand All @@ -52,10 +68,28 @@ def get_requisition_deployed_count(self) -> int:
return int(count)

def import_requisition(self, name: str, rescan: bool = False) -> bool:
status = self._put(
uri=f"{self.url}/{name}/import", data={}, params={"rescanExisting": rescan}
response = self._put(
uri=f"{self.url}/{name}/import",
params={"rescanExisting": rescan},
)
if status in [202, 204]:
if response.status_code in [202, 204]:
return True
else:
return False

def _put(
self,
uri: str,
data: dict = {},
params: dict = {},
) -> requests.Response:
response = requests.put(
uri, auth=self.auth, headers=self.headers, data=data, params=params
)
return response

def update_requisition(self, requisition: pyonms.models.requisition.Requisition):
response = self._post(
uri=self.url, headers=self.headers, json=requisition._to_dict()
)
return response
1 change: 1 addition & 0 deletions pyonms/models/alarm.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ class Alarm:
troubleTicket: str = None
troubleTicketLink: str = None
troubleTicketState: int = None
qosAlarmState: str = None
firstEvent: Union[Event, None] = field(default_factory=dict)
lastEvent: Union[Event, None] = field(default_factory=dict)
parameters: List[Union[EventParameter, None]] = field(default_factory=list)
Expand Down
26 changes: 11 additions & 15 deletions pyonms/models/business_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from dataclasses import dataclass, field
from typing import List, Optional

import pyonms.models.exceptions
from pyonms.models import exceptions


class Severity(Enum):
Expand Down Expand Up @@ -48,7 +48,7 @@ class MapFunction:

def __post_init__(self):
if self.type not in MAP_FUNCTIONS:
raise pyonms.models.exceptions.InvalidValueError(
raise exceptions.InvalidValueError(
name="MapFunction", value="self.type", valid=MAP_FUNCTIONS
)
if self.type == "SetTo" and self.status:
Expand Down Expand Up @@ -76,7 +76,7 @@ class ReduceFunction:

def __post_init__(self):
if self.type not in REDUCE_FUNCTIONS:
raise pyonms.models.exceptions.InvalidValueError(
raise exceptions.InvalidValueError(
name="ReduceFunction", value=self.type, valid=REDUCE_FUNCTIONS
)
if self.type == "ExponentialPropagation" and not self.properties:
Expand All @@ -85,7 +85,7 @@ def __post_init__(self):
if not self.properties:
self.properties["threshold"] = self.threshold
if self.threshold > 1:
raise pyonms.models.exceptions.InvalidValueError(
raise exceptions.InvalidValueError(
name="Threshold", value=self.threshold, valid="decimal between 0-1"
)
elif self.type == "HighestSeverityAbove" and not self.properties:
Expand Down Expand Up @@ -209,9 +209,7 @@ class IPServiceEdgeRequest:

def __post_init__(self):
if len(self.friendly_name) > 30:
raise pyonms.models.exceptions.StringLengthError(
30, value=self.friendly_name
)
raise exceptions.StringLengthError(30, value=self.friendly_name)
if isinstance(self.map_function, dict):
self.map_function = MapFunction(**self.map_function)

Expand Down Expand Up @@ -412,9 +410,7 @@ class ReductionKeyEdge:

def __post_init__(self):
if len(self.friendly_name) > 30:
raise pyonms.models.exceptions.StringLengthError(
30, value=self.friendly_name
)
raise exceptions.StringLengthError(30, value=self.friendly_name)
if isinstance(self.map_function, dict):
self.map_function = MapFunction(**self.map_function)

Expand Down Expand Up @@ -497,7 +493,7 @@ def add_attribute(self, attribute: Attribute) -> None:
)
self.attributes.append(attribute)

def update_edge(
def update_edge( # noqa C901
self,
ip_edge: IPServiceEdgeRequest = None,
child_edge: ChildEdgeRequest = None,
Expand All @@ -517,7 +513,7 @@ def update_edge(
)
self.ip_service_edges.append(ip_edge)
elif ip_edge:
raise pyonms.models.exceptions.InvalidValueError(
raise exceptions.InvalidValueError(
name="ip_edge", value=ip_edge, valid=[IPServiceEdgeRequest]
)
if isinstance(child_edge, ChildEdgeRequest):
Expand All @@ -531,7 +527,7 @@ def update_edge(
)
self.child_edges.append(child_edge)
elif child_edge:
raise pyonms.models.exceptions.InvalidValueError(
raise exceptions.InvalidValueError(
name="child_edge", value=child_edge, valid=[ChildEdgeRequest]
)
if isinstance(application_edge, ApplicationEdgeRequest):
Expand All @@ -547,7 +543,7 @@ def update_edge(
)
self.application_edges.append(application_edge)
elif application_edge:
raise pyonms.models.exceptions.InvalidValueError(
raise exceptions.InvalidValueError(
name="application_edge",
value=application_edge,
valid=[ApplicationEdgeRequest],
Expand All @@ -566,7 +562,7 @@ def update_edge(
)
self.reduction_key_edges.append(reduction_key_edge)
elif reduction_key_edge:
raise pyonms.models.exceptions.InvalidValueError(
raise exceptions.InvalidValueError(
name="reduction_key_edge",
value=reduction_key_edge,
valid=[ReductionKeyEdgeRequest],
Expand Down
Loading

0 comments on commit ba4a39d

Please sign in to comment.