Skip to content

Commit

Permalink
Added documentation, with change logs managed by towncrier
Browse files Browse the repository at this point in the history
Details:

* Added initial documentation.

* Added support for managing the change log with towncrier.

* Needed to increase minimum version of Pylint to 3.0.1, because
  the 2.15.0 version crashed on docs/conf.py.

Signed-off-by: Andreas Maier <maiera@de.ibm.com>
  • Loading branch information
andy-maier committed Sep 29, 2024
1 parent 354ab63 commit 51a1e2a
Show file tree
Hide file tree
Showing 27 changed files with 1,818 additions and 37 deletions.
12 changes: 6 additions & 6 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -153,12 +153,12 @@ jobs:
RUN_TYPE: ${{ steps.set-run-type.outputs.result }}
run: |
make build
# - name: Run builddoc
# env:
# PACKAGE_LEVEL: ${{ matrix.package_level }}
# RUN_TYPE: ${{ steps.set-run-type.outputs.result }}
# run: |
# make builddoc
- name: Run builddoc
env:
PACKAGE_LEVEL: ${{ matrix.package_level }}
RUN_TYPE: ${{ steps.set-run-type.outputs.result }}
run: |
make builddoc
- name: Run check
env:
PACKAGE_LEVEL: ${{ matrix.package_level }}
Expand Down
26 changes: 26 additions & 0 deletions .readthedocs.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Read the Docs (RTD) configuration file
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details

# RTD config file version
version: 2

# Environment RTD sets up for the docs build
build:
os: ubuntu-22.04
tools:
python: "3.11"

# Build documentation in the docs/ directory with Sphinx
sphinx:
configuration: docs/conf.py

# If using Sphinx, optionally build your docs in additional formats such as PDF
# formats:
# - pdf

# Python requirements required to build the docs
python:
install:
- requirements: requirements-base.txt
- requirements: requirements.txt
- requirements: requirements-develop.txt
11 changes: 5 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ doc_dir := docs

# Directory for generated API documentation
doc_build_dir := build_docs
doc_build_file := $(doc_build_dir)/html/docs/index.html
doc_build_file := $(doc_build_dir)/index.html

# Dependents for Sphinx documentation build
doc_dependent_files := \
Expand All @@ -164,12 +164,11 @@ doc_dependent_files := \
check_py_files := \
$(package_py_files) \
$(test_py_files) \
# TODO: Add conf.py once docs are created
# $(doc_dir)/conf.py \
$(doc_dir)/conf.py \

# Documentation generator command
doc_cmd := sphinx-build
doc_opts := -v -d $(doc_build_dir)/doctrees -c $(doc_dir) .
doc_opts := -v -c $(doc_dir)

# Directory for .done files
done_dir := done
Expand All @@ -188,7 +187,7 @@ flake8_rc_file := .flake8
pylint_rc_file := .pylintrc

# Packages whose dependencies are checked using pip-missing-reqs
check_reqs_packages := pip_check_reqs pipdeptree build pytest coverage coveralls flake8 pylint safety twine
check_reqs_packages := pip_check_reqs pipdeptree build pytest coverage coveralls flake8 pylint safety twine towncrier

ifdef TESTCASES
pytest_opts := $(TESTOPTS) -k $(TESTCASES)
Expand Down Expand Up @@ -355,7 +354,7 @@ $(done_dir)/install_$(pymn)_$(PACKAGE_LEVEL).done: $(done_dir)/base_$(pymn)_$(PA
$(doc_build_file): $(done_dir)/develop_$(pymn)_$(PACKAGE_LEVEL).done Makefile $(doc_dependent_files)
@echo "Makefile: Creating the HTML pages with top level file: $@"
-$(call RM_FUNC,$@)
$(doc_cmd) -b html $(doc_opts) $(doc_build_dir)/html
$(doc_cmd) -b html $(doc_opts) $(doc_dir) $(doc_build_dir)
@echo "Done: Created the HTML pages with top level file: $@"

$(sdist_file): $(done_dir)/develop_$(pymn)_$(PACKAGE_LEVEL).done Makefile $(dist_dependent_files)
Expand Down
34 changes: 24 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
# A log forwarder for the IBM Z HMC

[![Version on Pypi](https://img.shields.io/pypi/v/zhmc-log-forwarder.svg)](https://pypi.python.org/pypi/zhmc-log-forwarder/)
[![Docs status (master)](https://readthedocs.org/projects/zhmc-log-forwarder/badge/?version=latest)](https://readthedocs.org/projects/zhmc-log-forwarder/builds/)
[![Test status (master)](https://github.com/zhmcclient/zhmc-log-forwarder/actions/workflows/test.yml/badge.svg?branch=master)](https://github.com/zhmcclient/zhmc-log-forwarder/actions/workflows/test.yml?query=branch%3Amaster)
[![Test coverage (master)](https://coveralls.io/repos/github/zhmcclient/zhmc-log-forwarder/badge.svg?branch=master)](https://coveralls.io/github/zhmcclient/zhmc-log-forwarder?branch=master)
<!---
[![Docs status (master)](https://readthedocs.org/projects/zhmc-log-forwarder/badge/?version=latest)](https://readthedocs.org/projects/zhmc-log-forwarder/builds/)
--->

# Overview

The zhmc-log-forwarder package provides a log forwarder for the IBM Z
HMC, written in pure Python.
The zhmc-log-forwarder package provides a log forwarder for the
[IBM Z](https://www.ibm.com/it-infrastructure/z) Hardware Management Console
(HMC), written in pure Python.

It contains a command named `zhmc_log_forwarder` that collects security
logs and audit logs from the Z HMC and forwards the log entries to
Expand All @@ -23,8 +22,18 @@ The command can in addition subscribe for notifications from the HMC
about new log entries, so that it can wait for any future log entries to
appear.

A short overview presentation is here:
[IBM_Z\_HMC_Log_Forwarder.pdf](IBM_Z_HMC_Log_Forwarder.pdf).
The log forwarder supports the following destinations:

- Standard output
- Standard error
- rsyslog server

and the following formats:

- Single line format
- [Cloud Auditing Data Federation](https://www.dmtf.org/standards/cadf) (CADF)
format, represented as a JSON string


# Installation

Expand All @@ -40,7 +49,7 @@ clutter up your system Python.

# Quickstart

1. Make sure you installed the zhmc_log_forwarder package (see the
1. Make sure you installed the zhmc-log-forwarder package (see the
previous section).

2. Create a config file for the `zhmc_log_forwarder` command. The
Expand All @@ -59,13 +68,13 @@ clutter up your system Python.

Redirect that output into a file and edit that file as needed.

3. Optional: The zhmc_log_forwarder package includes a default HMC log
3. Optional: The zhmc-log-forwarder package includes a default HMC log
message file. That file is used when generating CADF output format
and defines how the HMC log messages are classified in the CADF
output. It is possible to specify your own HMC log message file
using the `log_message_file` parameter in the config file. When
omitting this parameter, or when setting it to `null`, the default
HMC log message file included with the zhmc_log_forwarder package is
HMC log message file included with the zhmc-log-forwarder package is
used.

An example HMC log message file explaining its format is shown when
Expand All @@ -86,6 +95,11 @@ clutter up your system Python.
The command will run forever (or until stopped with Ctrl-C) and will
forward the log records as specified in the config file.

# Documentation and Change Log

- [Documentation](http://zhmc-log-forwarder.readthedocs.io)
- [Change log](http://zhmc-log-forwarder.readthedocs.io/en/master/changes.html)

# License

The zhmc-log-forwarder package is licensed under the [Apache 2.0
Expand Down
2 changes: 2 additions & 0 deletions changes/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Keep this directory in git even if empty
!.gitignore
1 change: 1 addition & 0 deletions changes/48.feature.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Migrated to pyproject.toml.
77 changes: 77 additions & 0 deletions changes/changes.rst.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
{#
# Jinja2 template for towncrier to generate the change log from change fragments.
#
# Input variables (as of towncrier 22.8.0):
# - render_title (bool): Indicates whether a title should be rendered by the
# template. If False, the title is being added by towncrier to the result of
# the template.
# - sections: The change fragments, as a dict with key: section
# name, value: dict with key: category (=type) name, value: dict with key:
# change fragment text, value: list of issues.
# - definitions: The definitions of change categories (=types), as a dict
# with key: type name, value: dict with items 'name', 'showcontent'.
# - underlines (str): The underline characters to use for the different heading
# levels (following the top heading level)
# - versiondata (dict): Project name and version data, as a dict with items
# 'name', 'version', 'date'.
# - top_underline (str): The underline character to be used for the title
# of the change log when the template generates the title.
# - get_indent (func): Function to get the indentation for subsequent lines
# given the first line of a multi-line change fragment text.
#}
{% if render_title %}
{% if versiondata.name %}
{{ versiondata.name }} {{ versiondata.version }} ({{ versiondata.date }})
{{ top_underline * ((versiondata.name + versiondata.version + versiondata.date)|length + 4)}}
{% else %}
{{ versiondata.version }} ({{ versiondata.date }})
{{ top_underline * ((versiondata.version + versiondata.date)|length + 3)}}
{% endif %}
{% endif %}

Released: {{ versiondata.date }}

{% for section, _ in sections.items() %}
{% set underline = underlines[0] %}
{% if section %}
{{ section }}
{{ underline * section|length }}

{% set underline = underlines[1] %}
{% endif %}
{% if sections[section] %}
{% for category, val in definitions.items() if category in sections[section] and category != 'notshown' %}
**{{ definitions[category]['name'] }}:**

{% if definitions[category]['showcontent'] %}
{% for text, values in sections[section][category].items() %}
{% set issue_values = [] %}
{% for v in values if 'noissue' not in v %}
{% set _ = issue_values.append(v) %}
{% endfor %}
{% set issue_values_str = ' (' + issue_values|join(', ') + ')' if issue_values else '' %}
* {{ text }}{{ issue_values_str }}

{% endfor %}
{% else %}
{% set issue_values = [] %}
{% for v in sections[section][category][''] if 'noissue' not in v %}
{% set _ = issue_values.append(v) %}
{% endfor %}
{% if issue_values %}
* {{ issue_values|join(', ') }}

{% endif %}
{% endif %}
{% if sections[section][category]|length == 0 %}
No significant changes.

{% endif %}
{% endfor %}
{% else %}
No significant changes.

{% endif %}
{% endfor %}
{{ '' }}
{{ '' }}
1 change: 1 addition & 0 deletions changes/noissue.1.feature.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Changed 'make install' to install in non-editable mode.
1 change: 1 addition & 0 deletions changes/noissue.1.fix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Test: Fixed coveralls not found on MacOS with Python 3.9-3.11.
1 change: 1 addition & 0 deletions changes/noissue.2.feature.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Dev: Relaxed the conditions when safety issues are tolerated.
1 change: 1 addition & 0 deletions changes/noissue.2.fix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Test: Resolved new issues reported by Pylint 3.3.
1 change: 1 addition & 0 deletions changes/noissue.safety.fix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Addressed safety issues up to 2024-08-18.
123 changes: 123 additions & 0 deletions docs/_static/_sphinx_javascript_frameworks_compat.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
/* Compatability shim for jQuery and underscores.js.
*
* Copyright Sphinx contributors
* Released under the two clause BSD licence
*/

/**
* small helper function to urldecode strings
*
* See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent#Decoding_query_parameters_from_a_URL
*/
jQuery.urldecode = function(x) {
if (!x) {
return x
}
return decodeURIComponent(x.replace(/\+/g, ' '));
};

/**
* small helper function to urlencode strings
*/
jQuery.urlencode = encodeURIComponent;

/**
* This function returns the parsed url parameters of the
* current request. Multiple values per key are supported,
* it will always return arrays of strings for the value parts.
*/
jQuery.getQueryParameters = function(s) {
if (typeof s === 'undefined')
s = document.location.search;
var parts = s.substr(s.indexOf('?') + 1).split('&');
var result = {};
for (var i = 0; i < parts.length; i++) {
var tmp = parts[i].split('=', 2);
var key = jQuery.urldecode(tmp[0]);
var value = jQuery.urldecode(tmp[1]);
if (key in result)
result[key].push(value);
else
result[key] = [value];
}
return result;
};

/**
* highlight a given string on a jquery object by wrapping it in
* span elements with the given class name.
*/
jQuery.fn.highlightText = function(text, className) {
function highlight(node, addItems) {
if (node.nodeType === 3) {
var val = node.nodeValue;
var pos = val.toLowerCase().indexOf(text);
if (pos >= 0 &&
!jQuery(node.parentNode).hasClass(className) &&
!jQuery(node.parentNode).hasClass("nohighlight")) {
var span;
var isInSVG = jQuery(node).closest("body, svg, foreignObject").is("svg");
if (isInSVG) {
span = document.createElementNS("http://www.w3.org/2000/svg", "tspan");
} else {
span = document.createElement("span");
span.className = className;
}
span.appendChild(document.createTextNode(val.substr(pos, text.length)));
node.parentNode.insertBefore(span, node.parentNode.insertBefore(
document.createTextNode(val.substr(pos + text.length)),
node.nextSibling));
node.nodeValue = val.substr(0, pos);
if (isInSVG) {
var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect");
var bbox = node.parentElement.getBBox();
rect.x.baseVal.value = bbox.x;
rect.y.baseVal.value = bbox.y;
rect.width.baseVal.value = bbox.width;
rect.height.baseVal.value = bbox.height;
rect.setAttribute('class', className);
addItems.push({
"parent": node.parentNode,
"target": rect});
}
}
}
else if (!jQuery(node).is("button, select, textarea")) {
jQuery.each(node.childNodes, function() {
highlight(this, addItems);
});
}
}
var addItems = [];
var result = this.each(function() {
highlight(this, addItems);
});
for (var i = 0; i < addItems.length; ++i) {
jQuery(addItems[i].parent).before(addItems[i].target);
}
return result;
};

/*
* backward compatibility for jQuery.browser
* This will be supported until firefox bug is fixed.
*/
if (!jQuery.browser) {
jQuery.uaMatch = function(ua) {
ua = ua.toLowerCase();

var match = /(chrome)[ \/]([\w.]+)/.exec(ua) ||
/(webkit)[ \/]([\w.]+)/.exec(ua) ||
/(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) ||
/(msie) ([\w.]+)/.exec(ua) ||
ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) ||
[];

return {
browser: match[ 1 ] || "",
version: match[ 2 ] || "0"
};
};
jQuery.browser = {};
jQuery.browser[jQuery.uaMatch(navigator.userAgent).browser] = true;
}
2 changes: 2 additions & 0 deletions docs/_static/jquery.js

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions docs/_static/my_theme.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@

.wy-nav-content {
max-width: 1000px !important;
}
Loading

0 comments on commit 51a1e2a

Please sign in to comment.