Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Convert to module #153

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
__pycache__
*.pyc
.idea
.DS_Store
venv
.venv
bin
dist
/.tox
/.coverage

62 changes: 62 additions & 0 deletions README_POETRY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# Documentation for poetry
This is how packaging could work, it is not a complete documentation but a starting point for you.
Do what you want with this file, my intention was to make as less changes as possible to your code and
prevent braking changes.
The script can still be called on commandline like before after checking out from git, but now it
can also be installed as a pip package and can be imported.
When installed as pip package an os command will be installed in system path at ```/usr/local/bin/check_redfish```
or when using an virtual environment in your virtual environment.

From now there are 3 possibilities to call the script,

When you are in the root directory of the git repository:

```bash
python -m checkredfish
./check_redfish.py
```

From everywhere on your filesystem by calling the following command, the ```PATH``` variable must be set right:

```bash
check_redfish
```


## Create requirements.txt file from pyproject.toml file
```bash
poetry export -f requirements.txt --output requirements.txt
```

## install current package
```bash
poetry install
--no-root # do not install the root package (current project)
--only-root # dependencies nicht installieren
--with dev # dev dependencies installieren ([tool.poetry.group.dev.dependencies])
--dry-run # no changes
```

## remove the installed package
This must be done using pip

```bash
pip3 uninstall check-redfish
```


## build a package from current project
```bash
poetry build
pip3 install ./dist/check_redfish-<version>.tar.gz
```

## Publish to [pypi](https://pypi.org)
First create account and create a token on [pypi](https://pypi.org)
After this run following commands, replace ```<your-api-token>``` with the token received from [pypi](https://pypi.org)

```bash
poetry config pypi-token.pypi <your-api-token>
poetry build
poetry publish
```
181 changes: 2 additions & 179 deletions check_redfish.py
Original file line number Diff line number Diff line change
@@ -1,181 +1,4 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Copyright (c) 2020 - 2025 Ricardo Bartels. All rights reserved.
#
# check_redfish.py
#
# This work is licensed under the terms of the MIT license.
# For a copy, see file LICENSE.txt included in this
# repository or visit: <https://opensource.org/licenses/MIT>.
from checkredfish import *

description = """
This is a monitoring/inventory plugin to check components and
health status of systems which support Redfish.
It will also create a inventory of all components of a system.

R.I.P. IPMI
"""

__version__ = "1.10.0"
__version_date__ = "2025-01-17"
__author__ = "Ricardo Bartels <ricardo@bitchbrothers.com>"
__description__ = "Check Redfish Plugin"
__license__ = "MIT"


import logging
from argparse import ArgumentParser, RawDescriptionHelpFormatter

from cr_module.classes.plugin import PluginData
from cr_module.system_chassi import get_system_info, get_chassi_data, get_system_data
from cr_module.nic import get_network_interfaces
from cr_module.storage import get_storage
from cr_module.bmc import get_bmc_info
from cr_module.firmware import get_firmware_info
from cr_module.event import get_event_log
from cr_module.classes.redfish import default_conn_max_retries, default_conn_timeout
from cr_module.classes.inventory import Fan, PowerSupply, Temperature, Memory, Processor


def parse_command_line():
"""parse command line arguments
Also add current version and version date to description
"""

# define command line options
parser = ArgumentParser(
description=f"{description}\nVersion: {__version__} ({__version_date__})",
formatter_class=RawDescriptionHelpFormatter, add_help=False)

group = parser.add_argument_group(title="mandatory arguments")
group.add_argument("-H", "--host",
help="define the host to request. To change the port just add ':portnumber' to this parameter")

group = parser.add_argument_group(title="authentication arguments")
group.add_argument("-u", "--username", help="the login user name")
group.add_argument("-p", "--password", help="the login password")
group.add_argument("-f", "--authfile", help="authentication file with user name and password")
group.add_argument("--sessionfile", help="define name of session file")
group.add_argument("--sessionfiledir", help="define directory where the plugin saves session files")
group.add_argument("--sessionlock", action='store_true', help="prevents multiple sessions and locks the session file when connecting")
group.add_argument("--nosession", action='store_true',
help="Don't establish a persistent session and log out after check is finished")

group = parser.add_argument_group(title="optional arguments")
group.add_argument("-h", "--help", action='store_true',
help="show this help message and exit")
group.add_argument("-w", "--warning", default="",
help="set warning value")
group.add_argument("-c", "--critical", default="",
help="set critical value")
group.add_argument("-v", "--verbose", action='store_true',
help="this will add all https requests and responses to output, "
"also adds inventory source data to all inventory objects")
group.add_argument("-d", "--detailed", action='store_true',
help="always print detailed result")
group.add_argument("-m", "--max", type=int,
help="set maximum of returned items for --sel or --mel")
group.add_argument("-r", "--retries", type=int, default=default_conn_max_retries,
help=f"set number of maximum retries (default: {default_conn_max_retries})")
group.add_argument("-t", "--timeout", type=int, default=default_conn_timeout,
help=f"set number of request timeout per try/retry (default: {default_conn_timeout})")
group.add_argument("--log_exclude",
help="a comma separated list of log lines (regex) "
"to exclude from log status checks (--sel, --mel)")
group.add_argument("--ignore_missing_ps", action='store_true',
help="ignore the fact that no power supplies are present and report the status "
"of the power subsystem")
group.add_argument("--enable_bmc_security_warning", action='store_true',
help="return status WARNING if BMC security issues are detected (HPE iLO only)")

# require at least one argument
group = parser.add_argument_group(title="query status/health information (at least one is required)")
group.add_argument("--storage", dest="requested_query", action='append_const', const="storage",
help="request storage health")
group.add_argument("--proc", dest="requested_query", action='append_const', const="proc",
help="request processor health")
group.add_argument("--memory", dest="requested_query", action='append_const', const="memory",
help="request memory health")
group.add_argument("--power", dest="requested_query", action='append_const', const="power",
help="request power supply health")
group.add_argument("--temp", dest="requested_query", action='append_const', const="temp",
help="request temperature sensors status")
group.add_argument("--fan", dest="requested_query", action='append_const', const="fan",
help="request fan status")
group.add_argument("--nic", dest="requested_query", action='append_const', const="nic",
help="request network interface status")
group.add_argument("--bmc", dest="requested_query", action='append_const', const="bmc",
help="request bmc info and status")
group.add_argument("--info", dest="requested_query", action='append_const', const="info",
help="request system information")
group.add_argument("--firmware", dest="requested_query", action='append_const', const="firmware",
help="request firmware information")
group.add_argument("--sel", dest="requested_query", action='append_const', const="sel",
help="request System Log status")
group.add_argument("--mel", dest="requested_query", action='append_const', const="mel",
help="request Management Processor Log status")
group.add_argument("--all", dest="requested_query", action='append_const', const="all",
help="request all of the above information at once")

# inventory
group = parser.add_argument_group(title="query inventory information (no health check)")
group.add_argument("-i", "--inventory", action='store_true',
help="return inventory in json format instead of regular plugin output")
group.add_argument("--inventory_id",
help="set an ID which can be used to identify this host in the destination inventory")
group.add_argument("--inventory_name",
help="set a name which can be used to identify this host in the destination inventory")
group.add_argument("--inventory_file",
help="set file to write the inventory output to. Otherwise stdout will be used.")

result = parser.parse_args()

if result.help:
parser.print_help()
print("")
exit(0)

if result.requested_query is None:
parser.error("You need to specify at least one query command.")

# need to check this our self otherwise it's not
# possible to put the help command into an arguments group
if result.host is None:
parser.error("No remote host defined")

return result


if __name__ == "__main__":
# start here
args = parse_command_line()

if args.verbose:
# initialize logger
logging.basicConfig(level="DEBUG", format='%(asctime)s - %(levelname)s: %(message)s')

# initialize plugin object
plugin = PluginData(args, plugin_version=__version__)

# try to get systems, managers and chassis IDs
plugin.rf.discover_system_properties()

# get basic information
plugin.rf.determine_vendor()

if any(x in args.requested_query for x in ['power', 'all']): get_chassi_data(PowerSupply)
if any(x in args.requested_query for x in ['temp', 'all']): get_chassi_data(Temperature)
if any(x in args.requested_query for x in ['fan', 'all']): get_chassi_data(Fan)
if any(x in args.requested_query for x in ['proc', 'all']): get_system_data(Processor)
if any(x in args.requested_query for x in ['memory', 'all']): get_system_data(Memory)
if any(x in args.requested_query for x in ['nic', 'all']): get_network_interfaces()
if any(x in args.requested_query for x in ['storage', 'all']): get_storage()
if any(x in args.requested_query for x in ['bmc', 'all']): get_bmc_info()
if any(x in args.requested_query for x in ['info', 'all']): get_system_info()
if any(x in args.requested_query for x in ['firmware', 'all']): get_firmware_info()
if any(x in args.requested_query for x in ['mel', 'all']): get_event_log("Manager")
if any(x in args.requested_query for x in ['sel', 'all']): get_event_log("System")

plugin.do_exit()

# EOF
check_redfish
1 change: 1 addition & 0 deletions checkredfish/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
__all__ = ['check_redfish']
1 change: 1 addition & 0 deletions checkredfish/__main__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from checkredfish import check_redfish as check_redfish
Loading