From d89396449e5d17b6bfb562acf6ba18d474089029 Mon Sep 17 00:00:00 2001 From: Tom Bosmans Date: Tue, 1 Apr 2025 14:58:34 +0200 Subject: [PATCH 01/54] feature: first test setup --- conftest.py | 33 +++++++++++++++++++++++++++++++++ ibmsecurity/pytest/__init__.py | 0 test/__init__.py | 0 test/test_base_admin.py | 19 +++++++++++++++++++ 4 files changed, 52 insertions(+) create mode 100644 conftest.py create mode 100644 ibmsecurity/pytest/__init__.py create mode 100644 test/__init__.py create mode 100644 test/test_base_admin.py diff --git a/conftest.py b/conftest.py new file mode 100644 index 00000000..57bca7da --- /dev/null +++ b/conftest.py @@ -0,0 +1,33 @@ +"""PyTest fixtures for testing the project.""" +from __future__ import annotations + +import pytest + +from ibmsecurity.appliance.isamappliance import ISAMAppliance +from ibmsecurity.user.applianceuser import ApplianceUser +# pylint: disable=wildcard-import,unused-wildcard-import + + +class IviaLogin: + def __init__(self): + # Create a user credential for ISAM appliance + u = ApplianceUser(username="admin@local", password="admin") + # Create an ISAM appliance with above credential + self.isam_server = ISAMAppliance(hostname="192.168.1.11", user=u, lmi_port=443) + + +@pytest.fixture +def iviaServer(): + s = IviaLogin() + return s.isam_server + + +# ibmsecurity +def pytest_runtest_setup(item): + print("setting up function:", item.name) + + +# @pytest.fixture(autouse=True) +# def pytest_configure(config: Config) -> None: +# """Register custom markers.""" +# print('configure') diff --git a/ibmsecurity/pytest/__init__.py b/ibmsecurity/pytest/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/test/__init__.py b/test/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/test/test_base_admin.py b/test/test_base_admin.py new file mode 100644 index 00000000..ddc70fef --- /dev/null +++ b/test/test_base_admin.py @@ -0,0 +1,19 @@ +import logging + + +# from ibmsecurity.appliance.isamappliance import ISAMAppliance +# from ibmsecurity.user.applianceuser import ApplianceUser +import ibmsecurity +import ibmsecurity.isam.base.admin + +# Share credentials from conftest +# from conftest import iviaLogin + + +def test_get_base_admin(iviaServer, caplog) -> None: + caplog.set_level(logging.DEBUG) + + returnValue = ibmsecurity.isam.base.admin.get(isamAppliance=iviaServer) + + logging.log(logging.INFO, returnValue) + assert not returnValue.failed() From 63410988b096607335844481b3dac9a3d655d795 Mon Sep 17 00:00:00 2001 From: Tom Bosmans Date: Wed, 2 Apr 2025 08:44:36 +0200 Subject: [PATCH 02/54] feature: update test setup --- conftest.py | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/conftest.py b/conftest.py index 57bca7da..ebcbbecd 100644 --- a/conftest.py +++ b/conftest.py @@ -1,25 +1,27 @@ """PyTest fixtures for testing the project.""" from __future__ import annotations +import os + import pytest from ibmsecurity.appliance.isamappliance import ISAMAppliance from ibmsecurity.user.applianceuser import ApplianceUser -# pylint: disable=wildcard-import,unused-wildcard-import - - -class IviaLogin: - def __init__(self): - # Create a user credential for ISAM appliance - u = ApplianceUser(username="admin@local", password="admin") - # Create an ISAM appliance with above credential - self.isam_server = ISAMAppliance(hostname="192.168.1.11", user=u, lmi_port=443) @pytest.fixture def iviaServer(): - s = IviaLogin() - return s.isam_server + """Initiate an ISAMAppliance.""" + # s = IviaLogin() + _username = os.getenv('IVIA_ADMIN') + _pw = os.getenv('IVIA_PW') + _host = os.getenv('IVIA_HOST') + _port = os.getenv('IVIA_PORT') or 443 + # Create a user credential for ISAM appliance + u = ApplianceUser(username=_username, password=_pw) + # Create an ISAM appliance with above credential + isam_server = ISAMAppliance(hostname=_host, user=u, lmi_port=_port) + return isam_server # ibmsecurity From b2ea9163b008f12e459b16746a1f48d3096b9d9f Mon Sep 17 00:00:00 2001 From: Tom Bosmans Date: Wed, 2 Apr 2025 08:45:41 +0200 Subject: [PATCH 03/54] feature: update test base admin --- test/test_base_admin.py | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/test/test_base_admin.py b/test/test_base_admin.py index ddc70fef..ec6bbdf7 100644 --- a/test/test_base_admin.py +++ b/test/test_base_admin.py @@ -1,19 +1,34 @@ import logging - -# from ibmsecurity.appliance.isamappliance import ISAMAppliance -# from ibmsecurity.user.applianceuser import ApplianceUser -import ibmsecurity import ibmsecurity.isam.base.admin - -# Share credentials from conftest -# from conftest import iviaLogin +import ibmsecurity.isam.appliance def test_get_base_admin(iviaServer, caplog) -> None: + """Get all admincfg options.""" caplog.set_level(logging.DEBUG) returnValue = ibmsecurity.isam.base.admin.get(isamAppliance=iviaServer) + logging.log(logging.INFO, returnValue) + + assert not returnValue.failed() + + +def test_set_base_admin(iviaServer, caplog) -> None: + """Set some admincfg options.""" + caplog.set_level(logging.DEBUG) + returnValue = ibmsecurity.isam.base.admin.set(isamAppliance=iviaServer, force=False, minHeapSize=128, maxHeapSize=2048, sessionTimeout=720, httpPort=None, httpsPort=443, minThreads=None, maxThreads=None, maxPoolSize=100, lmiDebuggingEnabled=None, consoleLogLevel="OFF", acceptClientCerts=False, validateClientCertIdentity=True, excludeCsrfChecking=None, maxFiles=2, maxFileSize=20, enabledTLS=['TLSv1.2'], sshdPort=22, sessionCachePurge=120, sessionInactivityTimeout=90, enabledServerProtocols="TLSv1.2", loginHeader="IBM TEST", loginMessage="Ansible Me", baSessionTimeout=300, accessLogFormat="client=%h user=%u time=%t request=\"%r\" status=%s http_user_agent=\"%{User-Agent}\"", jsVersion="") logging.log(logging.INFO, returnValue) + + assert not returnValue.failed() + + +def test_commit(iviaServer, caplog) -> None: + """Not actually a test, but save the changes.""" + caplog.set_level(logging.INFO) + + returnValue = ibmsecurity.isam.appliance.commit(isamAppliance=iviaServer) + logging.log(logging.DEBUG, returnValue) + assert not returnValue.failed() From 82606dd5dc316638a06663a2362adb22204bf255 Mon Sep 17 00:00:00 2001 From: Tom Bosmans Date: Wed, 2 Apr 2025 08:49:31 +0200 Subject: [PATCH 04/54] feature: add test aac api protection --- test/test_aac_apiprotection.py | 93 ++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 test/test_aac_apiprotection.py diff --git a/test/test_aac_apiprotection.py b/test/test_aac_apiprotection.py new file mode 100644 index 00000000..c4215b87 --- /dev/null +++ b/test/test_aac_apiprotection.py @@ -0,0 +1,93 @@ +import logging + +import ibmsecurity.isam.aac.api_protection.definitions +import ibmsecurity.isam.appliance + +import pytest + + +def getTestData(): + testdata = [ + { + "name": "test1", + "tcmBehavior": "NEVER_PROMPT", + "authorizationCodeLength": 30, + "enforceSingleAccessTokenPerGrant": True, + "accessTokenLength": 20, + "enableMultipleRefreshTokensForFaultTolerance": True, + "pinPolicyEnabled": False, + "issueRefreshToken": False, + "description": "Issue Tokens", + "oidc": { + 'issueSecret': True, + 'fapiCompliant': False, + 'poc': 'https://webseal01/mga', + 'iss': 'https://webseal01', + 'lifetime': 3600, + 'cert': 'WebSEAL-Test-Only', + 'enabled': True, + 'dynamicClients': True, + 'enc': { + 'enabled': False + }, + 'includeIssInAuthResp': True, + 'alg': 'RS256', + 'db': 'pdsrv', + 'oidcCompliant': False + }, + "refreshTokenLength": 40, + "grantTypes": ['JWT_BEARER', + 'IMPLICIT_GRANT', + 'CLIENT_CREDENTIALS', + 'AUTHORIZATION_CODE' + ], + "tokenCharSet": '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwx', + "authorizationCodeLifetime": 300, + "enforceSingleUseAuthorizationGrant": True, + "pinLength": 4, + "maxAuthorizationGrantLifetime": 604800, + "accessTokenLifetime": 900 + }, + { + "name": "test2", + "description": "Issue Tokens", + "grantTypes": ['JWT_BEARER', + 'IMPLICIT_GRANT', + 'CLIENT_CREDENTIALS', + 'AUTHORIZATION_CODE' + ], + }, + ] + return testdata + + +@pytest.mark.parametrize("items", getTestData()) +def test_set_apiprotection_definition(iviaServer, caplog, items) -> None: + """Set api protection""" + caplog.set_level(logging.DEBUG) + # items is a key-value pair + logging.log(logging.INFO, items) + arg = {} + for k, v in items.items(): + if k == 'name': + name = v + continue + arg[k] = v + + returnValue = ibmsecurity.isam.aac.api_protection.definitions.set(iviaServer, + name, + **arg + ) + logging.log(logging.INFO, returnValue) + + assert not returnValue.failed() + + +def test_commit(iviaServer, caplog) -> None: + """Not actually a test, but save the changes.""" + caplog.set_level(logging.INFO) + + returnValue = ibmsecurity.isam.appliance.commit(isamAppliance=iviaServer) + logging.log(logging.DEBUG, returnValue) + + assert not returnValue.failed() From f8469376b4b2608db453fd4298e0d1830ae79fa7 Mon Sep 17 00:00:00 2001 From: Tom Bosmans Date: Wed, 2 Apr 2025 08:50:08 +0200 Subject: [PATCH 05/54] fix: remove unncessary stuff --- testisam.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/testisam.py b/testisam.py index 24640eac..3d82114d 100644 --- a/testisam.py +++ b/testisam.py @@ -1,9 +1,12 @@ +""" +Test script for ibmsecurity modules +""" import logging.config import pprint -from ibmsecurity.appliance.isamappliance import ISAMAppliance -from ibmsecurity.user.applianceuser import ApplianceUser import pkgutil import importlib +from ibmsecurity.appliance.isamappliance import ISAMAppliance +from ibmsecurity.user.applianceuser import ApplianceUser import ibmsecurity @@ -18,7 +21,7 @@ def import_submodules(package, recursive=True): if isinstance(package, str): package = importlib.import_module(package) results = {} - for loader, name, is_pkg in pkgutil.walk_packages(package.__path__): + for name, is_pkg in pkgutil.walk_packages(package.__path__): full_name = package.__name__ + "." + name results[full_name] = importlib.import_module(full_name) if recursive and is_pkg: From 83e265824ca7c2db41349bcf1116c8fa1eece619 Mon Sep 17 00:00:00 2001 From: Tom Bosmans Date: Wed, 2 Apr 2025 17:04:38 +0200 Subject: [PATCH 06/54] fix: pre-commit --- .pre-commit-config.yaml | 16 +++--- tox.ini | 106 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 114 insertions(+), 8 deletions(-) create mode 100644 tox.ini diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index c533d9af..c0c4e723 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -17,11 +17,11 @@ repos: hooks: - id: flake8 args: ["--ignore=E501"] - - repo: https://github.com/PyCQA/pylint - rev: v3.3.2 - hooks: - - id: pylint - args: [ - "-ry", - "--exit-zero" - ] +# - repo: https://github.com/PyCQA/pylint +# rev: v3.3.2 +# hooks: +# - id: pylint +# args: [ +# "-ry", +# "--exit-zero" +# ] diff --git a/tox.ini b/tox.ini new file mode 100644 index 00000000..6fec1258 --- /dev/null +++ b/tox.ini @@ -0,0 +1,106 @@ +[tox] +requires = + setuptools>=65.3 + tox>=4.24.2 + tox-extra>=2.1 + tox-uv>=1.25 +env_list = + py + py-devel + lint +skip_missing_interpreters = true + +[testenv] +description = + Run the tests under {base_python} + devel: and ansible devel branch + pre: and enable --pre when installing dependencies, testing prereleases +package = editable +deps = + devel: ansible-compat @ git+https://github.com/ansible/ansible-compat.git # GPLv3+ + devel: ansible-core @ git+https://github.com/ansible/ansible.git # GPLv3+ +extras = + test +pass_env = + CI + CURL_CA_BUNDLE + FORCE_COLOR + HOME + LANG + LC_* + NO_COLOR + PYTEST_* + PYTEST_REQPASS + PYTHON* + PYTHONBREAKPOINT + PYTHONIOENCODING + PYTHONPYCACHEPREFIX + PY_COLORS + REQUESTS_CA_BUNDLE + RTD_TOKEN + SETUPTOOLS_SCM_DEBUG + SSH_AUTH_SOCK + SSL_CERT_FILE + UV_* +set_env = + COVERAGE_FILE = {env:COVERAGE_FILE:{env_dir}/.coverage.{env_name}} + COVERAGE_PROCESS_START = {tox_root}/pyproject.toml + FORCE_COLOR = 1 + PIP_CONSTRAINT = {tox_root}/.config/constraints.txt + PIP_DISABLE_PIP_VERSION_CHECK = 1 + PRE_COMMIT_COLOR = always + PYTEST_REQPASS = 910 + UV_CONSTRAINT = {tox_root}/.config/constraints.txt + deps, devel, hook, lint, pkg, pre, py310, schemas: PIP_CONSTRAINT = /dev/null + deps, devel, hook, lint, pkg, pre, py310, schemas: UV_CONSTRAINT = /dev/null + devel: ANSIBLE_DEVEL_WARNING = false + pre: PIP_PRE = 1 +commands_pre = + sh -c "rm -f {env_dir}/.coverage.* 2>/dev/null || true" + {env_python} -m pip check + bash ./tools/install-reqs.sh + ansible --version +commands = + sh -c "{env_python} -m pip freeze > {env_dir}/log/requirements.txt" + coverage run -m pytest {posargs: \ + -n auto \ + -ra \ + --showlocals \ + --doctest-modules \ + --durations=10 \ + } + {py,py310,py311,py312,py313}: sh -c "coverage combine -a -q --data-file={env_dir}/.coverage {work_dir}/*/.coverage.* && coverage xml --data-file={env_dir}/.coverage -o {env_dir}/coverage.xml --fail-under=0 && coverage report --data-file={env_dir}/.coverage" +allowlist_externals = + ./tools/test-hook.sh + bash + find + git + pwd + rm + sh + tox + +[testenv:lint] +description = Run all linters +skip_install = true +deps = + pre-commit>=4.1 + pre-commit-uv>=4.1.4 + pytest>=7.2.2 # to updated schemas + setuptools>=51.1.1 +pass_env = + {[testenv]pass_env} + PRE_COMMIT_HOME +commands_pre = +commands = + {env_python} -m pre_commit run --all-files --show-diff-on-failure {posargs:} + +[testenv:clean] +description = Remove temporary files +skip_install = true +deps = +commands_pre = +commands = + find . -type d \( -name __pycache__ -o -name .mypy_cache \) -delete + find . -type f \( -name '*.py[co]' -o -name ".coverage*" -o -name coverage.xml \) -delete +commands_post = From b25b860e7b9e4cfbabb73cb2dac6af1d7af4b00d Mon Sep 17 00:00:00 2001 From: Tom Bosmans Date: Wed, 2 Apr 2025 17:06:17 +0200 Subject: [PATCH 07/54] fix: pre-commit --- .pre-commit-config.yaml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index c0c4e723..a6b57efa 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -12,11 +12,11 @@ repos: hooks: - id: black stages: [pre-push] - - repo: https://github.com/PyCQA/flake8 - rev: 7.1.1 - hooks: - - id: flake8 - args: ["--ignore=E501"] + #- repo: https://github.com/PyCQA/flake8 + # rev: 7.1.1 + # hooks: + # - id: flake8 + # args: ["--ignore=E501"] # - repo: https://github.com/PyCQA/pylint # rev: v3.3.2 # hooks: From 6dce9e41098b326a305a512d4daf781a674e1b2c Mon Sep 17 00:00:00 2001 From: Tom Bosmans Date: Wed, 2 Apr 2025 17:06:27 +0200 Subject: [PATCH 08/54] fix: remove trailing spaces --- ibmsecurity/appliance/isamappliance.py | 8 ++++---- ibmsecurity/appliance/isdsappliance.py | 8 ++++---- ibmsecurity/appliance/isvgappliance.py | 8 ++++---- ibmsecurity/isam/aac/fido2/metadata.py | 2 +- ibmsecurity/isam/aac/runtime_template/root.py | 8 ++++---- .../isam/aac/scim/enterprise_profile.py | 2 +- ibmsecurity/isam/aac/scim/general.py | 2 +- ibmsecurity/isam/aac/scim/group.py | 2 +- ibmsecurity/isam/aac/scim/isam_user.py | 2 +- ibmsecurity/isam/aac/scim/ldap_attrs.py | 2 +- ibmsecurity/isam/aac/scim/ldap_objs.py | 2 +- ibmsecurity/isam/aac/scim/mode.py | 2 +- ibmsecurity/isam/aac/scim/scim.py | 2 +- ibmsecurity/isam/aac/scim/user_profile.py | 2 +- .../isam/aac/scim_custom_schema_extensions.py | 1 - .../isam/aac/server_connections/redis.py | 2 +- ibmsecurity/isam/base/date_time.py | 2 +- .../ssl_certificates/certificate_databases.py | 6 +++--- .../ssl_certificates/certificate_requests.py | 8 ++++---- .../ssl_certificates/signer_certificate.py | 6 +++--- ibmsecurity/isam/statistics.py | 2 +- .../isam/web/authorization_server/logs.py | 2 +- ibmsecurity/isam/web/iag/export.py | 1 - .../reverse_proxy/federation_configuration.py | 10 +++++----- .../web/reverse_proxy/ivg_configuration.py | 3 +-- .../isam/web/reverse_proxy/junctions.py | 1 - .../web/reverse_proxy/junctions_config.py | 2 +- .../web/reverse_proxy/management_root/all.py | 4 ++-- .../web/reverse_proxy/oauth_configuration.py | 2 +- ibmsecurity/isam/web/runtime/acl.py | 3 +-- ibmsecurity/isvg/appliance.py | 4 ++-- ibmsecurity/isvg/available_updates.py | 6 +++--- ibmsecurity/isvg/certstore_personal.py | 2 +- ibmsecurity/isvg/certstore_signer.py | 2 +- ibmsecurity/isvg/cm/process.py | 4 ++-- ibmsecurity/isvg/im/certstore_personal.py | 4 ++-- ibmsecurity/isvg/im/certstore_signer.py | 4 ++-- ibmsecurity/isvg/im/db.py | 20 +++++++++---------- ibmsecurity/isvg/im/external_library.py | 4 ++-- ibmsecurity/isvg/im/jvm_property.py | 2 +- ibmsecurity/isvg/im/keystore.py | 2 +- ibmsecurity/isvg/im/ldap.py | 10 +++++----- ibmsecurity/isvg/im/mail.py | 6 +++--- ibmsecurity/isvg/im/nls.py | 2 +- ibmsecurity/isvg/im/openid.py | 6 +++--- ibmsecurity/isvg/im/process.py | 2 +- ibmsecurity/isvg/im/property.py | 4 ++-- ibmsecurity/isvg/im/workflowextension.py | 4 ++-- ibmsecurity/isvg/interfaces.py | 2 +- ibmsecurity/isvg/lmi.py | 2 +- ibmsecurity/isvg/lmi_auth.py | 8 ++++---- ibmsecurity/isvg/management_authentication.py | 2 +- .../isvg/management_ssl_certificate.py | 2 +- ibmsecurity/isvg/sdi/process.py | 4 ++-- ibmsecurity/utilities/tools.py | 2 +- 55 files changed, 106 insertions(+), 111 deletions(-) diff --git a/ibmsecurity/appliance/isamappliance.py b/ibmsecurity/appliance/isamappliance.py index 8ae82dd3..fcb2cfb2 100644 --- a/ibmsecurity/appliance/isamappliance.py +++ b/ibmsecurity/appliance/isamappliance.py @@ -52,19 +52,19 @@ def _set_ssl_verification(self, requests_verify_param): if self.verify is None or self.verify is False: self.disable_urllib_warnings = True self.logger.warning(""" -Certificate verification has been disabled. Python is NOT verifying the SSL -certificate of the host appliance and InsecureRequestWarning messages are +Certificate verification has been disabled. Python is NOT verifying the SSL +certificate of the host appliance and InsecureRequestWarning messages are being suppressed for the following host: https://{0}:{1} To use certificate verification: 1. When the certificate is trusted by your Python environment: - Instantiate all instances of ISAMAppliance with verify=True or set + Instantiate all instances of ISAMAppliance with verify=True or set the environment variable IBMSECLIB_VERIFY_CONNECTION=True. 2. When the certificate is not already trusted in your Python environment: Instantiate all instances of ISAMAppliance with the verify parameter set to the fully qualified path to a CA bundle. - + See the following URL for more details: https://requests.readthedocs.io/en/latest/user/advanced/#ssl-cert-verification """.format(self.hostname, self.lmi_port)) diff --git a/ibmsecurity/appliance/isdsappliance.py b/ibmsecurity/appliance/isdsappliance.py index 7ed4535b..fced6f1b 100644 --- a/ibmsecurity/appliance/isdsappliance.py +++ b/ibmsecurity/appliance/isdsappliance.py @@ -50,19 +50,19 @@ def _set_ssl_verification(self, requests_verify_param): if self.verify is None or self.verify is False: self.disable_urllib_warnings = True self.logger.warning(""" -Certificate verification has been disabled. Python is NOT verifying the SSL -certificate of the host appliance and InsecureRequestWarning messages are +Certificate verification has been disabled. Python is NOT verifying the SSL +certificate of the host appliance and InsecureRequestWarning messages are being suppressed for the following host: https://{0}:{1} To use certificate verification: 1. When the certificate is trusted by your Python environment: - Instantiate all instances of ISDSAppliance with verify=True or set + Instantiate all instances of ISDSAppliance with verify=True or set the environment variable IBMSECLIB_VERIFY_CONNECTION=True. 2. When the certificate is not already trusted in your Python environment: Instantiate all instances of ISAMAppliance with the verify parameter set to the fully qualified path to a CA bundle. - + See the following URL for more details: https://requests.readthedocs.io/en/latest/user/advanced/#ssl-cert-verification """.format(self.hostname, self.lmi_port)) diff --git a/ibmsecurity/appliance/isvgappliance.py b/ibmsecurity/appliance/isvgappliance.py index dc5fbd0d..5b4f8a09 100644 --- a/ibmsecurity/appliance/isvgappliance.py +++ b/ibmsecurity/appliance/isvgappliance.py @@ -50,19 +50,19 @@ def _set_ssl_verification(self, requests_verify_param): if self.verify is None or self.verify is False: self.disable_urllib_warnings = True self.logger.warning(""" -Certificate verification has been disabled. Python is NOT verifying the SSL -certificate of the host appliance and InsecureRequestWarning messages are +Certificate verification has been disabled. Python is NOT verifying the SSL +certificate of the host appliance and InsecureRequestWarning messages are being suppressed for the following host: https://{0}:{1} To use certificate verification: 1. When the certificate is trusted by your Python environment: - Instantiate all instances of ISVGAppliance with verify=True or set + Instantiate all instances of ISVGAppliance with verify=True or set the environment variable IBMSECLIB_VERIFY_CONNECTION=True. 2. When the certificate is not already trusted in your Python environment: Instantiate all instances of ISAMAppliance with the verify parameter set to the fully qualified path to a CA bundle. - + See the following URL for more details: https://requests.readthedocs.io/en/latest/user/advanced/#ssl-cert-verification """.format(self.hostname, self.lmi_port)) diff --git a/ibmsecurity/isam/aac/fido2/metadata.py b/ibmsecurity/isam/aac/fido2/metadata.py index 0e220086..445027cf 100644 --- a/ibmsecurity/isam/aac/fido2/metadata.py +++ b/ibmsecurity/isam/aac/fido2/metadata.py @@ -163,7 +163,7 @@ def _check(isamAppliance, fido2_metadata): logger.debug("Comparing server FIDO2 metadata configuration with desired configuration.") # Converting python ret_obj['data'] dict to valid JSON (RFC 8259) # e.g. converts python boolean 'True' -> to JSON literal lowercase value 'true' - cur_json_string = json.dumps(ret_obj['data']) + cur_json_string = json.dumps(ret_obj['data']) cur_sorted_json = tools.json_sort(cur_json_string) logger.debug("Server JSON : {0}".format(cur_sorted_json)) given_json_string = json.dumps(fido2_metadata) diff --git a/ibmsecurity/isam/aac/runtime_template/root.py b/ibmsecurity/isam/aac/runtime_template/root.py index cf69b25f..4d6e6cad 100644 --- a/ibmsecurity/isam/aac/runtime_template/root.py +++ b/ibmsecurity/isam/aac/runtime_template/root.py @@ -58,11 +58,11 @@ def import_file(isamAppliance, filename, delete_missing=False, check_mode=False, for info in zClientFile.infolist(): files_on_client.append(info.filename) missing_client_files = [x for x in files_on_server if x not in files_on_client] - + if missing_client_files != []: logger.info("list all missing files in {}, which will be deleted on the server: {}.".format(filename, missing_client_files)) - for x in missing_client_files: + for x in missing_client_files: if x.endswith('/'): search_dir= os.path.dirname(x[:-1]) + '/' if search_dir not in missing_client_files: @@ -108,10 +108,10 @@ def _check_import(isamAppliance, filename): tempfilename = "template_files.zip" tempfile = os.path.join(tempdir, tempfilename) export_file(isamAppliance, tempfile) - + if os.path.exists(tempfile): identical = files_same_zip_content(filename,tempfile) - + shutil.rmtree(tempdir) if identical: logger.info("runtime template files {} are identical with the server content. No update necessary.".format(filename)) diff --git a/ibmsecurity/isam/aac/scim/enterprise_profile.py b/ibmsecurity/isam/aac/scim/enterprise_profile.py index e5c4ab12..554b50ba 100644 --- a/ibmsecurity/isam/aac/scim/enterprise_profile.py +++ b/ibmsecurity/isam/aac/scim/enterprise_profile.py @@ -59,4 +59,4 @@ def set(isamAppliance, mappings, check_mode=False, force=False): requires_version=requires_version ) - return isamAppliance.create_return_object(changed=False) \ No newline at end of file + return isamAppliance.create_return_object(changed=False) diff --git a/ibmsecurity/isam/aac/scim/general.py b/ibmsecurity/isam/aac/scim/general.py index c8a39e21..4d2d8118 100644 --- a/ibmsecurity/isam/aac/scim/general.py +++ b/ibmsecurity/isam/aac/scim/general.py @@ -79,4 +79,4 @@ def set(isamAppliance, enable_header_authentication=None, enable_authz_filter=No new_obj, requires_modules=requires_modules, requires_version=requires_version) - return isamAppliance.create_return_object(changed=False) \ No newline at end of file + return isamAppliance.create_return_object(changed=False) diff --git a/ibmsecurity/isam/aac/scim/group.py b/ibmsecurity/isam/aac/scim/group.py index 22e555b4..4a8f2623 100644 --- a/ibmsecurity/isam/aac/scim/group.py +++ b/ibmsecurity/isam/aac/scim/group.py @@ -53,4 +53,4 @@ def set(isamAppliance, ldap_object_classes, group_dn, check_mode=False, force=Fa requires_version=requires_version ) - return isamAppliance.create_return_object(changed=False) \ No newline at end of file + return isamAppliance.create_return_object(changed=False) diff --git a/ibmsecurity/isam/aac/scim/isam_user.py b/ibmsecurity/isam/aac/scim/isam_user.py index dad004b1..811fb6a7 100644 --- a/ibmsecurity/isam/aac/scim/isam_user.py +++ b/ibmsecurity/isam/aac/scim/isam_user.py @@ -104,4 +104,4 @@ def set(isamAppliance, ldap_connection=None, isam_domain=None, update_native_use new_obj, requires_modules=requires_modules, requires_version=requires_version) - return isamAppliance.create_return_object(changed=False) \ No newline at end of file + return isamAppliance.create_return_object(changed=False) diff --git a/ibmsecurity/isam/aac/scim/ldap_attrs.py b/ibmsecurity/isam/aac/scim/ldap_attrs.py index 7b49877c..9b375b69 100644 --- a/ibmsecurity/isam/aac/scim/ldap_attrs.py +++ b/ibmsecurity/isam/aac/scim/ldap_attrs.py @@ -27,4 +27,4 @@ def get(isamAppliance, ldap_connection, ldap_objectclasses=None, check_mode=Fals uri, ldap_connection, ldap_objectclasses), requires_modules=requires_modules, requires_version=requires_version - ) \ No newline at end of file + ) diff --git a/ibmsecurity/isam/aac/scim/ldap_objs.py b/ibmsecurity/isam/aac/scim/ldap_objs.py index 43d897d1..69dd2e1d 100644 --- a/ibmsecurity/isam/aac/scim/ldap_objs.py +++ b/ibmsecurity/isam/aac/scim/ldap_objs.py @@ -16,4 +16,4 @@ def get(isamAppliance, ldap_connection, check_mode=False, force=False): uri, ldap_connection), requires_modules=requires_modules, requires_version=requires_version - ) \ No newline at end of file + ) diff --git a/ibmsecurity/isam/aac/scim/mode.py b/ibmsecurity/isam/aac/scim/mode.py index 86499942..01b328dc 100644 --- a/ibmsecurity/isam/aac/scim/mode.py +++ b/ibmsecurity/isam/aac/scim/mode.py @@ -108,4 +108,4 @@ def reset(isamAppliance, schema_name, scim_attribute, scim_subattribute=None, ch requires_version=requires_version ) - return isamAppliance.create_return_object(changed=False) \ No newline at end of file + return isamAppliance.create_return_object(changed=False) diff --git a/ibmsecurity/isam/aac/scim/scim.py b/ibmsecurity/isam/aac/scim/scim.py index 524addcb..818c54ca 100644 --- a/ibmsecurity/isam/aac/scim/scim.py +++ b/ibmsecurity/isam/aac/scim/scim.py @@ -308,7 +308,7 @@ def _check(isamAppliance, settings): logger.debug("Comparing server scim configuration with desired configuration.") # Converting python ret_obj['data'] and settings from type dict to valid JSON (RFC 8259) # e.g. converts python boolean 'True' -> to JSON literal lowercase value 'true' - cur_json_string = json.dumps(ret_obj['data']) + cur_json_string = json.dumps(ret_obj['data']) cur_sorted_json = json_sort(cur_json_string) logger.debug("Server JSON : {0}".format(cur_sorted_json)) given_json_string = json.dumps(settings) diff --git a/ibmsecurity/isam/aac/scim/user_profile.py b/ibmsecurity/isam/aac/scim/user_profile.py index b9503b49..c683b618 100644 --- a/ibmsecurity/isam/aac/scim/user_profile.py +++ b/ibmsecurity/isam/aac/scim/user_profile.py @@ -69,4 +69,4 @@ def set(isamAppliance, ldap_connection, search_suffix, user_suffix, ldap_object_ new_obj, requires_modules=requires_modules, requires_version=requires_version) - return isamAppliance.create_return_object() \ No newline at end of file + return isamAppliance.create_return_object() diff --git a/ibmsecurity/isam/aac/scim_custom_schema_extensions.py b/ibmsecurity/isam/aac/scim_custom_schema_extensions.py index c8dcbb14..26b45777 100644 --- a/ibmsecurity/isam/aac/scim_custom_schema_extensions.py +++ b/ibmsecurity/isam/aac/scim_custom_schema_extensions.py @@ -235,4 +235,3 @@ def _check_exists(isamAppliance, urn, name): return True return False - diff --git a/ibmsecurity/isam/aac/server_connections/redis.py b/ibmsecurity/isam/aac/server_connections/redis.py index 1732515e..0939d211 100644 --- a/ibmsecurity/isam/aac/server_connections/redis.py +++ b/ibmsecurity/isam/aac/server_connections/redis.py @@ -232,4 +232,4 @@ def test(isamAppliance, name, check_mode=False, force=False): if check_mode is True: return isamAppliance.create_return_object() - return isamAppliance.invoke_get("Test Redis Connection", f"/iam/access/v8/testconnection/redis/{name}") \ No newline at end of file + return isamAppliance.invoke_get("Test Redis Connection", f"/iam/access/v8/testconnection/redis/{name}") diff --git a/ibmsecurity/isam/base/date_time.py b/ibmsecurity/isam/base/date_time.py index c7c33d71..b2c3102f 100644 --- a/ibmsecurity/isam/base/date_time.py +++ b/ibmsecurity/isam/base/date_time.py @@ -25,7 +25,7 @@ def set(isamAppliance, ntpServers="", timeZone="America/New_York", enableNtp=Fal """ Update date/time settings (set NTP server and timezone) """ - + if dateTime is None: dateTime = "0000-00-00 00:00:00" diff --git a/ibmsecurity/isam/base/ssl_certificates/certificate_databases.py b/ibmsecurity/isam/base/ssl_certificates/certificate_databases.py index f0a0ea92..8801c762 100644 --- a/ibmsecurity/isam/base/ssl_certificates/certificate_databases.py +++ b/ibmsecurity/isam/base/ssl_certificates/certificate_databases.py @@ -94,7 +94,7 @@ def import_db(isamAppliance, kdb, stash, zip=None, check_mode=False, force=False """ # Grab the filename to use as identifier (strip path and extension) import os.path - + tmpdir=None if zip != None: with zipfile.ZipFile(zip,"r") as zip_ref: @@ -102,13 +102,13 @@ def import_db(isamAppliance, kdb, stash, zip=None, check_mode=False, force=False zip_ref.extractall(tmpdir) kdb = tmpdir + '/' + kdb stash = tmpdir + '/' + stash - + kdb_id = os.path.basename(kdb) kdb_id = os.path.splitext(kdb_id)[0] try: if force is True or _check(isamAppliance, kdb_id) is False: - if check_mode is True: + if check_mode is True: return isamAppliance.create_return_object(changed=True) else: return isamAppliance.invoke_post_files( diff --git a/ibmsecurity/isam/base/ssl_certificates/certificate_requests.py b/ibmsecurity/isam/base/ssl_certificates/certificate_requests.py index 1d28c952..897ae61c 100644 --- a/ibmsecurity/isam/base/ssl_certificates/certificate_requests.py +++ b/ibmsecurity/isam/base/ssl_certificates/certificate_requests.py @@ -25,9 +25,9 @@ def add(isamAppliance, kdb_id, label, dn, size='1024', signature_algorithm='', c """ Creating a certificate request in a certificate database """ - + warnings = [] - + if signature_algorithm is not None: if ibmsecurity.utilities.tools.version_compare(isamAppliance.facts["version"], "9.0.2.0") < 0: warnings.append("Appliance at version: {0}, signature_algorithm is not supported. Needs 9.0.2.0 or higher. " @@ -44,12 +44,12 @@ def add(isamAppliance, kdb_id, label, dn, size='1024', signature_algorithm='', c "size": size, "signature_algorithm": signature_algorithm } - + if force is True or _check(isamAppliance, kdb_id, label) is False: if check_mode is True: return isamAppliance.create_return_object(changed=True) else: - + return isamAppliance.invoke_post( "Creating a certificate request in a certificate database", "/isam/ssl_certificates/{0}/cert_request".format(kdb_id), diff --git a/ibmsecurity/isam/base/ssl_certificates/signer_certificate.py b/ibmsecurity/isam/base/ssl_certificates/signer_certificate.py index 793f50d7..2736c266 100644 --- a/ibmsecurity/isam/base/ssl_certificates/signer_certificate.py +++ b/ibmsecurity/isam/base/ssl_certificates/signer_certificate.py @@ -25,8 +25,8 @@ def get(isamAppliance, kdb_id, cert_id, check_mode=False, force=False): def load(isamAppliance, kdb_id, label, server, port, check_remote=False, check_mode=False, force=False): """ Load a certificate from a server - - check_remote controls if ansible should check remote certificate by retrieving it or simply by + + check_remote controls if ansible should check remote certificate by retrieving it or simply by checking for existence of the label in the kdb """ if check_remote: @@ -35,7 +35,7 @@ def load(isamAppliance, kdb_id, label, server, port, check_remote=False, check_m else: logger.debug("Check for existence of the label in the kdb. Use check_remote=True to switch to advanced remote certificate with appliance certificate checking.") tmp_check = _check(isamAppliance, kdb_id, label) - + if force is True or tmp_check is False: if check_mode is True: return isamAppliance.create_return_object(changed=True) diff --git a/ibmsecurity/isam/statistics.py b/ibmsecurity/isam/statistics.py index 57ac21a8..c343cbc4 100644 --- a/ibmsecurity/isam/statistics.py +++ b/ibmsecurity/isam/statistics.py @@ -43,7 +43,7 @@ def get_rp_throughput_summary(isamAppliance, date, duration, aspect, summary=Non tools.create_query_string(summary=summary, date=date, duration=duration, - aspect=aspect)), + aspect=aspect)), requires_model=requires_model, headers=headers) diff --git a/ibmsecurity/isam/web/authorization_server/logs.py b/ibmsecurity/isam/web/authorization_server/logs.py index 795b7b74..c93631fc 100644 --- a/ibmsecurity/isam/web/authorization_server/logs.py +++ b/ibmsecurity/isam/web/authorization_server/logs.py @@ -85,4 +85,4 @@ def _check(isamAppliance, id, file_id): logger.info("Found file_id '{0}'".format(file_id)) file_exists = True - return file_exists, warnings \ No newline at end of file + return file_exists, warnings diff --git a/ibmsecurity/isam/web/iag/export.py b/ibmsecurity/isam/web/iag/export.py index 5c6d1ea7..d3c5cfd6 100644 --- a/ibmsecurity/isam/web/iag/export.py +++ b/ibmsecurity/isam/web/iag/export.py @@ -71,4 +71,3 @@ def validate(isamAppliance, instance, junctions, features, check_mode=False, for else: logger.debug(f"Instance: {instance} does not exist, cannot export") return isamAppliance.create_return_object(warnings=f"Instance: {instance} does not exist, cannot export", rc=1) - diff --git a/ibmsecurity/isam/web/reverse_proxy/federation_configuration.py b/ibmsecurity/isam/web/reverse_proxy/federation_configuration.py index 22e16236..0e671791 100644 --- a/ibmsecurity/isam/web/reverse_proxy/federation_configuration.py +++ b/ibmsecurity/isam/web/reverse_proxy/federation_configuration.py @@ -39,11 +39,11 @@ def config(isamAppliance, instance_id, federation_id=None, federation_name=None, if federation_id == {}: logger.info("Federation {0}, not found. Skipping config.".format(federation_name)) return isamAppliance.create_return_object() - + if federation_id is None: logger.info("Required parameter federation_id missing. Skipping config.") return isamAppliance.create_return_object() - + if force is True or _check(isamAppliance, instance_id, federation_id) is False: if check_mode is True: return isamAppliance.create_return_object(changed=True) @@ -78,7 +78,7 @@ def unconfig(isamAppliance, instance_id, federation_id=None, federation_name=Non :param force: :return: """ - + if federation_name is not None: ret_obj = ibmsecurity.isam.fed.federations.search(isamAppliance, name=federation_name, check_mode=check_mode, force=force) @@ -87,11 +87,11 @@ def unconfig(isamAppliance, instance_id, federation_id=None, federation_name=Non if federation_id == {}: logger.info("Federation {0}, not found. Skipping config.".format(federation_name)) return isamAppliance.create_return_object() - + if federation_id is None: logger.info("Required parameter federation_id missing. Skipping config.") return isamAppliance.create_return_object() - + if force is True or _check(isamAppliance, instance_id, federation_id) is True: if check_mode is True: return isamAppliance.create_return_object(changed=True) diff --git a/ibmsecurity/isam/web/reverse_proxy/ivg_configuration.py b/ibmsecurity/isam/web/reverse_proxy/ivg_configuration.py index 7166967b..721462b9 100644 --- a/ibmsecurity/isam/web/reverse_proxy/ivg_configuration.py +++ b/ibmsecurity/isam/web/reverse_proxy/ivg_configuration.py @@ -7,7 +7,7 @@ requires_version = "10.0.2.0" -def config(isamAppliance, instance_id, junction="/ivg", mmfa=True, check_mode=False): +def config(isamAppliance, instance_id, junction="/ivg", mmfa=True, check_mode=False): """ IVG configuration for a reverse proxy instance @@ -32,4 +32,3 @@ def config(isamAppliance, instance_id, junction="/ivg", mmfa=True, check_mode=Fa requires_modules=requires_modules, requires_version=requires_version) return isamAppliance.create_return_object(warnings=warnings) - diff --git a/ibmsecurity/isam/web/reverse_proxy/junctions.py b/ibmsecurity/isam/web/reverse_proxy/junctions.py index 2843cbf6..2c220f4a 100644 --- a/ibmsecurity/isam/web/reverse_proxy/junctions.py +++ b/ibmsecurity/isam/web/reverse_proxy/junctions.py @@ -1041,4 +1041,3 @@ def junction_exists(isamAppliance, exist_jct, new_j): logger.debug("Junctions are found to be different. See JSON for difference.") __result = False return __result - diff --git a/ibmsecurity/isam/web/reverse_proxy/junctions_config.py b/ibmsecurity/isam/web/reverse_proxy/junctions_config.py index c2d0a551..db7e8301 100644 --- a/ibmsecurity/isam/web/reverse_proxy/junctions_config.py +++ b/ibmsecurity/isam/web/reverse_proxy/junctions_config.py @@ -16,4 +16,4 @@ 'operation_state': {'type': 'ignore'}, 'server_state': {'type': 'ignore'}, 'priority': {'type': 'number', 'min_version': "10.0.2.0"}, - 'server_cn': {'type': 'string', 'min_version': "10.0.2.0"}} \ No newline at end of file + 'server_cn': {'type': 'string', 'min_version': "10.0.2.0"}} diff --git a/ibmsecurity/isam/web/reverse_proxy/management_root/all.py b/ibmsecurity/isam/web/reverse_proxy/management_root/all.py index fbf761db..b604a94e 100644 --- a/ibmsecurity/isam/web/reverse_proxy/management_root/all.py +++ b/ibmsecurity/isam/web/reverse_proxy/management_root/all.py @@ -38,7 +38,7 @@ def import_zip(isamAppliance, instance_id, filename, delete_missing=False, check Feature delete_missing will compare import zip with server content and delete missing files in the import zip from server """ warnings = [] - + if force is True or _check_import(isamAppliance, instance_id, filename): if delete_missing is True: tempdir = get_random_temp_dir() @@ -60,7 +60,7 @@ def import_zip(isamAppliance, instance_id, filename, delete_missing=False, check if missing_client_files != []: logger.info("list all missing files in {}, which will be deleted on the server: {}.".format(filename, missing_client_files)) - for x in missing_client_files: + for x in missing_client_files: if x.endswith('/'): search_dir= os.path.dirname(x[:-1]) + '/' if search_dir not in missing_client_files: diff --git a/ibmsecurity/isam/web/reverse_proxy/oauth_configuration.py b/ibmsecurity/isam/web/reverse_proxy/oauth_configuration.py index b5fcb00b..4bf0074e 100644 --- a/ibmsecurity/isam/web/reverse_proxy/oauth_configuration.py +++ b/ibmsecurity/isam/web/reverse_proxy/oauth_configuration.py @@ -65,7 +65,7 @@ def config(isamAppliance, instance_id, hostname='127.0.0.1', port=443, username= "Appliance at version: {0}, fapi_compliant: {1} is not supported. Needs 10.0.0.0 or higher. Ignoring fapi_compliant for this call.".format( isamAppliance.facts["version"], fapi_compliant)) else: - json_data["fapi_compliant"] = fapi_compliant + json_data["fapi_compliant"] = fapi_compliant if check_mode is True: return isamAppliance.create_return_object(changed=True, warnings=warnings) else: diff --git a/ibmsecurity/isam/web/runtime/acl.py b/ibmsecurity/isam/web/runtime/acl.py index fca3bd76..420de100 100644 --- a/ibmsecurity/isam/web/runtime/acl.py +++ b/ibmsecurity/isam/web/runtime/acl.py @@ -67,7 +67,7 @@ def get_object_list(isamAppliance, isamUser, object=None, acl_name=None, acl_att return ret_obj -def compare(isamAppliance1, isamAppliance2, isamUser1, isamUser2, acl_attribute_name=None, acl_attribute_value=None, +def compare(isamAppliance1, isamAppliance2, isamUser1, isamUser2, acl_attribute_name=None, acl_attribute_value=None, admin_domain='Default'): """ Compare the list of ACLs between two appliances @@ -76,4 +76,3 @@ def compare(isamAppliance1, isamAppliance2, isamUser1, isamUser2, acl_attribute_ ret_obj2 = get_list(isamAppliance2, isamUser2, acl_attribute_name, acl_attribute_value, admin_domain=admin_domain) return ibmsecurity.utilities.tools.json_compare(ret_obj1, ret_obj2) - \ No newline at end of file diff --git a/ibmsecurity/isvg/appliance.py b/ibmsecurity/isvg/appliance.py index f05448b7..fc280451 100644 --- a/ibmsecurity/isvg/appliance.py +++ b/ibmsecurity/isvg/appliance.py @@ -19,7 +19,7 @@ def reboot(isvgAppliance, check_mode=False, force=False): before_reboot_last_boot = firm['last_boot'] logger.info( "Active partition last boot time {0} before reboot process initiated.".format(before_reboot_last_boot)) - + ret_obj = isvgAppliance.invoke_post("Rebooting appliance", "/diagnostics/restart_shutdown/reboot", {}) @@ -41,7 +41,7 @@ def reboot(isvgAppliance, check_mode=False, force=False): except Exception as e: logger.debug("Exception occured: {0}. Assuming appliance has now initiated reboot process".format(e)) pass - + return ret_obj diff --git a/ibmsecurity/isvg/available_updates.py b/ibmsecurity/isvg/available_updates.py index 7f8b18fd..c0400aa7 100644 --- a/ibmsecurity/isvg/available_updates.py +++ b/ibmsecurity/isvg/available_updates.py @@ -123,7 +123,7 @@ def install(isvgAppliance, type, version, release_date, name, check_mode=False, before_install_last_boot = firm['last_boot'] logger.info( "Active partition last boot time {0} before firmware installation.".format(before_install_last_boot)) - + # proceed with firmware installation ret_obj = isvgAppliance.invoke_post("Install Available Update", "/updates/available/install", @@ -137,7 +137,7 @@ def install(isvgAppliance, type, version, release_date, name, check_mode=False, ] }) isvgAppliance.facts['version'] = version - + # isvg appliance has so much work to do after installing the firmware, it can take up # to several minutes before it reboots by itself. # Loop until appliance returns an error, or reboot is detected, before returning control. @@ -155,7 +155,7 @@ def install(isvgAppliance, type, version, release_date, name, check_mode=False, except Exception as e: logger.debug("Exception occured: {0}. Assuming appliance has now initiated reboot process".format(e)) pass - + return ret_obj return isvgAppliance.create_return_object() diff --git a/ibmsecurity/isvg/certstore_personal.py b/ibmsecurity/isvg/certstore_personal.py index 4041bacb..5d8338a2 100644 --- a/ibmsecurity/isvg/certstore_personal.py +++ b/ibmsecurity/isvg/certstore_personal.py @@ -29,7 +29,7 @@ def search(isvgAppliance, label, check_mode=False, force=False): break return return_obj - + def upload(isvgAppliance, db, type, password, label="lmi", check_mode=False, force=False): """ diff --git a/ibmsecurity/isvg/certstore_signer.py b/ibmsecurity/isvg/certstore_signer.py index d00f9524..902c13a4 100644 --- a/ibmsecurity/isvg/certstore_signer.py +++ b/ibmsecurity/isvg/certstore_signer.py @@ -29,7 +29,7 @@ def search(isvgAppliance, subject, check_mode=False, force=False): break return return_obj - + def upload(isvgAppliance, certificate, subject, label, check_mode=False, force=False): """ diff --git a/ibmsecurity/isvg/cm/process.py b/ibmsecurity/isvg/cm/process.py index e1ad3f52..de2134da 100644 --- a/ibmsecurity/isvg/cm/process.py +++ b/ibmsecurity/isvg/cm/process.py @@ -38,7 +38,7 @@ def _check(isvgAppliance, operation): """ ret_obj = notifications.get(isvgAppliance) warnings = ret_obj['warnings'] - + if ret_obj['rc'] == 0 and len(ret_obj['data']) > 0 and 'items' in ret_obj['data']: for item in ret_obj['data']['items']: # code not tested yet with the right message id @@ -51,4 +51,4 @@ def _check(isvgAppliance, operation): operation)) return False,warnings - return False,warnings + return False,warnings diff --git a/ibmsecurity/isvg/im/certstore_personal.py b/ibmsecurity/isvg/im/certstore_personal.py index a889c191..5d358392 100644 --- a/ibmsecurity/isvg/im/certstore_personal.py +++ b/ibmsecurity/isvg/im/certstore_personal.py @@ -26,7 +26,7 @@ def search(isvgAppliance, serial, check_mode=False, force=False): return_obj['rc'] = 0 return return_obj - + def upload(isvgAppliance, db, type, password, serial, check_mode=False, force=False): """ @@ -40,7 +40,7 @@ def upload(isvgAppliance, db, type, password, serial, check_mode=False, force=Fa return isvgAppliance.create_return_object(changed=True, warnings=warnings) else: ret_obj = isvgAppliance.invoke_post_files( - "Import personal certificate", + "Import personal certificate", "/upload_object", [ { diff --git a/ibmsecurity/isvg/im/certstore_signer.py b/ibmsecurity/isvg/im/certstore_signer.py index 8df96435..3b51c985 100644 --- a/ibmsecurity/isvg/im/certstore_signer.py +++ b/ibmsecurity/isvg/im/certstore_signer.py @@ -30,7 +30,7 @@ def search(isvgAppliance, label, check_mode=False, force=False): break return return_obj - + def upload(isvgAppliance, certificate, label, check_mode=False, force=False): """ @@ -89,7 +89,7 @@ def delete(isvgAppliance, certificate, check_mode=False, force=False): Delete signer certificate """ warnings = [] - + ret_obj = search(isvgAppliance, label, check_mode=check_mode, force=force) if force is True or ret_obj['data'] != {}: diff --git a/ibmsecurity/isvg/im/db.py b/ibmsecurity/isvg/im/db.py index b6f5a565..347013d3 100644 --- a/ibmsecurity/isvg/im/db.py +++ b/ibmsecurity/isvg/im/db.py @@ -52,7 +52,7 @@ def add(isvgAppliance, name, hostName, port, dbName, adminName, adminPwd, userNa "hostName": hostName, "port": port, "dbName": dbName, - "oracleLocationName": oracleLocationName, + "oracleLocationName": oracleLocationName, "adminName": adminName, "adminPwd": adminPwd, "userName": userName, @@ -108,7 +108,7 @@ def update(isvgAppliance, name, hostName, port, dbName, adminName, adminPwd, use # JSON payload of interest is at first (and only) position of array ret_obj['data'] = ret_obj['data'][0] - uuid = ret_obj['data']['uuid'] + uuid = ret_obj['data']['uuid'] needs_update = False @@ -117,14 +117,14 @@ def update(isvgAppliance, name, hostName, port, dbName, adminName, adminPwd, use "name": name, "uuid": uuid } - + if 'action' in ret_obj['data']: del ret_obj['data']['action'] if 'lastmodified' in ret_obj['data']: del ret_obj['data']['lastmodified'] if 'certCheckSum' in ret_obj['data']: del ret_obj['data']['certCheckSum'] - + # mandatory attributes if hostName is not None: json_data['hostName'] = hostName @@ -188,21 +188,21 @@ def update(isvgAppliance, name, hostName, port, dbName, adminName, adminPwd, use if ret_obj['data']['retryInterval'] is not None: json_data['retryInterval'] = ret_obj['data']['retryInterval'] else: - del ret_obj['data']['retryInterval'] + del ret_obj['data']['retryInterval'] if maximumRetries is not None: json_data['maximumRetries'] = maximumRetries elif 'maximumRetries' in ret_obj['data']: if ret_obj['data']['maximumRetries'] is not None: json_data['maximumRetries'] = ret_obj['data']['maximumRetries'] else: - del ret_obj['data']['maximumRetries'] + del ret_obj['data']['maximumRetries'] if oracleLocationName is not None: json_data['oracleLocationName'] = oracleLocationName elif 'oracleLocationName' in ret_obj['data']: if ret_obj['data']['oracleLocationName'] is not None: json_data['oracleLocationName'] = ret_obj['data']['oracleLocationName'] else: - del ret_obj['data']['oracleLocationName'] + del ret_obj['data']['oracleLocationName'] # optional attributes if dropTables is not None: json_data['dropTables'] = dropTables @@ -210,21 +210,21 @@ def update(isvgAppliance, name, hostName, port, dbName, adminName, adminPwd, use if ret_obj['data']['dropTables'] is not None: json_data['dropTables'] = ret_obj['data']['dropTables'] else: - del ret_obj['data']['dropTables'] + del ret_obj['data']['dropTables'] if useSSL is not None: json_data['useSSL'] = useSSL elif 'useSSL' in ret_obj['data']: if ret_obj['data']['useSSL'] is not None: json_data['useSSL'] = ret_obj['data']['useSSL'] else: - del ret_obj['data']['useSSL'] + del ret_obj['data']['useSSL'] if altServerNames is not None: json_data['altServerNames'] = altServerNames elif 'altServerNames' in ret_obj['data']: if ret_obj['data']['altServerNames'] is not None: json_data['altServerNames'] = ret_obj['data']['altServerNames'] else: - del ret_obj['data']['altServerNames'] + del ret_obj['data']['altServerNames'] if altPortNumbers is not None: json_data['altPortNumbers'] = altPortNumbers elif 'altPortNumbers' in ret_obj['data']: diff --git a/ibmsecurity/isvg/im/external_library.py b/ibmsecurity/isvg/im/external_library.py index 9c124909..c014409b 100644 --- a/ibmsecurity/isvg/im/external_library.py +++ b/ibmsecurity/isvg/im/external_library.py @@ -29,7 +29,7 @@ def search(isvgAppliance, library, check_mode=False, force=False): break return return_obj - + def upload(isvgAppliance, library, check_mode=False, force=False): """ @@ -88,7 +88,7 @@ def delete(isvgAppliance, library, check_mode=False, force=False): Delete an existing external library """ warnings = [] - + ret_obj = search(isvgAppliance, library, check_mode=check_mode, force=force) if force is True or ret_obj['data'] != {}: diff --git a/ibmsecurity/isvg/im/jvm_property.py b/ibmsecurity/isvg/im/jvm_property.py index 06d51de1..f1293c35 100644 --- a/ibmsecurity/isvg/im/jvm_property.py +++ b/ibmsecurity/isvg/im/jvm_property.py @@ -23,7 +23,7 @@ def get(isvgAppliance, propertyName, check_mode=False, force=False): def search(isvgAppliance, propertyName, check_mode=False, force=False): """ - Search for existing property/value pair for a given file. + Search for existing property/value pair for a given file. Just care for presence of property, not its actual value. """ ret_obj = get(isvgAppliance, propertyName) diff --git a/ibmsecurity/isvg/im/keystore.py b/ibmsecurity/isvg/im/keystore.py index e2485b2e..1e811169 100644 --- a/ibmsecurity/isvg/im/keystore.py +++ b/ibmsecurity/isvg/im/keystore.py @@ -35,7 +35,7 @@ def search(isvgAppliance, keystore="itimKeystore.jceks", check_mode=False, force break return return_obj - + def upload(isvgAppliance, keystore, check_mode=False, force=False): """ diff --git a/ibmsecurity/isvg/im/ldap.py b/ibmsecurity/isvg/im/ldap.py index 97137ba0..d7dd9635 100644 --- a/ibmsecurity/isvg/im/ldap.py +++ b/ibmsecurity/isvg/im/ldap.py @@ -52,7 +52,7 @@ def add(isvgAppliance, hostName, port, bindDN, bindPwd, orgName, shortOrgName, d "hostName": hostName, "port": port, "bindDN": bindDN, - "bindPwd": bindPwd, + "bindPwd": bindPwd, "orgName": orgName, "shortOrgName": shortOrgName, "dnLocation": dnLocation, @@ -93,7 +93,7 @@ def update(isvgAppliance, hostName, port, bindDN, bindPwd, orgName, shortOrgName # JSON payload of interest is at first (and only) position of array ret_obj['data'] = ret_obj['data'][0] - uuid = ret_obj['data']['uuid'] + uuid = ret_obj['data']['uuid'] needs_update = False @@ -102,14 +102,14 @@ def update(isvgAppliance, hostName, port, bindDN, bindPwd, orgName, shortOrgName "name": "Identity User Registry", "uuid": uuid } - + if 'action' in ret_obj['data']: del ret_obj['data']['action'] if 'lastmodified' in ret_obj['data']: del ret_obj['data']['lastmodified'] if 'certCheckSum' in ret_obj['data']: del ret_obj['data']['certCheckSum'] - + # mandatory attributes if hostName is not None: json_data['hostName'] = hostName @@ -166,7 +166,7 @@ def update(isvgAppliance, hostName, port, bindDN, bindPwd, orgName, shortOrgName if ret_obj['data']['useSSL'] is not None: json_data['useSSL'] = ret_obj['data']['useSSL'] else: - del ret_obj['data']['useSSL'] + del ret_obj['data']['useSSL'] sorted_ret_obj = tools.json_sort(ret_obj['data']) sorted_json_data = tools.json_sort(json_data) diff --git a/ibmsecurity/isvg/im/mail.py b/ibmsecurity/isvg/im/mail.py index a92510d8..830f3912 100644 --- a/ibmsecurity/isvg/im/mail.py +++ b/ibmsecurity/isvg/im/mail.py @@ -85,7 +85,7 @@ def update(isvgAppliance, mailFrom, mailServer, mailUser, mailPwd, mailBaseUrl, # JSON payload of interest is at first (and only) position of array ret_obj['data'] = ret_obj['data'][0] - uuid = ret_obj['data']['uuid'] + uuid = ret_obj['data']['uuid'] needs_update = False @@ -94,12 +94,12 @@ def update(isvgAppliance, mailFrom, mailServer, mailUser, mailPwd, mailBaseUrl, "name": "Mail Configuration", "uuid": uuid } - + if 'lastModified' in ret_obj['data']: del ret_obj['data']['lastModified'] if 'certCheckSum' in ret_obj['data']: del ret_obj['data']['certCheckSum'] - + # mandatory attributes if mailFrom is not None: json_data['mailFrom'] = mailFrom diff --git a/ibmsecurity/isvg/im/nls.py b/ibmsecurity/isvg/im/nls.py index 18674de4..334154dd 100644 --- a/ibmsecurity/isvg/im/nls.py +++ b/ibmsecurity/isvg/im/nls.py @@ -37,7 +37,7 @@ def search(isvgAppliance, filename, check_mode=False, force=False): logger.debug("Found nls entry: {0}".format(return_obj)) return return_obj - + def upload(isvgAppliance, filename, check_mode=False, force=False): """ diff --git a/ibmsecurity/isvg/im/openid.py b/ibmsecurity/isvg/im/openid.py index 58da9a15..ffb7ec42 100644 --- a/ibmsecurity/isvg/im/openid.py +++ b/ibmsecurity/isvg/im/openid.py @@ -16,7 +16,7 @@ def get_all(isvgAppliance, check_mode=False, force=False): def search(isvgAppliance, name, check_mode=False, force=False): """ - Search for existing openid. + Search for existing openid. Just care for presence of openid, not its actual value. """ ret_obj = get_all(isvgAppliance) @@ -92,7 +92,7 @@ def update(isvgAppliance, name, clientID, secret, certAlias, domains, issuerIden ret_obj = search(isvgAppliance, name, check_mode=check_mode, force=force) warnings = ret_obj['warnings'] - uuid = ret_obj['data']['uuid'] + uuid = ret_obj['data']['uuid'] needs_update = False @@ -227,7 +227,7 @@ def update(isvgAppliance, name, clientID, secret, certAlias, domains, issuerIden return isvgAppliance.create_return_object(changed=True, warnings=warnings) else: return isvgAppliance.invoke_put( - "Update an existing openid entry", "{0}/{1}".format(uri, uuid), + "Update an existing openid entry", "{0}/{1}".format(uri, uuid), json_data, warnings=warnings) return isvgAppliance.create_return_object(warnings=warnings) diff --git a/ibmsecurity/isvg/im/process.py b/ibmsecurity/isvg/im/process.py index 11326403..3d3739f2 100644 --- a/ibmsecurity/isvg/im/process.py +++ b/ibmsecurity/isvg/im/process.py @@ -51,4 +51,4 @@ def _check(isvgAppliance, operation): operation)) return False,warnings - return False,warnings \ No newline at end of file + return False,warnings diff --git a/ibmsecurity/isvg/im/property.py b/ibmsecurity/isvg/im/property.py index 6b0a1c65..9c18f3d4 100644 --- a/ibmsecurity/isvg/im/property.py +++ b/ibmsecurity/isvg/im/property.py @@ -21,7 +21,7 @@ def get_all(isvgAppliance, propertyFile, check_mode=False, force=False): return isvgAppliance.invoke_get("Retrieve all property/value pair for a given file", "{0}?PropertyFile={1}".format(uri, propertyFile)) -def get(isvgAppliance, propertyFile, propertyName, check_mode=False, force=False): +def get(isvgAppliance, propertyFile, propertyName, check_mode=False, force=False): """ Retrieve specific property/value pair for a given property file """ @@ -37,7 +37,7 @@ def get(isvgAppliance, propertyFile, propertyName, check_mode=False, force=False def search(isvgAppliance, propertyFile, propertyName, check_mode=False, force=False): """ - Search for existing property/value pair for a given file. + Search for existing property/value pair for a given file. Just care for presence of property, not its actual value. """ ret_obj = get(isvgAppliance, propertyFile=propertyFile, propertyName=propertyName) diff --git a/ibmsecurity/isvg/im/workflowextension.py b/ibmsecurity/isvg/im/workflowextension.py index 459082cf..56bf86c6 100644 --- a/ibmsecurity/isvg/im/workflowextension.py +++ b/ibmsecurity/isvg/im/workflowextension.py @@ -16,7 +16,7 @@ def get_all(isvgAppliance, check_mode=False, force=False): def search(isvgAppliance, name, check_mode=False, force=False): """ - Search for existing extension. + Search for existing extension. Just care for presence of extension, not its actual content. """ ret_obj = get_all(isvgAppliance) @@ -93,7 +93,7 @@ def update(isvgAppliance, name, extension, check_mode=False, force=False): # extension content must be on a single line content = open(extension).read().replace('\n', '') - + needs_update = True if ret_obj['data'] != {}: if ret_obj['data']['extension'] == content: diff --git a/ibmsecurity/isvg/interfaces.py b/ibmsecurity/isvg/interfaces.py index 8ab309d8..b38efb44 100644 --- a/ibmsecurity/isvg/interfaces.py +++ b/ibmsecurity/isvg/interfaces.py @@ -50,4 +50,4 @@ def _check(isvgAppliance, address, netmask, network_type, ipFqdn, gateway, inter check_value = True break - return check_value \ No newline at end of file + return check_value diff --git a/ibmsecurity/isvg/lmi.py b/ibmsecurity/isvg/lmi.py index 52fa0af4..922b1608 100644 --- a/ibmsecurity/isvg/lmi.py +++ b/ibmsecurity/isvg/lmi.py @@ -41,4 +41,4 @@ def _check(isvgAppliance, operation): operation)) return False,warnings - return False,warnings \ No newline at end of file + return False,warnings diff --git a/ibmsecurity/isvg/lmi_auth.py b/ibmsecurity/isvg/lmi_auth.py index 548b25ba..a1fd1414 100644 --- a/ibmsecurity/isvg/lmi_auth.py +++ b/ibmsecurity/isvg/lmi_auth.py @@ -16,7 +16,7 @@ def get(isvgAppliance, check_mode=False, force=False): def search(isvgAppliance, name="LMI Authentication Registry", check_mode=False, force=False): """ - Search for existing LMI authentication configuration. + Search for existing LMI authentication configuration. """ ret_obj = get(isvgAppliance) return_obj = isvgAppliance.create_return_object() @@ -86,7 +86,7 @@ def update(isvgAppliance, hostName, port, dnLocation, userFilter, groupFilter, b # JSON payload of interest is at first (and only) position of array ret_obj['data'] = ret_obj['data'][0] - uuid = ret_obj['data']['uuid'] + uuid = ret_obj['data']['uuid'] needs_update = False @@ -95,10 +95,10 @@ def update(isvgAppliance, hostName, port, dnLocation, userFilter, groupFilter, b "name": "LMI Authentication Registry", "uuid": uuid } - + if 'lastModified' in ret_obj['data']: del ret_obj['data']['lastModified'] - + # mandatory attributes if hostName is not None: json_data['hostName'] = hostName diff --git a/ibmsecurity/isvg/management_authentication.py b/ibmsecurity/isvg/management_authentication.py index a1fea8ac..49899256 100644 --- a/ibmsecurity/isvg/management_authentication.py +++ b/ibmsecurity/isvg/management_authentication.py @@ -111,4 +111,4 @@ def compare(isvgAppliance1, isvgAppliance2): ret_obj1 = get(isvgAppliance1) ret_obj2 = get(isvgAppliance2) - return ibmsecurity.utilities.tools.json_compare(ret_obj1, ret_obj2, deleted_keys=[]) \ No newline at end of file + return ibmsecurity.utilities.tools.json_compare(ret_obj1, ret_obj2, deleted_keys=[]) diff --git a/ibmsecurity/isvg/management_ssl_certificate.py b/ibmsecurity/isvg/management_ssl_certificate.py index 26b1253f..ff9f0551 100644 --- a/ibmsecurity/isvg/management_ssl_certificate.py +++ b/ibmsecurity/isvg/management_ssl_certificate.py @@ -35,7 +35,7 @@ def set(isvgAppliance, certificate, password, check_mode=False, force=False): else: # # Create a new method isvgAppliance.invoke_post_file() in isvgAppliance to -# support the type of upload method required by /custfile_mgmt end-point that differs from +# support the type of upload method required by /custfile_mgmt end-point that differs from # other techniques used by other end-point /snapshort, available_updates, ... # # Ajust list of post data parameter as required diff --git a/ibmsecurity/isvg/sdi/process.py b/ibmsecurity/isvg/sdi/process.py index be35191c..be37631e 100644 --- a/ibmsecurity/isvg/sdi/process.py +++ b/ibmsecurity/isvg/sdi/process.py @@ -38,7 +38,7 @@ def _check(isvgAppliance, operation): """ ret_obj = notifications.get(isvgAppliance) warnings = ret_obj['warnings'] - + if ret_obj['rc'] == 0 and len(ret_obj['data']) > 0 and 'items' in ret_obj['data']: for item in ret_obj['data']['items']: # code not tested yet with the right message id @@ -51,4 +51,4 @@ def _check(isvgAppliance, operation): operation)) return False,warnings - return False,warnings + return False,warnings diff --git a/ibmsecurity/utilities/tools.py b/ibmsecurity/utilities/tools.py index 7323b5d6..45064bf0 100644 --- a/ibmsecurity/utilities/tools.py +++ b/ibmsecurity/utilities/tools.py @@ -203,7 +203,7 @@ def files_same_zip_content(original_file, new_file): logger.debug("Comparing original_file[{}] vs new_file[{}]".format(original_file, new_file)) z1 = zipfile.ZipFile(original_file) z2 = zipfile.ZipFile(new_file) - + if len(z1.infolist()) != len(z2.infolist()): logger.debug("number of archive elements differ: {} in {} vs {} from server".format(len(z1.infolist()), z1.filename, len(z2.infolist()))) identical = False From d6dfc31ba717948cbce55d92f7001471710119cf Mon Sep 17 00:00:00 2001 From: Tom Bosmans Date: Wed, 2 Apr 2025 17:09:39 +0200 Subject: [PATCH 09/54] fix: pre-commit update --- .pre-commit-config.yaml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index a6b57efa..24fb7238 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -17,11 +17,11 @@ repos: # hooks: # - id: flake8 # args: ["--ignore=E501"] -# - repo: https://github.com/PyCQA/pylint -# rev: v3.3.2 -# hooks: -# - id: pylint -# args: [ -# "-ry", -# "--exit-zero" -# ] + - repo: https://github.com/PyCQA/pylint + rev: v3.3.2 + hooks: + - id: pylint + args: [ + "-ry", + "--exit-zero" + ] From d8ce2bac6b5982dfc771d819c56b6589022d3bde Mon Sep 17 00:00:00 2001 From: Tom Bosmans Date: Wed, 2 Apr 2025 17:23:31 +0200 Subject: [PATCH 10/54] fix: pylint --- ibmsecurity/utilities/tools.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ibmsecurity/utilities/tools.py b/ibmsecurity/utilities/tools.py index 45064bf0..9e7caf4e 100644 --- a/ibmsecurity/utilities/tools.py +++ b/ibmsecurity/utilities/tools.py @@ -198,6 +198,7 @@ def files_same(original_file, new_file): else: return False + def files_same_zip_content(original_file, new_file): identical = True logger.debug("Comparing original_file[{}] vs new_file[{}]".format(original_file, new_file)) @@ -231,6 +232,7 @@ def files_same_zip_content(original_file, new_file): return identical + def get_random_temp_dir(): """ Create a temporary directory From a2004cc0bcc6f7ab1e69cbc0ad06440681153b28 Mon Sep 17 00:00:00 2001 From: Tom Bosmans Date: Wed, 2 Apr 2025 17:25:57 +0200 Subject: [PATCH 11/54] refactor: pyproject --- pyproject.toml | 253 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 252 insertions(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 10a40659..81379018 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,7 +7,7 @@ build-backend = "setuptools.build_meta" [project] name = "ibmsecurity" -version = "2025.3.28.0" +version = "2025.4.2.0" authors = [ { name="IBM", email="secorch@wwpdl.vnet.ibm.com" }, ] @@ -32,3 +32,254 @@ dependencies = [ [project.urls] "Homepage" = "https://github.com/IBM-Security/ibmsecurity" "Bug Tracker" = "https://github.com/IBM-Security/ibmsecurity/issues" + +[tool.pytest] +env_files = ".env" + +[tool.pytest.ini_options] +addopts = [ + "--import-mode=importlib", +] + +[tool.pylint.MASTER] +bad-names = [ + # spell-checker:ignore linenumber + "linenumber", # use lineno instead + "line_number" # use lineno instead +] +# pylint defaults + f,fh,v,id +good-names = ["i", "j", "k", "Run", "_", "f", "fh", "v", "id", "T"] +# Ignore as being generated: +ignore-paths = "^(examples|build|test/schemas/node_modules|.eggs|.cache|.direnv|.tox|src/ansiblelint/_version|.config/).*$" + +[tool.pylint.REPORTING] +output-format = "colorized" + +[tool.pylint.SUMMARY] +# We don't need the score spamming console, as we either pass or fail +score = "n" + +[tool.pylint.messages_control] +disable = [ + "unknown-option-value", + # https://gist.github.com/cidrblock/ec3412bacfeb34dbc2d334c1d53bef83 + "C0103", # invalid-name + "C0105", # typevar-name-incorrect-variance + "C0112", # empty-docstring / ruff D419 + "C0113", # unneeded-not / ruff SIM208 + "C0114", # missing-module-docstring / ruff D100 + "C0115", # missing-class-docstring / ruff D101 + "C0116", # missing-function-docstring / ruff D103 + "C0121", # singleton-comparison / ruff PLC0121 + "C0123", # unidiomatic-typecheck / ruff E721 + "C0131", # typevar-double-variance + "C0132", # typevar-name-mismatch + "C0198", # bad-docstring-quotes + "C0199", # docstring-first-line-empty + "C0201", # consider-iterating-dictionary + "C0202", # bad-classmethod-argument + "C0205", # single-string-used-for-slots / ruff PLC0205 + "C0208", # use-sequence-for-iteration / ruff PLC0208 + "C0301", # line-too-long + "C0303", # trailing-whitespace + "C0321", # multiple-statements + "C0410", # multiple-imports + "C0411", # wrong-import-order / ruff I001 + "C0412", # ungrouped-imports / ruff I001 + "C0413", # wrong-import-position / ruff E402 + "C0414", # useless-import-alias / ruff PLC0414 + "C0415", # import-outside-toplevel / ruff PLC0415 + "C0501", # consider-using-any-or-all / ruff PLC0501 + "C1901", # compare-to-empty-string / ruff PLC1901 + "C2201", # misplaced-comparison-constant / ruff SIM300 + "C2401", # non-ascii-name / ruff PLC2401 + "C2403", # non-ascii-module-import / ruff PLC2403 + "C2701", # import-private-name / ruff PLC2701 + "C2801", # unnecessary-dunder-call / ruff PLC2801 + "C3001", # unnecessary-lambda-assignment / ruff E731 + "C3002", # unnecessary-direct-lambda-call / ruff PLC3002 + # "E0001", # syntax-error / ruff E999 + "E0100", # init-is-generator / ruff PLE0100 + "E0101", # return-in-init / ruff PLE0101 + "E0102", # function-redefined / ruff F811 + "E0103", # not-in-loop / ruff PLE0103 + "E0104", # return-outside-function / ruff F706 + "E0105", # yield-outside-function / ruff F704 + "E0107", # nonexistent-operator / ruff B002 + "E0112", # too-many-star-expressions / ruff F622 + "E0115", # nonlocal-and-global / ruff PLE0115 + "E0116", # continue-in-finally / ruff PLE0116 + "E0117", # nonlocal-without-binding / ruff PLE0117 + "E0118", # used-prior-global-declaration / ruff PLE0118 + "E0211", # no-method-argument / ruff N805 + "E0213", # no-self-argument / ruff N805 + "E0237", # assigning-non-slot / ruff PLE0237 + "E0241", # duplicate-bases / ruff PLE0241 + "E0302", # unexpected-special-method-signature / ruff PLE0302 + "E0303", # invalid-length-returned / ruff PLE0303 + "E0304", # invalid-bool-returned / ruff PLE0304 + "E0305", # invalid-index-returned / ruff PLE0305 + "E0308", # invalid-bytes-returned / ruff PLE0308 + "E0309", # invalid-hash-returned / ruff PLE0309 + "E0402", # relative-beyond-top-level / ruff TID252 + "E0602", # undefined-variable / ruff F821 + "E0603", # undefined-all-variable / ruff F822 + "E0604", # invalid-all-object / ruff PLE0604 + "E0605", # invalid-all-format / ruff PLE0605 + "E0643", # potential-index-error / ruff PLE0643 + "E0704", # misplaced-bare-raise / ruff PLE0704 + "E0711", # notimplemented-raised / ruff F901 + "E1132", # repeated-keyword / ruff PLE1132 + "E1142", # await-outside-async / ruff PLE1142 + "E1205", # logging-too-many-args / ruff PLE1205 + "E1206", # logging-too-few-args / ruff PLE1206 + "E1300", # bad-format-character / ruff PLE1300 + "E1301", # truncated-format-string / ruff F501 + "E1302", # mixed-format-string / ruff F506 + "E1303", # format-needs-mapping / ruff F502 + "E1304", # missing-format-string-key / ruff F524 + "E1305", # too-many-format-args / ruff F522 + "E1306", # too-few-format-args / ruff F524 + "E1307", # bad-string-format-type / ruff PLE1307 + "E1310", # bad-str-strip-call / ruff PLE1310 + "E1519", # singledispatch-method / ruff PLE1519 + "E1520", # singledispatchmethod-function / ruff PLE5120 + "E1700", # yield-inside-async-function / ruff PLE1700 + "E2502", # bidirectional-unicode / ruff PLE2502 + "E2510", # invalid-character-backspace / ruff PLE2510 + "E2512", # invalid-character-sub / ruff PLE2512 + "E2513", # invalid-character-esc / ruff PLE2513 + "E2514", # invalid-character-nul / ruff PLE2514 + "E2515", # invalid-character-zero-width-space / ruff PLE2515 + "E4703", # modified-iterating-set / ruff PLE4703 + "R0123", # literal-comparison / ruff F632 + "R0124", # comparison-with-itself / ruff PLR0124 + "R0133", # comparison-of-constants / ruff PLR0133 + "R0202", # no-classmethod-decorator / ruff PLR0202 + "R0203", # no-staticmethod-decorator / ruff PLR0203 + "R0205", # useless-object-inheritance / ruff UP004 + "R0206", # property-with-parameters / ruff PLR0206 + "R0904", # too-many-public-methods / ruff PLR0904 + "R0911", # too-many-return-statements / ruff PLR0911 + "R0912", # too-many-branches / ruff PLR0912 + "R0913", # too-many-arguments / ruff PLR0913 + "R0914", # too-many-locals / ruff PLR0914 + "R0915", # too-many-statements / ruff PLR0915 + "R0916", # too-many-boolean-expressions / ruff PLR0916 + "R0917", # too-many-positional-arguments / ruff PLR0917 + "R1260", # too-complex / ruff C901 + "R1701", # consider-merging-isinstance / ruff PLR1701 + "R1702", # too-many-nested-blocks / ruff PLR1702 + "R1703", # simplifiable-if-statement / ruff SIM108 + "R1704", # redefined-argument-from-local / ruff PLR1704 + "R1705", # no-else-return / ruff RET505 + "R1706", # consider-using-ternary / ruff PLR1706 + "R1707", # trailing-comma-tuple / ruff COM818 + "R1710", # inconsistent-return-statements / ruff PLR1710 + "R1711", # useless-return + "R1714", # consider-using-in + "R1715", # consider-using-get + "R1717", # consider-using-dict-comprehension + "R1718", # consider-using-set-comprehension / ruff C401 + "R1719", # simplifiable-if-expression / ruff PLR1719 + "R1720", # no-else-raise + "R1721", # unnecessary-comprehension / ruff C416 + "R1722", # consider-using-sys-exit / ruff PLR1722 + "R1723", # no-else-break / ruff RET508 + "R1724", # no-else-continue / ruff RET507 + "R1725", # super-with-arguments / ruff UP008 + "R1728", # consider-using-generator / ruff C417 + "R1729", # use-a-generator / ruff C419 + "R1730", # consider-using-min-builtin / ruff PLR1730 + "R1731", # consider-using-max-builtin / ruff PLR1730 + "R1732", # consider-using-with / ruff SIM115 + "R1733", # unnecessary-dict-index-lookup / ruff PLR1733 + "R1734", # use-list-literal / ruff C405 + "R1735", # use-dict-literal / ruff C406 + "R1736", # unnecessary-list-index-lookup / ruff PLR1736 + "R2004", # magic-value-comparison / ruff PLR2004 + "R2044", # empty-comment / ruff PLR2044 + "R5501", # else-if-used / ruff PLR5501 + "R6002", # consider-using-alias / ruff UP006 + "R6003", # consider-alternative-union-syntax / ruff UP007 + "R6104", # consider-using-augmented-assign / ruff PLR6104 + "R6201", # use-set-for-membership / ruff PLR6201 + "R6301", # no-self-use / ruff PLR6301 + "W0102", # dangerous-default-value / ruff B006 + "W0104", # pointless-statement / ruff B018 + "W0106", # expression-not-assigned / ruff B018 + "W0107", # unnecessary-pass / ruff PIE790 + "W0108", # unnecessary-lambda / ruff PLW0108 + "W0109", # duplicate-key / ruff F601 + "W0120", # useless-else-on-loop / ruff PLW0120 + "W0122", # exec-used / ruff S102 + "W0123", # eval-used / ruff PGH001 + "W0127", # self-assigning-variable / ruff PLW0127 + "W0129", # assert-on-string-literal / ruff PLW0129 + "W0130", # duplicate-value / ruff B033 + "W0131", # named-expr-without-context / ruff PLW0131 + "W0133", # pointless-exception-statement / ruff PLW0133 + "W0150", # lost-exception / ruff B012 + "W0160", # consider-ternary-expression / ruff SIM108 + "W0177", # nan-comparison / ruff PLW0117 + "W0199", # assert-on-tuple / ruff F631 + "W0211", # bad-staticmethod-argument / ruff PLW0211 + "W0212", # protected-access / ruff SLF001 + "W0245", # super-without-brackets / ruff PLW0245 + "W0301", # unnecessary-semicolon / ruff E703 + "W0401", # wildcard-import / ruff F403 + "W0404", # reimported / ruff F811 + "W0406", # import-self / ruff PLW0406 + "W0410", # misplaced-future / ruff F404 + "W0602", # global-variable-not-assigned / ruff PLW0602 + "W0603", # global-statement / ruff PLW0603 + "W0604", # global-at-module-level / ruff PLW0604 + "W0611", # unused-import / ruff F401 + "W0612", # unused-variable / ruff F841 + "W0613", # unused-argument / ruff ARG001 + "W0622", # redefined-builtin / ruff A001 + "W0640", # cell-var-from-loop / ruff B023 + # "W0702", # bare-except + "W0705", # duplicate-except / ruff B014 + "W0706", # try-except-raise / ruff TRY302 + "W0707", # raise-missing-from / ruff TRY200 + "W0711", # binary-op-exception / ruff PLW0711 + "W0718", # broad-exception-caught / ruff PLW0718 + "W0719", # broad-exception-raised / ruff TRY002 + "W1113", # keyword-arg-before-vararg / ruff B026 + "W1201", # logging-not-lazy / ruff G + "W1202", # logging-format-interpolation / ruff G + "W1203", # logging-fstring-interpolation / ruff G + "W1300", # bad-format-string-key / ruff PLW1300 + "W1301", # unused-format-string-key / ruff F504 + "W1302", # bad-format-string / ruff PLW1302 + "W1303", # missing-format-argument-key / ruff F524 + "W1304", # unused-format-string-argument / ruff F507 + "W1305", # format-combined-specification / ruff F525 + "W1308", # duplicate-string-formatting-argument / ruff PLW1308 + "W1309", # f-string-without-interpolation / ruff F541 + "W1310", # format-string-without-interpolation / ruff F541 + "W1401", # anomalous-backslash-in-string / ruff W605 + "W1404", # implicit-str-concat / ruff ISC001 + "W1405", # inconsistent-quotes / ruff Q000 + "W1406", # redundant-u-string-prefix / ruff UP025 + "W1501", # bad-open-mode / ruff PLW1501 + "W1508", # invalid-envvar-default / ruff PLW1508 + "W1509", # subprocess-popen-preexec-fn / ruff PLW1509 + "W1510", # subprocess-run-check / ruff PLW1510 + "W1514", # unspecified-encoding / ruff PLW1514 + "W1515", # forgotten-debug-statement / ruff T100 + "W1518", # method-cache-max-size-none / ruff B019 + "W1641", # eq-without-hash / ruff PLW1641 + "W2101", # useless-with-lock / ruff PLW2101 + # "W2402", # non-ascii-file-name / ruff N999 + "W2901", # redefined-loop-name / ruff PLW2901 + "W3201", # bad-dunder-name / ruff PLW3201 + "W3301", # nested-min-max / ruff PLW3301 + "duplicate-code", + "fixme", + "too-few-public-methods", + "too-many-instance-attributes" +] +# increase from default is 50 which is too aggressive +max-statements = 60 From 724300699352231820c68cf8a2e9668f0738891b Mon Sep 17 00:00:00 2001 From: Tom Bosmans Date: Wed, 2 Apr 2025 17:29:16 +0200 Subject: [PATCH 12/54] refactor: pyproject --- pyproject.toml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 81379018..6373e871 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -206,12 +206,12 @@ disable = [ "R6201", # use-set-for-membership / ruff PLR6201 "R6301", # no-self-use / ruff PLR6301 "W0102", # dangerous-default-value / ruff B006 - "W0104", # pointless-statement / ruff B018 + # "W0104", # pointless-statement / ruff B018 "W0106", # expression-not-assigned / ruff B018 "W0107", # unnecessary-pass / ruff PIE790 "W0108", # unnecessary-lambda / ruff PLW0108 - "W0109", # duplicate-key / ruff F601 - "W0120", # useless-else-on-loop / ruff PLW0120 + # "W0109", # duplicate-key + # "W0120", # useless-else-on-loop / ruff PLW0120 "W0122", # exec-used / ruff S102 "W0123", # eval-used / ruff PGH001 "W0127", # self-assigning-variable / ruff PLW0127 @@ -222,13 +222,13 @@ disable = [ "W0150", # lost-exception / ruff B012 "W0160", # consider-ternary-expression / ruff SIM108 "W0177", # nan-comparison / ruff PLW0117 - "W0199", # assert-on-tuple / ruff F631 + # "W0199", # assert-on-tuple / ruff F631 "W0211", # bad-staticmethod-argument / ruff PLW0211 "W0212", # protected-access / ruff SLF001 "W0245", # super-without-brackets / ruff PLW0245 "W0301", # unnecessary-semicolon / ruff E703 "W0401", # wildcard-import / ruff F403 - "W0404", # reimported / ruff F811 + # "W0404", # reimported / ruff F811 "W0406", # import-self / ruff PLW0406 "W0410", # misplaced-future / ruff F404 "W0602", # global-variable-not-assigned / ruff PLW0602 From 134d4ffaf6cd015f0d0fc12eae6ec210cb2b9892 Mon Sep 17 00:00:00 2001 From: Tom Bosmans Date: Fri, 4 Apr 2025 14:01:26 +0200 Subject: [PATCH 13/54] documentation: start with documentation --- docs/contributing.md | 65 ++++++++++++++++++++++++++++++++++++++++++++ docs/index.md | 12 ++++++++ mkdocs.yml | 21 ++++++++++++++ 3 files changed, 98 insertions(+) create mode 100644 docs/contributing.md create mode 100644 docs/index.md create mode 100644 mkdocs.yml diff --git a/docs/contributing.md b/docs/contributing.md new file mode 100644 index 00000000..edfb679a --- /dev/null +++ b/docs/contributing.md @@ -0,0 +1,65 @@ +# Contributing to ibmsecurity WIP + +To contribute to ibmsecurity, please use pull requests on a branch of your own +fork. + +After [creating your fork on GitHub], you can do: + +```shell-session +$ git clone --recursive git@github.com:your-name/ibmsecurity +$ cd ibmsecurity +$ # Recommended: Initialize and activate a Python virtual environment +$ pip install --upgrade pip +$ pip install -e '.[test]' # Install testing dependencies +$ tox run -e lint +$ git checkout -b your-branch-name +# DO SOME CODING HERE +$ tox run -e lint +$ git add your new files +$ git commit -v +$ git push origin your-branch-name +``` + +You will then be able to create a pull request from your commit. + +Feel free to raise issues in the repo if you feel unable to contribute a code +fix. + +## Setup + +### Local appliance + +There is no mock code for testing, unfortunately. +So you need a running IBM Verify Access/IBM Identity Verify Access appliance or container to be able to run the tests. + +### Env + +Create a .env file in the root directory of the project, with the details to connect to your IVIA appliance, for instance : + +````properties +IVIA_ADMIN=admin@local +IVIA_PW=admin +IVIA_HOST= +# IVIA_PORT = 80 +```` + +## Standards + +Automated tests will be run against all PRs, to run checks locally before +pushing commits, just use [tox](https://tox.wiki/en/latest/). + +## Talk to us + + +## Code of Conduct + + + +## Module dependency graph + + + +## Documentation changes + +To build the docs, run `tox -e docs`. At the end of the build, you will see the +local location of your built docs. diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 00000000..5924d452 --- /dev/null +++ b/docs/index.md @@ -0,0 +1,12 @@ +# IBMSecurity Documentation + +## THIS IS WORK IN PROGRESS + +## About ibmsecurity + +This repository contains Python code to manage IBM Security Appliances using their respective REST APIs. +ISAM appliance has the most mature code. + +Code for ISDS appliance is under development. + +Code for ISVG appliance is brand new (tested with 10.0.1.0 and higher only). diff --git a/mkdocs.yml b/mkdocs.yml new file mode 100644 index 00000000..4d01abe1 --- /dev/null +++ b/mkdocs.yml @@ -0,0 +1,21 @@ +--- +site_name: ibmsecurity +site_url: https://ibmsecurity.readthedocs.io/projects/ +repo_url: https://github.com/IBM-Security/ibmsecurity +edit_uri: blob/main/docs/ +copyright: Copyright © IBM +docs_dir: docs +strict: true + + +extra: + social: + - icon: fontawesome/brands/github-alt + link: https://github.com/IBM-Security/ibmsecurity + name: GitHub + +nav: + - Home: + - home: index.md + - Developer Guide: + - Contributing: contributing.md From 7cdfd660233c9e12fb819f4f3587a820e56efd24 Mon Sep 17 00:00:00 2001 From: Tom Bosmans Date: Fri, 4 Apr 2025 14:02:05 +0200 Subject: [PATCH 14/54] refactor: setup build and test WIP --- .config/requirements-docs.in | 6 + .config/requirements-test.in | 22 ++ .config/requirements.in | 11 + pyproject.toml | 406 +++++++++++++++++------------------ tox.ini | 84 ++------ 5 files changed, 256 insertions(+), 273 deletions(-) create mode 100644 .config/requirements-docs.in create mode 100644 .config/requirements-test.in create mode 100644 .config/requirements.in diff --git a/.config/requirements-docs.in b/.config/requirements-docs.in new file mode 100644 index 00000000..e2e1333e --- /dev/null +++ b/.config/requirements-docs.in @@ -0,0 +1,6 @@ +mkdocs +mkdocs-material +markdown-exec +mkdocstrings +pymdown-extensions +markdown_include diff --git a/.config/requirements-test.in b/.config/requirements-test.in new file mode 100644 index 00000000..a3fb44d1 --- /dev/null +++ b/.config/requirements-test.in @@ -0,0 +1,22 @@ +black # IDE support +coverage-enable-subprocess # see https://github.com/nedbat/coveragepy/issues/1341#issuecomment-1228942657 +coverage[toml] >= 6.4.4 +jmespath +license-expression >= 30.3.0 # Apache 2.0 +mypy # IDE support +netaddr # needed by ipwrap filter +pip # tox command +psutil # soft-dep of pytest-xdist +pylint # IDE support +pytest >= 7.2.2 +pytest-instafail >= 0.5.0 # only for local development, via PYTEST_ADDOPTS=-edit +pytest-mock +pytest-dotenv +pytest-sugar # shows failures immediately, even with xdist +pytest-xdist[psutil,setproctitle] >= 2.1.0 +tox >= 4.0.0 +tox-extra>=2.1 +tox-uv>=1.25 +tox>=4.24.2 +types-jsonschema # IDE support +types-pyyaml # IDE support diff --git a/.config/requirements.in b/.config/requirements.in new file mode 100644 index 00000000..54dcaeb0 --- /dev/null +++ b/.config/requirements.in @@ -0,0 +1,11 @@ +# alphabetically sorted: +black>=24.3.0 # MIT (security) +filelock>=3.8.2 # The Unlicense +importlib-metadata # Apache +jsonschema>=4.10.0 # MIT, version needed for improved errors +packaging>=22.0 # Apache-2.0,BSD-2-Clause +pathspec>=0.10.3 # Mozilla Public License 2.0 (MPL 2.0) +pyyaml>=6.0.2 # MIT (compilation probles with older versions) +requests +jmespath>=1.0.0 +PyYAML diff --git a/pyproject.toml b/pyproject.toml index 6373e871..5a2db7dc 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -23,16 +23,17 @@ classifiers = [ "Intended Audience :: System Administrators", "Topic :: Software Development :: Build Tools" ] -dependencies = [ - "requests", - "jmespath>=1.0.0", - "PyYAML" -] +dynamic = ["dependencies", "optional-dependencies"] [project.urls] "Homepage" = "https://github.com/IBM-Security/ibmsecurity" "Bug Tracker" = "https://github.com/IBM-Security/ibmsecurity/issues" +[tool.setuptools.dynamic] +dependencies = {file = [".config/requirements.in"]} +optional-dependencies.docs = {file = [".config/requirements-docs.in"]} +optional-dependencies.test = {file = [".config/requirements-test.in"]} + [tool.pytest] env_files = ".env" @@ -50,7 +51,7 @@ bad-names = [ # pylint defaults + f,fh,v,id good-names = ["i", "j", "k", "Run", "_", "f", "fh", "v", "id", "T"] # Ignore as being generated: -ignore-paths = "^(examples|build|test/schemas/node_modules|.eggs|.cache|.direnv|.tox|src/ansiblelint/_version|.config/).*$" +ignore-paths = "^(examples|build|test/schemas/node_modules|.eggs|.cache|.direnv|.tox|.config/).*$" [tool.pylint.REPORTING] output-format = "colorized" @@ -62,220 +63,219 @@ score = "n" [tool.pylint.messages_control] disable = [ "unknown-option-value", - # https://gist.github.com/cidrblock/ec3412bacfeb34dbc2d334c1d53bef83 "C0103", # invalid-name "C0105", # typevar-name-incorrect-variance - "C0112", # empty-docstring / ruff D419 - "C0113", # unneeded-not / ruff SIM208 - "C0114", # missing-module-docstring / ruff D100 - "C0115", # missing-class-docstring / ruff D101 - "C0116", # missing-function-docstring / ruff D103 - "C0121", # singleton-comparison / ruff PLC0121 - "C0123", # unidiomatic-typecheck / ruff E721 + "C0112", # empty-docstring + "C0113", # unneeded-not + "C0114", # missing-module-docstring + "C0115", # missing-class-docstring + "C0116", # missing-function-docstring + "C0121", # singleton-comparison + "C0123", # unidiomatic-typecheck "C0131", # typevar-double-variance "C0132", # typevar-name-mismatch "C0198", # bad-docstring-quotes "C0199", # docstring-first-line-empty "C0201", # consider-iterating-dictionary "C0202", # bad-classmethod-argument - "C0205", # single-string-used-for-slots / ruff PLC0205 - "C0208", # use-sequence-for-iteration / ruff PLC0208 + "C0205", # single-string-used-for-slots + "C0208", # use-sequence-for-iteration "C0301", # line-too-long "C0303", # trailing-whitespace "C0321", # multiple-statements "C0410", # multiple-imports - "C0411", # wrong-import-order / ruff I001 - "C0412", # ungrouped-imports / ruff I001 - "C0413", # wrong-import-position / ruff E402 - "C0414", # useless-import-alias / ruff PLC0414 - "C0415", # import-outside-toplevel / ruff PLC0415 - "C0501", # consider-using-any-or-all / ruff PLC0501 - "C1901", # compare-to-empty-string / ruff PLC1901 - "C2201", # misplaced-comparison-constant / ruff SIM300 - "C2401", # non-ascii-name / ruff PLC2401 - "C2403", # non-ascii-module-import / ruff PLC2403 - "C2701", # import-private-name / ruff PLC2701 - "C2801", # unnecessary-dunder-call / ruff PLC2801 - "C3001", # unnecessary-lambda-assignment / ruff E731 - "C3002", # unnecessary-direct-lambda-call / ruff PLC3002 - # "E0001", # syntax-error / ruff E999 - "E0100", # init-is-generator / ruff PLE0100 - "E0101", # return-in-init / ruff PLE0101 - "E0102", # function-redefined / ruff F811 - "E0103", # not-in-loop / ruff PLE0103 - "E0104", # return-outside-function / ruff F706 - "E0105", # yield-outside-function / ruff F704 - "E0107", # nonexistent-operator / ruff B002 - "E0112", # too-many-star-expressions / ruff F622 - "E0115", # nonlocal-and-global / ruff PLE0115 - "E0116", # continue-in-finally / ruff PLE0116 - "E0117", # nonlocal-without-binding / ruff PLE0117 - "E0118", # used-prior-global-declaration / ruff PLE0118 - "E0211", # no-method-argument / ruff N805 - "E0213", # no-self-argument / ruff N805 - "E0237", # assigning-non-slot / ruff PLE0237 - "E0241", # duplicate-bases / ruff PLE0241 - "E0302", # unexpected-special-method-signature / ruff PLE0302 - "E0303", # invalid-length-returned / ruff PLE0303 - "E0304", # invalid-bool-returned / ruff PLE0304 - "E0305", # invalid-index-returned / ruff PLE0305 - "E0308", # invalid-bytes-returned / ruff PLE0308 - "E0309", # invalid-hash-returned / ruff PLE0309 - "E0402", # relative-beyond-top-level / ruff TID252 - "E0602", # undefined-variable / ruff F821 - "E0603", # undefined-all-variable / ruff F822 - "E0604", # invalid-all-object / ruff PLE0604 - "E0605", # invalid-all-format / ruff PLE0605 - "E0643", # potential-index-error / ruff PLE0643 - "E0704", # misplaced-bare-raise / ruff PLE0704 - "E0711", # notimplemented-raised / ruff F901 - "E1132", # repeated-keyword / ruff PLE1132 - "E1142", # await-outside-async / ruff PLE1142 - "E1205", # logging-too-many-args / ruff PLE1205 - "E1206", # logging-too-few-args / ruff PLE1206 - "E1300", # bad-format-character / ruff PLE1300 - "E1301", # truncated-format-string / ruff F501 - "E1302", # mixed-format-string / ruff F506 - "E1303", # format-needs-mapping / ruff F502 - "E1304", # missing-format-string-key / ruff F524 - "E1305", # too-many-format-args / ruff F522 - "E1306", # too-few-format-args / ruff F524 - "E1307", # bad-string-format-type / ruff PLE1307 - "E1310", # bad-str-strip-call / ruff PLE1310 - "E1519", # singledispatch-method / ruff PLE1519 - "E1520", # singledispatchmethod-function / ruff PLE5120 - "E1700", # yield-inside-async-function / ruff PLE1700 - "E2502", # bidirectional-unicode / ruff PLE2502 - "E2510", # invalid-character-backspace / ruff PLE2510 - "E2512", # invalid-character-sub / ruff PLE2512 - "E2513", # invalid-character-esc / ruff PLE2513 - "E2514", # invalid-character-nul / ruff PLE2514 - "E2515", # invalid-character-zero-width-space / ruff PLE2515 - "E4703", # modified-iterating-set / ruff PLE4703 - "R0123", # literal-comparison / ruff F632 - "R0124", # comparison-with-itself / ruff PLR0124 - "R0133", # comparison-of-constants / ruff PLR0133 - "R0202", # no-classmethod-decorator / ruff PLR0202 - "R0203", # no-staticmethod-decorator / ruff PLR0203 - "R0205", # useless-object-inheritance / ruff UP004 - "R0206", # property-with-parameters / ruff PLR0206 - "R0904", # too-many-public-methods / ruff PLR0904 - "R0911", # too-many-return-statements / ruff PLR0911 - "R0912", # too-many-branches / ruff PLR0912 - "R0913", # too-many-arguments / ruff PLR0913 - "R0914", # too-many-locals / ruff PLR0914 - "R0915", # too-many-statements / ruff PLR0915 - "R0916", # too-many-boolean-expressions / ruff PLR0916 - "R0917", # too-many-positional-arguments / ruff PLR0917 - "R1260", # too-complex / ruff C901 - "R1701", # consider-merging-isinstance / ruff PLR1701 - "R1702", # too-many-nested-blocks / ruff PLR1702 - "R1703", # simplifiable-if-statement / ruff SIM108 - "R1704", # redefined-argument-from-local / ruff PLR1704 - "R1705", # no-else-return / ruff RET505 - "R1706", # consider-using-ternary / ruff PLR1706 - "R1707", # trailing-comma-tuple / ruff COM818 - "R1710", # inconsistent-return-statements / ruff PLR1710 + "C0411", # wrong-import-order + "C0412", # ungrouped-imports + "C0413", # wrong-import-position + "C0414", # useless-import-alias + "C0415", # import-outside-toplevel + "C0501", # consider-using-any-or-all + "C1901", # compare-to-empty-string + "C2201", # misplaced-comparison-constant + "C2401", # non-ascii-name + "C2403", # non-ascii-module-import + "C2701", # import-private-name + "C2801", # unnecessary-dunder-call + "C3001", # unnecessary-lambda-assignment + "C3002", # unnecessary-direct-lambda-call + "E0001", # syntax-error + "E0100", # init-is-generator + "E0101", # return-in-init + "E0102", # function-redefined + "E0103", # not-in-loop + "E0104", # return-outside-function + "E0105", # yield-outside-function + "E0107", # nonexistent-operator + "E0112", # too-many-star-expressions + "E0115", # nonlocal-and-global + "E0116", # continue-in-finally + "E0117", # nonlocal-without-binding + "E0118", # used-prior-global-declaration + "E0211", # no-method-argument + "E0213", # no-self-argument + "E0237", # assigning-non-slot + "E0241", # duplicate-bases + "E0302", # unexpected-special-method-signature + "E0303", # invalid-length-returned + "E0304", # invalid-bool-returned + "E0305", # invalid-index-returned + "E0308", # invalid-bytes-returned + "E0309", # invalid-hash-returned + "E0402", # relative-beyond-top-level + "E0602", # undefined-variable + "E0603", # undefined-all-variable + "E0604", # invalid-all-object + "E0605", # invalid-all-format + "E0643", # potential-index-error + "E0704", # misplaced-bare-raise + "E0711", # notimplemented-raised + "E1132", # repeated-keyword + "E1142", # await-outside-async + "E1205", # logging-too-many-args + "E1206", # logging-too-few-args + "E1300", # bad-format-character + "E1301", # truncated-format-string + "E1302", # mixed-format-string + "E1303", # format-needs-mapping + "E1304", # missing-format-string-key + "E1305", # too-many-format-args + "E1306", # too-few-format-args + "E1307", # bad-string-format-type + "E1310", # bad-str-strip-call + "E1519", # singledispatch-method + "E1520", # singledispatchmethod-function + "E1700", # yield-inside-async-function + "E2502", # bidirectional-unicode + "E2510", # invalid-character-backspace + "E2512", # invalid-character-sub + "E2513", # invalid-character-esc + "E2514", # invalid-character-nul + "E2515", # invalid-character-zero-width-space + "E4703", # modified-iterating-set + "R0123", # literal-comparison + "R0124", # comparison-with-itself + "R0133", # comparison-of-constants + "R0202", # no-classmethod-decorator + "R0203", # no-staticmethod-decorator + "R0205", # useless-object-inheritance + "R0206", # property-with-parameters + "R0904", # too-many-public-methods + "R0911", # too-many-return-statements + "R0912", # too-many-branches + "R0913", # too-many-arguments + "R0914", # too-many-locals + "R0915", # too-many-statements + "R0916", # too-many-boolean-expressions + "R0917", # too-many-positional-arguments + "R1260", # too-complex + "R1701", # consider-merging-isinstance + "R1702", # too-many-nested-blocks + "R1703", # simplifiable-if-statement + "R1704", # redefined-argument-from-local + "R1705", # no-else-return + "R1706", # consider-using-ternary + "R1707", # trailing-comma-tuple + "R1710", # inconsistent-return-statements "R1711", # useless-return "R1714", # consider-using-in "R1715", # consider-using-get "R1717", # consider-using-dict-comprehension - "R1718", # consider-using-set-comprehension / ruff C401 - "R1719", # simplifiable-if-expression / ruff PLR1719 + "R1718", # consider-using-set-comprehension + "R1719", # simplifiable-if-expression "R1720", # no-else-raise - "R1721", # unnecessary-comprehension / ruff C416 - "R1722", # consider-using-sys-exit / ruff PLR1722 - "R1723", # no-else-break / ruff RET508 - "R1724", # no-else-continue / ruff RET507 - "R1725", # super-with-arguments / ruff UP008 - "R1728", # consider-using-generator / ruff C417 - "R1729", # use-a-generator / ruff C419 - "R1730", # consider-using-min-builtin / ruff PLR1730 - "R1731", # consider-using-max-builtin / ruff PLR1730 - "R1732", # consider-using-with / ruff SIM115 - "R1733", # unnecessary-dict-index-lookup / ruff PLR1733 - "R1734", # use-list-literal / ruff C405 - "R1735", # use-dict-literal / ruff C406 - "R1736", # unnecessary-list-index-lookup / ruff PLR1736 - "R2004", # magic-value-comparison / ruff PLR2004 - "R2044", # empty-comment / ruff PLR2044 - "R5501", # else-if-used / ruff PLR5501 - "R6002", # consider-using-alias / ruff UP006 - "R6003", # consider-alternative-union-syntax / ruff UP007 - "R6104", # consider-using-augmented-assign / ruff PLR6104 - "R6201", # use-set-for-membership / ruff PLR6201 - "R6301", # no-self-use / ruff PLR6301 - "W0102", # dangerous-default-value / ruff B006 - # "W0104", # pointless-statement / ruff B018 - "W0106", # expression-not-assigned / ruff B018 - "W0107", # unnecessary-pass / ruff PIE790 - "W0108", # unnecessary-lambda / ruff PLW0108 - # "W0109", # duplicate-key - # "W0120", # useless-else-on-loop / ruff PLW0120 - "W0122", # exec-used / ruff S102 - "W0123", # eval-used / ruff PGH001 - "W0127", # self-assigning-variable / ruff PLW0127 - "W0129", # assert-on-string-literal / ruff PLW0129 - "W0130", # duplicate-value / ruff B033 - "W0131", # named-expr-without-context / ruff PLW0131 - "W0133", # pointless-exception-statement / ruff PLW0133 - "W0150", # lost-exception / ruff B012 - "W0160", # consider-ternary-expression / ruff SIM108 - "W0177", # nan-comparison / ruff PLW0117 - # "W0199", # assert-on-tuple / ruff F631 - "W0211", # bad-staticmethod-argument / ruff PLW0211 - "W0212", # protected-access / ruff SLF001 - "W0245", # super-without-brackets / ruff PLW0245 - "W0301", # unnecessary-semicolon / ruff E703 - "W0401", # wildcard-import / ruff F403 - # "W0404", # reimported / ruff F811 - "W0406", # import-self / ruff PLW0406 - "W0410", # misplaced-future / ruff F404 - "W0602", # global-variable-not-assigned / ruff PLW0602 - "W0603", # global-statement / ruff PLW0603 - "W0604", # global-at-module-level / ruff PLW0604 - "W0611", # unused-import / ruff F401 - "W0612", # unused-variable / ruff F841 - "W0613", # unused-argument / ruff ARG001 - "W0622", # redefined-builtin / ruff A001 - "W0640", # cell-var-from-loop / ruff B023 - # "W0702", # bare-except - "W0705", # duplicate-except / ruff B014 - "W0706", # try-except-raise / ruff TRY302 - "W0707", # raise-missing-from / ruff TRY200 - "W0711", # binary-op-exception / ruff PLW0711 - "W0718", # broad-exception-caught / ruff PLW0718 - "W0719", # broad-exception-raised / ruff TRY002 - "W1113", # keyword-arg-before-vararg / ruff B026 - "W1201", # logging-not-lazy / ruff G - "W1202", # logging-format-interpolation / ruff G - "W1203", # logging-fstring-interpolation / ruff G - "W1300", # bad-format-string-key / ruff PLW1300 - "W1301", # unused-format-string-key / ruff F504 - "W1302", # bad-format-string / ruff PLW1302 - "W1303", # missing-format-argument-key / ruff F524 - "W1304", # unused-format-string-argument / ruff F507 - "W1305", # format-combined-specification / ruff F525 - "W1308", # duplicate-string-formatting-argument / ruff PLW1308 - "W1309", # f-string-without-interpolation / ruff F541 - "W1310", # format-string-without-interpolation / ruff F541 - "W1401", # anomalous-backslash-in-string / ruff W605 - "W1404", # implicit-str-concat / ruff ISC001 - "W1405", # inconsistent-quotes / ruff Q000 - "W1406", # redundant-u-string-prefix / ruff UP025 - "W1501", # bad-open-mode / ruff PLW1501 - "W1508", # invalid-envvar-default / ruff PLW1508 - "W1509", # subprocess-popen-preexec-fn / ruff PLW1509 - "W1510", # subprocess-run-check / ruff PLW1510 - "W1514", # unspecified-encoding / ruff PLW1514 - "W1515", # forgotten-debug-statement / ruff T100 - "W1518", # method-cache-max-size-none / ruff B019 - "W1641", # eq-without-hash / ruff PLW1641 - "W2101", # useless-with-lock / ruff PLW2101 - # "W2402", # non-ascii-file-name / ruff N999 - "W2901", # redefined-loop-name / ruff PLW2901 - "W3201", # bad-dunder-name / ruff PLW3201 - "W3301", # nested-min-max / ruff PLW3301 + "R1721", # unnecessary-comprehension + "R1722", # consider-using-sys-exit + "R1723", # no-else-break + "R1724", # no-else-continue + "R1725", # super-with-arguments + "R1728", # consider-using-generator + "R1729", # use-a-generator + "R1730", # consider-using-min-builtin + "R1731", # consider-using-max-builtin + "R1732", # consider-using-with + "R1733", # unnecessary-dict-index-lookup + "R1734", # use-list-literal + "R1735", # use-dict-literal + "R1736", # unnecessary-list-index-lookup + "R2004", # magic-value-comparison + "R2044", # empty-comment + "R5501", # else-if-used + "R6002", # consider-using-alias + "R6003", # consider-alternative-union-syntax + "R6104", # consider-using-augmented-assign + "R6201", # use-set-for-membership + "R6301", # no-self-use + "W0102", # dangerous-default-value + "W0104", # pointless-statement + "W0106", # expression-not-assigned + "W0107", # unnecessary-pass + "W0108", # unnecessary-lambda + "W0109", # duplicate-key + "W0120", # useless-else-on-loop + "W0122", # exec-used + "W0123", # eval-used + "W0127", # self-assigning-variable + "W0129", # assert-on-string-literal + "W0130", # duplicate-value + "W0131", # named-expr-without-context + "W0133", # pointless-exception-statement + "W0150", # lost-exception + "W0160", # consider-ternary-expression + "W0177", # nan-comparison + "W0199", # assert-on-tuple + "W0211", # bad-staticmethod-argument + "W0212", # protected-access + "W0245", # super-without-brackets + "W0301", # unnecessary-semicolon + "W0401", # wildcard-import + "W0404", # reimported + "W0406", # import-self + "W0410", # misplaced-future + "W0602", # global-variable-not-assigned + "W0603", # global-statement + "W0604", # global-at-module-level + "W0611", # unused-import + "W0612", # unused-variable + "W0613", # unused-argument + "W0622", # redefined-builtin + "W0640", # cell-var-from-loop + "W0702", # bare-except + "W0705", # duplicate-except + "W0706", # try-except-raise + "W0707", # raise-missing-from + "W0711", # binary-op-exception + "W0718", # broad-exception-caught + "W0719", # broad-exception-raised + "W1113", # keyword-arg-before-vararg + "W1201", # logging-not-lazy + "W1202", # logging-format-interpolation + "W1203", # logging-fstring-interpolation + "W1300", # bad-format-string-key + "W1301", # unused-format-string-key + "W1302", # bad-format-string + "W1303", # missing-format-argument-key + "W1304", # unused-format-string-argument + "W1305", # format-combined-specification + "W1308", # duplicate-string-formatting-argument + "W1309", # f-string-without-interpolation + "W1310", # format-string-without-interpolation + "W1401", # anomalous-backslash-in-string + "W1404", # implicit-str-concat + "W1405", # inconsistent-quotes + "W1406", # redundant-u-string-prefix + "W1501", # bad-open-mode + "W1508", # invalid-envvar-default + "W1509", # subprocess-popen-preexec-fn + "W1510", # subprocess-run-check + "W1514", # unspecified-encoding + "W1515", # forgotten-debug-statement + "W1518", # method-cache-max-size-none + "W1641", # eq-without-hash + "W2101", # useless-with-lock + "W2402", # non-ascii-file-name + "W2901", # redefined-loop-name + "W3201", # bad-dunder-name + "W3301", # nested-min-max "duplicate-code", "fixme", "too-few-public-methods", diff --git a/tox.ini b/tox.ini index 6fec1258..8654768f 100644 --- a/tox.ini +++ b/tox.ini @@ -10,76 +10,6 @@ env_list = lint skip_missing_interpreters = true -[testenv] -description = - Run the tests under {base_python} - devel: and ansible devel branch - pre: and enable --pre when installing dependencies, testing prereleases -package = editable -deps = - devel: ansible-compat @ git+https://github.com/ansible/ansible-compat.git # GPLv3+ - devel: ansible-core @ git+https://github.com/ansible/ansible.git # GPLv3+ -extras = - test -pass_env = - CI - CURL_CA_BUNDLE - FORCE_COLOR - HOME - LANG - LC_* - NO_COLOR - PYTEST_* - PYTEST_REQPASS - PYTHON* - PYTHONBREAKPOINT - PYTHONIOENCODING - PYTHONPYCACHEPREFIX - PY_COLORS - REQUESTS_CA_BUNDLE - RTD_TOKEN - SETUPTOOLS_SCM_DEBUG - SSH_AUTH_SOCK - SSL_CERT_FILE - UV_* -set_env = - COVERAGE_FILE = {env:COVERAGE_FILE:{env_dir}/.coverage.{env_name}} - COVERAGE_PROCESS_START = {tox_root}/pyproject.toml - FORCE_COLOR = 1 - PIP_CONSTRAINT = {tox_root}/.config/constraints.txt - PIP_DISABLE_PIP_VERSION_CHECK = 1 - PRE_COMMIT_COLOR = always - PYTEST_REQPASS = 910 - UV_CONSTRAINT = {tox_root}/.config/constraints.txt - deps, devel, hook, lint, pkg, pre, py310, schemas: PIP_CONSTRAINT = /dev/null - deps, devel, hook, lint, pkg, pre, py310, schemas: UV_CONSTRAINT = /dev/null - devel: ANSIBLE_DEVEL_WARNING = false - pre: PIP_PRE = 1 -commands_pre = - sh -c "rm -f {env_dir}/.coverage.* 2>/dev/null || true" - {env_python} -m pip check - bash ./tools/install-reqs.sh - ansible --version -commands = - sh -c "{env_python} -m pip freeze > {env_dir}/log/requirements.txt" - coverage run -m pytest {posargs: \ - -n auto \ - -ra \ - --showlocals \ - --doctest-modules \ - --durations=10 \ - } - {py,py310,py311,py312,py313}: sh -c "coverage combine -a -q --data-file={env_dir}/.coverage {work_dir}/*/.coverage.* && coverage xml --data-file={env_dir}/.coverage -o {env_dir}/coverage.xml --fail-under=0 && coverage report --data-file={env_dir}/.coverage" -allowlist_externals = - ./tools/test-hook.sh - bash - find - git - pwd - rm - sh - tox - [testenv:lint] description = Run all linters skip_install = true @@ -104,3 +34,17 @@ commands = find . -type d \( -name __pycache__ -o -name .mypy_cache \) -delete find . -type f \( -name '*.py[co]' -o -name ".coverage*" -o -name coverage.xml \) -delete commands_post = + +[testenv:docs] +description = Builds docs +package = editable +skip_install = false +extras = + docs +set_env = + NO_COLOR = 1 + TERM = dump +commands_pre = + +commands = + mkdocs {posargs:build --strict --site-dir=_readthedocs/html/} From 20bb5ed0cfb68920c843dc2086bba5544a1a7389 Mon Sep 17 00:00:00 2001 From: Tom Bosmans Date: Fri, 4 Apr 2025 14:02:18 +0200 Subject: [PATCH 15/54] feature: test for risk profiles --- test/test_aac_riskprofiles.py | 55 +++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 test/test_aac_riskprofiles.py diff --git a/test/test_aac_riskprofiles.py b/test/test_aac_riskprofiles.py new file mode 100644 index 00000000..2e89ef2d --- /dev/null +++ b/test/test_aac_riskprofiles.py @@ -0,0 +1,55 @@ +import logging + +import ibmsecurity.isam.aac.risk_profiles +import ibmsecurity.isam.appliance + +import pytest + +def getTestData(): + testdata = [ + { + "name": "Risk profile 1", + "active": True, + "description": "Test for risk profiles", + "attributes": [{"name": "accessTime", "weight": 60}, + {"name": "http:userAgent", "weight": 10}] + }, + ] + return testdata + + +@pytest.mark.parametrize("items", getTestData()) +def test_set_riskprofiles(iviaServer, caplog, items) -> None: + """Set api protection""" + caplog.set_level(logging.DEBUG) + # items is a key-value pair + logging.log(logging.INFO, items) + arg = {} + active = False + for k, v in items.items(): + if k == 'name': + name = v + continue + if k == 'active': + active = v + continue + arg[k] = v + + returnValue = ibmsecurity.isam.aac.risk_profiles.set(iviaServer, + name, + active, + **arg + ) + logging.log(logging.INFO, returnValue) + + assert not returnValue.failed() + + +def test_commit(iviaServer, caplog) -> None: + """Not actually a test, but save the changes.""" + caplog.set_level(logging.INFO) + + returnValue = ibmsecurity.isam.appliance.commit(isamAppliance=iviaServer) + logging.log(logging.DEBUG, returnValue) + + assert not returnValue.failed() From 9a212b8d250f0a158c7a542e9f391940ee9df7c6 Mon Sep 17 00:00:00 2001 From: Tom Bosmans Date: Fri, 4 Apr 2025 14:37:30 +0200 Subject: [PATCH 16/54] documentation: update --- docs/contributing.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/docs/contributing.md b/docs/contributing.md index edfb679a..2e3d11cd 100644 --- a/docs/contributing.md +++ b/docs/contributing.md @@ -14,7 +14,8 @@ $ pip install -e '.[test]' # Install testing dependencies $ tox run -e lint $ git checkout -b your-branch-name # DO SOME CODING HERE -$ tox run -e lint +# Add tests under `test/` +$ tox run -e lint,py $ git add your new files $ git commit -v $ git push origin your-branch-name @@ -22,9 +23,6 @@ $ git push origin your-branch-name You will then be able to create a pull request from your commit. -Feel free to raise issues in the repo if you feel unable to contribute a code -fix. - ## Setup ### Local appliance From 21044da66252eb026d31c3b248be3da23e33498e Mon Sep 17 00:00:00 2001 From: Tom Bosmans Date: Fri, 4 Apr 2025 14:44:16 +0200 Subject: [PATCH 17/54] documentation: update version --- pyproject.toml | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 5a2db7dc..42ed65ba 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,7 +7,7 @@ build-backend = "setuptools.build_meta" [project] name = "ibmsecurity" -version = "2025.4.2.0" +version = "2025.4.4.0" authors = [ { name="IBM", email="secorch@wwpdl.vnet.ibm.com" }, ] diff --git a/setup.py b/setup.py index 3a6b5e13..e7d1f812 100644 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ packages=find_packages(), # Date of release used for version - please be sure to use YYYY.MM.DD.seq#, MM and DD should be two digits e.g. 2017.02.05.0 # seq# will be zero unless there are multiple release on a given day - then increment by one for additional release for that date - version="2025.3.28.0", + version="2025.4.4.0", description="Idempotent functions for IBM Security Appliance REST APIs", author="IBM", author_email="secorch@wwpdl.vnet.ibm.com", From 79fe33e819bf7df877648965832f4180ab0912be Mon Sep 17 00:00:00 2001 From: Tom Bosmans Date: Fri, 4 Apr 2025 14:44:26 +0200 Subject: [PATCH 18/54] refactor: update tox --- tox.ini | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/tox.ini b/tox.ini index 8654768f..1cf445d3 100644 --- a/tox.ini +++ b/tox.ini @@ -4,12 +4,70 @@ requires = tox>=4.24.2 tox-extra>=2.1 tox-uv>=1.25 + coverage>=6.4.4 env_list = py py-devel lint skip_missing_interpreters = true +[testenv] +description = + Run the tests under {base_python} +package = editable +deps = + pytest + pip +extras = +pass_env = + CI + CURL_CA_BUNDLE + FORCE_COLOR + HOME + LANG + LC_* + NO_COLOR + PYTEST_* + PYTHON* + PYTHONBREAKPOINT + PYTHONIOENCODING + PYTHONPYCACHEPREFIX + PY_COLORS + REQUESTS_CA_BUNDLE + SETUPTOOLS_SCM_DEBUG + SSH_AUTH_SOCK + SSL_CERT_FILE + UV_* +set_env = + COVERAGE_FILE = {env:COVERAGE_FILE:{env_dir}/.coverage.{envname}} + COVERAGE_PROCESS_START = {tox_root}/pyproject.toml + FORCE_COLOR = 1 + PIP_CONSTRAINT = /dev/null + PIP_DISABLE_PIP_VERSION_CHECK = 1 + PRE_COMMIT_COLOR = always + UV_CONSTRAINT = /dev/null +commands_pre = + sh -c "rm -f {env_dir}/.coverage.* 2>/dev/null || true" + {env_python} -m pip check +commands = + sh -c "{env_python} -m pip freeze > {env_dir}/log/requirements.txt" + coverage run -m pytest {posargs: \ + # -n auto \ # Using this breaks coverage (UNIQUE constraint failed: context.context) + -ra \ + --showlocals \ + --durations=10 \ + test + } + {py,py310,py311,py312,py313}: sh -c "coverage combine -a -q --data-file={env_dir}/.coverage {work_dir}/*/.coverage.* && coverage xml --data-file={env_dir}/.coverage -o {env_dir}/coverage.xml --fail-under=0 && coverage report --data-file={env_dir}/.coverage" +allowlist_externals = + bash + find + git + pwd + rm + sh + tox + [testenv:lint] description = Run all linters skip_install = true From c07d5ce323b50e7eff1ca5ae0bf67824ae45a2a6 Mon Sep 17 00:00:00 2001 From: Tom Bosmans Date: Fri, 4 Apr 2025 14:47:33 +0200 Subject: [PATCH 19/54] refactor: update pylint github action --- .github/workflows/pylint.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pylint.yml b/.github/workflows/pylint.yml index c73e032c..6e21c90d 100644 --- a/.github/workflows/pylint.yml +++ b/.github/workflows/pylint.yml @@ -7,7 +7,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.8", "3.9", "3.10"] + python-version: ["3.11"] steps: - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} From 4b68beefa7451e7c22ad8b7db2ab9ed0ab8561b8 Mon Sep 17 00:00:00 2001 From: Tom Bosmans Date: Fri, 4 Apr 2025 14:51:33 +0200 Subject: [PATCH 20/54] refactor: avoid error --- testisds.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/testisds.py b/testisds.py index f38c1218..2cc9b362 100644 --- a/testisds.py +++ b/testisds.py @@ -28,7 +28,12 @@ def import_submodules(package, recursive=True): # Import all packages within ibmsecurity!!! -import_submodules(ibmsecurity) +try: + import_submodules(ibmsecurity) +except Exception as e: + print('Failed to import some submodules: ' + str(e)) + + # logging.getLogger(__name__).addHandler(logging.NullHandler()) logging.basicConfig() From 89ac36055971f697b524d11a839939556c4fd3c0 Mon Sep 17 00:00:00 2001 From: Tom Bosmans Date: Wed, 7 May 2025 16:24:13 +0200 Subject: [PATCH 21/54] documentation: typo --- ibmsecurity/isam/aac/authentication/policies.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ibmsecurity/isam/aac/authentication/policies.py b/ibmsecurity/isam/aac/authentication/policies.py index 0e1eaafe..a12016ba 100644 --- a/ibmsecurity/isam/aac/authentication/policies.py +++ b/ibmsecurity/isam/aac/authentication/policies.py @@ -114,7 +114,7 @@ def add(isamAppliance, name, policy, uri, description="", dialect="urn:ibm:secur if enabled is not None: if tools.version_compare(isamAppliance.facts["version"], "9.0.2.1") < 0: warnings.append( - "Appliance is at version: {0}. Enabled parameter not supported unless atleast 9.0.2.1. Ignoring value.".format( + "Appliance is at version: {0}. Enabled parameter not supported unless at least 9.0.2.1. Ignoring value.".format( isamAppliance.facts["version"])) else: json_data["enabled"] = enabled From 5ab6fdfc73b51cdf7ead6d101694983190d0fe5d Mon Sep 17 00:00:00 2001 From: Tom Bosmans Date: Tue, 27 May 2025 10:22:29 +0200 Subject: [PATCH 22/54] feature: support for type=federation --- .../isam/base/management_authentication.py | 155 ++++++++++-------- 1 file changed, 91 insertions(+), 64 deletions(-) diff --git a/ibmsecurity/isam/base/management_authentication.py b/ibmsecurity/isam/base/management_authentication.py index 0ae3343f..d42ddb4b 100644 --- a/ibmsecurity/isam/base/management_authentication.py +++ b/ibmsecurity/isam/base/management_authentication.py @@ -13,92 +13,119 @@ def get(isamAppliance, check_mode=False, force=False): def set(isamAppliance, - ldap_host=None, - ldap_port=None, - base_dn=None, - admin_group_dn=None, - type='remote', - enable_ssl=False, - key_database=None, - cert_label=None, - user_attribute='uid', - group_member_attribute='member', - anon_bind=True, - bind_dn=None, - bind_password=None, - ldap_debug=None, - enable_usermapping=False, - usermapping_script=None, check_mode=False, - force=False): + force=False, + ignore_password_for_idempotency=False, + type='remote', + **kwargs, + ): """ Set management authentication to remote + + ldap_host=None, + ldap_port=None, + base_dn=None, + admin_group_dn=None, + enable_ssl=False, + key_database=None, + cert_label=None, + user_attribute='uid', + group_member_attribute='member', + anon_bind=True, + bind_dn=None, + bind_password=None, + ldap_debug=None, + enable_usermapping=False, + usermapping_script=None, + enable_ssh_pubkey_auth + ssh_pubkey_auth_attribute=None + oidc_client_id String No The OIDC Client Identifier. This field is required if type == "federation". + oidc_client_secret String No The OIDC Client Secret. This field is required if type == "federation". + oidc_discovery_endpoint String No The OIDC Discovery (well-known) endpoint. This field is required if type == "federation". + oidc_enable_pkce Boolean No Specifies whether the Public key Code Exchange extension is enforced. This field is required if type == "federation". + oidc_enable_admin_group Boolean No Specifies whether a user must be a member of a particular group to be considered an administrator user. This field is required if type == "federation". + oidc_group_claim String Yes The OIDC token claim to use as group membership. This claim can either be a String, or a list of Strings. The default value is "groups". + oidc_admin_group String Yes The name of the group which a user must be a member of to be considered an administrator user. The default value is "adminGroup". + oidc_user_claim String Yes Specifies the OIDC token claim to use as the username. The default value is "sub". + oidc_keystore String Yes The SSL Truststore to verify connections the the OIDC OP. The default value if "lmi_trust_store". + enable_tokenmapping Boolean No Specifies whether custom claim to identity mapping is performed using a JavaScript code fragment. This field is required if type == "federation". + tokenmapping_script String Yes The custom JavaScript code fragment to map an identity token to a username/group membership. + """ warnings = [] update_required = False + json_data = { 'type': type } - if ldap_host is not None: - json_data["ldap_host"] = ldap_host - if ldap_port is not None: - json_data["ldap_port"] = ldap_port - if enable_ssl is not None: - json_data["enable_ssl"] = enable_ssl - if key_database is not None: - json_data["key_database"] = key_database - if cert_label is not None: - json_data["cert_label"] = cert_label - if user_attribute is not None: - json_data["user_attribute"] = user_attribute - if group_member_attribute is not None: - json_data["group_member_attribute"] = group_member_attribute - if base_dn is not None: - json_data["base_dn"] = base_dn - if admin_group_dn is not None: - json_data["admin_group_dn"] = admin_group_dn - if anon_bind is not None: - json_data["anon_bind"] = anon_bind - if bind_dn is not None: - json_data["bind_dn"] = bind_dn - if bind_password is not None: - json_data["bind_password"] = bind_password - if ldap_debug is not None or ldap_debug == '': - if ibmsecurity.utilities.tools.version_compare(isamAppliance.facts["version"], "9.0.4.0") < 0: - warnings.append( - "Appliance at version: {0}, ldap_debug: {1} is not supported. Needs 9.0.4.0 or higher. Ignoring ldap_debug for this call.".format( - isamAppliance.facts["version"], ldap_debug)) - else: - json_data["ldap_debug"] = ldap_debug - elif ibmsecurity.utilities.tools.version_compare(isamAppliance.facts["version"], "9.0.4.0") >= 0: - json_data["ldap_debug"] = False - if ibmsecurity.utilities.tools.version_compare(isamAppliance.facts["version"], "10.0.2.0") >= 0: - json_data["enable_usermapping"] = enable_usermapping - if usermapping_script is not None and enable_usermapping: - json_data["usermapping_script"] = usermapping_script - if force is False: - if bind_password is not None: - warnings.append("Unable to read existing bind password to check idempotency.") + + for k, v in kwargs.items(): + if k == 'ldap_debug' and v == '': + if ibmsecurity.utilities.tools.version_compare(isamAppliance.facts["version"], "9.0.4.0") < 0: + warnings.append( + "Appliance at version: {0}, ldap_debug: {1} is not supported. Needs 9.0.4.0 or higher. Ignoring ldap_debug for this call.".format( + isamAppliance.facts["version"], ldap_debug)) + continue + if k == 'enable_usermapping': + # only valid if type == remote + if type == 'remote': + if ibmsecurity.utilities.tools.version_compare(isamAppliance.facts["version"], "10.0.2.0") < 0: + warnings.append( + f"Appliance at version: {isamAppliance.facts['version']}, {k}: {v} is not supported. Needs 10.0.2.0 or higher. Ignoring {k} for this call.") + continue + else: + warnings.append(f"{k} is only supported for type remote. Ignoring it for now.") + continue + if k in ('ssh_pubkey_auth_attribute','enable_ssh_pubkey_auth'): + if ibmsecurity.utilities.tools.version_compare(isamAppliance.facts['version'], "10.0.6") < 0: + warnings.append(f"Appliance at version: {isamAppliance.facts['version']}, {k}: {v} is not supported. Needs 10.0.8.0 or higher. Ignoring {k} for this call.") + continue + if k.startswith('oidc_') or k in ('enable_tokenmapping', 'tokenmapping_script'): + if ibmsecurity.utilities.tools.version_compare(isamAppliance.facts['version'], "10.0.8") < 0: + warnings.append(f"Appliance at version: {isamAppliance.facts['version']}, {k}: {v} is not supported. Needs 10.0.8.0 or higher. Ignoring {k} for this call.") + continue + json_data[k] = v + # Set defaults for type remote + if type == 'remote': + if json_data.get('user_attribute', None) is None: + json_data['user_attribute'] = 'uid' + if json_data.get('group_member_attribute', None) is None: + json_data['group_member_attribute'] = 'member' + if json_data.get('anon_bind', None) is None: + json_data['anon_bind'] = True + # Defaults for type federation (new in 10.0.8) + if type == 'federation': + if json_data.get('oidc_group_claim', None) is None: + json_data['oidc_group_claim'] = 'groups' + if json_data.get('oidc_admin_group', None) is None: + json_data['oidc_admin_group'] = 'adminGroup' + if json_data.get('oidc_user_claim', None) is None: + json_data['oidc_user_claim'] = "sub" + if json_data.get('oidc_keystore', None) is None: + json_data['oidc_keystore'] = "lmi_trust_store" + if not force: + if not ignore_password_for_idempotency and json_data.get('bind_password', None) is not None: + warnings.append("Unable to read existing bind password to check idempotency. You can disable this behaviour by passing `ignore_password_for_idempotency=True`") update_required = True else: ret_obj = get(isamAppliance) if "bind_dn" in ret_obj['data']: if ret_obj["data"]["bind_dn"] is None: del ret_obj["data"]["bind_dn"] - sorted_json_data = ibmsecurity.utilities.tools.json_sort(json_data) - logger.debug("Sorted input: {0}".format(sorted_json_data)) - sorted_ret_obj = ibmsecurity.utilities.tools.json_sort(ret_obj['data']) - logger.debug("Sorted existing data: {0}".format(sorted_ret_obj)) + sorted_json_data = json.dumps(json_data, skipkeys=True, sort_keys=True) + logger.debug(f"Sorted input: {sorted_json_data}") + sorted_ret_obj = json.dumps(ret_obj['data'], skipkeys=True, sort_keys=True) + logger.debug(f"Sorted existing data: {sorted_ret_obj}") if sorted_ret_obj != sorted_json_data: logger.info("Changes detected, update needed.") update_required = True - if force is True or update_required is True: - if check_mode is True: + if force or update_required: + if check_mode: return isamAppliance.create_return_object(changed=True, warnings=warnings) else: return isamAppliance.invoke_put( - "Set management authentication to remote", + f"Set management authentication to {type}", "/isam/management_authentication/", json_data, warnings=warnings) From fb69de370644f34fe5789f2b29a8a1c152f3fc9a Mon Sep 17 00:00:00 2001 From: Tom Bosmans Date: Tue, 27 May 2025 17:59:43 +0200 Subject: [PATCH 23/54] fix: corrections --- .../isam/base/management_authentication.py | 26 ++++++++++++------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/ibmsecurity/isam/base/management_authentication.py b/ibmsecurity/isam/base/management_authentication.py index d42ddb4b..ab8c5067 100644 --- a/ibmsecurity/isam/base/management_authentication.py +++ b/ibmsecurity/isam/base/management_authentication.py @@ -1,5 +1,6 @@ import logging import ibmsecurity.utilities.tools +import json logger = logging.getLogger(__name__) @@ -58,7 +59,6 @@ def set(isamAppliance, json_data = { 'type': type } - for k, v in kwargs.items(): if k == 'ldap_debug' and v == '': if ibmsecurity.utilities.tools.version_compare(isamAppliance.facts["version"], "9.0.4.0") < 0: @@ -85,7 +85,7 @@ def set(isamAppliance, warnings.append(f"Appliance at version: {isamAppliance.facts['version']}, {k}: {v} is not supported. Needs 10.0.8.0 or higher. Ignoring {k} for this call.") continue json_data[k] = v - # Set defaults for type remote + # Set defaults for type remote and cleanup if type == 'remote': if json_data.get('user_attribute', None) is None: json_data['user_attribute'] = 'uid' @@ -93,7 +93,10 @@ def set(isamAppliance, json_data['group_member_attribute'] = 'member' if json_data.get('anon_bind', None) is None: json_data['anon_bind'] = True - # Defaults for type federation (new in 10.0.8) + if not json_data.get('enable_usermapping', False): + json_data["usermapping_script"] = '' + + # Defaults for type federation (new in 10.0.8) and cleanup if type == 'federation': if json_data.get('oidc_group_claim', None) is None: json_data['oidc_group_claim'] = 'groups' @@ -103,19 +106,24 @@ def set(isamAppliance, json_data['oidc_user_claim'] = "sub" if json_data.get('oidc_keystore', None) is None: json_data['oidc_keystore'] = "lmi_trust_store" + if not json_data.get('enable_tokenmapping', False): + json_data["tokenmapping_script"] = '' + if not force: if not ignore_password_for_idempotency and json_data.get('bind_password', None) is not None: warnings.append("Unable to read existing bind password to check idempotency. You can disable this behaviour by passing `ignore_password_for_idempotency=True`") update_required = True else: ret_obj = get(isamAppliance) - if "bind_dn" in ret_obj['data']: - if ret_obj["data"]["bind_dn"] is None: - del ret_obj["data"]["bind_dn"] - sorted_json_data = json.dumps(json_data, skipkeys=True, sort_keys=True) - logger.debug(f"Sorted input: {sorted_json_data}") + json_data_compare = json_data.copy() + if json_data.get("bind_dn", None) is None: + ret_obj["data"].pop("bind_dn", None) + ret_obj["data"].pop("bind_password", None) + json_data_compare.pop("bind_password", None) + sorted_json_data = json.dumps(json_data_compare, skipkeys=True, sort_keys=True) + logger.debug(f"\n\nSorted input: {sorted_json_data}") sorted_ret_obj = json.dumps(ret_obj['data'], skipkeys=True, sort_keys=True) - logger.debug(f"Sorted existing data: {sorted_ret_obj}") + logger.debug(f"\n\nSorted existing data: {sorted_ret_obj}") if sorted_ret_obj != sorted_json_data: logger.info("Changes detected, update needed.") update_required = True From e7e67980254082fbdbefd1bb9b15cd9d208fd65d Mon Sep 17 00:00:00 2001 From: Tom Bosmans Date: Wed, 28 May 2025 08:53:39 +0200 Subject: [PATCH 24/54] feature: test for management authentication --- test/test_base_management_authentication.py | 104 ++++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100644 test/test_base_management_authentication.py diff --git a/test/test_base_management_authentication.py b/test/test_base_management_authentication.py new file mode 100644 index 00000000..7c2b55ca --- /dev/null +++ b/test/test_base_management_authentication.py @@ -0,0 +1,104 @@ +import logging + +import ibmsecurity.isam.base.management_authentication +import ibmsecurity.isam.appliance + +import pytest + +def getTestData(): + testdata = [ + { + "type": "remote", + "ignore_password_for_idempotency": True, + "ldap_host": "127.0.0.1", + "ldap_port": 636, + "enable_ssl": True, + "key_database": "lmi_trust_store", + "cert_label": "server", + "user_attribute": "uid", + "group_member_attribute": "groups", + "base_dn": "base DN", + "admin_group_dn": "adminGroup", + "anon_bind": False, + "bind_dn": "cn=root", + "bind_password": "bind password", + "ldap_debug": False, + "enable_usermapping": False, + "usermapping_script": "function mapUser(props){...}", + "enable_ssh_pubkey_auth": True, + "ssh_pubkey_auth_attribute": "sshKey" + }, + ] + return testdata + +def getTestDataSSO(): + testdata = [ + { + "type": "federation", + "ignore_password_for_idempotency": False, + "oidc_client_id": "clientId", + "oidc_client_secret": "clientSecret", + "oidc_discovery_endpoint": "https://www.myidp.ibm.com/mga/sps/oauth/oauth20/metadata/TEST", + "oidc_enable_pkce": True, + "enable_tokenmapping": True, + "tokenmapping_script": "function mapToken(operation, token){return 0;}" + }, + ] + return testdata + +@pytest.mark.parametrize("items", getTestData()) +def test_set_base_management_authentication_remote(iviaServer, caplog, items) -> None: + """Set some admincfg options.""" + caplog.set_level(logging.DEBUG) + + arg = {} + type = 'remote' + ignore_password_for_idempotency = False + for k, v in items.items(): + if k == 'type': + type = v + continue + if k == 'ignore_password_for_idempotency': + ignore_password_for_idempotency = v + arg[k] = v + + returnValue = ibmsecurity.isam.base.management_authentication.set(isamAppliance=iviaServer, + force=False, + type=type, + **arg) + logging.log(logging.INFO, returnValue) + + assert not returnValue.failed() + +@pytest.mark.parametrize("items", getTestDataSSO()) +def test_set_base_management_authentication_federation(iviaServer, caplog, items) -> None: + """Set some admincfg options.""" + caplog.set_level(logging.DEBUG) + + arg = {} + type = 'remote' + ignore_password_for_idempotency = False + for k, v in items.items(): + if k == 'type': + type = v + continue + if k == 'ignore_password_for_idempotency': + ignore_password_for_idempotency = v + arg[k] = v + + returnValue = ibmsecurity.isam.base.management_authentication.set(isamAppliance=iviaServer, + force=False, + type=type, + **arg) + logging.log(logging.INFO, returnValue) + + assert not returnValue.failed() + +def test_commit(iviaServer, caplog) -> None: + """Not actually a test, but save the changes.""" + caplog.set_level(logging.INFO) + + returnValue = ibmsecurity.isam.appliance.commit(isamAppliance=iviaServer) + logging.log(logging.DEBUG, returnValue) + + assert not returnValue.failed() From 464f4d0a008c9d347b6acd44a0af616732fc33c5 Mon Sep 17 00:00:00 2001 From: Tom Bosmans Date: Wed, 28 May 2025 09:21:37 +0200 Subject: [PATCH 25/54] fix: add new parameters for oauth configuration of rp --- .../web/reverse_proxy/oauth_configuration.py | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/ibmsecurity/isam/web/reverse_proxy/oauth_configuration.py b/ibmsecurity/isam/web/reverse_proxy/oauth_configuration.py index 4bf0074e..946fb5cd 100644 --- a/ibmsecurity/isam/web/reverse_proxy/oauth_configuration.py +++ b/ibmsecurity/isam/web/reverse_proxy/oauth_configuration.py @@ -9,6 +9,7 @@ def config(isamAppliance, instance_id, hostname='127.0.0.1', port=443, username=None, password=None, junction="/mga", reuse_certs=False, reuse_acls=False, api=False, browser=False, auth_register=None, fapi_compliant=None, + load_certificate=None, enable_mtls=None, mutual_key_label=None, check_mode=False, force=False): """ Oauth and Oidc configuration for a reverse proxy instance @@ -28,6 +29,9 @@ def config(isamAppliance, instance_id, hostname='127.0.0.1', port=443, username= :param check_mode: :param force: :param fapi_compliant: + :param load_certificate # new in ? + :param enable_mtls # new in 10.0.8 + :param mutual_key_label # new in 10.0.8 :return: """ if username is None: @@ -66,6 +70,27 @@ def config(isamAppliance, instance_id, hostname='127.0.0.1', port=443, username= isamAppliance.facts["version"], fapi_compliant)) else: json_data["fapi_compliant"] = fapi_compliant + if load_certificate is not None: + if ibmsecurity.utilities.tools.version_compare(isamAppliance.facts["version"], "10.0.0.0") < 0: + warnings.append( + "Appliance at version: {0}, load_certificate: {1} is not supported. Needs 10.0.0.0 or higher. Ignoring load_certificate for this call.".format( + isamAppliance.facts["version"], load_certificate)) + else: + json_data["load_certificate"] = load_certificate + if enable_mtls is not None: + if ibmsecurity.utilities.tools.version_compare(isamAppliance.facts["version"], "10.0.8.0") < 0: + warnings.append( + "Appliance at version: {0}, enable_mtls: {1} is not supported. Needs 10.0.8.0 or higher. Ignoring enable_mtls for this call.".format( + isamAppliance.facts["version"], enable_mtls)) + else: + json_data["enable_mtls"] = enable_mtls + if mutual_key_label is not None: + if ibmsecurity.utilities.tools.version_compare(isamAppliance.facts["version"], "10.0.8.0") < 0: + warnings.append( + "Appliance at version: {0}, mutual_key_label: {1} is not supported. Needs 10.0.8.0 or higher. Ignoring mutual_key_label for this call.".format( + isamAppliance.facts["version"], mutual_key_label)) + else: + json_data["mutual_key_label"] = mutual_key_label if check_mode is True: return isamAppliance.create_return_object(changed=True, warnings=warnings) else: From fa51a29b86f5e19cd531188f5514c89595a81fec Mon Sep 17 00:00:00 2001 From: Tom Bosmans Date: Wed, 28 May 2025 09:25:39 +0200 Subject: [PATCH 26/54] fix: replace .format with f-strings --- .../web/reverse_proxy/oauth_configuration.py | 23 ++++++++----------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/ibmsecurity/isam/web/reverse_proxy/oauth_configuration.py b/ibmsecurity/isam/web/reverse_proxy/oauth_configuration.py index 946fb5cd..0469bd34 100644 --- a/ibmsecurity/isam/web/reverse_proxy/oauth_configuration.py +++ b/ibmsecurity/isam/web/reverse_proxy/oauth_configuration.py @@ -43,7 +43,7 @@ def config(isamAppliance, instance_id, hostname='127.0.0.1', port=443, username= return isamAppliance.create_return_object(warning=["Required parameter password missing. Skipping config."]) warnings = [ - "Idempotency logic will check for existence of {} junction. Use force=True to override.".format(junction)] + f"Idempotency logic will check for existence of {junction} junction. Use force=True to override."] if force is True or _check_config(isamAppliance, instance_id, junction) is False: json_data = { "junction": junction, @@ -59,36 +59,31 @@ def config(isamAppliance, instance_id, hostname='127.0.0.1', port=443, username= if auth_register is not None: if ibmsecurity.utilities.tools.version_compare(isamAppliance.facts["version"], "9.0.5.0") < 0: warnings.append( - "Appliance at version: {0}, auth_register: {1} is not supported. Needs 9.0.5.0 or higher. Ignoring auth_register for this call.".format( - isamAppliance.facts["version"], auth_register)) + f"Appliance at version: {isamAppliance.facts['version']}, auth_register: {auth_register} is not supported. Needs 9.0.5.0 or higher. Ignoring auth_register for this call.") else: json_data["auth_register"] = auth_register if fapi_compliant is not None: if ibmsecurity.utilities.tools.version_compare(isamAppliance.facts["version"], "10.0.0.0") < 0: warnings.append( - "Appliance at version: {0}, fapi_compliant: {1} is not supported. Needs 10.0.0.0 or higher. Ignoring fapi_compliant for this call.".format( - isamAppliance.facts["version"], fapi_compliant)) + f"Appliance at version: {isamAppliance.facts['version']}, fapi_compliant: {fapi_compliant} is not supported. Needs 10.0.0.0 or higher. Ignoring fapi_compliant for this call.") else: json_data["fapi_compliant"] = fapi_compliant if load_certificate is not None: if ibmsecurity.utilities.tools.version_compare(isamAppliance.facts["version"], "10.0.0.0") < 0: warnings.append( - "Appliance at version: {0}, load_certificate: {1} is not supported. Needs 10.0.0.0 or higher. Ignoring load_certificate for this call.".format( - isamAppliance.facts["version"], load_certificate)) + f"Appliance at version: {isamAppliance.facts['version']}, load_certificate: {load_certificate} is not supported. Needs 10.0.0.0 or higher. Ignoring load_certificate for this call.") else: json_data["load_certificate"] = load_certificate if enable_mtls is not None: if ibmsecurity.utilities.tools.version_compare(isamAppliance.facts["version"], "10.0.8.0") < 0: warnings.append( - "Appliance at version: {0}, enable_mtls: {1} is not supported. Needs 10.0.8.0 or higher. Ignoring enable_mtls for this call.".format( - isamAppliance.facts["version"], enable_mtls)) + f"Appliance at version: {isamAppliance.facts['version']}, enable_mtls: {enable_mtls} is not supported. Needs 10.0.8.0 or higher. Ignoring enable_mtls for this call.") else: json_data["enable_mtls"] = enable_mtls if mutual_key_label is not None: if ibmsecurity.utilities.tools.version_compare(isamAppliance.facts["version"], "10.0.8.0") < 0: warnings.append( - "Appliance at version: {0}, mutual_key_label: {1} is not supported. Needs 10.0.8.0 or higher. Ignoring mutual_key_label for this call.".format( - isamAppliance.facts["version"], mutual_key_label)) + f"Appliance at version: {isamAppliance.facts['version']}, mutual_key_label: {mutual_key_label} is not supported. Needs 10.0.8.0 or higher. Ignoring mutual_key_label for this call.") else: json_data["mutual_key_label"] = mutual_key_label if check_mode is True: @@ -96,7 +91,9 @@ def config(isamAppliance, instance_id, hostname='127.0.0.1', port=443, username= else: return isamAppliance.invoke_post( "OAuth configuration for a reverse proxy instance", - "/wga/reverseproxy/{0}/oauth_config".format(instance_id), json_data, warnings=warnings, + f"/wga/reverseproxy/{instance_id}/oauth_config", + json_data, + warnings=warnings, requires_modules=requires_modules, requires_version=requires_version) return isamAppliance.create_return_object(warnings=warnings) @@ -113,7 +110,7 @@ def _check_config(isamAppliance, instance_id, junction): for j in ret_obj['data']: if j['id'] == junction: - logger.info("Junction {} was found - hence oauth config must have already executed.".format(junction)) + logger.info(f"Junction {junction} was found - hence oauth config must have already executed.") return True return False From a12eb1bdb1b28091cfa9b57f2af41e885616733d Mon Sep 17 00:00:00 2001 From: Tom Bosmans Date: Wed, 28 May 2025 09:42:43 +0200 Subject: [PATCH 27/54] feature: new module --- .../web/reverse_proxy/oauth2_configuration.py | 82 +++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 ibmsecurity/isam/web/reverse_proxy/oauth2_configuration.py diff --git a/ibmsecurity/isam/web/reverse_proxy/oauth2_configuration.py b/ibmsecurity/isam/web/reverse_proxy/oauth2_configuration.py new file mode 100644 index 00000000..c41aa8d9 --- /dev/null +++ b/ibmsecurity/isam/web/reverse_proxy/oauth2_configuration.py @@ -0,0 +1,82 @@ +import logging +import ibmsecurity.utilities.tools +from ibmsecurity.isam.web.reverse_proxy import junctions + +logger = logging.getLogger(__name__) +requires_modules = ["wga"] +requires_version = "10.0.4.0" + + +def config(isamAppliance, instance_id, hostname='127.0.0.1', port=443, + junction="/isvaop", enable_mtls=None, mutual_key_label=None, reuse_certs=False, + reuse_acls=False, load_certificate=True, + check_mode=False, force=False): + """ + OAuth2 IBM Security Verify OIDC Provider configuration + + :param isamAppliance: + :param instance_id: + :param junction: + :param hostname: + :param port: + :param enable_mtls # new in 10.0.8 + :param mutual_key_label # new in 10.0.8 + :param reuse_certs: + :param reuse_acls: + :param check_mode: + :param force: + :param load_certificate # new in ? Default is true + :return: + """ + + warnings = [ + f"Idempotency logic will check for existence of {junction} junction. Use force=True to override."] + if force or _check_config(isamAppliance, instance_id, junction) is False: + json_data = { + "junction": junction, + "hostname": hostname, + "port": port, + "reuse_certs": reuse_certs, + "reuse_acls": reuse_acls, + "load_certificate": load_certificate + } + if enable_mtls is not None: + if ibmsecurity.utilities.tools.version_compare(isamAppliance.facts["version"], "10.0.8.0") < 0: + warnings.append( + f"Appliance at version: {isamAppliance.facts['version']}, enable_mtls: {enable_mtls} is not supported. Needs 10.0.8.0 or higher. Ignoring enable_mtls for this call.") + else: + json_data["enable_mtls"] = enable_mtls + if mutual_key_label is not None: + if ibmsecurity.utilities.tools.version_compare(isamAppliance.facts["version"], "10.0.8.0") < 0: + warnings.append( + f"Appliance at version: {isamAppliance.facts['version']}, mutual_key_label: {mutual_key_label} is not supported. Needs 10.0.8.0 or higher. Ignoring mutual_key_label for this call.") + else: + json_data["mutual_key_label"] = mutual_key_label + if check_mode is True: + return isamAppliance.create_return_object(changed=True, warnings=warnings) + else: + return isamAppliance.invoke_post( + "OAuth2 IBM Security Verify OIDC Provider configuration for a reverse proxy instance", + f"/wga/reverseproxy/{instance_id}/oauth2_config", + json_data, + warnings=warnings, + requires_modules=requires_modules, requires_version=requires_version) + return isamAppliance.create_return_object(warnings=warnings) + +def _check_config(isamAppliance, instance_id, junction): + """ + Check if the junction for oauth already created. This is overly simplistic. + + :param isamAppliance: + :param instance_id: + :param junction: + :return: + """ + ret_obj = junctions.get_all(isamAppliance, instance_id) + + for j in ret_obj['data']: + if j['id'] == junction: + logger.info(f"Junction {junction} was found - hence oauth2 config must have already executed.") + return True + + return False From 20866f95f7815bd9bf0e3f01b6c39b0e022ecdda Mon Sep 17 00:00:00 2001 From: Tom Bosmans Date: Wed, 28 May 2025 09:42:59 +0200 Subject: [PATCH 28/54] fix: comments --- ibmsecurity/isam/web/reverse_proxy/oauth_configuration.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ibmsecurity/isam/web/reverse_proxy/oauth_configuration.py b/ibmsecurity/isam/web/reverse_proxy/oauth_configuration.py index 0469bd34..664c957a 100644 --- a/ibmsecurity/isam/web/reverse_proxy/oauth_configuration.py +++ b/ibmsecurity/isam/web/reverse_proxy/oauth_configuration.py @@ -99,7 +99,7 @@ def config(isamAppliance, instance_id, hostname='127.0.0.1', port=443, username= def _check_config(isamAppliance, instance_id, junction): """ - Check if the junction for oauth already created + Check if the junction for oauth already created. This is overly simplistic. :param isamAppliance: :param instance_id: From 6cf3636084146ae29aafc8273bbd9954b6fe74bf Mon Sep 17 00:00:00 2001 From: Tom Bosmans Date: Wed, 28 May 2025 09:50:28 +0200 Subject: [PATCH 29/54] feature: test for new module --- test/test_web_reverseproxy_oauth2.py | 52 ++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 test/test_web_reverseproxy_oauth2.py diff --git a/test/test_web_reverseproxy_oauth2.py b/test/test_web_reverseproxy_oauth2.py new file mode 100644 index 00000000..37915f89 --- /dev/null +++ b/test/test_web_reverseproxy_oauth2.py @@ -0,0 +1,52 @@ +import logging + +import ibmsecurity.isam.web.reverse_proxy.oauth2_configuration +import ibmsecurity.isam.appliance + +import pytest + +def getTestData(): + testdata = [ + { + "hostname": "127.0.0.1", + "port": "443", + "reuse_certs": True, + "load_certificate": True, + "reuse_acls": True, + "junction": "/isvaop" + }, + ] + return testdata + + +@pytest.mark.parametrize("items", getTestData()) +def test_set_reverseproxy_isamop(iviaServer, caplog, items) -> None: + """Set some isvaop stuff.""" + caplog.set_level(logging.DEBUG) + + arg = {} + instance_id = 'default' + for k, v in items.items(): + if k == 'instance_id': + instance_id = v + continue + arg[k] = v + + returnValue = ibmsecurity.isam.web.reverse_proxy.oauth2_configuration.config(iviaServer, + instance_id, + force=False, + **arg) + logging.log(logging.INFO, returnValue) + + assert not returnValue.failed() + + + +def test_commit(iviaServer, caplog) -> None: + """Not actually a test, but save the changes.""" + caplog.set_level(logging.INFO) + + returnValue = ibmsecurity.isam.appliance.commit(iviaServer) + logging.log(logging.DEBUG, returnValue) + + assert not returnValue.failed() From 4b8ac703626ed78251f7c206848de738367aaff6 Mon Sep 17 00:00:00 2001 From: Tom Bosmans Date: Wed, 28 May 2025 10:00:55 +0200 Subject: [PATCH 30/54] feature: new sms connection module --- .../isam/aac/server_connections/sms.py | 193 ++++++++++++++++++ 1 file changed, 193 insertions(+) create mode 100644 ibmsecurity/isam/aac/server_connections/sms.py diff --git a/ibmsecurity/isam/aac/server_connections/sms.py b/ibmsecurity/isam/aac/server_connections/sms.py new file mode 100644 index 00000000..052b130b --- /dev/null +++ b/ibmsecurity/isam/aac/server_connections/sms.py @@ -0,0 +1,193 @@ +import logging +from ibmsecurity.utilities import tools + +logger = logging.getLogger(__name__) + +requires_modules = ["mga", "federation"] +requires_version = "10.0.8.0" + +uri='/mga/server_connections/sms' + +def get_all(isamAppliance, check_mode=False, force=False): + """ + Retrieving a list of all SMS server connections + """ + return isamAppliance.invoke_get("Retrieving a list of all SMS server connections", + f"{uri}/v1", + requires_modules=requires_modules, requires_version=requires_version) + + +def get(isamAppliance, name, check_mode=False, force=False): + """ + Retrieving a SMS server connection + """ + ret_obj = search(isamAppliance, name=name) + id = ret_obj['data'] + + if id == {}: + return isamAppliance.create_return_object() + else: + return isamAppliance.invoke_get("Retrieving a SMS server connection", + f"{uri}/{id}/v1", + requires_modules=requires_modules, requires_version=requires_version) + + +def set(isamAppliance, name, connection, description='', locked=False, connectionManager=None, new_name=None, ignore_password_for_idempotency=False, + check_mode=False, force=False): + """ + Creating or Modifying an SMS server connection + """ + if _check_exists(isamAppliance, name=name) is False: + # Force the add - we already know connection does not exist + return add(isamAppliance=isamAppliance, name=name, connection=connection, description=description, + locked=locked, connectionManager=connectionManager, check_mode=check_mode, force=True) + else: + # Update request + return update(isamAppliance=isamAppliance, name=name, connection=connection, description=description, + locked=locked, connectionManager=connectionManager, new_name=new_name, ignore_password_for_idempotency=ignore_password_for_idempotency, + check_mode=check_mode, force=force) + + +def add(isamAppliance, name, connection, description='', locked=False, connectionManager=None, check_mode=False, + force=False): + """ + Creating a SMS server connection + """ + if force is True or _check_exists(isamAppliance, name=name) is False: + if check_mode is True: + return isamAppliance.create_return_object(changed=True) + else: + return isamAppliance.invoke_post( + "Creating a SMS server connection", + f"{uri}/v1", + _create_json(name=name, description=description, locked=locked, connection=connection, + connectionManager=connectionManager), + requires_modules=requires_modules, requires_version=requires_version) + + return isamAppliance.create_return_object() + + +def delete(isamAppliance, name, check_mode=False, force=False): + """ + Deleting a SMS server connection + """ + if force is True or _check_exists(isamAppliance, name=name) is True: + if check_mode is True: + return isamAppliance.create_return_object(changed=True) + else: + ret_obj = search(isamAppliance, name=name) + id = ret_obj['data'] + return isamAppliance.invoke_delete( + "Deleting a SMS server connection", + f"{uri}/{id}/v1", + requires_modules=requires_modules, requires_version=requires_version) + + return isamAppliance.create_return_object() + + +def update(isamAppliance, name, connection, description='', locked=False, connectionManager=None, new_name=None, ignore_password_for_idempotency=False, + check_mode=False, force=False): + """ + Modifying a SMS server connection + + Use new_name to rename the connection. + """ + ret_obj = get(isamAppliance, name) + warnings = ret_obj["warnings"] + + if ret_obj["data"] == {}: + warnings.append("SMS server connection {0} not found, skipping update.".format(name)) + return isamAppliance.create_return_object(warnings=warnings) + else: + id = ret_obj["data"]["uuid"] + + needs_update = False + + json_data = _create_json(name=name, description=description, locked=locked, connection=connection, connectionManager=connectionManager) + if new_name is not None: # Rename condition + json_data['name'] = new_name + + if force is not True: + ret_obj['data'].pop('uuid', None) + if ignore_password_for_idempotency: + if 'password' in connection: + warnings.append("Request made to ignore password for idempotency check.") + connection.pop('password', None) + + sorted_ret_obj = tools.json_sort(ret_obj['data']) + sorted_json_data = tools.json_sort(json_data) + logger.debug("Sorted Existing Data:{0}".format(sorted_ret_obj)) + logger.debug("Sorted Desired Data:{0}".format(sorted_json_data)) + + if sorted_ret_obj != sorted_json_data: + needs_update = True + + if force is True or needs_update is True: + if check_mode is True: + return isamAppliance.create_return_object(changed=True, warnings=warnings) + else: + return isamAppliance.invoke_put( + "Modifying a SMS server connection", + f"{uri}/{id}/v1", + json_data, + requires_modules=requires_modules, requires_version=requires_version, warnings=warnings) + +def _create_json(name, description, locked, connection, connectionManager): + """ + Create a JSON to be used for the REST API call + """ + json = { + "connection": connection, + "type": "sms", + "name": name, + "description": description, + "locked": locked + } + # connection manager is optional + if connectionManager is not None: + json['connectionManager'] = connectionManager + + return json + + +def search(isamAppliance, name, check_mode=False, force=False): + """ + Retrieve UUID for named SMS connection + """ + ret_obj = get_all(isamAppliance) + + ret_obj_new = isamAppliance.create_return_object() + + for obj in ret_obj['data']: + if obj['name'] == name: + ret_obj_new['data'] = obj['uuid'] + + return ret_obj_new + + +def _check_exists(isamAppliance, name=None, id=None): + """ + Check if SMS Connection already exists + """ + ret_obj = get_all(isamAppliance) + + for obj in ret_obj['data']: + if (name is not None and obj['name'] == name) or (id is not None and obj['uuid'] == id): + return True + + return False + + +def compare(isamAppliance1, isamAppliance2): + """ + Compare SMS Connections between two appliances + """ + ret_obj1 = get_all(isamAppliance1) + ret_obj2 = get_all(isamAppliance2) + + for obj in ret_obj1['data']: + del obj['uuid'] + for obj in ret_obj2['data']: + del obj['uuid'] + + return ibmsecurity.utilities.tools.json_compare(ret_obj1, ret_obj2, deleted_keys=['uuid']) From fe83776011921101fb275fb27a455f5e48b8b0f5 Mon Sep 17 00:00:00 2001 From: Tom Bosmans Date: Wed, 28 May 2025 10:04:05 +0200 Subject: [PATCH 31/54] fix: format to f-string --- ibmsecurity/isam/aac/server_connections/sms.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ibmsecurity/isam/aac/server_connections/sms.py b/ibmsecurity/isam/aac/server_connections/sms.py index 052b130b..643d7746 100644 --- a/ibmsecurity/isam/aac/server_connections/sms.py +++ b/ibmsecurity/isam/aac/server_connections/sms.py @@ -96,7 +96,7 @@ def update(isamAppliance, name, connection, description='', locked=False, connec warnings = ret_obj["warnings"] if ret_obj["data"] == {}: - warnings.append("SMS server connection {0} not found, skipping update.".format(name)) + warnings.append(f"SMS server connection {name} not found, skipping update.") return isamAppliance.create_return_object(warnings=warnings) else: id = ret_obj["data"]["uuid"] @@ -116,8 +116,8 @@ def update(isamAppliance, name, connection, description='', locked=False, connec sorted_ret_obj = tools.json_sort(ret_obj['data']) sorted_json_data = tools.json_sort(json_data) - logger.debug("Sorted Existing Data:{0}".format(sorted_ret_obj)) - logger.debug("Sorted Desired Data:{0}".format(sorted_json_data)) + logger.debug(f"Sorted Existing Data:{sorted_ret_obj}") + logger.debug(f"Sorted Desired Data:{sorted_json_data}") if sorted_ret_obj != sorted_json_data: needs_update = True From b99dcc82c9a2864f15e63388f2fde6cc432ba508 Mon Sep 17 00:00:00 2001 From: Tom Bosmans Date: Wed, 28 May 2025 10:27:28 +0200 Subject: [PATCH 32/54] fix: change compare method --- .../isam/aac/server_connections/sms.py | 22 ++++++++----------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/ibmsecurity/isam/aac/server_connections/sms.py b/ibmsecurity/isam/aac/server_connections/sms.py index 643d7746..5aa1a805 100644 --- a/ibmsecurity/isam/aac/server_connections/sms.py +++ b/ibmsecurity/isam/aac/server_connections/sms.py @@ -1,5 +1,5 @@ import logging -from ibmsecurity.utilities import tools +import json logger = logging.getLogger(__name__) @@ -106,24 +106,20 @@ def update(isamAppliance, name, connection, description='', locked=False, connec json_data = _create_json(name=name, description=description, locked=locked, connection=connection, connectionManager=connectionManager) if new_name is not None: # Rename condition json_data['name'] = new_name - - if force is not True: + if not force: ret_obj['data'].pop('uuid', None) if ignore_password_for_idempotency: if 'password' in connection: warnings.append("Request made to ignore password for idempotency check.") connection.pop('password', None) - - sorted_ret_obj = tools.json_sort(ret_obj['data']) - sorted_json_data = tools.json_sort(json_data) - logger.debug(f"Sorted Existing Data:{sorted_ret_obj}") - logger.debug(f"Sorted Desired Data:{sorted_json_data}") - + sorted_json_data = json.dumps(json_data, skipkeys=True, sort_keys=True) + logger.debug(f"\n\nSorted input: {sorted_json_data}") + sorted_ret_obj = json.dumps(ret_obj['data'], skipkeys=True, sort_keys=True) + logger.debug(f"\n\nSorted existing data: {sorted_ret_obj}") if sorted_ret_obj != sorted_json_data: - needs_update = True - - if force is True or needs_update is True: - if check_mode is True: + needs_update = True + if force or needs_update: + if check_mode: return isamAppliance.create_return_object(changed=True, warnings=warnings) else: return isamAppliance.invoke_put( From f1933ed917c53891e3888f772ef722a37ad7c921 Mon Sep 17 00:00:00 2001 From: Tom Bosmans Date: Wed, 28 May 2025 10:30:30 +0200 Subject: [PATCH 33/54] fix: disable all pylint checks --- pylintrc | 36 +++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/pylintrc b/pylintrc index 7fb89105..78c788fe 100644 --- a/pylintrc +++ b/pylintrc @@ -429,30 +429,32 @@ confidence=HIGH, # --enable=similarities". If you want to run only the classes checker, but have # no Warning level messages displayed, use "--disable=all --enable=classes # --disable=W". -disable=raw-checker-failed, - bad-inline-option, - locally-disabled, - file-ignored, - suppressed-message, - useless-suppression, - deprecated-pragma, - use-symbolic-message-instead, - use-implicit-booleaness-not-comparison-to-string, - use-implicit-booleaness-not-comparison-to-zero, - C0103, - R0913, - R0917, - C0103, - W0613, - W0622 +#disable=raw-checker-failed, +# bad-inline-option, +# locally-disabled, +# file-ignored, +# suppressed-message, +# useless-suppression, +# deprecated-pragma, +# use-symbolic-message-instead, +# use-implicit-booleaness-not-comparison-to-string, +# use-implicit-booleaness-not-comparison-to-zero, +# C0103, +# R0913, +# R0917, +# C0103, +# W0613, +# W0622, +# R0801 +disable=all # Enable the message, report, category or checker with the given id(s). You can # either give multiple identifier separated by comma (,) or put this option # multiple time (only on the command line, not in the configuration file where # it should appear only once). See also the "--disable" option for examples. +#enable=R1705 enable= - [METHOD_ARGS] # List of qualified names (i.e., library.method) which require a timeout From dab917751427abbd913525d2ae63d069c2d057d9 Mon Sep 17 00:00:00 2001 From: Tom Bosmans Date: Wed, 28 May 2025 10:40:54 +0200 Subject: [PATCH 34/54] feature: add test for sms connection --- docs/contributing.md | 1 + pylintrc | 2 +- test/test_aac_serverconnections_sms.py | 82 ++++++++++++++++++++++++++ 3 files changed, 84 insertions(+), 1 deletion(-) create mode 100644 test/test_aac_serverconnections_sms.py diff --git a/docs/contributing.md b/docs/contributing.md index 2e3d11cd..1aa51e71 100644 --- a/docs/contributing.md +++ b/docs/contributing.md @@ -49,6 +49,7 @@ pushing commits, just use [tox](https://tox.wiki/en/latest/). ## Talk to us + ## Code of Conduct diff --git a/pylintrc b/pylintrc index 78c788fe..9572874e 100644 --- a/pylintrc +++ b/pylintrc @@ -453,7 +453,7 @@ disable=all # multiple time (only on the command line, not in the configuration file where # it should appear only once). See also the "--disable" option for examples. #enable=R1705 -enable= +enable=C0209 [METHOD_ARGS] diff --git a/test/test_aac_serverconnections_sms.py b/test/test_aac_serverconnections_sms.py new file mode 100644 index 00000000..3352fe85 --- /dev/null +++ b/test/test_aac_serverconnections_sms.py @@ -0,0 +1,82 @@ +import logging + +import ibmsecurity.isam.aac.server_connections +import ibmsecurity.isam.aac.server_connections.sms +import ibmsecurity.isam.appliance + +import pytest + +def getTestData(): + testdata = [ + { + "connection": { + "url": "https://localhost", + "user": "isamUser", + "password": "password", + "sslTruststore": "lmi_trust_store", + "sslAuthKey": "server" + }, + "connectionManager": { + "requestParameters": "from = +12345678, to = $DEST_NO$, message = $MSG$", + "successReturnCode": "201", + "responseBodyRegex": ".*" + }, + "name": "SMSTestConnection", + "description": "A test connection to a SMS server", + "locked": False, + "ignore_password_for_idempotency": True + } + ] + return testdata + + +def test_get_serverconnection_sms(iviaServer, caplog) -> None: + """Get sms protection""" + caplog.set_level(logging.DEBUG) + arg = {} + + returnValue = ibmsecurity.isam.aac.server_connections.sms.get_all(iviaServer, + **arg + ) + logging.log(logging.INFO, returnValue) + + + assert not returnValue.failed() + + +@pytest.mark.parametrize("items", getTestData()) +def test_set_serverconnection_sms(iviaServer, caplog, items) -> None: + """Set api protection""" + caplog.set_level(logging.DEBUG) + # items is a key-value pair + logging.log(logging.INFO, items) + arg = {} + connection = {} + for k, v in items.items(): + if k == 'name': + name = v + continue + if k == 'connection': + connection = v + continue + arg[k] = v + + returnValue = ibmsecurity.isam.aac.server_connections.sms.set(iviaServer, + name, + connection, + **arg + ) + logging.log(logging.INFO, returnValue) + + if returnValue is not None: + assert not returnValue.failed() + + +def test_commit(iviaServer, caplog) -> None: + """Not actually a test, but save the changes.""" + caplog.set_level(logging.INFO) + + returnValue = ibmsecurity.isam.appliance.commit(isamAppliance=iviaServer) + logging.log(logging.DEBUG, returnValue) + + assert not returnValue.failed() From 9c5e5f18bd2564367dc7b16ca392cb25ae5c8346 Mon Sep 17 00:00:00 2001 From: Tom Bosmans Date: Wed, 28 May 2025 11:01:43 +0200 Subject: [PATCH 35/54] feature: update pre-commit --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 24fb7238..164e1d08 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -22,6 +22,6 @@ repos: hooks: - id: pylint args: [ - "-ry", + "--recursive=y", "--exit-zero" ] From e3bc929617c6d94e174ec602c83ca3a3e77b3234 Mon Sep 17 00:00:00 2001 From: Tom Bosmans Date: Wed, 28 May 2025 11:02:00 +0200 Subject: [PATCH 36/54] feature: update pylint config --- .github/workflows/pylint.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pylint.yml b/.github/workflows/pylint.yml index 6e21c90d..bdc851f2 100644 --- a/.github/workflows/pylint.yml +++ b/.github/workflows/pylint.yml @@ -20,4 +20,4 @@ jobs: pip install pylint - name: Analysing the code with pylint run: | - pylint $(git ls-files '*.py') + pylint $(git ls-files 'ibmsecurity/isam/*.py') --exit-zero From 5c8a0183a7f8ab7327588fae918cdbec562de3df Mon Sep 17 00:00:00 2001 From: Tom Bosmans Date: Wed, 28 May 2025 11:05:29 +0200 Subject: [PATCH 37/54] fix: format() -> f-string --- ibmsecurity/isam/aac/server_connections/ci.py | 12 +++++----- .../aac/server_connections/isamruntime.py | 18 +++++++-------- .../isam/aac/server_connections/jdbc.py | 12 +++++----- .../isam/aac/server_connections/ldap.py | 12 +++++----- .../isam/aac/server_connections/redis.py | 22 +++++++++---------- .../isam/aac/server_connections/smtp.py | 12 +++++----- ibmsecurity/isam/aac/server_connections/ws.py | 20 ++++++++--------- 7 files changed, 54 insertions(+), 54 deletions(-) diff --git a/ibmsecurity/isam/aac/server_connections/ci.py b/ibmsecurity/isam/aac/server_connections/ci.py index 1662ac1d..55ea1d9b 100644 --- a/ibmsecurity/isam/aac/server_connections/ci.py +++ b/ibmsecurity/isam/aac/server_connections/ci.py @@ -27,7 +27,7 @@ def get(isamAppliance, name, check_mode=False, force=False): return isamAppliance.create_return_object() else: return isamAppliance.invoke_get("Retrieving a CI server connection", - "/mga/server_connections/ci/{0}/v1".format(id), + f"/mga/server_connections/ci/{id}/v1", requires_modules=requires_modules, requires_version=requires_version) @@ -75,7 +75,7 @@ def delete(isamAppliance, name, check_mode=False, force=False): id = ret_obj['data'] return isamAppliance.invoke_delete( "Deleting a CI server connection", - "/mga/server_connections/ci/{0}/v1".format(id), requires_modules=requires_modules, + f"/mga/server_connections/ci/{id}/v1", requires_modules=requires_modules, requires_version=requires_version) return isamAppliance.create_return_object() @@ -90,7 +90,7 @@ def update(isamAppliance, name, connection, description='', locked=False, new_na warnings = ret_obj["warnings"] if ret_obj["data"] == {}: - warnings.append("CI server connection {0} not found, skipping update.".format(name)) + warnings.append(f"CI server connection {name} not found, skipping update.") return isamAppliance.create_return_object(warnings=warnings) else: id = ret_obj["data"]["uuid"] @@ -111,8 +111,8 @@ def update(isamAppliance, name, connection, description='', locked=False, new_na sorted_ret_obj = tools.json_sort(ret_obj['data']) sorted_json_data = tools.json_sort(json_data) - logger.debug("Sorted Existing Data:{0}".format(sorted_ret_obj)) - logger.debug("Sorted Desired Data:{0}".format(sorted_json_data)) + logger.debug(f"Sorted Existing Data:{sorted_ret_obj}") + logger.debug(f"Sorted Desired Data:{sorted_json_data}") if sorted_ret_obj != sorted_json_data: needs_update = True @@ -123,7 +123,7 @@ def update(isamAppliance, name, connection, description='', locked=False, new_na else: return isamAppliance.invoke_put( "Modifying a CI server connection", - "/mga/server_connections/ci/{0}/v1".format(id), json_data, requires_modules=requires_modules, + f"/mga/server_connections/ci/{id}/v1", json_data, requires_modules=requires_modules, requires_version=requires_version) return isamAppliance.create_return_object(warnings=warnings) diff --git a/ibmsecurity/isam/aac/server_connections/isamruntime.py b/ibmsecurity/isam/aac/server_connections/isamruntime.py index 4d2b0d8b..63847728 100644 --- a/ibmsecurity/isam/aac/server_connections/isamruntime.py +++ b/ibmsecurity/isam/aac/server_connections/isamruntime.py @@ -12,7 +12,7 @@ def get_all(isamAppliance, check_mode=False, force=False): Retrieving a list of all ISAM Runtime server connections """ return isamAppliance.invoke_get("Retrieving a list of all ISAM Runtime server connections", - "{0}/v1".format(uri), + f"{uri}/v1", requires_modules=requires_modules, requires_version=requires_version) @@ -28,7 +28,7 @@ def get(isamAppliance, name, check_mode=False, force=False): return isamAppliance.create_return_object() else: return isamAppliance.invoke_get("Retrieving an ISAM Runtime server connection", - "{0}/{1}/v1".format(uri, id), + f"{uri}/{id}/v1", requires_modules=requires_modules, requires_version=requires_version) @@ -43,7 +43,7 @@ def add(isamAppliance, name, connection, description="", locked=False, check_mod else: return isamAppliance.invoke_post( "Creating an ISAM Runtime server connection", - "{0}/v1".format(uri), + f"{uri}/v1", { "locked": locked, "description": description, @@ -68,7 +68,7 @@ def update(isamAppliance, name, connection, locked=False, description='', new_na warnings = ret_obj["warnings"] if ret_obj["data"] == {}: - warnings.append("ISAM Runtime server connection {0} not found, skipping update.".format(name)) + warnings.append(f"ISAM Runtime server connection {name} not found, skipping update.") return isamAppliance.create_return_object(warnings=warnings) else: id = ret_obj["data"]["uuid"] @@ -89,8 +89,8 @@ def update(isamAppliance, name, connection, locked=False, description='', new_na sorted_ret_obj = tools.json_sort(ret_obj['data']) sorted_json_data = tools.json_sort(json_data) - logger.debug("Sorted Existing Data:{0}".format(sorted_ret_obj)) - logger.debug("Sorted Desired Data:{0}".format(sorted_json_data)) + logger.debug(f"Sorted Existing Data:{sorted_ret_obj}") + logger.debug(f"Sorted Desired Data:{sorted_json_data}") if sorted_ret_obj != sorted_json_data: needs_update = True @@ -101,7 +101,7 @@ def update(isamAppliance, name, connection, locked=False, description='', new_na else: return isamAppliance.invoke_put( "Modifying an ISAM Runtime server connection", - "{0}/{1}/v1".format(uri, id), + f"{uri}/{id}/v1", json_data, requires_modules=requires_modules, requires_version=requires_version ) @@ -141,7 +141,7 @@ def delete(isamAppliance, name, check_mode=False, force=False): return isamAppliance.invoke_delete( "Deleting an ISAM Runtime server connection", - "{0}/{1}/v1".format(uri, id), + f"{uri}/{id}/v1", requires_modules=requires_modules, requires_version=requires_version ) @@ -173,7 +173,7 @@ def search(isamAppliance, name, force=False, check_mode=False): for obj in ret_obj['data']: if obj['name'] == name: - logger.info("Found isamruntime '{0}' uuid: '{1}'".format(name, obj['uuid'])) + logger.info(f"Found isamruntime '{name}' uuid: '{obj['uuid']}'") ret_obj_new['data'] = obj['uuid'] return ret_obj_new diff --git a/ibmsecurity/isam/aac/server_connections/jdbc.py b/ibmsecurity/isam/aac/server_connections/jdbc.py index 4dc71fac..6a72ec30 100644 --- a/ibmsecurity/isam/aac/server_connections/jdbc.py +++ b/ibmsecurity/isam/aac/server_connections/jdbc.py @@ -24,7 +24,7 @@ def get(isamAppliance, name, check_mode=False, force=False): return isamAppliance.create_return_object() else: return isamAppliance.invoke_get("Retrieving a JDBC server connection", - "/mga/server_connections/jdbc/{0}/v1".format(id)) + f"/mga/server_connections/jdbc/{id}/v1") def set(isamAppliance, name, connection, type, jndiId, description='', locked=False, connectionManager=None, @@ -74,7 +74,7 @@ def delete(isamAppliance, name, check_mode=False, force=False): id = ret_obj['data'] return isamAppliance.invoke_delete( "Deleting a JDBC server connection", - "/mga/server_connections/jdbc/{0}/v1".format(id)) + f"/mga/server_connections/jdbc/{id}/v1") return isamAppliance.create_return_object() @@ -89,7 +89,7 @@ def update(isamAppliance, name, connection, type, jndiId, description='', locked warnings = ret_obj["warnings"] if ret_obj["data"] == {}: - warnings.append("JDBC server connection {0} not found, skipping update.".format(name)) + warnings.append(f"JDBC server connection {name} not found, skipping update.") return isamAppliance.create_return_object(warnings=warnings) else: id = ret_obj["data"]["uuid"] @@ -111,8 +111,8 @@ def update(isamAppliance, name, connection, type, jndiId, description='', locked sorted_ret_obj = tools.json_sort(ret_obj['data']) sorted_json_data = tools.json_sort(json_data) - logger.debug("Sorted Existing Data:{0}".format(sorted_ret_obj)) - logger.debug("Sorted Desired Data:{0}".format(sorted_json_data)) + logger.debug(f"Sorted Existing Data:{sorted_ret_obj}") + logger.debug(f"Sorted Desired Data:{sorted_json_data}") if sorted_ret_obj != sorted_json_data: needs_update = True @@ -123,7 +123,7 @@ def update(isamAppliance, name, connection, type, jndiId, description='', locked else: return isamAppliance.invoke_put( "Modifying a JDBC server connection", - "/mga/server_connections/jdbc/{0}/v1".format(id), json_data, requires_modules=requires_modules, + f"/mga/server_connections/jdbc/{id}/v1", json_data, requires_modules=requires_modules, requires_version=requires_version, warnings=warnings) return isamAppliance.create_return_object(warnings=warnings) diff --git a/ibmsecurity/isam/aac/server_connections/ldap.py b/ibmsecurity/isam/aac/server_connections/ldap.py index 1e466b3c..8f543c83 100644 --- a/ibmsecurity/isam/aac/server_connections/ldap.py +++ b/ibmsecurity/isam/aac/server_connections/ldap.py @@ -26,7 +26,7 @@ def get(isamAppliance, name, check_mode=False, force=False): return isamAppliance.create_return_object() else: return isamAppliance.invoke_get("Retrieving an LDAP server connection", - "/mga/server_connections/ldap/{0}/v1".format(id), + f"/mga/server_connections/ldap/{id}/v1", requires_modules=requires_modules, requires_version=requires_version) @@ -78,7 +78,7 @@ def delete(isamAppliance, name, check_mode=False, force=False): id = ret_obj['data'] return isamAppliance.invoke_delete( "Deleting an LDAP server connection", - "/mga/server_connections/ldap/{0}/v1".format(id), + f"/mga/server_connections/ldap/{id}/v1", requires_modules=requires_modules, requires_version=requires_version) return isamAppliance.create_return_object() @@ -95,7 +95,7 @@ def update(isamAppliance, name, connection, description='', locked=False, connec warnings = ret_obj["warnings"] if ret_obj["data"] == {}: - warnings.append("LDAP server connection {0} not found, skipping update.".format(name)) + warnings.append(f"LDAP server connection {name} not found, skipping update.") return isamAppliance.create_return_object(warnings=warnings) else: id = ret_obj["data"]["uuid"] @@ -116,8 +116,8 @@ def update(isamAppliance, name, connection, description='', locked=False, connec sorted_ret_obj = tools.json_sort(ret_obj['data']) sorted_json_data = tools.json_sort(json_data) - logger.debug("Sorted Existing Data:{0}".format(sorted_ret_obj)) - logger.debug("Sorted Desired Data:{0}".format(sorted_json_data)) + logger.debug(f"Sorted Existing Data:{sorted_ret_obj}") + logger.debug(f"Sorted Desired Data:{sorted_json_data}") if sorted_ret_obj != sorted_json_data: needs_update = True @@ -128,7 +128,7 @@ def update(isamAppliance, name, connection, description='', locked=False, connec else: return isamAppliance.invoke_put( "Modifying an LDAP server connection", - "/mga/server_connections/ldap/{0}/v1".format(id), json_data, + f"/mga/server_connections/ldap/{id}/v1", json_data, requires_modules=requires_modules, requires_version=requires_version, warnings=warnings) return isamAppliance.create_return_object(warnings=warnings) diff --git a/ibmsecurity/isam/aac/server_connections/redis.py b/ibmsecurity/isam/aac/server_connections/redis.py index 0939d211..2686f328 100644 --- a/ibmsecurity/isam/aac/server_connections/redis.py +++ b/ibmsecurity/isam/aac/server_connections/redis.py @@ -16,7 +16,7 @@ def get_all(isamAppliance, check_mode=False, force=False): Retrieving a list of all Redis connections """ return isamAppliance.invoke_get("Retrieving a list of all Redis connections", - "{0}/v1".format(uri), requires_modules=requires_modules, + f"{uri}/v1", requires_modules=requires_modules, requires_version=requires_version) @@ -28,11 +28,11 @@ def get(isamAppliance, name=None, check_mode=False, force=False): id = ret_obj["data"] if id == {}: - logger.info("Redis Service connection {0} had no match, skipping retrieval.".format(name)) + logger.info(f"Redis Service connection {name} had no match, skipping retrieval.") return isamAppliance.create_return_object() else: return isamAppliance.invoke_get("Retrieving a Redis Service connection", - "{0}/{1}/v1".format(uri, id), + f"{uri}/{id}/v1", requires_modules=requires_modules, requires_version=requires_version) @@ -47,7 +47,7 @@ def search(isamAppliance, name, check_mode=False, force=False): for obj in ret_obj['data']: if obj['name'] == name: - logger.info("Found Redis Service connection {0} id: {1}".format(name, obj['uuid'])) + logger.info(f"Found Redis Service connection {name} id: {obj['uuid']}") return_obj['data'] = obj['uuid'] return_obj['rc'] = 0 @@ -64,7 +64,7 @@ def add(isamAppliance, name, connection, description='', connectionManager=None, else: return isamAppliance.invoke_post( "Creating a Redis Service connection", - "{0}/v1".format(uri), + f"{uri}/v1", _create_json(name=name, description=description, locked=locked, @@ -89,7 +89,7 @@ def delete(isamAppliance, name, check_mode=False, force=False): else: return isamAppliance.invoke_delete( "Deleting a Redis connection", - "{0}/{1}/v1".format(uri, id), requires_modules=requires_modules, + f"{uri}/{id}/v1", requires_modules=requires_modules, requires_version=requires_version) return isamAppliance.create_return_object() @@ -106,7 +106,7 @@ def update(isamAppliance, name, connection, description='', locked=False, connec warnings = ret_obj["warnings"] if ret_obj["data"] == {}: - warnings.append("Redis connection {0} not found, skipping update.".format(name)) + warnings.append(f"Redis connection {name} not found, skipping update.") return isamAppliance.create_return_object(warnings=warnings) else: id = ret_obj["data"]["uuid"] @@ -134,14 +134,14 @@ def update(isamAppliance, name, connection, description='', locked=False, connec if 'servers' in ret_obj['data']: for x in ret_obj['data']['servers']: if 'uuid' in x: - logger.debug("Deleting uuid from returned object:\n{0}".format(x['uuid'])) + logger.debug(f"Deleting uuid from returned object:\n{x['uuid']}") del x['uuid'] sorted_ret_obj = json.dumps(ret_obj['data'], skipkeys=True, sort_keys=True) sorted_json_data = json.dumps(json_data, skipkeys=True, sort_keys=True) - logger.debug("Sorted Existing Data:\n{0}".format(sorted_ret_obj)) - logger.debug("Sorted Desired Data:\n{0}".format(sorted_json_data)) + logger.debug(f"Sorted Existing Data:\n{sorted_ret_obj}") + logger.debug(f"Sorted Desired Data:\n{sorted_json_data}") if sorted_ret_obj != sorted_json_data: needs_update = True @@ -156,7 +156,7 @@ def update(isamAppliance, name, connection, description='', locked=False, connec else: return isamAppliance.invoke_put( "Modifying a Redis connection", - "{0}/{1}/v1".format(uri, id), json_data, requires_modules=requires_modules, + f"{uri}/{id}/v1", json_data, requires_modules=requires_modules, requires_version=requires_version, warnings=warnings) return isamAppliance.create_return_object(warnings=warnings) diff --git a/ibmsecurity/isam/aac/server_connections/smtp.py b/ibmsecurity/isam/aac/server_connections/smtp.py index f415d8f9..b2e379bd 100644 --- a/ibmsecurity/isam/aac/server_connections/smtp.py +++ b/ibmsecurity/isam/aac/server_connections/smtp.py @@ -26,7 +26,7 @@ def get(isamAppliance, name, check_mode=False, force=False): return isamAppliance.create_return_object() else: return isamAppliance.invoke_get("Retrieving a SMTP server connection", - "/mga/server_connections/smtp/{0}/v1".format(id), + f"/mga/server_connections/smtp/{id}/v1", requires_modules=requires_modules, requires_version=requires_version) @@ -77,7 +77,7 @@ def delete(isamAppliance, name, check_mode=False, force=False): id = ret_obj['data'] return isamAppliance.invoke_delete( "Deleting a SMTP server connection", - "/mga/server_connections/smtp/{0}/v1".format(id), + f"/mga/server_connections/smtp/{id}/v1", requires_modules=requires_modules, requires_version=requires_version) return isamAppliance.create_return_object() @@ -94,7 +94,7 @@ def update(isamAppliance, name, connection, description='', locked=False, connec warnings = ret_obj["warnings"] if ret_obj["data"] == {}: - warnings.append("LDAP server connection {0} not found, skipping update.".format(name)) + warnings.append(f"LDAP server connection {name} not found, skipping update.") return isamAppliance.create_return_object(warnings=warnings) else: id = ret_obj["data"]["uuid"] @@ -115,8 +115,8 @@ def update(isamAppliance, name, connection, description='', locked=False, connec sorted_ret_obj = tools.json_sort(ret_obj['data']) sorted_json_data = tools.json_sort(json_data) - logger.debug("Sorted Existing Data:{0}".format(sorted_ret_obj)) - logger.debug("Sorted Desired Data:{0}".format(sorted_json_data)) + logger.debug(f"Sorted Existing Data:{sorted_ret_obj}") + logger.debug(f"Sorted Desired Data:{sorted_json_data}") if sorted_ret_obj != sorted_json_data: needs_update = True @@ -127,7 +127,7 @@ def update(isamAppliance, name, connection, description='', locked=False, connec else: return isamAppliance.invoke_put( "Modifying a SMTP server connection", - "/mga/server_connections/smtp/{0}/v1".format(id), json_data, + f"/mga/server_connections/smtp/{id}/v1", json_data, requires_modules=requires_modules, requires_version=requires_version, warnings=warnings) def _create_json(name, description, locked, connection, connectionManager): diff --git a/ibmsecurity/isam/aac/server_connections/ws.py b/ibmsecurity/isam/aac/server_connections/ws.py index 3a0d9e68..88dba019 100644 --- a/ibmsecurity/isam/aac/server_connections/ws.py +++ b/ibmsecurity/isam/aac/server_connections/ws.py @@ -14,7 +14,7 @@ def get_all(isamAppliance, check_mode=False, force=False): Retrieving a list of all Web Service connections """ return isamAppliance.invoke_get("Retrieving a list of all Web Service connections", - "{0}/v1".format(uri), requires_modules=requires_modules, + f"{uri}/v1", requires_modules=requires_modules, requires_version=requires_version) @@ -26,11 +26,11 @@ def get(isamAppliance, name=None, check_mode=False, force=False): id = ret_obj["data"] if id == {}: - logger.info("Web Service connection {0} had no match, skipping retrieval.".format(name)) + logger.info(f"Web Service connection {name} had no match, skipping retrieval.") return isamAppliance.create_return_object() else: return isamAppliance.invoke_get("Retrieving a Web Service connection", - "{0}/{1}/v1".format(uri, id), + f"{uri}/{id}/v1", requires_modules=requires_modules, requires_version=requires_version) @@ -45,7 +45,7 @@ def search(isamAppliance, name, check_mode=False, force=False): for obj in ret_obj['data']: if obj['name'] == name: - logger.info("Found Web Service connection {0} id: {1}".format(name, obj['uuid'])) + logger.info(f"Found Web Service connection {name} id: {obj['uuid']}") return_obj['data'] = obj['uuid'] return_obj['rc'] = 0 @@ -62,7 +62,7 @@ def add(isamAppliance, name, connection, description='', locked=False, check_mod else: return isamAppliance.invoke_post( "Creating a Web Service connection", - "{0}/v1".format(uri), + f"{uri}/v1", _create_json(name=name, description=description, locked=locked, connection=connection), requires_modules=requires_modules, requires_version=requires_version) @@ -82,7 +82,7 @@ def delete(isamAppliance, name, check_mode=False, force=False): else: return isamAppliance.invoke_delete( "Deleting a Web Service connection", - "{0}/{1}/v1".format(uri, id), requires_modules=requires_modules, + f"{uri}/{id}/v1", requires_modules=requires_modules, requires_version=requires_version) return isamAppliance.create_return_object() @@ -99,7 +99,7 @@ def update(isamAppliance, name, connection, description='', locked=False, new_na warnings = ret_obj["warnings"] if ret_obj["data"] == {}: - warnings.append("Web Service connection {0} not found, skipping update.".format(name)) + warnings.append(f"Web Service connection {name} not found, skipping update.") return isamAppliance.create_return_object(warnings=warnings) else: id = ret_obj["data"]["uuid"] @@ -120,8 +120,8 @@ def update(isamAppliance, name, connection, description='', locked=False, new_na sorted_ret_obj = tools.json_sort(ret_obj['data']) sorted_json_data = tools.json_sort(json_data) - logger.debug("Sorted Existing Data:{0}".format(sorted_ret_obj)) - logger.debug("Sorted Desired Data:{0}".format(sorted_json_data)) + logger.debug(f"Sorted Existing Data:{sorted_ret_obj}") + logger.debug(f"Sorted Desired Data:{sorted_json_data}") if sorted_ret_obj != sorted_json_data: needs_update = True @@ -135,7 +135,7 @@ def update(isamAppliance, name, connection, description='', locked=False, new_na else: return isamAppliance.invoke_put( "Modifying a Web Service connection", - "{0}/{1}/v1".format(uri, id), json_data, requires_modules=requires_modules, + f"{uri}/{id}/v1", json_data, requires_modules=requires_modules, requires_version=requires_version, warnings=warnings) return isamAppliance.create_return_object(warnings=warnings) From 46759df42e0625eba5e40032380f97a02c7c9064 Mon Sep 17 00:00:00 2001 From: Tom Bosmans Date: Wed, 28 May 2025 11:11:06 +0200 Subject: [PATCH 38/54] fix: pylint generate text report --- .pre-commit-config.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 164e1d08..a0cac1b6 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -23,5 +23,6 @@ repos: - id: pylint args: [ "--recursive=y", - "--exit-zero" + "--exit-zero", + "--output-format=text:report.txt" ] From 00378f3c42123824da212bfa15f3544eb6a69c80 Mon Sep 17 00:00:00 2001 From: Tom Bosmans Date: Wed, 28 May 2025 11:16:43 +0200 Subject: [PATCH 39/54] fix: format() -> f-string --- .../isam/aac/access_control/policies.py | 63 ++++++-------- .../aac/access_control/policy_attachments.py | 85 ++++++++----------- .../isam/aac/access_control/policy_sets.py | 46 +++++----- 3 files changed, 82 insertions(+), 112 deletions(-) diff --git a/ibmsecurity/isam/aac/access_control/policies.py b/ibmsecurity/isam/aac/access_control/policies.py index 65c35ff9..44f70465 100644 --- a/ibmsecurity/isam/aac/access_control/policies.py +++ b/ibmsecurity/isam/aac/access_control/policies.py @@ -34,17 +34,13 @@ def get_all( if formatting == "json": return isamAppliance.invoke_get( "Retrieve a list of policies (JSON)", - "{0}/{1}".format( - uri_json, - tools.create_query_string(filter=filter, sortBy=sortBy, count=count)), + f"{uri_json}/{tools.create_query_string(filter=filter, sortBy=sortBy, count=count)}", warnings=warnings, ) else: return isamAppliance.invoke_get( "Retrieve a list of policies", - "{0}/{1}".format( - uri, - tools.create_query_string(filter=filter, sortBy=sortBy)), + f"{uri}/{tools.create_query_string(filter=filter, sortBy=sortBy)}", warnings=warnings, ) @@ -63,7 +59,7 @@ def get(isamAppliance, name, formatting="xml", check_mode=False, force=False): pol_id = ret_obj["data"] if pol_id == {}: - logger.info("Policy {0} had no match, skipping retrieval.".format(name)) + logger.info(f"Policy {name} had no match, skipping retrieval.") return isamAppliance.create_return_object() else: return _get(isamAppliance, pol_id, formatting=formatting) @@ -77,21 +73,20 @@ def _get(isamAppliance, pol_id, formatting="xml"): if formatting == "json": if tools.version_compare(isamAppliance.facts["version"], "10.0.6.0") < 0: warnings.append( - "Appliance is at version: {0}. JSON format not supported unless at least 10.0.6.0. Setting to xml.".format( - isamAppliance.facts["version"] + "Appliance is at version: {0}. JSON format not supported unless at least 10.0.6.0. Setting to xml.".format( isamAppliance.facts["version"] ) ) formatting = "xml" if formatting == "json": return isamAppliance.invoke_get( "Retrieve a specific policy (JSON)", - "{0}/{1}".format(uri_json, pol_id), + f"{uri_json}/{pol_id}", warnings=warnings, ) else: return isamAppliance.invoke_get( "Retrieve a specific policy", - "{0}/{1}".format(uri, pol_id), + f"{uri}/{pol_id}", warnings=warnings, ) @@ -114,9 +109,7 @@ def export_xacml( if formatting == "json": if tools.version_compare(isamAppliance.facts["version"], "10.0.6.0") < 0: warnings.append( - "Appliance is at version: {0}. JSON format not supported unless at 10.0.6.0 or higher. Setting to xml.".format( - isamAppliance.facts["version"] - ) + f"Appliance is at version: {isamAppliance.facts['version']}. JSON format not supported unless at 10.0.6.0 or higher. Setting to xml." ) formatting = "xml" if not force: @@ -167,7 +160,7 @@ def search(isamAppliance, name, formatting="xml", force=False, check_mode=False) for obj in ret_obj["data"]: if obj["name"] == name: - logger.info("Found Policy {0} id: {1}".format(name, obj["id"])) + logger.info(f"Found Policy {name} id: {obj['id']}") return_obj["data"] = obj["id"] return_obj["rc"] = 0 @@ -241,7 +234,7 @@ def set( """ if (search(isamAppliance, name=name, formatting=formatting))["data"] == {}: # Force the add - we already know policy does not exist - logger.info("Policy {0} had no match, requesting to add new one.".format(name)) + logger.info(f"Policy {name} had no match, requesting to add new one.") return add( isamAppliance, name, @@ -256,7 +249,7 @@ def set( ) else: # Update request - logger.info("Policy {0} exists, requesting to update.".format(name)) + logger.info(f"Policy {name} exists, requesting to update.") return update( isamAppliance, name, @@ -302,9 +295,7 @@ def add( tools.version_compare(isamAppliance.facts["version"], "10.0.6.0") < 0 ): warnings.append( - "Appliance is at version: {0}. JSON format not supported unless at least 10.0.6.0. Setting to xml.".format( - isamAppliance.facts["version"] - ) + f"Appliance is at version: {isamAppliance.facts['version']}. JSON format not supported unless at least 10.0.6.0. Setting to xml." ) formatting = "xml" if formatting == "json": @@ -330,7 +321,7 @@ def add( # For it to be valid XML, it has to start with 0: if check_mode is True: @@ -361,7 +350,7 @@ def publish_list(isamAppliance, attachments, check_mode=False, force=False): else: return isamAppliance.invoke_put( "Publish a list of policy attachments", - "{0}/deployment".format(uri), + f"{uri}/deployment", {"policyAttachmentIds": ",".join(id_list)}, ) @@ -391,9 +380,9 @@ def _convert_policy_name_to_id(isamAppliance, policies): ) pol_id = ret_obj["data"] if pol_id != {}: - logger.debug("Converting policy {0} to ID: {1}".format(name, pol_id)) + logger.debug(f"Converting policy {name} to ID: {pol_id}") else: - logger.warning("Unable to find policy {0}, skipping.".format(name)) + logger.warning(f"Unable to find policy {name}, skipping.") elif type == "policyset": ret_obj = ibmsecurity.isam.aac.access_control.policy_sets.search( isamAppliance, name @@ -401,10 +390,10 @@ def _convert_policy_name_to_id(isamAppliance, policies): pol_id = ret_obj["data"] if pol_id != {}: logger.debug( - "Converting policy set {0} to ID: {1}".format(name, pol_id) + f"Converting policy set {name} to ID: {pol_id}" ) else: - logger.warning("Unable to find policy set {0}, skipping.".format(name)) + logger.warning(f"Unable to find policy set {name}, skipping.") elif type == "definition": ret_obj = ibmsecurity.isam.aac.api_protection.definitions.search( isamAppliance, name @@ -412,17 +401,17 @@ def _convert_policy_name_to_id(isamAppliance, policies): pol_id = ret_obj["data"] if pol_id != {}: logger.debug( - "Converting api definition {0} to ID: {1}".format(name, pol_id) + f"Converting api definition {name} to ID: {pol_id}" ) else: logger.warning( - "Unable to find api definition {0}, skipping.".format(name) + f"Unable to find api definition {name}, skipping." ) else: from ibmsecurity.appliance.ibmappliance import IBMError raise IBMError( - "999", "Policy specified with unknown type: {0}/{1}".format(type, name) + "999", f"Policy specified with unknown type: {type}/{name}" ) pol_ids.append({"id": pol_id, "type": type}) @@ -454,10 +443,10 @@ def _convert_policy_id_to_name(isamAppliance, policies): pol_name = ret_obj["data"]["name"] if pol_name != {}: logger.debug( - "Converting policy {0} to Name: {1}".format(pol_id, pol_name) + f"Converting policy {pol_id} to Name: {pol_name}" ) else: - logger.warning("Unable to find policy {0}, skipping.".format(pol_id)) + logger.warning(f"Unable to find policy {pol_id}, skipping.") elif type == "policyset": ret_obj = ibmsecurity.isam.aac.access_control.policy_sets._get( isamAppliance, pol_id @@ -465,11 +454,11 @@ def _convert_policy_id_to_name(isamAppliance, policies): pol_name = ret_obj["data"]["name"] if pol_name != {}: logger.debug( - "Converting policy set {0} to Name: {1}".format(pol_id, pol_name) + f"Converting policy set {pol_id} to Name: {pol_name}" ) else: logger.warning( - "Unable to find policy set {0}, skipping.".format(pol_id) + f"Unable to find policy set {pol_id}, skipping." ) elif type == "definition": ret_obj = ibmsecurity.isam.aac.api_protection.definitions._get( @@ -478,20 +467,18 @@ def _convert_policy_id_to_name(isamAppliance, policies): pol_name = ret_obj["data"]["name"] if pol_name != {}: logger.debug( - "Converting api definition {0} to Name: {1}".format( - pol_id, pol_name - ) + f"Converting api definition {pol_id} to Name: {pol_name}" ) else: logger.warning( - "Unable to find api definition {0}, skipping.".format(pol_id) + f"Unable to find api definition {pol_id}, skipping." ) else: from ibmsecurity.appliance.ibmappliance import IBMError raise IBMError( "999", - "Policy specified with unknown type: {0}/{1}".format(type, pol_id), + f"Policy specified with unknown type: {type}/{pol_id}", ) pol_ids.append({"name": pol_name, "type": type}) @@ -510,16 +497,14 @@ def delete(isamAppliance, server, resourceUri, check_mode=False, force=False): if resourceID == {}: logger.info( - "ResourceURI {0}/{1} not found, skipping delete.".format( - server, resourceUri - ) + f"ResourceURI {server}/{resourceUri} not found, skipping delete." ) else: if check_mode is True: return isamAppliance.create_return_object(changed=True) else: return isamAppliance.invoke_delete( - "Delete a configured resource", "{0}/{1}".format(uri, resourceID) + "Delete a configured resource", f"{uri}/{resourceID}" ) return isamAppliance.create_return_object() diff --git a/ibmsecurity/isam/aac/access_control/policy_sets.py b/ibmsecurity/isam/aac/access_control/policy_sets.py index f9e07d97..d1b3f68e 100644 --- a/ibmsecurity/isam/aac/access_control/policy_sets.py +++ b/ibmsecurity/isam/aac/access_control/policy_sets.py @@ -13,7 +13,7 @@ def get_all(isamAppliance, filter=None, sortBy=None, check_mode=False, force=Fal """ return isamAppliance.invoke_get( "Retrieve a list of policy sets", - "{0}/{1}".format(uri, tools.create_query_string(filter=filter, sortBy=sortBy)), + f"{uri}/{tools.create_query_string(filter=filter, sortBy=sortBy)}", ) @@ -25,11 +25,11 @@ def get(isamAppliance, name, check_mode=False, force=False): pol_id = ret_obj["data"] if pol_id == {}: - logger.info("Policy {0} had no match, skipping retrieval.".format(name)) + logger.info(f"Policy {name} had no match, skipping retrieval.") return isamAppliance.create_return_object() else: return isamAppliance.invoke_get( - "Retrieve a specific policy set", "{0}/{1}".format(uri, pol_id) + "Retrieve a specific policy set", f"{uri}/{pol_id}" ) @@ -41,12 +41,12 @@ def get_policies(isamAppliance, name, check_mode=False, force=False): pol_id = ret_obj["data"] if pol_id == {}: - logger.info("Policy {0} had no match, skipping retrieval.".format(name)) + logger.info(f"Policy {name} had no match, skipping retrieval.") return isamAppliance.create_return_object() else: return isamAppliance.invoke_get( "Retrieve policies in a specific policy set", - "{0}/{1}/policies".format(uri, pol_id), + f"{uri}/{pol_id}/policies", ) @@ -59,7 +59,7 @@ def search(isamAppliance, name, force=False, check_mode=False): for obj in ret_obj["data"]: if obj["name"] == name: - logger.info("Found Policy Set {0} id: {1}".format(name, obj["id"])) + logger.info(f"Found Policy Set {name} id: {obj['id']}") return_obj["data"] = obj["id"] return_obj["rc"] = 0 @@ -85,7 +85,7 @@ def set( if (search(isamAppliance, name=name))["data"] == {}: # Force the add - we already know policy set does not exist logger.info( - "Policy Set {0} had no match, requesting to add new one.".format(name) + f"Policy Set {name} had no match, requesting to add new one." ) return add( isamAppliance, @@ -99,7 +99,7 @@ def set( ) else: # Update request - logger.info("Policy Set {0} exists, requesting to update.".format(name)) + logger.info(f"Policy Set {name} exists, requesting to update.") return update( isamAppliance, name, @@ -162,9 +162,9 @@ def _convert_policy_name_to_id(isamAppliance, policies): pol_id = ret_obj["data"] if pol_id != {}: pol_ids.append(pol_id) - logger.debug("Converting policy {0} to ID: {1}".format(pol_name, pol_id)) + logger.debug(f"Converting policy {pol_name} to ID: {pol_id}") else: - logger.warning("Unable to find policy {0}, skipping.".format(pol_name)) + logger.warning(f"Unable to find policy {pol_name}, skipping.") return pol_ids @@ -180,9 +180,9 @@ def _convert_policy_id_to_name(isamAppliance, policies): if ret_obj["data"] != {}: pol_name = ret_obj["data"]["name"] pol_names.append(pol_name) - logger.debug("Converting policy {0} to Name: {1}".format(pol_id, pol_name)) + logger.debug(f"Converting policy {pol_id} to Name: {pol_name}") else: - logger.warning("Unable to find policy {0}, skipping.".format(pol_id)) + logger.warning(f"Unable to find policy {pol_id}, skipping.") return pol_names @@ -195,13 +195,13 @@ def delete(isamAppliance, name, check_mode=False, force=False): pol_id = ret_obj["data"] if pol_id == {}: - logger.info("Policy Set {0} not found, skipping delete.".format(name)) + logger.info(f"Policy Set {name} not found, skipping delete.") else: if check_mode is True: return isamAppliance.create_return_object(changed=True) else: return isamAppliance.invoke_delete( - "Delete a Policy Set", "{0}/{1}".format(uri, pol_id) + "Delete a Policy Set", f"{uri}/{pol_id}" ) return isamAppliance.create_return_object() @@ -236,7 +236,7 @@ def update( from ibmsecurity.appliance.ibmappliance import IBMError raise IBMError( - "999", "Cannot update data for unknown policy set: {0}".format(name) + "999", f"Cannot update data for unknown policy set: {name}" ) if force is True or update_required is True: @@ -245,7 +245,7 @@ def update( else: return isamAppliance.invoke_put( "Update a specified policy set", - "{0}/{1}".format(uri, pol_id), + f"{uri}/{pol_id}", json_data, ) @@ -298,9 +298,9 @@ def _check( import ibmsecurity.utilities.tools sorted_json_data = ibmsecurity.utilities.tools.json_sort(json_data) - logger.debug("Sorted input: {0}".format(sorted_json_data)) + logger.debug(f"Sorted input: {sorted_json_data}") sorted_ret_obj = ibmsecurity.utilities.tools.json_sort(ret_obj["data"]) - logger.debug("Sorted existing data: {0}".format(sorted_ret_obj)) + logger.debug(f"Sorted existing data: {sorted_ret_obj}") if sorted_ret_obj != sorted_json_data: logger.info("Changes detected, update needed.") update_required = True @@ -324,7 +324,7 @@ def update_policies( from ibmsecurity.appliance.ibmappliance import IBMError raise IBMError( - "999", "Cannot update data for unknown policy set: {0}".format(name) + "999", f"Cannot update data for unknown policy set: {name}" ) if force is True or update_required is True: @@ -333,9 +333,7 @@ def update_policies( else: return isamAppliance.invoke_put( "Update a specified policy set", - "{0}/{1}/policies{2}".format( - uri, pol_id, tools.create_query_string(action=action) - ), + f"{uri}/{pol_id}/policies{tools.create_query_string(action=action)}", json_data, ) @@ -364,7 +362,7 @@ def _check_policies(isamAppliance, name, policies, action): if action == "add": if exists: logger.info( - "Policy ID {0} already exists skipping.".format(new_pol_id) + f"Policy ID {new_pol_id} already exists skipping." ) else: pol_ids.append(new_pol_ids) @@ -386,7 +384,7 @@ def _check_policies(isamAppliance, name, policies, action): else: from ibmsecurity.appliance.ibmappliance import IBMError - raise IBMError("999", "Unknown action: {0}.".format(action)) + raise IBMError("999", f"Unknown action: {action}.") json_data["policies"] = pol_ids return pol_id, update_required, json_data From 3de52fa54315e27272028e11838728d50c4db556 Mon Sep 17 00:00:00 2001 From: Tom Bosmans Date: Wed, 28 May 2025 11:20:20 +0200 Subject: [PATCH 40/54] fix: format() -> f-string --- .pre-commit-config.yaml | 5 +++-- changelog.md | 5 +++++ .../aac/access_control/policy_attachments.py | 17 +++++------------ .../isam/aac/access_control/policy_sets.py | 8 ++------ 4 files changed, 15 insertions(+), 20 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index a0cac1b6..d60af7e2 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -18,11 +18,12 @@ repos: # - id: flake8 # args: ["--ignore=E501"] - repo: https://github.com/PyCQA/pylint - rev: v3.3.2 + rev: v3.3.7 hooks: - id: pylint args: [ "--recursive=y", "--exit-zero", - "--output-format=text:report.txt" + "--rcfile=pylintrc", + "--output-format=github:report.txt" ] diff --git a/changelog.md b/changelog.md index 0167e1cb..fc10a60e 100644 --- a/changelog.md +++ b/changelog.md @@ -2,6 +2,11 @@ ## Latest +- feature: base/management_authentication.py - type federation +- build: test setup +- feature: web/reverse_proxy/oauth_configuration.py - add new parameters in 10.0.8 +- feature: web/reverse_proxy/oauth2_configuration.py - OAuth2 IBM Security Verify OIDC Provider configuration (new in 10.0.4) +- feature: aac/server_connections/sms.py - SMS Server Connection (new in 10.0.8) ## 2025.3.28.0 diff --git a/ibmsecurity/isam/aac/access_control/policy_attachments.py b/ibmsecurity/isam/aac/access_control/policy_attachments.py index 19467294..e6c48f81 100644 --- a/ibmsecurity/isam/aac/access_control/policy_attachments.py +++ b/ibmsecurity/isam/aac/access_control/policy_attachments.py @@ -152,8 +152,7 @@ def config( if policyType is not None: if tools.version_compare(isamAppliance.facts["version"], "9.0.6.0") < 0: warnings.append( - "Appliance at version: {0}, policyType: {1} is not supported. Needs 9.0.6.0 or higher. Ignoring policyType for this call.".format(isamAppliance.facts["version"], cache - ) + f"Appliance at version: {isamAppliance.facts['version']}, policyType: {cache} is not supported. Needs 9.0.6.0 or higher. Ignoring policyType for this call." ) else: json_data["type"] = policyType @@ -164,8 +163,7 @@ def config( if cache is not None: if tools.version_compare(isamAppliance.facts["version"], "9.0.3.0") < 0: warnings.append( - "Appliance at version: {0}, cache: {1} is not supported. Needs 9.0.3.0 or higher. Ignoring cache for this call.".format(isamAppliance.facts["version"], cache - ) + f"Appliance at version: {isamAppliance.facts['version']}, cache: {cache} is not supported. Needs 9.0.3.0 or higher. Ignoring cache for this call." ) else: json_data["cache"] = int(cache) @@ -203,8 +201,7 @@ def update( if cache is not None: if tools.version_compare(isamAppliance.facts["version"], "9.0.3.0") < 0: warnings.append( - "Appliance at version: {0}, cache: {1} is not supported. Needs 9.0.3.0 or higher. Ignoring cache for this call.".format(isamAppliance.facts["version"], cache - ) + f"Appliance at version: {isamAppliance.facts['version']}, cache: {cache} is not supported. Needs 9.0.3.0 or higher. Ignoring cache for this call." ) else: json_data["cache"] = int(cache) @@ -247,9 +244,7 @@ def update_attachments( new_policies = _convert_policy_name_to_id(isamAppliance, attachments) return isamAppliance.invoke_put( "Update the attachments for a resource", - "{0}/{1}/policies{2}".format( - uri, ret_obj["data"]["id"], tools.create_query_string(action=action) - ), + f"{uri}/{ret_obj['data']['id']}/policies{tools.create_query_string(action=action)}", new_policies, ) return isamAppliance.create_return_object() @@ -266,9 +261,7 @@ def _check(policies, attachments, action): new_pol["name"] == cur_pol["name"] and new_pol["type"] == cur_pol["type"] ): logger.info( - "At least one policy already exists {0}/{1}".format( - new_pol["type"], new_pol["name"] - ) + f"At least one policy already exists {new_pol['type']}/{new_pol['name']}" ) match = True break diff --git a/ibmsecurity/isam/aac/access_control/policy_sets.py b/ibmsecurity/isam/aac/access_control/policy_sets.py index d1b3f68e..7a554f07 100644 --- a/ibmsecurity/isam/aac/access_control/policy_sets.py +++ b/ibmsecurity/isam/aac/access_control/policy_sets.py @@ -367,17 +367,13 @@ def _check_policies(isamAppliance, name, policies, action): else: pol_ids.append(new_pol_ids) logger.info( - "Policy ID {0} does not exist, appending to list for additon.".format( - new_pol_id - ) + f"Policy ID {new_pol_id} does not exist, appending to list for additon." ) elif action == "delete": if exists: pol_ids.append(new_pol_ids) logger.info( - "Policy ID {0} exists, appending to list for deletion.".format( - new_pol_id - ) + f"Policy ID {new_pol_id} exists, appending to list for deletion." ) else: logger.info("Policy ID {0} does not exist skipping.") From de1eae7430fbe1c9eb6b66b0af7f9fd9abb45757 Mon Sep 17 00:00:00 2001 From: Tom Bosmans Date: Wed, 28 May 2025 11:42:05 +0200 Subject: [PATCH 41/54] fix: format() -> f-string --- .../isam/aac/api_protection/clients.py | 104 ++++++++---------- .../isam/aac/api_protection/definitions.py | 52 ++++----- .../aac/api_protection/dynamic_clients.py | 9 +- .../dynamic_clients_migration.py | 4 +- ibmsecurity/isam/aac/api_protection/grants.py | 9 +- .../isam/aac/api_protection/grants_user.py | 4 +- 6 files changed, 77 insertions(+), 105 deletions(-) diff --git a/ibmsecurity/isam/aac/api_protection/clients.py b/ibmsecurity/isam/aac/api_protection/clients.py index 505d5c19..8addc8c8 100644 --- a/ibmsecurity/isam/aac/api_protection/clients.py +++ b/ibmsecurity/isam/aac/api_protection/clients.py @@ -27,15 +27,15 @@ def get(isamAppliance, name, check_mode=False, force=False): warnings = ret_obj["warnings"] if client_id == {}: - logger.info("Client {0} had no match, skipping retrieval.".format(name)) - warnings.append("Client Name {0} had no match.".format(name)) + logger.info(f"Client {name} had no match, skipping retrieval.") + warnings.append(f"Client Name {name} had no match.") return isamAppliance.create_return_object(warnings=warnings) else: return _get(isamAppliance, client_id) def _get(isamAppliance, client_id): - return isamAppliance.invoke_get("Retrieve a specific API protection client", "{0}/{1}".format(uri, client_id), + return isamAppliance.invoke_get("Retrieve a specific API protection client", f"{uri}/{client_id}", requires_modules=requires_modules, requires_version=requires_version) @@ -49,7 +49,7 @@ def search(isamAppliance, name, check_mode=False, force=False): for obj in ret_obj['data']: if obj['name'] == name: - logger.info("Found API Protection Client {0} id: {1}".format(name, obj['id'])) + logger.info(f"Found API Protection Client {name} id: {obj['id']}") return_obj['data'] = obj['id'] return_obj['rc'] = 0 @@ -65,7 +65,7 @@ def search_id(isamAppliance, clientId, check_mode=False, force=False): for obj in ret_obj['data']: if obj['clientId'] == clientId: - logger.info("Found API Protection Client {0} id: {1}".format(clientId, obj['id'])) + logger.info(f"Found API Protection Client {clientId} id: {obj['id']}") return_obj['data'] = obj['id'] return_obj['rc'] = 0 @@ -81,7 +81,7 @@ def _get_id(isamAppliance, clientId, check_mode=False, force=False): for obj in ret_obj['data']: if obj['clientId'] == clientId: - logger.info("Found API Protection Client {0} id: {1}".format(clientId, obj['id'])) + logger.info(f"Found API Protection Client {clientId} id: {obj['id']}") return_obj['data'] = obj return_obj['rc'] = 0 @@ -92,7 +92,7 @@ def generate_client_id(isamAppliance, check_mode=False, force=False): """ Generate a client ID """ - return isamAppliance.invoke_get("Generate a client ID", "{0}/clientid".format(uri), + return isamAppliance.invoke_get("Generate a client ID", f"{uri}/clientid", requires_modules=requires_modules, requires_version=requires_version) @@ -101,7 +101,7 @@ def generate_client_secret(isamAppliance, check_mode=False, force=False): """ Generate a client secret """ - return isamAppliance.invoke_get("Generate a client secret", "{0}/clientsecret".format(uri), + return isamAppliance.invoke_get("Generate a client secret", f"{uri}/clientsecret", requires_modules=requires_modules, requires_version=requires_version) @@ -117,7 +117,7 @@ def add(isamAppliance, name, definitionName, companyName, redirectUri=None, comp if ret_obj['data'] == {}: warnings = ret_obj["warnings"] warnings.append( - "API Protection Definition {0} is not found. Cannot process client request.".format(definitionName)) + f"API Protection Definition {definitionName} is not found. Cannot process client request.") return isamAppliance.create_return_object(warnings=warnings) else: definition = ret_obj['data'] @@ -157,43 +157,37 @@ def add(isamAppliance, name, definitionName, companyName, redirectUri=None, comp if requirePkce is not None: if tools.version_compare(isamAppliance.facts["version"], "9.0.4.0") < 0: warnings.append( - "Appliance at version: {0}, requirePkce: {1} is not supported. Needs 9.0.4.0 or higher. Ignoring requirePkce for this call.".format( - isamAppliance.facts["version"], requirePkce)) + f"Appliance at version: {isamAppliance.facts['version']}, requirePkce: {requirePkce} is not supported. Needs 9.0.4.0 or higher. Ignoring requirePkce for this call.") else: client_json["requirePkce"] = requirePkce if encryptionDb is not None: if tools.version_compare(isamAppliance.facts["version"], "9.0.4.0") < 0: warnings.append( - "Appliance at version: {0}, encryptionDb: {1} is not supported. Needs 9.0.4.0 or higher. Ignoring encryptionDb for this call.".format( - isamAppliance.facts["version"], encryptionDb)) + f"Appliance at version: {isamAppliance.facts['version']}, encryptionDb: {encryptionDb} is not supported. Needs 9.0.4.0 or higher. Ignoring encryptionDb for this call.") else: client_json["encryptionDb"] = encryptionDb if encryptionCert is not None: if tools.version_compare(isamAppliance.facts["version"], "9.0.4.0") < 0: warnings.append( - "Appliance at version: {0}, encryptionCert: {1} is not supported. Needs 9.0.4.0 or higher. Ignoring encryptionCert for this call.".format( - isamAppliance.facts["version"], encryptionCert)) + f"Appliance at version: {isamAppliance.facts['version']}, encryptionCert: {encryptionCert} is not supported. Needs 9.0.4.0 or higher. Ignoring encryptionCert for this call.") else: client_json["encryptionCert"] = encryptionCert if jwksUri is not None: if tools.version_compare(isamAppliance.facts["version"], "9.0.4.0") < 0: warnings.append( - "Appliance at version: {0}, jwksUri: {1} is not supported. Needs 9.0.4.0 or higher. Ignoring jwksUri for this call.".format( - isamAppliance.facts["version"], jwksUri)) + f"Appliance at version: {isamAppliance.facts['version']}, jwksUri: {jwksUri} is not supported. Needs 9.0.4.0 or higher. Ignoring jwksUri for this call.") else: client_json["jwksUri"] = jwksUri if extProperties is not None: if tools.version_compare(isamAppliance.facts["version"], "9.0.5.0") < 0: warnings.append( - "Appliance at version: {0}, extProperties: {1} is not supported. Needs 9.0.5.0 or higher. Ignoring extProperties for this call.".format( - isamAppliance.facts["version"], extProperties)) + f"Appliance at version: {isamAppliance.facts['version']}, extProperties: {extProperties} is not supported. Needs 9.0.5.0 or higher. Ignoring extProperties for this call.") else: client_json["extProperties"] = extProperties if introspectWithSecret is not None: if tools.version_compare(isamAppliance.facts["version"], "9.0.7.0") < 0: warnings.append( - "Appliance at version: {0}, introspectWithSecret: {1} is not supported. Needs 9.0.7.0 or higher. Ignoring introspectWithSecret for this call.".format( - isamAppliance.facts["version"], introspectWithSecret)) + f"Appliance at version: {isamAppliance.facts['version']}, introspectWithSecret: {introspectWithSecret} is not supported. Needs 9.0.7.0 or higher. Ignoring introspectWithSecret for this call.") else: client_json["introspectWithSecret"] = introspectWithSecret @@ -213,13 +207,13 @@ def delete(isamAppliance, name, check_mode=False, force=False): warnings = ret_obj["warnings"] if client_id == {}: - logger.info("Client {0} not found, skipping delete.".format(name)) + logger.info(f"Client {name} not found, skipping delete.") else: if check_mode is True: return isamAppliance.create_return_object(changed=True, warnings=warnings) else: return isamAppliance.invoke_delete( - "Delete an API protection client registration", "{0}/{1}".format(uri, client_id), + "Delete an API protection client registration", f"{uri}/{client_id}", requires_modules=requires_modules, requires_version=requires_version, warnings=warnings) return isamAppliance.create_return_object(warnings=warnings) @@ -236,7 +230,7 @@ def update(isamAppliance, name, definitionName, companyName, redirectUri=None, c if ret_obj['data'] == {}: warnings = ret_obj["warnings"] warnings.append( - "API Protection Definition {0} is not found. Cannot process client request.".format(definitionName)) + f"API Protection Definition {definitionName} is not found. Cannot process client request.") return isamAppliance.create_return_object(warnings=warnings) else: definition = ret_obj['data'] @@ -245,7 +239,7 @@ def update(isamAppliance, name, definitionName, companyName, redirectUri=None, c warnings = ret_obj["warnings"] if ret_obj["data"] == {}: - warnings.append("Client {0} not found, skipping update.".format(name)) + warnings.append(f"Client {name} not found, skipping update.") return isamAppliance.create_return_object(warnings=warnings) else: id = ret_obj["data"]["id"] @@ -329,8 +323,7 @@ def update(isamAppliance, name, definitionName, companyName, redirectUri=None, c if requirePkce is not None: if tools.version_compare(isamAppliance.facts["version"], "9.0.4.0") < 0: warnings.append( - "Appliance at version: {0}, requirePkce: {1} is not supported. Needs 9.0.4.0 or higher. Ignoring requirePkce for this call.".format( - isamAppliance.facts["version"], requirePkce)) + f"Appliance at version: {isamAppliance.facts['version']}, requirePkce: {requirePkce} is not supported. Needs 9.0.4.0 or higher. Ignoring requirePkce for this call.") else: json_data['requirePkce'] = requirePkce elif 'requirePkce' in ret_obj['data']: @@ -341,8 +334,7 @@ def update(isamAppliance, name, definitionName, companyName, redirectUri=None, c if encryptionDb is not None: if tools.version_compare(isamAppliance.facts["version"], "9.0.4.0") < 0: warnings.append( - "Appliance at version: {0}, encryptionDb: {1} is not supported. Needs 9.0.4.0 or higher. Ignoring encryptionDb for this call.".format( - isamAppliance.facts["version"], encryptionDb)) + f"Appliance at version: {isamAppliance.facts['version']}, encryptionDb: {encryptionDb} is not supported. Needs 9.0.4.0 or higher. Ignoring encryptionDb for this call.") else: json_data['encryptionDb'] = encryptionDb elif 'encryptionDb' in ret_obj['data']: @@ -353,8 +345,7 @@ def update(isamAppliance, name, definitionName, companyName, redirectUri=None, c if encryptionCert is not None: if tools.version_compare(isamAppliance.facts["version"], "9.0.4.0") < 0: warnings.append( - "Appliance at version: {0}, encryptionCert: {1} is not supported. Needs 9.0.4.0 or higher. Ignoring encryptionCert for this call.".format( - isamAppliance.facts["version"], encryptionCert)) + f"Appliance at version: {isamAppliance.facts['version']}, encryptionCert: {encryptionCert} is not supported. Needs 9.0.4.0 or higher. Ignoring encryptionCert for this call.") else: json_data['encryptionCert'] = encryptionCert elif 'encryptionCert' in ret_obj['data']: @@ -365,8 +356,7 @@ def update(isamAppliance, name, definitionName, companyName, redirectUri=None, c if jwksUri is not None: if tools.version_compare(isamAppliance.facts["version"], "9.0.4.0") < 0: warnings.append( - "Appliance at version: {0}, jwksUri: {1} is not supported. Needs 9.0.4.0 or higher. Ignoring jwksUri for this call.".format( - isamAppliance.facts["version"], jwksUri)) + f"Appliance at version: {isamAppliance.facts['version']}, jwksUri: {jwksUri} is not supported. Needs 9.0.4.0 or higher. Ignoring jwksUri for this call.") else: json_data['jwksUri'] = jwksUri elif 'jwksUri' in ret_obj['data']: @@ -377,8 +367,7 @@ def update(isamAppliance, name, definitionName, companyName, redirectUri=None, c if extProperties is not None: if tools.version_compare(isamAppliance.facts["version"], "9.0.5.0") < 0: warnings.append( - "Appliance at version: {0}, extProperties: {1} is not supported. Needs 9.0.5.0 or higher. Ignoring extProperties for this call.".format( - isamAppliance.facts["version"], extProperties)) + f"Appliance at version: {isamAppliance.facts['version']}, extProperties: {extProperties} is not supported. Needs 9.0.5.0 or higher. Ignoring extProperties for this call.") else: json_data['extProperties'] = extProperties elif 'extProperties' in ret_obj['data']: @@ -389,8 +378,7 @@ def update(isamAppliance, name, definitionName, companyName, redirectUri=None, c if introspectWithSecret is not None: if tools.version_compare(isamAppliance.facts["version"], "9.0.7.0") < 0: warnings.append( - "Appliance at version: {0}, introspectWithSecret: {1} is not supported. Needs 9.0.7.0 or higher. Ignoring introspectWithSecret for this call.".format( - isamAppliance.facts["version"], introspectWithSecret)) + f"Appliance at version: {isamAppliance.facts['version']}, introspectWithSecret: {introspectWithSecret} is not supported. Needs 9.0.7.0 or higher. Ignoring introspectWithSecret for this call.") else: json_data["introspectWithSecret"] = introspectWithSecret elif 'introspectWithSecret' in ret_obj['data']: @@ -401,8 +389,8 @@ def update(isamAppliance, name, definitionName, companyName, redirectUri=None, c sorted_ret_obj = tools.json_sort(ret_obj['data']) sorted_json_data = tools.json_sort(json_data) - logger.debug("Sorted Existing Data:{0}".format(sorted_ret_obj)) - logger.debug("Sorted Desired Data:{0}".format(sorted_json_data)) + logger.debug(f"Sorted Existing Data:{sorted_ret_obj}") + logger.debug(f"Sorted Desired Data:{sorted_json_data}") if sorted_ret_obj != sorted_json_data: needs_update = True @@ -411,7 +399,7 @@ def update(isamAppliance, name, definitionName, companyName, redirectUri=None, c return isamAppliance.create_return_object(changed=True, warnings=warnings) else: return isamAppliance.invoke_put( - "Update a specified mapping rule", "{0}/{1}".format(uri, id), json_data, + "Update a specified mapping rule", f"{uri}/{id}", json_data, requires_modules=requires_modules, requires_version=requires_version, warnings=warnings) return isamAppliance.create_return_object(warnings=warnings) @@ -426,7 +414,7 @@ def set(isamAppliance, name, definitionName, companyName, redirectUri=None, comp """ if (search(isamAppliance, name=name))['data'] == {}: # Force the add - we already know policy does not exist - logger.info("Definition {0} had no match, requesting to add new one.".format(name)) + logger.info(f"Definition {name} had no match, requesting to add new one.") return add(isamAppliance, name, definitionName, companyName, redirectUri=redirectUri, companyUrl=companyUrl, contactPerson=contactPerson, contactType=contactType, email=email, phone=phone, otherInfo=otherInfo, clientId=clientId, clientSecret=clientSecret, requirePkce=requirePkce, encryptionDb=encryptionDb, @@ -434,7 +422,7 @@ def set(isamAppliance, name, definitionName, companyName, redirectUri=None, comp check_mode=check_mode, force=True) else: # Update request - logger.info("Definition {0} exists, requesting to update.".format(name)) + logger.info(f"Definition {name} exists, requesting to update.") return update(isamAppliance, name, definitionName, companyName, redirectUri=redirectUri, companyUrl=companyUrl, contactPerson=contactPerson, contactType=contactType, email=email, phone=phone, otherInfo=otherInfo, clientId=clientId, clientSecret=clientSecret, new_name=new_name, @@ -453,7 +441,7 @@ def update_id(isamAppliance, clientId, name, definitionName, companyName, redire if ret_obj['data'] == {}: warnings = ret_obj["warnings"] warnings.append( - "API Protection Definition {0} is not found. Cannot process client request.".format(definitionName)) + f"API Protection Definition {definitionName} is not found. Cannot process client request.") return isamAppliance.create_return_object(warnings=warnings) else: definition = ret_obj['data'] @@ -462,7 +450,7 @@ def update_id(isamAppliance, clientId, name, definitionName, companyName, redire warnings = ret_obj["warnings"] if ret_obj["data"] == {}: - warnings.append("Client {0} not found, skipping update.".format(clientId)) + warnings.append(f"Client {clientId} not found, skipping update.") return isamAppliance.create_return_object(warnings=warnings) else: id = ret_obj["data"]["id"] @@ -541,8 +529,7 @@ def update_id(isamAppliance, clientId, name, definitionName, companyName, redire if requirePkce is not None: if tools.version_compare(isamAppliance.facts["version"], "9.0.4.0") < 0: warnings.append( - "Appliance at version: {0}, requirePkce: {1} is not supported. Needs 9.0.4.0 or higher. Ignoring requirePkce for this call.".format( - isamAppliance.facts["version"], requirePkce)) + f"Appliance at version: {isamAppliance.facts['version']}, requirePkce: {requirePkce} is not supported. Needs 9.0.4.0 or higher. Ignoring requirePkce for this call.") else: json_data["requirePkce"] = requirePkce elif 'requirePkce' in ret_obj['data']: @@ -553,8 +540,7 @@ def update_id(isamAppliance, clientId, name, definitionName, companyName, redire if encryptionDb is not None: if tools.version_compare(isamAppliance.facts["version"], "9.0.4.0") < 0: warnings.append( - "Appliance at version: {0}, encryptionDb: {1} is not supported. Needs 9.0.4.0 or higher. Ignoring encryptionDb for this call.".format( - isamAppliance.facts["version"], encryptionDb)) + f"Appliance at version: {isamAppliance.facts['version']}, encryptionDb: {encryptionDb} is not supported. Needs 9.0.4.0 or higher. Ignoring encryptionDb for this call.") else: json_data["encryptionDb"] = encryptionDb elif 'encryptionDb' in ret_obj['data']: @@ -565,8 +551,7 @@ def update_id(isamAppliance, clientId, name, definitionName, companyName, redire if encryptionCert is not None: if tools.version_compare(isamAppliance.facts["version"], "9.0.4.0") < 0: warnings.append( - "Appliance at version: {0}, encryptionCert: {1} is not supported. Needs 9.0.4.0 or higher. Ignoring encryptionCert for this call.".format( - isamAppliance.facts["version"], encryptionCert)) + f"Appliance at version: {isamAppliance.facts['version']}, encryptionCert: {encryptionCert} is not supported. Needs 9.0.4.0 or higher. Ignoring encryptionCert for this call.") else: json_data["encryptionCert"] = encryptionCert elif 'encryptionCert' in ret_obj['data']: @@ -577,8 +562,7 @@ def update_id(isamAppliance, clientId, name, definitionName, companyName, redire if jwksUri is not None: if tools.version_compare(isamAppliance.facts["version"], "9.0.4.0") < 0: warnings.append( - "Appliance at version: {0}, jwksUri: {1} is not supported. Needs 9.0.4.0 or higher. Ignoring jwksUri for this call.".format( - isamAppliance.facts["version"], jwksUri)) + f"Appliance at version: {isamAppliance.facts['version']}, jwksUri: {jwksUri} is not supported. Needs 9.0.4.0 or higher. Ignoring jwksUri for this call.") else: json_data["jwksUri"] = jwksUri elif 'jwksUri' in ret_obj['data']: @@ -589,8 +573,7 @@ def update_id(isamAppliance, clientId, name, definitionName, companyName, redire if extProperties is not None: if tools.version_compare(isamAppliance.facts["version"], "9.0.5.0") < 0: warnings.append( - "Appliance at version: {0}, extProperties: {1} is not supported. Needs 9.0.5.0 or higher. Ignoring extProperties for this call.".format( - isamAppliance.facts["version"], extProperties)) + f"Appliance at version: {isamAppliance.facts['version']}, extProperties: {extProperties} is not supported. Needs 9.0.5.0 or higher. Ignoring extProperties for this call.") else: json_data["extProperties"] = extProperties elif 'extProperties' in ret_obj['data']: @@ -601,8 +584,7 @@ def update_id(isamAppliance, clientId, name, definitionName, companyName, redire if introspectWithSecret is not None: if tools.version_compare(isamAppliance.facts["version"], "9.0.7.0") < 0: warnings.append( - "Appliance at version: {0}, introspectWithSecret: {1} is not supported. Needs 9.0.7.0 or higher. Ignoring introspectWithSecret for this call.".format( - isamAppliance.facts["version"], introspectWithSecret)) + f"Appliance at version: {isamAppliance.facts['version']}, introspectWithSecret: {introspectWithSecret} is not supported. Needs 9.0.7.0 or higher. Ignoring introspectWithSecret for this call.") else: json_data["introspectWithSecret"] = introspectWithSecret elif 'introspectWithSecret' in ret_obj['data']: @@ -613,8 +595,8 @@ def update_id(isamAppliance, clientId, name, definitionName, companyName, redire sorted_ret_obj = tools.json_sort(ret_obj['data']) sorted_json_data = tools.json_sort(json_data) - logger.debug("Sorted Existing Data:{0}".format(sorted_ret_obj)) - logger.debug("Sorted Desired Data:{0}".format(sorted_json_data)) + logger.debug(f"Sorted Existing Data:{sorted_ret_obj}") + logger.debug(f"Sorted Desired Data:{sorted_json_data}") if sorted_ret_obj != sorted_json_data: needs_update = True @@ -623,7 +605,7 @@ def update_id(isamAppliance, clientId, name, definitionName, companyName, redire return isamAppliance.create_return_object(changed=True, warnings=warnings) else: return isamAppliance.invoke_put( - "Update a specified mapping rule", "{0}/{1}".format(uri, id), json_data, + "Update a specified mapping rule", f"{uri}/{id}", json_data, requires_modules=requires_modules, requires_version=requires_version, warnings=warnings) return isamAppliance.create_return_object(warnings=warnings) @@ -638,7 +620,7 @@ def set_id(isamAppliance, clientId, name, definitionName, companyName, redirectU """ if (search_id(isamAppliance, clientId))['data'] == {}: # Force the add - we already know policy does not exist - logger.info("Definition {0} had no match, requesting to add new one.".format(clientId)) + logger.info(f"Definition {clientId} had no match, requesting to add new one.") return add(isamAppliance, name=name, definitionName=definitionName, companyName=companyName, redirectUri=redirectUri, companyUrl=companyUrl, contactPerson=contactPerson, contactType=contactType, email=email, phone=phone, otherInfo=otherInfo, clientId=clientId, clientSecret=clientSecret, requirePkce=requirePkce, encryptionDb=encryptionDb, @@ -646,7 +628,7 @@ def set_id(isamAppliance, clientId, name, definitionName, companyName, redirectU check_mode=check_mode, force=True) else: # Update request - logger.info("Definition {0} exists, requesting to update.".format(clientId)) + logger.info(f"Definition {clientId} exists, requesting to update.") return update_id(isamAppliance, clientId=clientId, definitionName=definitionName, companyName=companyName, name=name, redirectUri=redirectUri, companyUrl=companyUrl, contactPerson=contactPerson, contactType=contactType, email=email, phone=phone, otherInfo=otherInfo, clientSecret=clientSecret, new_clientId=new_clientId, diff --git a/ibmsecurity/isam/aac/api_protection/definitions.py b/ibmsecurity/isam/aac/api_protection/definitions.py index 153bfa80..05c46ad2 100644 --- a/ibmsecurity/isam/aac/api_protection/definitions.py +++ b/ibmsecurity/isam/aac/api_protection/definitions.py @@ -35,8 +35,8 @@ def get(isamAppliance, name, check_mode=False, force=False): warnings = ret_obj["warnings"] if defn_id == {}: - logger.info("Definition {0} had no match, skipping retrieval.".format(name)) - warnings.append("Definition Name {0} had no match.".format(name)) + logger.info(f"Definition {name} had no match, skipping retrieval.") + warnings.append(f"Definition Name {name} had no match.") return isamAppliance.create_return_object(warnings=warnings) else: return _get(isamAppliance, defn_id) @@ -44,7 +44,7 @@ def get(isamAppliance, name, check_mode=False, force=False): def _get(isamAppliance, defn_id): return isamAppliance.invoke_get("Retrieve a specific API protection definition", - "{0}/{1}".format(uri, defn_id), requires_modules=requires_modules, + f"{uri}/{defn_id}", requires_modules=requires_modules, requires_version=requires_version) @@ -58,7 +58,7 @@ def search(isamAppliance, name, check_mode=False, force=False): for obj in ret_obj['data']: if obj['name'] == name: - logger.info("Found definition {0} id: {1}".format(name, obj['id'])) + logger.info(f"Found definition {name} id: {obj['id']}") return_obj['data'] = obj['id'] return_obj['rc'] = 0 @@ -109,15 +109,14 @@ def add(isamAppliance, name, description="", accessPolicyName=None, grantTypes=[ if accessPolicyName is not None: if tools.version_compare(isamAppliance.facts["version"], "9.0.4.0") < 0: warnings.append( - "Appliance at version: {0}, access policy: {1} is not supported. Needs 9.0.4.0 or higher. Ignoring access policy for this call.".format( - isamAppliance.facts["version"], oidc)) + f"Appliance at version: {isamAppliance.facts['version']}, access policy: {oidc} is not supported. Needs 9.0.4.0 or higher. Ignoring access policy for this call.") accessPolicyName = None else: ap_ret_obj = access_policy.search(isamAppliance, accessPolicyName, check_mode=check_mode, force=force) if ap_ret_obj['data'] == {}: warnings = ap_ret_obj["warnings"] warnings.append( - "Access Policy {0} is not found. Cannot add definition.".format(accessPolicyName)) + f"Access Policy {accessPolicyName} is not found. Cannot add definition.") return isamAppliance.create_return_object(warnings=warnings) else: json_data["accessPolicyId"] = int(ap_ret_obj['data']) @@ -125,8 +124,7 @@ def add(isamAppliance, name, description="", accessPolicyName=None, grantTypes=[ if oidc is not None: if tools.version_compare(isamAppliance.facts["version"], "9.0.4.0") < 0: warnings.append( - "Appliance at version: {0}, oidc: {1} is not supported. Needs 9.0.4.0 or higher. Ignoring oidc for this call.".format( - isamAppliance.facts["version"], oidc)) + f"Appliance at version: {isamAppliance.facts['version']}, oidc: {oidc} is not supported. Needs 9.0.4.0 or higher. Ignoring oidc for this call.") else: if 'attributeSources' in oidc: oidc['attributeSources'] = _map_oidc_attributeSources(isamAppliance, oidc['attributeSources'], check_mode, force) @@ -134,14 +132,12 @@ def add(isamAppliance, name, description="", accessPolicyName=None, grantTypes=[ if 'dynamicClients' in json_data['oidc']: if tools.version_compare(isamAppliance.facts["version"], "9.0.5.0") < 0: warnings.append( - "Appliance at version: {0}, dynamicClients: {1} is not supported. Needs 9.0.5.0 or higher. Ignoring dynamicClients for this call.".format( - isamAppliance.facts["version"], json_data['oidc']['dynamicClients'])) + f"Appliance at version: {isamAppliance.facts['version']}, dynamicClients: {json_data['oidc']['dynamicClients']} is not supported. Needs 9.0.5.0 or higher. Ignoring dynamicClients for this call.") del json_data['oidc']['dynamicClients'] if 'issueSecret' in json_data['oidc']: if tools.version_compare(isamAppliance.facts["version"], "9.0.5.0") < 0: warnings.append( - "Appliance at version: {0}, issueSecret: {1} is not supported. Needs 9.0.5.0 or higher. Ignoring issueSecret for this call.".format( - isamAppliance.facts["version"], json_data['oidc']['issueSecret'])) + f"Appliance at version: {isamAppliance.facts['version']}, issueSecret: {json_data['oidc']['issueSecret']} is not supported. Needs 9.0.5.0 or higher. Ignoring issueSecret for this call.") del json_data['oidc']['issueSecret'] return isamAppliance.invoke_post( @@ -160,14 +156,14 @@ def delete(isamAppliance, name, check_mode=False, force=False): warnings = ret_obj["warnings"] if defn_id == {}: - logger.info("Definition {0} not found, skipping delete.".format(name)) + logger.info(f"Definition {name} not found, skipping delete.") else: if check_mode is True: return isamAppliance.create_return_object(changed=True, warnings=warnings) else: return isamAppliance.invoke_delete( "Delete an API protection definition", - "{0}/{1}".format(uri, defn_id), requires_modules=requires_modules, + f"{uri}/{defn_id}", requires_modules=requires_modules, requires_version=requires_version, warnings=warnings) return isamAppliance.create_return_object(warnings=warnings) @@ -188,7 +184,7 @@ def update(isamAppliance, name, description="", accessPolicyName=None, grantType warnings = ret_obj["warnings"] if ret_obj["data"] == {}: - warnings.append("Definiton {0} not found, skipping update.".format(name)) + warnings.append(f"Definiton {name} not found, skipping update.") return isamAppliance.create_return_object(warnings=warnings) else: defn_id = ret_obj["data"]["id"] @@ -216,15 +212,14 @@ def update(isamAppliance, name, description="", accessPolicyName=None, grantType if accessPolicyName is not None: if tools.version_compare(isamAppliance.facts["version"], "9.0.4.0") < 0: warnings.append( - "Appliance at version: {0}, access policy: {1} is not supported. Needs 9.0.4.0 or higher. Ignoring access policy for this call.".format( - isamAppliance.facts["version"], oidc)) + f"Appliance at version: {isamAppliance.facts['version']}, access policy: {oidc} is not supported. Needs 9.0.4.0 or higher. Ignoring access policy for this call.") accessPolicyName = None else: ap_ret_obj = access_policy.search(isamAppliance, accessPolicyName, check_mode=check_mode, force=force) if ap_ret_obj['data'] == {}: warnings = ap_ret_obj["warnings"] warnings.append( - "Access Policy {0} is not found. Cannot update definition.".format(accessPolicyName)) + f"Access Policy {accessPolicyName} is not found. Cannot update definition.") return isamAppliance.create_return_object(warnings=warnings) else: json_data["accessPolicyId"] = int(ap_ret_obj['data']) @@ -232,8 +227,7 @@ def update(isamAppliance, name, description="", accessPolicyName=None, grantType if oidc is not None: if tools.version_compare(isamAppliance.facts["version"], "9.0.4.0") < 0: warnings.append( - "Appliance at version: {0}, oidc: {1} is not supported. Needs 9.0.4.0 or higher. Ignoring oidc for this call.".format( - isamAppliance.facts["version"], oidc)) + f"Appliance at version: {isamAppliance.facts['version']}, oidc: {oidc} is not supported. Needs 9.0.4.0 or higher. Ignoring oidc for this call.") oidc = None else: if 'attributeSources' in oidc: @@ -288,8 +282,7 @@ def update(isamAppliance, name, description="", accessPolicyName=None, grantType if 'dynamicClients' in json_data['oidc']: if tools.version_compare(isamAppliance.facts["version"], "9.0.5.0") < 0: warnings.append( - "Appliance at version: {0}, dynamicClients: {1} is not supported. Needs 9.0.5.0 or higher. Ignoring dynamicClients for this call.".format( - isamAppliance.facts["version"], json_data['oidc']['dynamicClients'])) + f"Appliance at version: {isamAppliance.facts['version']}, dynamicClients: {json_data['oidc']['dynamicClients']} is not supported. Needs 9.0.5.0 or higher. Ignoring dynamicClients for this call.") del json_data['oidc']['dynamicClients'] else: if tools.version_compare(isamAppliance.facts["version"], "9.0.5.0") >= 0: @@ -300,8 +293,7 @@ def update(isamAppliance, name, description="", accessPolicyName=None, grantType if 'issueSecret' in json_data['oidc']: if tools.version_compare(isamAppliance.facts["version"], "9.0.5.0") < 0: warnings.append( - "Appliance at version: {0}, issueSecret: {1} is not supported. Needs 9.0.5.0 or higher. Ignoring issueSecret for this call.".format( - isamAppliance.facts["version"], json_data['oidc']['issueSecret'])) + f"Appliance at version: {isamAppliance.facts['version']}, issueSecret: {json_data['oidc']['issueSecret']} is not supported. Needs 9.0.5.0 or higher. Ignoring issueSecret for this call.") del json_data['oidc']['issueSecret'] else: if tools.version_compare(isamAppliance.facts["version"], "9.0.5.0") >= 0: @@ -318,8 +310,8 @@ def update(isamAppliance, name, description="", accessPolicyName=None, grantType sorted_ret_obj = tools.json_sort(ret_obj['data']) sorted_json_data = tools.json_sort(json_data) - logger.debug("Sorted Existing Data:{0}".format(sorted_ret_obj)) - logger.debug("Sorted Desired Data:{0}".format(sorted_json_data)) + logger.debug(f"Sorted Existing Data:{sorted_ret_obj}") + logger.debug(f"Sorted Desired Data:{sorted_json_data}") if sorted_ret_obj != sorted_json_data: needs_update = True @@ -329,7 +321,7 @@ def update(isamAppliance, name, description="", accessPolicyName=None, grantType else: return isamAppliance.invoke_put( "Update a specified API protection definition", - "{0}/{1}".format(uri, defn_id), json_data, requires_modules=requires_modules, + f"{uri}/{defn_id}", json_data, requires_modules=requires_modules, requires_version=requires_version, warnings=warnings) return isamAppliance.create_return_object(warnings=warnings) @@ -352,7 +344,7 @@ def set(isamAppliance, name, description="", accessPolicyName=None, grantTypes=[ if (search(isamAppliance, name=name))['data'] == {}: # Force the add - we already know policy does not exist - logger.info("Definition {0} had no match, requesting to add new one.".format(name)) + logger.info(f"Definition {name} had no match, requesting to add new one.") return add(isamAppliance=isamAppliance, name=name, description=description, accessPolicyName=accessPolicyName, grantTypes=grantTypes, tcmBehavior=tcmBehavior, accessTokenLifetime=accessTokenLifetime, accessTokenLength=accessTokenLength, @@ -366,7 +358,7 @@ def set(isamAppliance, name, description="", accessPolicyName=None, grantTypes=[ tokenCharSet=tokenCharSet, oidc=oidc, check_mode=check_mode, force=True) else: # Update request - logger.info("Definition {0} exists, requesting to update.".format(name)) + logger.info(f"Definition {name} exists, requesting to update.") return update(isamAppliance=isamAppliance, name=name, description=description, accessPolicyName=accessPolicyName, grantTypes=grantTypes, tcmBehavior=tcmBehavior, diff --git a/ibmsecurity/isam/aac/api_protection/dynamic_clients.py b/ibmsecurity/isam/aac/api_protection/dynamic_clients.py index 05632091..a9fa3a1b 100644 --- a/ibmsecurity/isam/aac/api_protection/dynamic_clients.py +++ b/ibmsecurity/isam/aac/api_protection/dynamic_clients.py @@ -14,8 +14,7 @@ def get_all(isamAppliance, sortBy=None, count=None, start=None, filter=None, che Retrieve a list of API protection clients """ return isamAppliance.invoke_get("Retrieve several dynamically registered clients", - "{0}/{1}".format(uri, tools.create_query_string(filter=filter, sortBy=sortBy, - count=count, start=start)), + f"{uri}/{tools.create_query_string(filter=filter, sortBy=sortBy, count=count, start=start)}", requires_modules=requires_modules, requires_version=requires_version) @@ -23,7 +22,7 @@ def get(isamAppliance, client_id, check_mode=False, force=False): """ Retrieve a dynamically registered client """ - return isamAppliance.invoke_get("Retrieve a dynamically registered client", "{0}/{1}".format(uri, client_id), + return isamAppliance.invoke_get("Retrieve a dynamically registered client", f"{uri}/{client_id}", requires_modules=requires_modules, requires_version=requires_version) @@ -35,7 +34,7 @@ def search(isamAppliance, client_id, check_mode=False, force=False): for obj in ret_obj['data']: if obj['clientId'] == client_id: - logger.info("Found API Protection Dynamic Client id: {0}".format(client_id)) + logger.info(f"Found API Protection Dynamic Client id: {client_id}") return True return False @@ -51,7 +50,7 @@ def delete(isamAppliance, client_id, check_mode=False, force=False): return isamAppliance.create_return_object(changed=True) else: return isamAppliance.invoke_delete( - "Delete a dynamically registered client", "{0}/{1}".format(uri, client_id), + "Delete a dynamically registered client", f"{uri}/{client_id}", requires_modules=requires_modules, requires_version=requires_version) return isamAppliance.create_return_object() diff --git a/ibmsecurity/isam/aac/api_protection/dynamic_clients_migration.py b/ibmsecurity/isam/aac/api_protection/dynamic_clients_migration.py index 1289ad3e..d3137f8f 100644 --- a/ibmsecurity/isam/aac/api_protection/dynamic_clients_migration.py +++ b/ibmsecurity/isam/aac/api_protection/dynamic_clients_migration.py @@ -22,7 +22,7 @@ def bulk_migration(isamAppliance, definitionName, definitionId, check_mode=False return isamAppliance.invoke_post( "Dynamic client bulk migration", - "{0}".format(uri), + f"{uri}", { 'definitionName': definitionName, 'definitionId': definitionId @@ -43,7 +43,7 @@ def client_migration(isamAppliance, definitionName, client_id, check_mode=False, return isamAppliance.invoke_post( "Dynamic client bulk migration", - "{0}/{1}".format(uri, client_id), + f"{uri}/{client_id}", { 'definitionName': definitionName }, diff --git a/ibmsecurity/isam/aac/api_protection/grants.py b/ibmsecurity/isam/aac/api_protection/grants.py index 8939929f..ac0363fc 100644 --- a/ibmsecurity/isam/aac/api_protection/grants.py +++ b/ibmsecurity/isam/aac/api_protection/grants.py @@ -14,7 +14,7 @@ def get(isamAppliance, state_id, check_mode=False, force=False): Get a grant """ return isamAppliance.invoke_get("Get a grant", - "/iam/access/v8/grants/{0}".format(state_id)) + f"/iam/access/v8/grants/{state_id}") def get_all(isamAppliance, check_mode=False, force=False): @@ -30,8 +30,7 @@ def get_users(isamAppliance, sortBy=None, filter=None, check_mode=False, force=F Get all users that have grants """ return isamAppliance.invoke_get("Get all users that have grants", - "/iam/access/v8/grants/userIds{0}".format( - tools.create_query_string(sortBy=sortBy, filter=filter))) + f"/iam/access/v8/grants/userIds{tools.create_query_string(sortBy=sortBy, filter=filter)}") def set(isamAppliance, state_id, attributes=[], isEnabled=True, check_mode=False, @@ -54,7 +53,7 @@ def set(isamAppliance, state_id, attributes=[], isEnabled=True, check_mode=False return isamAppliance.create_return_object(changed=True) else: return isamAppliance.invoke_put("Update a specified grant", - "/iam/access/v8/grants/{0}".format(state_id), + f"/iam/access/v8/grants/{state_id}", { 'isEnabled': isEnabled, 'attributes': attributes @@ -72,7 +71,7 @@ def delete(isamAppliance, state_id, check_mode=False, force=False): return isamAppliance.create_return_object(changed=True) else: return isamAppliance.invoke_delete("Delete a grant", - "/iam/access/v8/grants/{0}".format(state_id)) + f"/iam/access/v8/grants/{state_id}") return isamAppliance.create_return_object() diff --git a/ibmsecurity/isam/aac/api_protection/grants_user.py b/ibmsecurity/isam/aac/api_protection/grants_user.py index ad2f7440..e14183bc 100644 --- a/ibmsecurity/isam/aac/api_protection/grants_user.py +++ b/ibmsecurity/isam/aac/api_protection/grants_user.py @@ -8,7 +8,7 @@ def get(isamAppliance, userid, check_mode=False, force=False): Get grants by userid """ return isamAppliance.invoke_get("Get grants by userid", - "/iam/access/v8/grants/userIds/{0}".format(userid)) + f"/iam/access/v8/grants/userIds/{userid}") def get_recent(isamAppliance, userid, timestamp, token_type='refresh_token', check_mode=False, force=False): @@ -46,7 +46,7 @@ def delete(isamAppliance, userid, check_mode=False, force=False): return isamAppliance.create_return_object(changed=True) else: return isamAppliance.invoke_delete("Delete grants by userid", - "/iam/access/v8/grants/userIds/{0}".format(userid)) + f"/iam/access/v8/grants/userIds/{userid}") return isamAppliance.create_return_object() From 2b43aa3bd278fc57d40ccedb32b7871969acd498 Mon Sep 17 00:00:00 2001 From: Tom Bosmans Date: Wed, 28 May 2025 15:14:29 +0200 Subject: [PATCH 42/54] fix: pytest move commit to fixture --- conftest.py | 34 ++++++++++++++++++--- test/test_aac_apiprotection.py | 10 ------ test/test_aac_riskprofiles.py | 10 ------ test/test_aac_serverconnections_sms.py | 10 ------ test/test_base_admin.py | 10 ------ test/test_base_management_authentication.py | 9 ------ test/test_web_reverseproxy_oauth2.py | 11 ------- 7 files changed, 30 insertions(+), 64 deletions(-) diff --git a/conftest.py b/conftest.py index ebcbbecd..764e4605 100644 --- a/conftest.py +++ b/conftest.py @@ -7,9 +7,9 @@ from ibmsecurity.appliance.isamappliance import ISAMAppliance from ibmsecurity.user.applianceuser import ApplianceUser +import ibmsecurity.isam.appliance - -@pytest.fixture +@pytest.fixture(scope="session") def iviaServer(): """Initiate an ISAMAppliance.""" # s = IviaLogin() @@ -21,15 +21,41 @@ def iviaServer(): u = ApplianceUser(username=_username, password=_pw) # Create an ISAM appliance with above credential isam_server = ISAMAppliance(hostname=_host, user=u, lmi_port=_port) - return isam_server - + yield isam_server + returnValue = ibmsecurity.isam.appliance.commit(isamAppliance=isam_server) + print('\nCommit result') + print( returnValue ) + print('\n') + return returnValue # ibmsecurity def pytest_runtest_setup(item): print("setting up function:", item.name) + yield # @pytest.fixture(autouse=True) # def pytest_configure(config: Config) -> None: # """Register custom markers.""" # print('configure') + +#@pytest.fixture(scope="session", autouse=True) +#def ivia_commit(iviaServer): +# """Commit the changes""" +# print('TEST') +# # caplog.set_level(logging.INFO) + +# returnValue = ibmsecurity.isam.appliance.commit(isamAppliance=iviaServer) +# # logging.log(logging.DEBUG, returnValue) +# print(returnValue) + +#@pytest.hookimpl(hookwrapper=True) +#def pytest_sessionfinish(session, iviaServer): +# """Commit the changes""" +# # caplog.set_level(logging.INFO) +# +# returnValue = ibmsecurity.isam.appliance.commit(isamAppliance=iviaServer) +# yield returnValue +# # logging.log(logging.DEBUG, returnValue) +# print(returnValue) +# print("\nTest session finished!") diff --git a/test/test_aac_apiprotection.py b/test/test_aac_apiprotection.py index c4215b87..b4fe0e27 100644 --- a/test/test_aac_apiprotection.py +++ b/test/test_aac_apiprotection.py @@ -81,13 +81,3 @@ def test_set_apiprotection_definition(iviaServer, caplog, items) -> None: logging.log(logging.INFO, returnValue) assert not returnValue.failed() - - -def test_commit(iviaServer, caplog) -> None: - """Not actually a test, but save the changes.""" - caplog.set_level(logging.INFO) - - returnValue = ibmsecurity.isam.appliance.commit(isamAppliance=iviaServer) - logging.log(logging.DEBUG, returnValue) - - assert not returnValue.failed() diff --git a/test/test_aac_riskprofiles.py b/test/test_aac_riskprofiles.py index 2e89ef2d..68cf8764 100644 --- a/test/test_aac_riskprofiles.py +++ b/test/test_aac_riskprofiles.py @@ -43,13 +43,3 @@ def test_set_riskprofiles(iviaServer, caplog, items) -> None: logging.log(logging.INFO, returnValue) assert not returnValue.failed() - - -def test_commit(iviaServer, caplog) -> None: - """Not actually a test, but save the changes.""" - caplog.set_level(logging.INFO) - - returnValue = ibmsecurity.isam.appliance.commit(isamAppliance=iviaServer) - logging.log(logging.DEBUG, returnValue) - - assert not returnValue.failed() diff --git a/test/test_aac_serverconnections_sms.py b/test/test_aac_serverconnections_sms.py index 3352fe85..1d677302 100644 --- a/test/test_aac_serverconnections_sms.py +++ b/test/test_aac_serverconnections_sms.py @@ -70,13 +70,3 @@ def test_set_serverconnection_sms(iviaServer, caplog, items) -> None: if returnValue is not None: assert not returnValue.failed() - - -def test_commit(iviaServer, caplog) -> None: - """Not actually a test, but save the changes.""" - caplog.set_level(logging.INFO) - - returnValue = ibmsecurity.isam.appliance.commit(isamAppliance=iviaServer) - logging.log(logging.DEBUG, returnValue) - - assert not returnValue.failed() diff --git a/test/test_base_admin.py b/test/test_base_admin.py index ec6bbdf7..d3933034 100644 --- a/test/test_base_admin.py +++ b/test/test_base_admin.py @@ -22,13 +22,3 @@ def test_set_base_admin(iviaServer, caplog) -> None: logging.log(logging.INFO, returnValue) assert not returnValue.failed() - - -def test_commit(iviaServer, caplog) -> None: - """Not actually a test, but save the changes.""" - caplog.set_level(logging.INFO) - - returnValue = ibmsecurity.isam.appliance.commit(isamAppliance=iviaServer) - logging.log(logging.DEBUG, returnValue) - - assert not returnValue.failed() diff --git a/test/test_base_management_authentication.py b/test/test_base_management_authentication.py index 7c2b55ca..dc1cd726 100644 --- a/test/test_base_management_authentication.py +++ b/test/test_base_management_authentication.py @@ -93,12 +93,3 @@ def test_set_base_management_authentication_federation(iviaServer, caplog, items logging.log(logging.INFO, returnValue) assert not returnValue.failed() - -def test_commit(iviaServer, caplog) -> None: - """Not actually a test, but save the changes.""" - caplog.set_level(logging.INFO) - - returnValue = ibmsecurity.isam.appliance.commit(isamAppliance=iviaServer) - logging.log(logging.DEBUG, returnValue) - - assert not returnValue.failed() diff --git a/test/test_web_reverseproxy_oauth2.py b/test/test_web_reverseproxy_oauth2.py index 37915f89..dee02eab 100644 --- a/test/test_web_reverseproxy_oauth2.py +++ b/test/test_web_reverseproxy_oauth2.py @@ -39,14 +39,3 @@ def test_set_reverseproxy_isamop(iviaServer, caplog, items) -> None: logging.log(logging.INFO, returnValue) assert not returnValue.failed() - - - -def test_commit(iviaServer, caplog) -> None: - """Not actually a test, but save the changes.""" - caplog.set_level(logging.INFO) - - returnValue = ibmsecurity.isam.appliance.commit(iviaServer) - logging.log(logging.DEBUG, returnValue) - - assert not returnValue.failed() From 8e659f4a8ced7587fde08a13c72ade4acf87b7f5 Mon Sep 17 00:00:00 2001 From: Tom Bosmans Date: Wed, 28 May 2025 16:02:15 +0200 Subject: [PATCH 43/54] feature: new attributes in 10.0.8 --- .../ssl_certificates/certificate_databases.py | 113 ++++++++++++++---- 1 file changed, 92 insertions(+), 21 deletions(-) diff --git a/ibmsecurity/isam/base/ssl_certificates/certificate_databases.py b/ibmsecurity/isam/base/ssl_certificates/certificate_databases.py index 8801c762..521c081b 100644 --- a/ibmsecurity/isam/base/ssl_certificates/certificate_databases.py +++ b/ibmsecurity/isam/base/ssl_certificates/certificate_databases.py @@ -7,6 +7,35 @@ logger = logging.getLogger(__name__) requires_model = "Appliance" +certificate_database_optional_args = ( + "token_label", + "serial_number", + "passcode", + "hsm_type", + "ip", + "port", + "kneti_hash", + "esn", + "use_rfs", + "rfs", + "rfs_port", + "rfs_auth", + "safenet_pw", + "secondary_ip", + "secondary_port", + "secondary_kneti_hash", + "secondary_esn", + "update_zip" +) +certificate_database_new_10_05 = ( + "safenet_keystore_list", + "safenet_primary_keystore", + "safenet_user" +) +certificate_database_new_10_08 = ( + "serial_number" +) + def get_all(isamAppliance, check_mode=False, force=False): """ @@ -25,34 +54,76 @@ def get(isamAppliance, cert_dbase_id, check_mode=False, force=False): requires_model=requires_model) -def create(isamAppliance, kdb_name, type='kdb', token_label=None, passcode=None, hsm_type=None, ip=None, port=None, - kneti_hash=None, esn=None, rfs=None, rfs_port=None, rfs_auth=None, safenet_pw=None, check_mode=False, - force=False): +def create(isamAppliance, kdb_name, type='kdb', + check_mode=False, force=False + **kwargs, + ): """ Create a certificate database + token_label=None, + serial_number=None, + passcode=None, + hsm_type=None, + ip=None, port=None, kneti_hash=None, esn=None, + secondary_ip=None, secondary_port=None, secondary_kneti_hash=None, secondary_esn=None, + use_rfs=None, + rfs=None, rfs_port=None, rfs_auth=None, safenet_user=None, safenet_pw=None, + update_zip=None, + safenet_keystore_list=None, safenet_primary_keystore=None, + TODO: Update zip does not work atm. """ - if force is True or _check(isamAppliance, kdb_name) is False: - if check_mode is True: + warnings = [] + if force or not _check(isamAppliance, kdb_name): + if check_modee: return isamAppliance.create_return_object(changed=True) else: - return isamAppliance.invoke_post( - "Creating certificate database '{0}'".format(kdb_name), - "/isam/ssl_certificates", - { + + json_data = { "kdb_name": kdb_name, "type": type, - "token_label": token_label, - "passcode": passcode, - "hsm_type": hsm_type, - "ip": ip, - "port": port, - "kneti_hash": kneti_hash, - "esn": esn, - "rfs": rfs, - "rfs_port": rfs_port, - "rfs_auth": rfs_auth, - "safenet_pw": safenet_pw - }) + } + for k, v in kwargs.items(): + if k in certificate_database_optional_args: + json_data[k] = v + # new in 10.0.5 + if k in certificate_database_new_10_05: + if ibmsecurity.utilities.tools.version_compare(isamAppliance.facts["version"], "10.0.8.0") < 0: + warnings.append( "Appliance at version: {0}, load_certificate: {1} is not supported. Needs 10.0.0.0 or higher. Ignoring load_certificate for this call.".format( isamAppliance.facts["version"], load_certificate)) + else: + json_data[k] = v + # new in 10.0.8 + if k in certificate_database_new_10_08: + if ibmsecurity.utilities.tools.version_compare(isamAppliance.facts["version"], "10.0.8.0") < 0: + warnings.append( "Appliance at version: {0}, load_certificate: {1} is not supported. Needs 10.0.0.0 or higher. Ignoring load_certificate for this call.".format( isamAppliance.facts["version"], load_certificate)) + else: + json_data[k] = v + # Logic + if type != 'p11' or json_data.get("hsm_type", None) not in ("safenet","safenet-ha"): + warnings.append("Serial number, safenet_* are only valid for safenet hsm, removed from input") + json_data.pop("serial_number", None) + json_data.pop("safenet_user", None) + json_data.pop("safenet_pw", None) + json_data.pop("safenet_keystore_list", None) + json_data.pop("safenet_primary_keystore", None) + if type != 'p11' or json_data.get("hsm_type", None) != "ncipher": + warnings.append("kneti_hash, port, secondary_*, rfs are only valid for ncipher hsm, removed from input") + json_data.pop("port", None) + json_data.pop("kneti_hash", None) + json_data.pop("secondary_ip", None) + json_data.pop("secondary_port", None) + json_data.pop("secondary_kneti_hash", None) + json_data.pop("secondary_esn", None) + json_data.pop("use_rfs", None) + json_data.pop("rfs", None) + json_data.pop("rfs_port", None) + json_data.pop("rfs_auth", None) + + return isamAppliance.invoke_post( + f"Creating certificate database '{kdb_name}'", + "/isam/ssl_certificates", + json_data, + warnings=warnings + ) return isamAppliance.create_return_object() From fe7fe7c2ede922a7b7d05b70c72fef33a701637f Mon Sep 17 00:00:00 2001 From: Tom Bosmans Date: Wed, 28 May 2025 16:13:27 +0200 Subject: [PATCH 44/54] fix: format() -> f-string --- ibmsecurity/isam/base/activation.py | 6 ++-- ibmsecurity/isam/base/admin.py | 8 ++--- .../isam/base/advanced_tuning_parameters.py | 7 ++-- .../base/application_database_settings.py | 4 +-- ibmsecurity/isam/base/audit/configuration.py | 8 ++--- ibmsecurity/isam/base/audit_configuration.py | 8 ++--- ibmsecurity/isam/base/available_updates.py | 21 +++++------ .../isam/base/cluster/config_database.py | 2 +- .../isam/base/cluster/configuration.py | 13 ++++--- ibmsecurity/isam/base/cluster/log.py | 6 ++-- ibmsecurity/isam/base/cluster/node.py | 4 +-- ibmsecurity/isam/base/cluster/property.py | 6 ++-- .../isam/base/cluster/runtime_database.py | 2 +- ibmsecurity/isam/base/container_ext/repo.py | 8 ++--- ibmsecurity/isam/base/dsc.py | 4 +-- ibmsecurity/isam/base/extensions.py | 16 ++++----- ibmsecurity/isam/base/file_downloads.py | 4 +-- ibmsecurity/isam/base/fips.py | 14 ++++---- ibmsecurity/isam/base/firmware.py | 2 +- ibmsecurity/isam/base/fixpack.py | 4 +-- ibmsecurity/isam/base/geolocation_db.py | 4 +-- ibmsecurity/isam/base/host/name.py | 6 ++-- ibmsecurity/isam/base/host/records.py | 4 +-- ibmsecurity/isam/base/license.py | 2 +- ibmsecurity/isam/base/lmi.py | 4 +-- .../isam/base/management_authentication.py | 7 ++-- .../base/management_authorization/feature.py | 2 +- .../base/management_authorization/role.py | 4 +-- .../management_authorization/role_feature.py | 4 +-- .../management_authorization/role_group.py | 6 ++-- .../management_authorization/role_user.py | 6 ++-- .../isam/base/network/active_status.py | 4 +-- .../felb/advanced_tuning/at_logging.py | 4 +-- .../network/felb/advanced_tuning/config.py | 8 ++--- .../felb/attributes/advanced_tuning.py | 8 ++--- .../isam/base/network/felb/attributes/log.py | 4 +-- ibmsecurity/isam/base/network/felb/config.py | 8 ++--- .../isam/base/network/felb/error_page.py | 8 ++--- ibmsecurity/isam/base/network/felb/ha.py | 4 +-- .../network/felb/services/advanced_tuning.py | 11 +++--- .../isam/base/network/felb/services/config.py | 6 ++-- .../isam/base/network/felb/services/layer.py | 8 ++--- .../base/network/felb/services/servers.py | 14 ++++---- ibmsecurity/isam/base/network/host_records.py | 10 +++--- ibmsecurity/isam/base/network/interfaces.py | 2 +- .../isam/base/network/interfaces_ipv4.py | 8 ++--- .../isam/base/network/interfaces_ipv6.py | 8 ++--- .../isam/base/network/interfaces_vlan.py | 6 ++-- ibmsecurity/isam/base/network/packet_trace.py | 8 ++--- .../isam/base/network/static_routes.py | 36 +++++++++---------- .../isam/base/remote_syslog/forwarder.py | 20 +++++------ .../base/remote_syslog/forwarder_sources.py | 6 ++-- ibmsecurity/isam/base/runtime/cluster.py | 4 +-- .../isam/base/runtime/listening_interfaces.py | 8 ++--- ibmsecurity/isam/base/runtime/process.py | 7 ++-- .../isam/base/runtime/tuning_parameters.py | 12 +++---- .../isam/base/scheduled_security_updates.py | 4 +-- ibmsecurity/isam/base/service_agreement.py | 4 +-- ibmsecurity/isam/base/silent_config.py | 18 +++++----- ibmsecurity/isam/base/snapshots.py | 10 +++--- ibmsecurity/isam/base/snmp_monitoring.py | 4 +-- .../ssl_certificates/certificate_databases.py | 18 +++++----- .../ssl_certificates/certificate_requests.py | 15 ++++---- .../ssl_certificates/personal_certificate.py | 25 +++++++------ .../ssl_certificates/signer_certificate.py | 24 ++++++------- ibmsecurity/isam/base/support.py | 14 ++++---- ibmsecurity/isam/base/sysaccount/groups.py | 4 +-- ibmsecurity/isam/base/sysaccount/users.py | 6 ++-- ibmsecurity/isam/base/system_alerts/alerts.py | 2 +- ibmsecurity/isam/base/system_alerts/email.py | 6 ++-- ibmsecurity/isam/base/system_alerts/logdb.py | 6 ++-- .../isam/base/system_alerts/rsyslog.py | 6 ++-- ibmsecurity/isam/base/system_alerts/snmp.py | 6 ++-- ibmsecurity/isam/base/update_servers.py | 22 ++++++------ 74 files changed, 294 insertions(+), 318 deletions(-) diff --git a/ibmsecurity/isam/base/activation.py b/ibmsecurity/isam/base/activation.py index c2574efc..a274c195 100644 --- a/ibmsecurity/isam/base/activation.py +++ b/ibmsecurity/isam/base/activation.py @@ -18,7 +18,7 @@ def get(isamAppliance, id=None, check_mode=False, force=False): """ if force is True or check(isamAppliance, id) is True: return isamAppliance.invoke_get("Retrieve a specified activation offering", - "/isam/capabilities/{0}/v1".format(id)) + f"/isam/capabilities/{id}/v1") return isamAppliance.create_return_object() @@ -39,7 +39,7 @@ def update(isamAppliance, enabled, id=None, check_mode=False, force=False): return isamAppliance.create_return_object(changed=True) else: return isamAppliance.invoke_put("Update an activation offering", - "/isam/capabilities/{0}/v1".format(id), + f"/isam/capabilities/{id}/v1", {'enabled': enabled.capitalize()} ) @@ -79,7 +79,7 @@ def delete(isamAppliance, id, check_mode=False, force=False): else: ret_obj = isamAppliance.invoke_delete( "Deleting activation of Module", - "/isam/capabilities/{0}/v1".format(id)) + f"/isam/capabilities/{id}/v1") # Update 'facts', remove module isamAppliance.facts['activations'].remove(id) return ret_obj diff --git a/ibmsecurity/isam/base/admin.py b/ibmsecurity/isam/base/admin.py index eb2c3b0d..c68de456 100644 --- a/ibmsecurity/isam/base/admin.py +++ b/ibmsecurity/isam/base/admin.py @@ -29,13 +29,13 @@ def set_pw(isamAppliance, oldPassword, newPassword, sessionTimeout="30", httpsPo "sessionTimeout": sessionTimeout } if httpsPort is not None: - if ibmsecurity.utilities.tools.version_compare(isamAppliance.facts["version"], "9.0.1.0") < 0: + if ibmsecurity.utilities.tools.version_compare(isamAppliance.facts['version'], "9.0.1.0") < 0: warnings.append( "Appliance at version: {0}, httpsPort not supported. Needs 9.0.1.0 or higher. Ignoring httpsPort for this call.") else: json_data['httpsPort'] = httpsPort else: - if ibmsecurity.utilities.tools.version_compare(isamAppliance.facts["version"], "9.0.1.0") < 0: + if ibmsecurity.utilities.tools.version_compare(isamAppliance.facts['version'], "9.0.1.0") < 0: pass # Can safely ignore httpsPort else: warnings.append("Default httpsPort of 443 will be set on the appliance.") @@ -151,7 +151,7 @@ def _check(isamAppliance, json_data = {} for k, v in kwargs.items(): - iviaVersion = isamAppliance.facts["version"] + iviaVersion = isamAppliance.facts['version'] if v is None: # Skip None inputs continue @@ -226,7 +226,7 @@ def _check(isamAppliance, if sorted_ret_obj != sorted_json_data: logger.debug("Admin Settings are found to be different. See above JSON for difference.") # Ensure users know how REST API handles httpsPort default value - I think everybody should know this by now - # if json_data.get("httpsPort", "") == "" and ibmsecurity.utilities.tools.version_compare(isamAppliance.facts["version"], + # if json_data.get("httpsPort", "") == "" and ibmsecurity.utilities.tools.version_compare(isamAppliance.facts['version'], # "9.0.1.0") >= 0: # warnings.append("Default httpsPort of 443 will be set on the appliance.") return True, warnings, json_data diff --git a/ibmsecurity/isam/base/advanced_tuning_parameters.py b/ibmsecurity/isam/base/advanced_tuning_parameters.py index cc327d24..53f76295 100644 --- a/ibmsecurity/isam/base/advanced_tuning_parameters.py +++ b/ibmsecurity/isam/base/advanced_tuning_parameters.py @@ -63,7 +63,7 @@ def _check(isamAppliance, key, value=None): if param['key'] == key: exist_value_list.append(str(param['value'])) uuid.append(param['uuid']) - logger.info("Advanced tuning parameter key: {0} and value: {1} exists".format(key, value)) + logger.info(f"Advanced tuning parameter key: {key} and value: {value} exists") # value being none - means called from delete function if value is not None: @@ -73,8 +73,7 @@ def _check(isamAppliance, key, value=None): rc = ibmsecurity.utilities.tools.json_sort(exist_value_list) == ibmsecurity.utilities.tools.json_sort( given_value_list) logger.info( - "Advanced tuning parameter: {0} has existing values: {1}, and given values: {2} - match status: {3}".format( - key, exist_value_list, given_value_list, rc)) + f"Advanced tuning parameter: {key} has existing values: {exist_value_list}, and given values: {given_value_list} - match status: {rc}") return rc, uuid @@ -109,7 +108,7 @@ def _del(isamAppliance, uuid): for u in uuid: r = isamAppliance.invoke_delete( "Deleting existing advanced tuning parameter", - "/core/adv_params/{0}".format(u)) + f"/core/adv_params/{u}") ret_obj['changed'] = ret_obj['changed'] or r['changed'] ret_obj['data'].append(r['data']) ret_obj['warnings'].extend(r['warnings']) diff --git a/ibmsecurity/isam/base/application_database_settings.py b/ibmsecurity/isam/base/application_database_settings.py index 8e856a7f..a0db9749 100644 --- a/ibmsecurity/isam/base/application_database_settings.py +++ b/ibmsecurity/isam/base/application_database_settings.py @@ -75,9 +75,9 @@ def _check(isamAppliance, enableIprAutoUpdate, useProxy, proxyHost, proxyPort, u # Compare to establish idempotency sorted_json_data = ibmsecurity.utilities.tools.json_sort(json_data) - logger.debug("Sorted input: {0}".format(sorted_json_data)) + logger.debug(f"Sorted input: {sorted_json_data}") sorted_ret_obj = ibmsecurity.utilities.tools.json_sort(ret_obj['data']) - logger.debug("Sorted existing data: {0}".format(sorted_ret_obj)) + logger.debug(f"Sorted existing data: {sorted_ret_obj}") if sorted_ret_obj != sorted_json_data: logger.info("Changes detected, update needed.") update_required = True diff --git a/ibmsecurity/isam/base/audit/configuration.py b/ibmsecurity/isam/base/audit/configuration.py index d8d53081..8282a476 100644 --- a/ibmsecurity/isam/base/audit/configuration.py +++ b/ibmsecurity/isam/base/audit/configuration.py @@ -153,7 +153,7 @@ def set(isamAppliance, id, config, enabled=True, type='Syslog', verbose=True, ch pol_id, update_required, json_data = _check(isamAppliance, id, config, enabled, type, verbose, use_json, components) if pol_id is None: from ibmsecurity.appliance.ibmappliance import IBMError - raise IBMError("999", "Cannot update data for unknown Audit Configuration ID: {0}".format(id)) + raise IBMError("999", f"Cannot update data for unknown Audit Configuration ID: {id}") if force is True or update_required is True: if check_mode is True: @@ -161,7 +161,7 @@ def set(isamAppliance, id, config, enabled=True, type='Syslog', verbose=True, ch else: return isamAppliance.invoke_put( "Update Audit Configuration", - "{0}/{1}".format(uri, id), json_data, requires_modules=requires_modules, + f"{uri}/{id}", json_data, requires_modules=requires_modules, requires_version=requires_version) return isamAppliance.create_return_object() @@ -217,9 +217,9 @@ def _check(isamAppliance, id, config, enabled, type, verbose, use_json=False, co else: import ibmsecurity.utilities.tools sorted_json_data = ibmsecurity.utilities.tools.json_sort(json_data) - logger.debug("Sorted input: {0}".format(sorted_json_data)) + logger.debug(f"Sorted input: {sorted_json_data}") sorted_ret_obj = ibmsecurity.utilities.tools.json_sort(aud_cfg) - logger.debug("Sorted existing data: {0}".format(sorted_ret_obj)) + logger.debug(f"Sorted existing data: {sorted_ret_obj}") if sorted_ret_obj != sorted_json_data: logger.info("Changes detected, update needed.") update_required = True diff --git a/ibmsecurity/isam/base/audit_configuration.py b/ibmsecurity/isam/base/audit_configuration.py index f8bb4a91..6a23b3f8 100644 --- a/ibmsecurity/isam/base/audit_configuration.py +++ b/ibmsecurity/isam/base/audit_configuration.py @@ -163,7 +163,7 @@ def set(isamAppliance, id, config, enabled=True, type='Syslog', verbose=True, ch pol_id, update_required, json_data = _check(isamAppliance, id, config, enabled, type, verbose, use_json, components) if pol_id is None: from ibmsecurity.appliance.ibmappliance import IBMError - raise IBMError("999", "Cannot update data for unknown Audit Configuration ID: {0}".format(id)) + raise IBMError("999", f"Cannot update data for unknown Audit Configuration ID: {id}") if force is True or update_required is True: if check_mode is True: @@ -171,7 +171,7 @@ def set(isamAppliance, id, config, enabled=True, type='Syslog', verbose=True, ch else: return isamAppliance.invoke_put( "Update Audit Configuration", - "{0}/{1}".format(uri, id), json_data, requires_modules=requires_modules, + f"{uri}/{id}", json_data, requires_modules=requires_modules, requires_version=requires_version, warnings=warnings) return isamAppliance.create_return_object() @@ -227,9 +227,9 @@ def _check(isamAppliance, id, config, enabled, type, verbose, use_json=False, co else: import ibmsecurity.utilities.tools sorted_json_data = ibmsecurity.utilities.tools.json_sort(json_data) - logger.debug("Sorted input: {0}".format(sorted_json_data)) + logger.debug(f"Sorted input: {sorted_json_data}") sorted_ret_obj = ibmsecurity.utilities.tools.json_sort(aud_cfg) - logger.debug("Sorted existing data: {0}".format(sorted_ret_obj)) + logger.debug(f"Sorted existing data: {sorted_ret_obj}") if sorted_ret_obj != sorted_json_data: logger.info("Changes detected, update needed.") update_required = True diff --git a/ibmsecurity/isam/base/available_updates.py b/ibmsecurity/isam/base/available_updates.py index 0f987678..c1018336 100644 --- a/ibmsecurity/isam/base/available_updates.py +++ b/ibmsecurity/isam/base/available_updates.py @@ -55,12 +55,12 @@ def _check_file(isamAppliance, file): # If there is an exception then simply return False # Sample filename - isam_9.0.2.0_20161102-2353.pkg - logger.debug("Checking provided file is ready to upload: {0}".format(file)) + logger.debug(f"Checking provided file is ready to upload: {file}") try: # Extract file name from path f = os.path.basename(file) fn = os.path.splitext(f) - logger.debug("File name without path: {0}".format(fn[0])) + logger.debug(f"File name without path: {fn[0]}") # Split of file by '-' hyphen and '_' under score import re @@ -68,7 +68,7 @@ def _check_file(isamAppliance, file): firm_file_version = fp[1] firm_file_product = fp[0] firm_file_date = fp[2] - logger.debug("PKG file details: {0}: version: {1} date: {2}".format(firm_file_product, firm_file_version, firm_file_date)) + logger.debug(f"PKG file details: {firm_file_product}: version: {firm_file_version} date: {firm_file_date}") # Check if firmware level already contains the update to be uploaded or greater, check Active partition # firmware "name" of format - isam_9.0.2.0_20161102-2353 @@ -80,18 +80,16 @@ def _check_file(isamAppliance, file): firm_appl_version = fp[1] firm_appl_product = fp[0] firm_appl_date = fp[2] - logger.debug("Partition details ({0}): {1}: version: {2} date: {3}".format(firm['partition'], firm_appl_product, firm_appl_version, firm_appl_date)) + logger.debug(f"Partition details ({firm['partition']}): {firm_appl_product}: version: {firm_appl_version} date: {firm_appl_date}") if firm['active'] is True: from ibmsecurity.utilities import tools if tools.version_compare(firm_appl_version, firm_file_version) >= 0: logger.info( - "Active partition has version {0} which is greater or equals than install package at version {1}.".format( - firm_appl_version, firm_file_version)) + f"Active partition has version {firm_appl_version} which is greater or equals than install package at version {firm_file_version}.") return True else: logger.info( - "Active partition has version {0} which is smaller than install package at version {1}.".format( - firm_appl_version, firm_file_version)) + f"Active partition has version {firm_appl_version} which is smaller than install package at version {firm_file_version}.") # Check if update uploaded - will not show up if installed though ret_obj = get(isamAppliance) @@ -101,7 +99,7 @@ def _check_file(isamAppliance, file): if upd['version'] == fp[1] and rd == fp[2]: # Version of format 9.0.2.0 return True except Exception as e: - logger.debug("Exception occured: {0}".format(e)) + logger.debug(f"Exception occured: {e}") pass return False @@ -138,13 +136,12 @@ def _check(isamAppliance, type, version, release_date, name): # If there is an installation in progress then abort # API changed in v10.0.5.0 , state, schedule_date, # iso_scheduled_date and expired_install are no longer available. - if ibmsecurity.utilities.tools.version_compare(isamAppliance.facts["version"], "10.0.5.0") >= 0: + if ibmsecurity.utilities.tools.version_compare(isamAppliance.facts['version'], "10.0.5.0") >= 0: if 'state' in upd and upd['state'] == 'Installing': logger.debug("Detecting a state of installing...") return False else: - warnings.append("Appliance at version: {0}, state can no longer be checked in 10.0.5.0 or higher. Ignoring for this call.".format( - isamAppliance.facts["version"])) + warnings.append(f"Appliance at version: {isamAppliance.facts['version']}, state can no longer be checked in 10.0.5.0 or higher. Ignoring for this call.") logger.info(upd) diff --git a/ibmsecurity/isam/base/cluster/config_database.py b/ibmsecurity/isam/base/cluster/config_database.py index 2df6365b..6d0bc8af 100644 --- a/ibmsecurity/isam/base/cluster/config_database.py +++ b/ibmsecurity/isam/base/cluster/config_database.py @@ -15,7 +15,7 @@ def export(isamAppliance, filename, type="db2", check_mode=False, force=False): if check_mode is False: # No point downloading a file if in check_mode return isamAppliance.invoke_get_file( "Export the configuration database", - "/isam/cluster/configdb/v1?type={0}".format(type), + f"/isam/cluster/configdb/v1?type={type}", filename, requires_model=requires_model, ) diff --git a/ibmsecurity/isam/base/cluster/configuration.py b/ibmsecurity/isam/base/cluster/configuration.py index 5d17d058..990a76e2 100644 --- a/ibmsecurity/isam/base/cluster/configuration.py +++ b/ibmsecurity/isam/base/cluster/configuration.py @@ -145,10 +145,9 @@ def set(isamAppliance, primary_master='127.0.0.1', secondary_master=None, master cfgdb_solid_tc = ast.literal_eval(cfgdb_solid_tc) cluster_json["cfgdb_solid_tc"] = cfgdb_solid_tc if cfgdb_fs is not None: - if ibmsecurity.utilities.tools.version_compare(isamAppliance.facts["version"], "9.0.2.0") < 0: + if ibmsecurity.utilities.tools.version_compare(isamAppliance.facts['version'], "9.0.2.0") < 0: warnings.append( - "Appliance at version: {0}, cfgdb_fs: {1} is not supported. Needs 9.0.2.0 or higher. Ignoring cfgdb_fs for this call.".format( - isamAppliance.facts["version"], cfgdb_fs)) + f"Appliance at version: {isamAppliance.facts['version']}, cfgdb_fs: {cfgdb_fs} is not supported. Needs 9.0.2.0 or higher. Ignoring cfgdb_fs for this call.") else: cluster_json["cfgdb_fs"] = cfgdb_fs if cfgdb_db_truststore is not None and cfgdb_db_truststore != "": @@ -193,7 +192,7 @@ def _check(isamAppliance, cluster_json, ignore_password_for_idempotency): del temp["hvdb_password"] if 'cfgdb_password' in temp: del temp["cfgdb_password"] - logger.debug("Passwordless JSON to Apply: {0}".format(temp)) + logger.debug(f"Passwordless JSON to Apply: {temp}") else: temp = cluster_json @@ -204,13 +203,13 @@ def _check(isamAppliance, cluster_json, ignore_password_for_idempotency): if key in temp: temp_retobj[key] = value else: - logger.debug("Ignoring {0}".format(key)) + logger.debug(f"Ignoring {key}") sorted_ret_obj = json.dumps(temp_retobj, skipkeys=True, sort_keys=True) sorted_json_data = json.dumps(temp, skipkeys=True, sort_keys=True) - logger.debug("Sorted Existing Data:{0}".format(sorted_ret_obj)) - logger.debug("Sorted Desired Data:{0}".format(sorted_json_data)) + logger.debug(f"Sorted Existing Data:{sorted_ret_obj}") + logger.debug(f"Sorted Desired Data:{sorted_json_data}") if sorted_ret_obj == sorted_json_data: logger.debug("JSON provided already is contained in current appliance configuration.") diff --git a/ibmsecurity/isam/base/cluster/log.py b/ibmsecurity/isam/base/cluster/log.py index 64772ae9..005adf0b 100644 --- a/ibmsecurity/isam/base/cluster/log.py +++ b/ibmsecurity/isam/base/cluster/log.py @@ -19,7 +19,7 @@ def get(isamAppliance, file_id, size=100, start=None, options=None, check_mode=F Retrieve a log file snippet """ return isamAppliance.invoke_get("Retrieve a log file snippet", - "/isam/cluster/logging/{0}/v1".format(file_id), requires_model=requires_model) + f"/isam/cluster/logging/{file_id}/v1", requires_model=requires_model) def _check(isamAppliance, file_id): @@ -46,7 +46,7 @@ def delete(isamAppliance, file_id, check_mode=False, force=False): else: return isamAppliance.invoke_delete( "Clear a log file", - "/isam/cluster/logging/{0}/v1".format(file_id), requires_model=requires_model) + f"/isam/cluster/logging/{file_id}/v1", requires_model=requires_model) return isamAppliance.create_return_object(warnings=warnings) @@ -61,7 +61,7 @@ def export_file(isamAppliance, file_id, filename, check_mode=False, force=False) if check_mode is False: # No point downloading a file if in check_mode return isamAppliance.invoke_get_file( "Export a cluster manager log file", - "/isam/cluster/logging/{0}/v1?export".format(file_id), + f"/isam/cluster/logging/{file_id}/v1?export", filename, requires_model=requires_model) return isamAppliance.create_return_object() diff --git a/ibmsecurity/isam/base/cluster/node.py b/ibmsecurity/isam/base/cluster/node.py index f45a015e..499db875 100644 --- a/ibmsecurity/isam/base/cluster/node.py +++ b/ibmsecurity/isam/base/cluster/node.py @@ -46,7 +46,7 @@ def get_state(isamAppliance, cluster_id, check_mode=False, force=False): if not cluster_id: return isamAppliance.create_return_object() return isamAppliance.invoke_get("Validate a cluster identifier", - "/isam/cluster/id/address/{0}/state/v2".format(cluster_id), + f"/isam/cluster/id/address/{cluster_id}/state/v2", requires_model=requires_model) @@ -159,7 +159,7 @@ def delete(isamAppliance, id, check_mode=False, force=False): else: return isamAppliance.invoke_delete( "Remove a node from the cluster", - "/isam/cluster/nodes/{0}/v1".format(id), requires_model=requires_model) + f"/isam/cluster/nodes/{id}/v1", requires_model=requires_model) return isamAppliance.create_return_object(warnings=check_obj['warnings']) diff --git a/ibmsecurity/isam/base/cluster/property.py b/ibmsecurity/isam/base/cluster/property.py index 646266ca..d4d13d2e 100644 --- a/ibmsecurity/isam/base/cluster/property.py +++ b/ibmsecurity/isam/base/cluster/property.py @@ -8,7 +8,7 @@ def get(isamAppliance, id, check_mode=False, force=False): Retrieve the value of a property in the cluster configuration """ return isamAppliance.invoke_get("Retrieve the value of a property in the cluster configuration", - "/isam/cluster/property/{0}/v2".format(id)) + f"/isam/cluster/property/{id}/v2") def add(isamAppliance, id, value, check_mode=False, force=False): @@ -40,7 +40,7 @@ def update(isamAppliance, id, value, check_mode=False, force=False): else: return isamAppliance.invoke_put( "Update the value of a property in the cluster configuration", - "/isam/cluster/property/{0}/v2".format(id), + f"/isam/cluster/property/{id}/v2", { "value": value }) @@ -74,6 +74,6 @@ def delete(isamAppliance, id, check_mode=False, force=False): else: return isamAppliance.invoke_delete( "Delete a property from the cluster configuration", - "/isam/cluster/property/{0}/v2".format(id)) + f"/isam/cluster/property/{id}/v2") return isamAppliance.create_return_object() diff --git a/ibmsecurity/isam/base/cluster/runtime_database.py b/ibmsecurity/isam/base/cluster/runtime_database.py index e59560f8..63a343ad 100644 --- a/ibmsecurity/isam/base/cluster/runtime_database.py +++ b/ibmsecurity/isam/base/cluster/runtime_database.py @@ -14,7 +14,7 @@ def export(isamAppliance, filename, type='db2', check_mode=False, force=False): if force is True or os.path.exists(filename) is False: if check_mode is False: # No point downloading a file if in check_mode - return isamAppliance.invoke_get_file("Export the Runtime database", "{0}/v1?type={1}".format(uri, type), + return isamAppliance.invoke_get_file("Export the Runtime database", f"{uri}/v1?type={type}", filename, requires_model=requires_model) return isamAppliance.create_return_object() diff --git a/ibmsecurity/isam/base/container_ext/repo.py b/ibmsecurity/isam/base/container_ext/repo.py index 59fa04e6..868d0cf2 100644 --- a/ibmsecurity/isam/base/container_ext/repo.py +++ b/ibmsecurity/isam/base/container_ext/repo.py @@ -136,12 +136,8 @@ def update( if check_mode: return isamAppliance.create_return_object(changed=True, warnings=warnings) else: - if tools.version_compare(isamAppliance.facts["version"], "10.0.9.0") < 0: - warnings.append( - "Appliance is at version: {0}. Using the previous format for container repo.".format( - isamAppliance.facts["version"] - ) - ) + if tools.version_compare(isamAppliance.facts['version'], "10.0.9.0") < 0: + warnings.append(f"Appliance is at version: {isamAppliance.facts['version']}. Using the previous format") put_data = { "host": registry, "user": user, diff --git a/ibmsecurity/isam/base/dsc.py b/ibmsecurity/isam/base/dsc.py index 05420290..6dbef8b8 100644 --- a/ibmsecurity/isam/base/dsc.py +++ b/ibmsecurity/isam/base/dsc.py @@ -59,8 +59,8 @@ def _check(isamAppliance, cluster_json): ret_obj = get(isamAppliance) sorted_ret_obj = tools.json_sort(ret_obj['data']) sorted_json_data = tools.json_sort(cluster_json) - logger.debug("Sorted Existing Data:{0}".format(sorted_ret_obj)) - logger.debug("Sorted Desired Data:{0}".format(sorted_json_data)) + logger.debug(f"Sorted Existing Data:{sorted_ret_obj}") + logger.debug(f"Sorted Desired Data:{sorted_json_data}") if sorted_ret_obj != sorted_json_data: logger.info("Existing and input data do not match - updated needed.") diff --git a/ibmsecurity/isam/base/extensions.py b/ibmsecurity/isam/base/extensions.py index 7985f7e1..82ac847e 100644 --- a/ibmsecurity/isam/base/extensions.py +++ b/ibmsecurity/isam/base/extensions.py @@ -22,7 +22,7 @@ def get_all(isamAppliance, check_mode=False, force=False): """ return isamAppliance.invoke_get( "Retrieve installed extensions list", - "{0}/".format(uri), + f"{uri}/", requires_modules=requires_modules, requires_version=requires_version, ) @@ -78,7 +78,7 @@ def add( extId = inspect(isamAppliance, extension) logger.debug(f"We got {extId}") except Exception as e: - warning_str = "Exception occurred: {0}".format(e) + warning_str = f"Exception occurred: {e}" return isamAppliance.create_return_object(warnings=[warning_str]) config_str = _get_config_data(extId, config_data) @@ -102,7 +102,7 @@ def add( else: counter = 0 for file in third_party_package: - third_party = "third_party_package{0}".format(counter) + third_party = f"third_party_package{counter}" files[third_party] = (tools.path_leaf(file), open(file, "rb")) counter = counter + 1 @@ -111,7 +111,7 @@ def add( return isamAppliance.invoke_post_files( "Installing an Extension", - "{0}/activate".format(uri), + f"{uri}/activate", [], files, requires_modules=requires_modules, @@ -177,13 +177,13 @@ def update( else: counter = 0 for file in third_party_package: - third_party = "third_party_package{0}".format(counter) + third_party = f"third_party_package{counter}" files[third_party] = (tools.path_leaf(file), open(file, "rb")) counter = counter + 1 return isamAppliance.invoke_post_files( "Update an Extension", - "{0}/{1}".format(uri, extId), + f"{uri}/{extId}", [], files, requires_modules=requires_modules, @@ -236,7 +236,7 @@ def delete(isamAppliance, extId, check_mode=False, force=False): return isamAppliance.create_return_object(changed=True) else: return isamAppliance.invoke_delete( - "Delete an installed extension", "{0}/{1}".format(uri, extId) + "Delete an installed extension", f"{uri}/{extId}" ) return isamAppliance.create_return_object(changed=False) @@ -254,7 +254,7 @@ def inspect(isamAppliance, extension, check_mode=False, force=False): """ obj = isamAppliance.invoke_post_files( "Inspect extension", - "{0}/inspect".format(uri), + f"{uri}/inspect", [ { "file_formfield": "extension_support_package", diff --git a/ibmsecurity/isam/base/file_downloads.py b/ibmsecurity/isam/base/file_downloads.py index b7cb562d..d5dd949c 100644 --- a/ibmsecurity/isam/base/file_downloads.py +++ b/ibmsecurity/isam/base/file_downloads.py @@ -8,7 +8,7 @@ def get(isamAppliance, file_path='/', recursive=True, check_mode=False, force=Fa Retrieving the contents of a directory from the file downloads area """ return isamAppliance.invoke_get("Retrieving the contents of a directory from the file downloads area", - "/isam/downloads/{0}/?recursive={1}".format(file_path, recursive)) + f"/isam/downloads/{file_path}/?recursive={recursive}") def export_file(isamAppliance, file_path, filename, check_mode=False, force=False): @@ -22,7 +22,7 @@ def export_file(isamAppliance, file_path, filename, check_mode=False, force=Fals # NOTE: this call requires no headers return isamAppliance.invoke_get_file( "Downloading a file from the file downloads area", - "/isam/downloads/{0}?type=File&browser=&".format(file_path), + f"/isam/downloads/{file_path}?type=File&browser=&", filename, True) return isamAppliance.create_return_object() diff --git a/ibmsecurity/isam/base/fips.py b/ibmsecurity/isam/base/fips.py index f051fa84..8f7fca60 100644 --- a/ibmsecurity/isam/base/fips.py +++ b/ibmsecurity/isam/base/fips.py @@ -70,8 +70,7 @@ def restart_and_wait(isamAppliance, wait_time=300, check_freq=5, check_mode=Fals if isamAppliance.facts['model'] != "Appliance": return isamAppliance.create_return_object( - warnings="API invoked requires model: {0}, appliance is of deployment model: {1}.".format( - requires_model, isamAppliance.facts['model'])) + warnings=f"API invoked requires model: {requires_model}, appliance is of deployment model: {isamAppliance.facts['model']}.") warnings = [] if check_mode is True: @@ -101,12 +100,11 @@ def restart_and_wait(isamAppliance, wait_time=300, check_freq=5, check_mode=Fals time.sleep(check_freq) sec += check_freq logger.debug( - "Server is not responding yet. Waited for {0} secs, next check in {1} secs.".format(sec, - check_freq)) + f"Server is not responding yet. Waited for {sec} secs, next check in {check_freq} secs.") if sec >= wait_time: warnings.append( - "The FIPS restart not detected or completed, exiting... after {0} seconds".format(sec)) + f"The FIPS restart not detected or completed, exiting... after {sec} seconds") break return isamAppliance.create_return_object(warnings=warnings) @@ -119,17 +117,17 @@ def _check(isamAppliance, fipsEnabled, tlsv10Enabled, tlsv11Enabled): obj['warnings'] = ret_obj['warnings'] if ret_obj['data']['fipsEnabled'] != fipsEnabled: - logger.info("fipsEnabled change to {0}".format(fipsEnabled)) + logger.info(f"fipsEnabled change to {fipsEnabled}") obj['value'] = False return obj if ret_obj['data']['tlsv10Enabled'] != tlsv10Enabled: - logger.info("TLS v1.0 change to {0}".format(tlsv10Enabled)) + logger.info(f"TLS v1.0 change to {tlsv10Enabled}") obj['value'] = False return obj if ret_obj['data']['tlsv11Enabled'] != tlsv11Enabled: - logger.info("TLS v1.1 change to {0}".format(tlsv11Enabled)) + logger.info(f"TLS v1.1 change to {tlsv11Enabled}") obj['value'] = False return obj diff --git a/ibmsecurity/isam/base/firmware.py b/ibmsecurity/isam/base/firmware.py index 308c7d93..e2304d3f 100644 --- a/ibmsecurity/isam/base/firmware.py +++ b/ibmsecurity/isam/base/firmware.py @@ -56,7 +56,7 @@ def set(isamAppliance, id, comment, check_mode=False, force=False): return isamAppliance.create_return_object(changed=True, warnings=warnings) else: return isamAppliance.invoke_put("Updating a comment for a partition", - "/firmware_settings/{0}".format(id), + f"/firmware_settings/{id}", {'comment': comment}, requires_model=requires_model) return isamAppliance.create_return_object(warnings=warnings) diff --git a/ibmsecurity/isam/base/fixpack.py b/ibmsecurity/isam/base/fixpack.py index 38f86988..43ae6a3a 100644 --- a/ibmsecurity/isam/base/fixpack.py +++ b/ibmsecurity/isam/base/fixpack.py @@ -118,7 +118,7 @@ def _extract_fixpack_name(fixpack): for s in ibmsecurity.utilities.tools.strings(fixpack): match_obj = re.search(r"FIXPACK_NAME=\"(?P\w+)\"", s) if match_obj: - logger.info("Fixpack name extracted from file using strings method: {0}".format(match_obj.group('fp_name'))) + logger.info(f"Fixpack name extracted from file using strings method: {match_obj.group('fp_name')}") return match_obj.group('fp_name') # Unable to extract fixpack name from binary @@ -129,7 +129,7 @@ def _extract_fixpack_name(fixpack): else: fixpack_name, ext_name = file_name.split('.') logger.info( - "Fixpack name could not be extracted from binary, use name derived from the filename: {0}".format(fixpack_name)) + f"Fixpack name could not be extracted from binary, use name derived from the filename: {fixpack_name}") return fixpack_name diff --git a/ibmsecurity/isam/base/geolocation_db.py b/ibmsecurity/isam/base/geolocation_db.py index 9da3fe55..958298d5 100644 --- a/ibmsecurity/isam/base/geolocation_db.py +++ b/ibmsecurity/isam/base/geolocation_db.py @@ -11,7 +11,7 @@ def get(isamAppliance, check_mode=False, force=False): """ Get the status of the geolocation database load """ - return isamAppliance.invoke_get("Get the status of the geolocation database load", "{}/status".format(uri), + return isamAppliance.invoke_get("Get the status of the geolocation database load", f"{uri}/status", requires_modules=requires_modules, requires_version=requires_version) @@ -24,7 +24,7 @@ def cancel(isamAppliance, check_mode=False, force=False): if check_mode is True: return isamAppliance.create_return_object(changed=True) else: - return isamAppliance.invoke_get("Cancel the most recent geolocation database load", "{}/cancel".format(uri), + return isamAppliance.invoke_get("Cancel the most recent geolocation database load", f"{uri}/cancel", requires_modules=requires_modules, requires_version=requires_version) return isamAppliance.create_return_object() diff --git a/ibmsecurity/isam/base/host/name.py b/ibmsecurity/isam/base/host/name.py index ee612134..706ddae4 100644 --- a/ibmsecurity/isam/base/host/name.py +++ b/ibmsecurity/isam/base/host/name.py @@ -16,7 +16,7 @@ def add(isamAppliance, host_address, hostname, check_mode=False, force=False): else: return isamAppliance.invoke_post( "Adding a host name to a host IP address", - "{0}/{1}/hostnames".format(uri, host_address), + f"{uri}/{host_address}/hostnames", {"name": hostname}, requires_modules=requires_modules, requires_version=requires_version, @@ -35,7 +35,7 @@ def delete(isamAppliance, host_address, hostname, check_mode=False, force=False) else: return isamAppliance.invoke_delete( "Removing a host name from a host IP address", - "{0}/{1}/hostnames/{2}".format(uri, host_address, hostname), + f"{uri}/{host_address}/hostnames/{hostname}", requires_modules=requires_modules, requires_version=requires_version, ) @@ -57,7 +57,7 @@ def _check(isamAppliance, host_address, hostname): from ibmsecurity.appliance.ibmappliance import IBMError raise IBMError( - "999", "Unable to find host record with adress: {0}".format(host_address) + "999", f"Unable to find host record with adress: {host_address}" ) for hosts in ret_obj["data"]: diff --git a/ibmsecurity/isam/base/host/records.py b/ibmsecurity/isam/base/host/records.py index 1fde6bf5..260b542c 100644 --- a/ibmsecurity/isam/base/host/records.py +++ b/ibmsecurity/isam/base/host/records.py @@ -25,7 +25,7 @@ def get(isamAppliance, host_address, check_mode=False, force=False): """ return isamAppliance.invoke_get( "Retrieving the list of host names associated with a host IP address", - "{0}/{1}/hostnames".format(uri, host_address), + f"{uri}/{host_address}/hostnames", requires_modules=requires_modules, requires_version=requires_version, ) @@ -100,7 +100,7 @@ def delete(isamAppliance, host_address, check_mode=False, force=False): else: return isamAppliance.invoke_delete( "Removing a host record (IP address and associated host names)", - "{0}/{1}".format(uri, host_address), + f"{uri}/{host_address}", requires_modules=requires_modules, requires_version=requires_version, ) diff --git a/ibmsecurity/isam/base/license.py b/ibmsecurity/isam/base/license.py index 3ea8a26e..fa014af8 100644 --- a/ibmsecurity/isam/base/license.py +++ b/ibmsecurity/isam/base/license.py @@ -43,7 +43,7 @@ def get_all(isamAppliance, check_mode=False, force=False): Retrieve all licenses installed in the appliance """ return isamAppliance.invoke_get("Retrieve all licenses installed in the appliance", - "{0}".format(uri), requires_modules=requires_modules, + f"{uri}", requires_modules=requires_modules, requires_version=requires_version) diff --git a/ibmsecurity/isam/base/lmi.py b/ibmsecurity/isam/base/lmi.py index 7e317d97..d24dc690 100644 --- a/ibmsecurity/isam/base/lmi.py +++ b/ibmsecurity/isam/base/lmi.py @@ -59,10 +59,10 @@ def await_startup(isamAppliance, wait_time=300, check_freq=5, start_time=None, c time.sleep(check_freq) sec += check_freq logger.debug( - "Server is not responding yet. Waited for {0} secs, next check in {1} secs.".format(sec, check_freq)) + f"Server is not responding yet. Waited for {sec} secs, next check in {check_freq} secs.") if sec >= wait_time: - warnings.append("The LMI restart not detected or completed, exiting... after {0} seconds".format(sec)) + warnings.append(f"The LMI restart not detected or completed, exiting... after {sec} seconds") break return isamAppliance.create_return_object(warnings=warnings) diff --git a/ibmsecurity/isam/base/management_authentication.py b/ibmsecurity/isam/base/management_authentication.py index ab8c5067..1cdeb296 100644 --- a/ibmsecurity/isam/base/management_authentication.py +++ b/ibmsecurity/isam/base/management_authentication.py @@ -61,15 +61,14 @@ def set(isamAppliance, } for k, v in kwargs.items(): if k == 'ldap_debug' and v == '': - if ibmsecurity.utilities.tools.version_compare(isamAppliance.facts["version"], "9.0.4.0") < 0: + if ibmsecurity.utilities.tools.version_compare(isamAppliance.facts['version'], "9.0.4.0") < 0: warnings.append( - "Appliance at version: {0}, ldap_debug: {1} is not supported. Needs 9.0.4.0 or higher. Ignoring ldap_debug for this call.".format( - isamAppliance.facts["version"], ldap_debug)) + f"Appliance at version: {isamAppliance.facts['version']}, ldap_debug: {ldap_debug} is not supported. Needs 9.0.4.0 or higher. Ignoring ldap_debug for this call.") continue if k == 'enable_usermapping': # only valid if type == remote if type == 'remote': - if ibmsecurity.utilities.tools.version_compare(isamAppliance.facts["version"], "10.0.2.0") < 0: + if ibmsecurity.utilities.tools.version_compare(isamAppliance.facts['version'], "10.0.2.0") < 0: warnings.append( f"Appliance at version: {isamAppliance.facts['version']}, {k}: {v} is not supported. Needs 10.0.2.0 or higher. Ignoring {k} for this call.") continue diff --git a/ibmsecurity/isam/base/management_authorization/feature.py b/ibmsecurity/isam/base/management_authorization/feature.py index d34fe33b..8616fa3a 100644 --- a/ibmsecurity/isam/base/management_authorization/feature.py +++ b/ibmsecurity/isam/base/management_authorization/feature.py @@ -17,7 +17,7 @@ def get_user(isamAppliance, user): NOTE: Getting an unexplained error for this function, URL maybe wrong """ return isamAppliance.invoke_get("Get permitted features for user", - "/authorization/features/users/{0}/v1".format(user)) + f"/authorization/features/users/{user}/v1") def get_current(isamAppliance): diff --git a/ibmsecurity/isam/base/management_authorization/role.py b/ibmsecurity/isam/base/management_authorization/role.py index 6fb7e445..429c8215 100644 --- a/ibmsecurity/isam/base/management_authorization/role.py +++ b/ibmsecurity/isam/base/management_authorization/role.py @@ -18,7 +18,7 @@ def get(isamAppliance, name, check_mode=False, force=False): Get management authorization role """ return isamAppliance.invoke_get("Get management authorization role", - "/authorization/roles/{0}/v1".format(name)) + f"/authorization/roles/{name}/v1") def _check(isamAppliance, name): @@ -107,7 +107,7 @@ def delete(isamAppliance, name, check_mode=False, force=False): else: return isamAppliance.invoke_delete( "Delete management authorization role", - "/authorization/roles/{0}/v1".format(name)) + f"/authorization/roles/{name}/v1") return isamAppliance.create_return_object() diff --git a/ibmsecurity/isam/base/management_authorization/role_feature.py b/ibmsecurity/isam/base/management_authorization/role_feature.py index e0ebe3f9..83818e9d 100644 --- a/ibmsecurity/isam/base/management_authorization/role_feature.py +++ b/ibmsecurity/isam/base/management_authorization/role_feature.py @@ -31,7 +31,7 @@ def set(isamAppliance, name, feature_name, access=None, check_mode=False, force= else: return isamAppliance.invoke_put( "Add group to management authorization role", - "/authorization/roles/{0}/v1".format(name), ret_obj['data']) + f"/authorization/roles/{name}/v1", ret_obj['data']) def delete(isamAppliance, name, feature_name, check_mode=False, force=False): @@ -56,4 +56,4 @@ def delete(isamAppliance, name, feature_name, check_mode=False, force=False): else: return isamAppliance.invoke_put( "Delete feature from management authorization role", - "/authorization/roles/{0}/v1".format(name), ret_obj['data']) + f"/authorization/roles/{name}/v1", ret_obj['data']) diff --git a/ibmsecurity/isam/base/management_authorization/role_group.py b/ibmsecurity/isam/base/management_authorization/role_group.py index 80382fcf..6d450970 100644 --- a/ibmsecurity/isam/base/management_authorization/role_group.py +++ b/ibmsecurity/isam/base/management_authorization/role_group.py @@ -9,7 +9,7 @@ def get(isamAppliance, name, check_mode=False, force=False): Retrieving the list of groups for an authorization roles """ return isamAppliance.invoke_get("Retrieving the list of groups for an authorization roles", - "/authorization/roles/{0}/groups/v1".format(name)) + f"/authorization/roles/{name}/groups/v1") def set(isamAppliance, name, group_name, type='embedded_ldap', check_mode=False, force=False): @@ -40,7 +40,7 @@ def set(isamAppliance, name, group_name, type='embedded_ldap', check_mode=False, else: return isamAppliance.invoke_put( "Add group to management authorization role", - "/authorization/roles/{0}/v1".format(name), ret_obj['data']) + f"/authorization/roles/{name}/v1", ret_obj['data']) def delete(isamAppliance, name, group_name, check_mode=False, force=False): @@ -65,4 +65,4 @@ def delete(isamAppliance, name, group_name, check_mode=False, force=False): else: return isamAppliance.invoke_put( "Delete group from management authorization role", - "/authorization/roles/{0}/v1".format(name), ret_obj['data']) + f"/authorization/roles/{name}/v1", ret_obj['data']) diff --git a/ibmsecurity/isam/base/management_authorization/role_user.py b/ibmsecurity/isam/base/management_authorization/role_user.py index d72825b3..4c8f1df3 100644 --- a/ibmsecurity/isam/base/management_authorization/role_user.py +++ b/ibmsecurity/isam/base/management_authorization/role_user.py @@ -9,7 +9,7 @@ def get(isamAppliance, name, check_mode=False, force=False): Retrieving the list of users for an authorization roles """ return isamAppliance.invoke_get("Retrieving the list of users for an authorization roles", - "/authorization/roles/{0}/users/v1".format(name)) + f"/authorization/roles/{name}/users/v1") def set(isamAppliance, name, user_name, type='embedded_ldap', check_mode=False, force=False): @@ -40,7 +40,7 @@ def set(isamAppliance, name, user_name, type='embedded_ldap', check_mode=False, else: return isamAppliance.invoke_put( "Add user to management authorization role", - "/authorization/roles/{0}/v1".format(name), ret_obj['data']) + f"/authorization/roles/{name}/v1", ret_obj['data']) def delete(isamAppliance, name, user_name, check_mode=False, force=False): @@ -65,4 +65,4 @@ def delete(isamAppliance, name, user_name, check_mode=False, force=False): else: return isamAppliance.invoke_put( "Delete user from management authorization role", - "/authorization/roles/{0}/v1".format(name), ret_obj['data']) + f"/authorization/roles/{name}/v1", ret_obj['data']) diff --git a/ibmsecurity/isam/base/network/active_status.py b/ibmsecurity/isam/base/network/active_status.py index a1a2c604..093c5ac5 100644 --- a/ibmsecurity/isam/base/network/active_status.py +++ b/ibmsecurity/isam/base/network/active_status.py @@ -9,7 +9,7 @@ def get_routes(isamAppliance, check_mode=False, force=False): """ Retrieving the current active system routes """ - return isamAppliance.invoke_get("Retrieving the current active system routes", "{}/routes".format(uri), + return isamAppliance.invoke_get("Retrieving the current active system routes", f"{uri}/routes", requires_model=requires_model) @@ -17,5 +17,5 @@ def get_addresses(isamAppliance, check_mode=False, force=False): """ Retrieving the currently assigned addresses """ - return isamAppliance.invoke_get("Retrieving the currently assigned addresses", "{}/ifaces".format(uri), + return isamAppliance.invoke_get("Retrieving the currently assigned addresses", f"{uri}/ifaces", requires_model=requires_model) diff --git a/ibmsecurity/isam/base/network/felb/advanced_tuning/at_logging.py b/ibmsecurity/isam/base/network/felb/advanced_tuning/at_logging.py index c7aad885..a121c8f3 100644 --- a/ibmsecurity/isam/base/network/felb/advanced_tuning/at_logging.py +++ b/ibmsecurity/isam/base/network/felb/advanced_tuning/at_logging.py @@ -61,8 +61,8 @@ def _check(isamAppliance, json_data): sorted_ret_obj = tools.json_sort(ret_obj['data']) sorted_json_data = tools.json_sort(json_data) - logger.debug("Sorted Existing Data:{0}".format(sorted_ret_obj)) - logger.debug("Sorted Desired Data:{0}".format(sorted_json_data)) + logger.debug(f"Sorted Existing Data:{sorted_ret_obj}") + logger.debug(f"Sorted Desired Data:{sorted_json_data}") if sorted_ret_obj != sorted_json_data: change_required = True diff --git a/ibmsecurity/isam/base/network/felb/advanced_tuning/config.py b/ibmsecurity/isam/base/network/felb/advanced_tuning/config.py index 57751b54..fec93e35 100644 --- a/ibmsecurity/isam/base/network/felb/advanced_tuning/config.py +++ b/ibmsecurity/isam/base/network/felb/advanced_tuning/config.py @@ -55,7 +55,7 @@ def delete(isamAppliance, name, check_mode=False, force=False): if check_mode is True: return isamAppliance.create_return_object(changed=True, warnings=warnings) else: - return isamAppliance.invoke_delete("Deleting an attribute", "{0}/{1}".format(module_uri, name), + return isamAppliance.invoke_delete("Deleting an attribute", f"{module_uri}/{name}", requires_modules=requires_modules, requires_version=requires_version, requires_model=requires_model) else: @@ -66,7 +66,7 @@ def get(isamAppliance, attribute_name): """ Retrieving an attribute """ - return isamAppliance.invoke_get("Retrieving an attribute", "{0}/{1}".format(module_uri, attribute_name), + return isamAppliance.invoke_get("Retrieving an attribute", f"{module_uri}/{attribute_name}", requires_modules=requires_modules, requires_version=requires_version, requires_model=requires_model) @@ -76,7 +76,7 @@ def get_all(isamAppliance): Retrieving attribute names """ - return isamAppliance.invoke_get("Retrieving attribute names", "{0}/".format(module_uri), + return isamAppliance.invoke_get("Retrieving attribute names", f"{module_uri}/", requires_modules=requires_modules, requires_version=requires_version, requires_model=requires_model) @@ -92,7 +92,7 @@ def update(isamAppliance, attribute_name, value, check_mode=False, force=False): if check_mode is True: return isamAppliance.create_return_object(changed=True, warnings=warnings) else: - return isamAppliance.invoke_put("Updating an attribute", "{0}/{1}".format(module_uri, attribute_name), + return isamAppliance.invoke_put("Updating an attribute", f"{module_uri}/{attribute_name}", { "value": value }, requires_version=requires_version, requires_modules=requires_modules, diff --git a/ibmsecurity/isam/base/network/felb/attributes/advanced_tuning.py b/ibmsecurity/isam/base/network/felb/attributes/advanced_tuning.py index 069d63bd..c2cafac9 100644 --- a/ibmsecurity/isam/base/network/felb/attributes/advanced_tuning.py +++ b/ibmsecurity/isam/base/network/felb/attributes/advanced_tuning.py @@ -40,7 +40,7 @@ def delete(isamAppliance, attribute_name, check_mode=False, force=False): if check_mode is True: return isamAppliance.create_return_object(changed=True, warnings=warnings) else: - return isamAppliance.invoke_delete("Deleting an attribute", "{0}/{1}".format(module_uri, attribute_name), + return isamAppliance.invoke_delete("Deleting an attribute", f"{module_uri}/{attribute_name}", requires_modules=requires_modules, requires_version=requires_version, requires_model=requires_model) @@ -51,7 +51,7 @@ def get(isamAppliance, attribute_name): """ Retrieving an attribute """ - return isamAppliance.invoke_get("Retrieving an attribute", "{0}/{1}".format(module_uri, attribute_name), + return isamAppliance.invoke_get("Retrieving an attribute", f"{module_uri}/{attribute_name}", requires_modules=requires_modules, requires_version=requires_version, requires_model=requires_model) @@ -60,7 +60,7 @@ def get_all(isamAppliance): """ Retrieving attribute names """ - return isamAppliance.invoke_get("Retrieving attribute names", "{0}/".format(module_uri), + return isamAppliance.invoke_get("Retrieving attribute names", f"{module_uri}/", requires_modules=requires_modules, requires_version=requires_version, requires_model=requires_model) @@ -75,7 +75,7 @@ def update(isamAppliance, attribute_name, value, check_mode=False, force=False): if check_mode is True: return isamAppliance.create_return_object(changed=True, warnings=warnings) else: - return isamAppliance.invoke_put("Updating an attribute", "{0}/{1}".format(module_uri, attribute_name), + return isamAppliance.invoke_put("Updating an attribute", f"{module_uri}/{attribute_name}", { "value": value }, requires_version=requires_version, requires_modules=requires_modules, diff --git a/ibmsecurity/isam/base/network/felb/attributes/log.py b/ibmsecurity/isam/base/network/felb/attributes/log.py index 14b0aecb..1b6656fc 100644 --- a/ibmsecurity/isam/base/network/felb/attributes/log.py +++ b/ibmsecurity/isam/base/network/felb/attributes/log.py @@ -57,8 +57,8 @@ def _check(isamAppliance, json_data): sorted_ret_obj = tools.json_sort(ret_obj['data']) sorted_json_data = tools.json_sort(json_data) - logger.debug("Sorted Existing Data:{0}".format(sorted_ret_obj)) - logger.debug("Sorted Desired Data:{0}".format(sorted_json_data)) + logger.debug(f"Sorted Existing Data:{sorted_ret_obj}") + logger.debug(f"Sorted Desired Data:{sorted_json_data}") if sorted_ret_obj != sorted_json_data: change_required = True diff --git a/ibmsecurity/isam/base/network/felb/config.py b/ibmsecurity/isam/base/network/felb/config.py index 62b51627..e8a53560 100644 --- a/ibmsecurity/isam/base/network/felb/config.py +++ b/ibmsecurity/isam/base/network/felb/config.py @@ -21,7 +21,7 @@ def get_config(isamAppliance, check_mode=False, force=False): """ Retrieving FELB configuration """ - return isamAppliance.invoke_get("Retrieving FELB configuration", "{0}/configuration".format(module_uri), + return isamAppliance.invoke_get("Retrieving FELB configuration", f"{module_uri}/configuration", requires_modules=requires_modules, requires_version=requires_version, requires_model=requires_model) @@ -60,9 +60,9 @@ def _check(isamAppliance, enabled, debug, ha, logging, ssl, services, attributes "attributes": attributes } sorted_json_data = ibmsecurity.utilities.tools.json_sort(json_data) - logger.debug("Sorted input: {0}".format(sorted_json_data)) + logger.debug(f"Sorted input: {sorted_json_data}") sorted_ret_obj = ibmsecurity.utilities.tools.json_sort(ret_obj['data']) - logger.debug("Sorted existing data: {0}".format(sorted_ret_obj)) + logger.debug(f"Sorted existing data: {sorted_ret_obj}") if sorted_ret_obj != sorted_json_data: logger.info("Changes detected, update needed.") update_required = True @@ -77,7 +77,7 @@ def export_file(isamAppliance, filename, check_mode=False, force=False): import os.path if force is True or os.path.exists(filename) is False: if check_mode is False: # No point downloading a file if in check_mode - return isamAppliance.invoke_get_file("Exporting FELB configuration", "{}?export=true".format(module_uri), + return isamAppliance.invoke_get_file("Exporting FELB configuration", f"{module_uri}?export=true", filename=filename, requires_modules=requires_modules, requires_version=requires_version, requires_model=requires_model) diff --git a/ibmsecurity/isam/base/network/felb/error_page.py b/ibmsecurity/isam/base/network/felb/error_page.py index 9a316bb5..337ad828 100644 --- a/ibmsecurity/isam/base/network/felb/error_page.py +++ b/ibmsecurity/isam/base/network/felb/error_page.py @@ -13,7 +13,7 @@ def get(isamAppliance, error_page, check_mode=False, force=False): """ Retrieving an error page """ - return isamAppliance.invoke_get("Retrieving an error page", "{0}{1}".format(module_uri, error_page), + return isamAppliance.invoke_get("Retrieving an error page", f"{module_uri}{error_page}", requires_modules=requires_modules, requires_version=requires_version, requires_model=requires_model) @@ -44,7 +44,7 @@ def set(isamAppliance, error_page, contents, check_mode=False, force=False): if check_mode is True: return isamAppliance.create_return_object(changed=True, warnings=warnings) else: - return isamAppliance.invoke_put("Updating an error page", "{0}{1}".format(module_uri, error_page), + return isamAppliance.invoke_put("Updating an error page", f"{module_uri}{error_page}", { "contents": contents }, requires_version=requires_version, requires_modules=requires_modules, @@ -65,7 +65,7 @@ def import_file(isamAppliance, error_page, filename, check_mode=False, force=Fal return isamAppliance.create_return_object(changed=True, warnings=warnings) else: return isamAppliance.invoke_post_files(description="Uploading an error page", - uri="{0}{1}".format(module_uri, error_page), + uri=f"{module_uri}{error_page}", fileinfo=[{ 'file_formfield': 'file', 'filename': filename, @@ -88,7 +88,7 @@ def export_file(isamAppliance, error_page, filename, check_mode=False, force=Fal if check_mode is False: # No point downloading a file if in check_mode return isamAppliance.invoke_get_file( "Downloading an error page", - "{0}{1}?export=true".format(module_uri, error_page), + f"{module_uri}{error_page}?export=true", filename=filename, requires_model=requires_model ) diff --git a/ibmsecurity/isam/base/network/felb/ha.py b/ibmsecurity/isam/base/network/felb/ha.py index f728e2a3..0f793b69 100644 --- a/ibmsecurity/isam/base/network/felb/ha.py +++ b/ibmsecurity/isam/base/network/felb/ha.py @@ -136,8 +136,8 @@ def _check_update(isamAppliance, json_data): sorted_ret_obj = tools.json_sort(ret_obj['data']) sorted_json_data = tools.json_sort(json_data) - logger.debug("Sorted Existing Data:{0}".format(sorted_ret_obj)) - logger.debug("Sorted Desired Data:{0}".format(sorted_json_data)) + logger.debug(f"Sorted Existing Data:{sorted_ret_obj}") + logger.debug(f"Sorted Desired Data:{sorted_json_data}") if sorted_ret_obj != sorted_json_data: return True, warnings else: diff --git a/ibmsecurity/isam/base/network/felb/services/advanced_tuning.py b/ibmsecurity/isam/base/network/felb/services/advanced_tuning.py index 0e3e97ae..5acedbdf 100644 --- a/ibmsecurity/isam/base/network/felb/services/advanced_tuning.py +++ b/ibmsecurity/isam/base/network/felb/services/advanced_tuning.py @@ -20,7 +20,7 @@ def add(isamAppliance, service_name, name, value, check_mode=False, force=False) return isamAppliance.create_return_object(changed=True, warnings=warnings) else: return isamAppliance.invoke_post("Creating a service attribute", - "{0}{1}/attributes".format(module_uri, service_name), + f"{module_uri}{service_name}/attributes", { "name": name, "value": value @@ -41,8 +41,7 @@ def delete(isamAppliance, service_name, attribute_name, check_mode=False, force= return isamAppliance.create_return_object(changed=True, warnings=warnings) else: return isamAppliance.invoke_delete("Deleting a service attribute", - "{0}{1}/attributes/{2}".format(module_uri, service_name, - attribute_name), + f"{module_uri}{service_name}/attributes/{attribute_name}", requires_version=requires_versions, requires_modules=requires_modules, requires_model=requires_model) else: @@ -55,7 +54,7 @@ def get(isamAppliance, service_name, attribute_name): """ return isamAppliance.invoke_get("Retrieving a service attribute", - "{0}{1}/attributes/{2}".format(module_uri, service_name, attribute_name), + f"{module_uri}{service_name}/attributes/{attribute_name}", requires_version=requires_versions, requires_modules=requires_modules, requires_model=requires_model) @@ -66,7 +65,7 @@ def get_all(isamAppliance, service_name): Retrieving service attribute names """ return isamAppliance.invoke_get("Retrieving service attribute names", - "{0}{1}/attributes?includeAllValues=true".format(module_uri, service_name), + f"{module_uri}{service_name}/attributes?includeAllValues=true", requires_version=requires_versions, requires_modules=requires_modules, requires_model=requires_model) @@ -84,7 +83,7 @@ def update(isamAppliance, service_name, attribute_name, attribute_value, check_m return isamAppliance.create_return_object(changed=True, warnings=warnings) else: return isamAppliance.invoke_put("Updating a service attribute", - "{0}{1}/attributes/{2}".format(module_uri, service_name, attribute_name), + f"{module_uri}{service_name}/attributes/{attribute_name}", { "value": attribute_value }, diff --git a/ibmsecurity/isam/base/network/felb/services/config.py b/ibmsecurity/isam/base/network/felb/services/config.py index 9d519b69..1821ac06 100644 --- a/ibmsecurity/isam/base/network/felb/services/config.py +++ b/ibmsecurity/isam/base/network/felb/services/config.py @@ -52,7 +52,7 @@ def delete(isamAppliance, service_name, check_mode=False, force=False): if check_mode is True: return isamAppliance.create_return_object(changed=True, warnings=warnings) else: - return isamAppliance.invoke_delete("Deleting a service", "{0}/{1}".format(module_uri, service_name), + return isamAppliance.invoke_delete("Deleting a service", f"{module_uri}/{service_name}", requires_version=requires_version, requires_modules=requires_modules, requires_model=requires_model) else: return isamAppliance.create_return_object(warnings=warnings) @@ -63,7 +63,7 @@ def get(isamAppliance, service_name, check_mode=False, force=False): Receives a single service """ return isamAppliance.invoke_get( - "Retrieving a service", "{0}/{1}".format(module_uri, service_name), requires_version=requires_version, + "Retrieving a service", f"{module_uri}/{service_name}", requires_version=requires_version, requires_modules=requires_modules, requires_model=requires_model) @@ -87,7 +87,7 @@ def update(isamAppliance, service_name, enabled, name, address, port, netmask, i if check_mode is True: return isamAppliance.create_return_object(changed=True, warnings=warnings) else: - return isamAppliance.invoke_put("Updating a service", "{0}/{1}".format(module_uri, service_name), + return isamAppliance.invoke_put("Updating a service", f"{module_uri}/{service_name}", { "address": address, "enabled": enabled, diff --git a/ibmsecurity/isam/base/network/felb/services/layer.py b/ibmsecurity/isam/base/network/felb/services/layer.py index 1f924904..7ea75236 100644 --- a/ibmsecurity/isam/base/network/felb/services/layer.py +++ b/ibmsecurity/isam/base/network/felb/services/layer.py @@ -15,7 +15,7 @@ def get(isamAppliance, service_name, check_mode=False, force=False): """ Retrieving Layer Configuration """ - return isamAppliance.invoke_get("Retrieving Layer Configuration", "{0}/{1}/layer".format(module_uri, service_name), + return isamAppliance.invoke_get("Retrieving Layer Configuration", f"{module_uri}/{service_name}/layer", requires_version=requires_version, requires_modules=requires_modules, requires_model=requires_model) @@ -38,7 +38,7 @@ def update(isamAppliance, service_name, type, layer7_secure, layer7_ssl_label, l if check_mode is True: return isamAppliance.create_return_object(changed=True, warnings=warnings) else: - return isamAppliance.invoke_put("Updating Service Layer", "{0}/{1}/layer".format(module_uri, service_name), + return isamAppliance.invoke_put("Updating Service Layer", f"{module_uri}/{service_name}/layer", json_data, requires_version=requires_version, requires_modules=requires_modules, requires_model=requires_model) else: @@ -58,8 +58,8 @@ def _check(isamAppliance, service_name, json_data): sorted_ret_obj = tools.json_sort(ret_obj['data']) sorted_json_data = tools.json_sort(json_data) - logger.debug("Sorted Existing Data:{0}".format(sorted_ret_obj)) - logger.debug("Sorted Desired Data:{0}".format(sorted_json_data)) + logger.debug(f"Sorted Existing Data:{sorted_ret_obj}") + logger.debug(f"Sorted Desired Data:{sorted_json_data}") if sorted_ret_obj != sorted_json_data: return True, warnings diff --git a/ibmsecurity/isam/base/network/felb/services/servers.py b/ibmsecurity/isam/base/network/felb/services/servers.py index 0b220352..2ce9bff1 100644 --- a/ibmsecurity/isam/base/network/felb/services/servers.py +++ b/ibmsecurity/isam/base/network/felb/services/servers.py @@ -23,7 +23,7 @@ def add(isamAppliance, service_name, address, active, port, weight, secure, ssll else: return isamAppliance.invoke_post("Creating a server", - "{0}/{1}/servers".format(module_uri, service_name), + f"{module_uri}/{service_name}/servers", { "active": active, "address": address, @@ -50,7 +50,7 @@ def delete(isamAppliance, service_name, address, port, check_mode=False, force=F else: id = address + ":" + str(port) return isamAppliance.invoke_delete("Deleting a server", - "{0}/{1}/servers/{2}".format(module_uri, service_name, id), + f"{module_uri}/{service_name}/servers/{id}", requires_version=requires_version, requires_modules=requires_modules, requires_model=requires_model) else: @@ -63,7 +63,7 @@ def get(isamAppliance, service_name, address, port, check_mode=False, force=Fals """ id = address + ":" + str(port) - return (isamAppliance.invoke_get("Retrieving a server", "{0}/{1}/servers/{2}".format(module_uri, service_name, id), + return (isamAppliance.invoke_get("Retrieving a server", f"{module_uri}/{service_name}/servers/{id}", requires_version=requires_version, requires_modules=requires_modules, requires_model=requires_model)) @@ -72,7 +72,7 @@ def get_all(isamAppliance, service_name, check_mode=False, force=False): Retrieves a list of servers under a specified service """ return isamAppliance.invoke_get("Retrieving servers for a service", - "{0}/{1}/servers".format(module_uri, service_name), + f"{module_uri}/{service_name}/servers", requires_version=requires_version, requires_modules=requires_modules, requires_model=requires_model) @@ -99,7 +99,7 @@ def update(isamAppliance, service_name, address, active, port, weight, secure=Fa else: return isamAppliance.invoke_put("Updating a server", - "{0}/{1}/servers/{2}".format(module_uri, service_name, id), + f"{module_uri}/{service_name}/servers/{id}", json_data, requires_modules=requires_modules, requires_version=requires_version, @@ -125,8 +125,8 @@ def _check_update(isamAppliance, service_name, address, port, json_data): sorted_ret_data = tools.json_sort(ret_data) sorted_json_data = tools.json_sort(json_data) - logger.debug("Sorted Existing Data:{0}".format(sorted_ret_data)) - logger.debug("Sorted Desired Data:{0}".format(sorted_json_data)) + logger.debug(f"Sorted Existing Data:{sorted_ret_data}") + logger.debug(f"Sorted Desired Data:{sorted_json_data}") if sorted_ret_data != sorted_json_data: return True, warnings diff --git a/ibmsecurity/isam/base/network/host_records.py b/ibmsecurity/isam/base/network/host_records.py index 0f8652ed..d905fed9 100644 --- a/ibmsecurity/isam/base/network/host_records.py +++ b/ibmsecurity/isam/base/network/host_records.py @@ -24,8 +24,8 @@ def get(isamAppliance, addr, check_mode=False, force=False): """ Retrieving the list of host names associated with a host IP address """ - return isamAppliance.invoke_get("Retrieving the list of host names associated with a host IP address {0}".format(addr), - "/isam/host_records/{0}/hostnames".format(addr), requires_model=requires_model) + return isamAppliance.invoke_get(f"Retrieving the list of host names associated with a host IP address {addr}", + f"/isam/host_records/{addr}/hostnames", requires_model=requires_model) def set(isamAppliance, addr, hostnames, check_mode=False, force=False): @@ -141,7 +141,7 @@ def update(isamAppliance, addr, name, check_mode=False, force=False): else: return isamAppliance.invoke_post( "Adding a host name to a host IP address", - "/isam/host_records/{0}/hostnames".format(addr), + f"/isam/host_records/{addr}/hostnames", {'name': hostnames_remaining[0]}, requires_model=requires_model ) @@ -176,14 +176,14 @@ def delete(isamAppliance, addr, name=None, check_mode=False, force=False): # Delete specific entry return isamAppliance.invoke_delete( "Removing a host name from a host IP address", - "/isam/host_records/{0}/hostnames/{1}".format(addr, name), + f"/isam/host_records/{addr}/hostnames/{name}", requires_model=requires_model ) elif exists is False and name is None: # Delete all entries for address if no name given return isamAppliance.invoke_delete( "Removing a host record (IP address and associated host names)", - "/isam/host_records/{0}".format(addr), + f"/isam/host_records/{addr}", requires_model=requires_model ) diff --git a/ibmsecurity/isam/base/network/interfaces.py b/ibmsecurity/isam/base/network/interfaces.py index fee4c12c..6c909471 100644 --- a/ibmsecurity/isam/base/network/interfaces.py +++ b/ibmsecurity/isam/base/network/interfaces.py @@ -142,7 +142,7 @@ def search(isamAppliance, label=None, vlanId=None, address=None, check_mode=Fals def _update_interface(isamAppliance, json_data): - return isamAppliance.invoke_put("Updating a (VLAN) interface", "/net/ifaces/{0}".format(json_data['uuid']), + return isamAppliance.invoke_put("Updating a (VLAN) interface", f"/net/ifaces/{json_data['uuid']}", json_data, requires_model=requires_model) diff --git a/ibmsecurity/isam/base/network/interfaces_ipv4.py b/ibmsecurity/isam/base/network/interfaces_ipv4.py index 906ce520..530ac427 100644 --- a/ibmsecurity/isam/base/network/interfaces_ipv4.py +++ b/ibmsecurity/isam/base/network/interfaces_ipv4.py @@ -22,7 +22,7 @@ def add(isamAppliance, label, address, maskOrPrefix, overrideSubnetChecking=Fals if addr['address'] == address: add_needed = False else: - warnings.append("Interface {0} not found, Add is not supported.".format(label)) + warnings.append(f"Interface {label} not found, Add is not supported.") return isamAppliance.create_return_object(changed=False, warnings=warnings) if add_needed is True: @@ -64,7 +64,7 @@ def delete(isamAppliance, label, address, vlanId=None, overrideSubnetChecking=Fa ret_obj['ipv4']['overrideSubnetChecking'] = overrideSubnetChecking break else: - warnings.append("Interface {0} not found, Delete is not supported.".format(label)) + warnings.append(f"Interface {label} not found, Delete is not supported.") return isamAppliance.create_return_object(changed=False, warnings=warnings) if force is True or delete_needed is True: @@ -105,7 +105,7 @@ def update(isamAppliance, label, address, new_address, maskOrPrefix, vlanId=None ret_obj['ipv4']['overrideSubnetChecking'] = overrideSubnetChecking break else: - warnings.append("Interface {0} not found, Update is not supported.".format(label)) + warnings.append(f"Interface {label} not found, Update is not supported.") return isamAppliance.create_return_object(changed=False, warnings=warnings) if force is True or update_needed is True: @@ -141,7 +141,7 @@ def set_dhcp(isamAppliance, label, vlanId=None, enabled=False, allowManagement=F if (update_needed is True): ret_obj['ipv4']['dhcp'] = upd_dhcp else: - warnings.append("Interface {0} not found, Set dhcp is not supported.".format(label)) + warnings.append(f"Interface {label} not found, Set dhcp is not supported.") return isamAppliance.create_return_object(changed=False, warnings=warnings) if force is True or update_needed is True: diff --git a/ibmsecurity/isam/base/network/interfaces_ipv6.py b/ibmsecurity/isam/base/network/interfaces_ipv6.py index b1297997..cc91acc8 100644 --- a/ibmsecurity/isam/base/network/interfaces_ipv6.py +++ b/ibmsecurity/isam/base/network/interfaces_ipv6.py @@ -24,7 +24,7 @@ def add(isamAppliance, label, address, prefixLength, vlanId=None, allowManagemen add_needed = False break else: - warnings.append("Interface {0} not found, Add is not supported.".format(label)) + warnings.append(f"Interface {label} not found, Add is not supported.") return isamAppliance.create_return_object(changed=False, warnings=warnings) # Cannot add an address and keep dhcp enabled @@ -68,7 +68,7 @@ def delete(isamAppliance, label, address, vlanId=None, check_mode=False, force=F ret_obj['ipv6']['addresses'].remove(addr) break else: - warnings.append("Interface {0} not found, Delete is not supported.".format(label)) + warnings.append(f"Interface {label} not found, Delete is not supported.") return isamAppliance.create_return_object(changed=False, warnings=warnings) if force is True or delete_needed is True: @@ -109,7 +109,7 @@ def update(isamAppliance, label, address, new_address, prefixLength, vlanId=None ret_obj['ipv6']['addresses'].append(upd_addr) break else: - warnings.append("Interface {0} not found, Update is not supported.".format(label)) + warnings.append(f"Interface {label} not found, Update is not supported.") return isamAppliance.create_return_object(changed=False, warnings=warnings) if force is True or update_needed is True: @@ -145,7 +145,7 @@ def set_dhcp(isamAppliance, label, vlanId=None, enabled=False, allowManagement=F if enabled is True: ret_obj['ipv6']['addresses'] = [] else: - warnings.append("Interface {0} not found, Set dhcp is not supported.".format(label)) + warnings.append(f"Interface {label} not found, Set dhcp is not supported.") return isamAppliance.create_return_object(changed=False, warnings=warnings) if force is True or update_needed is True: diff --git a/ibmsecurity/isam/base/network/interfaces_vlan.py b/ibmsecurity/isam/base/network/interfaces_vlan.py index 72009ac3..f70df13e 100644 --- a/ibmsecurity/isam/base/network/interfaces_vlan.py +++ b/ibmsecurity/isam/base/network/interfaces_vlan.py @@ -70,7 +70,7 @@ def delete(isamAppliance, label, vlanId, check_mode=False, force=False): if check_mode is True: return isamAppliance.create_return_object(changed=True, warnings=warnings) else: - return isamAppliance.invoke_delete("Deleting a (VLAN) interface", "/net/ifaces/{0}".format(ret_obj['uuid']), requires_model=requires_model) + return isamAppliance.invoke_delete("Deleting a (VLAN) interface", f"/net/ifaces/{ret_obj['uuid']}", requires_model=requires_model) return isamAppliance.create_return_object(warnings=warnings) @@ -111,9 +111,9 @@ def update(isamAppliance, name, comment, label, enabled, vlanId=None, bondedTo=N } } sorted_json_data = ibmsecurity.utilities.tools.json_sort(json_data) - logger.debug("Sorted input: {0}".format(sorted_json_data)) + logger.debug(f"Sorted input: {sorted_json_data}") sorted_ret_obj = ibmsecurity.utilities.tools.json_sort(ret_obj) - logger.debug("Sorted existing data: {0}".format(sorted_ret_obj)) + logger.debug(f"Sorted existing data: {sorted_ret_obj}") if sorted_ret_obj != sorted_json_data: logger.info("Changes detected, update needed.") update_needed = True diff --git a/ibmsecurity/isam/base/network/packet_trace.py b/ibmsecurity/isam/base/network/packet_trace.py index da9c5bbf..a3525be3 100644 --- a/ibmsecurity/isam/base/network/packet_trace.py +++ b/ibmsecurity/isam/base/network/packet_trace.py @@ -35,11 +35,9 @@ def execute(isamAppliance, enabled, filter=None, interface=None, max_size=None, json_data['max_size'] = interface if snaplen is not None: - if tools.version_compare(isamAppliance.facts["version"], "9.0.6.0") < 0: + if tools.version_compare(isamAppliance.facts['version'], "9.0.6.0") < 0: warnings.append( - "Appliance at version: {}, snaplen: {1} is not supported. Needs 9.0.6.0 or higher. Ignoring snaplen for this call.".format( - isamAppliance.facts["version"], snaplen - ) + f"Appliance at version: {isamAppliance.facts['version']}, snaplen: {snaplen} is not supported. Needs 9.0.6.0 or higher. Ignoring snaplen for this call." ) else: json_data["snaplen"] = snaplen @@ -82,7 +80,7 @@ def export_file(isamAppliance, filepath, filename, check_mode=False, force=False else: return isamAppliance.invoke_get_file( "Exporting the packet tracing PCAP file", - "/isam/packet_tracing/pcap/{0}?export".format(filename), filepath, requires_model=requires_model + f"/isam/packet_tracing/pcap/{filename}?export", filepath, requires_model=requires_model ) return isamAppliance.create_return_object() diff --git a/ibmsecurity/isam/base/network/static_routes.py b/ibmsecurity/isam/base/network/static_routes.py index d8eda9ab..a690fcf0 100644 --- a/ibmsecurity/isam/base/network/static_routes.py +++ b/ibmsecurity/isam/base/network/static_routes.py @@ -24,7 +24,7 @@ def get(isamAppliance, uuid, check_mode=False, force=False): Retrieving a single static route """ return isamAppliance.invoke_get("Retrieving a single static route", - "/net/routes/{0}".format(uuid), requires_model=requires_model) + f"/net/routes/{uuid}", requires_model=requires_model) def add(isamAppliance, address, enabled=True, comment=None, table='main', maskOrPrefix=None, gateway=None, label=None, @@ -34,7 +34,7 @@ def add(isamAppliance, address, enabled=True, comment=None, table='main', maskOr """ if isamAppliance.facts['model'] != requires_model: - warnings = ["API invoked requires model: {0}, appliance is of deployment model: {1}.".format(requires_model, isamAppliance.facts['model'])] + warnings = [f"API invoked requires model: {requires_model}, appliance is of deployment model: {isamAppliance.facts['model']}."] return isamAppliance.create_return_object(warnings=warnings) if table.lower() != 'main': @@ -51,12 +51,12 @@ def add(isamAppliance, address, enabled=True, comment=None, table='main', maskOr if item['uuid'] == table: found_table = True if found_table is False: - logger.debug("Route table {0} is not found, Add static route is not supported.".format(table)) + logger.debug(f"Route table {table} is not found, Add static route is not supported.") return isamAppliance.create_return_object(changed=False) interfaceUUID = _get_interfaceUUID(isamAppliance, label, vlanId) if interfaceUUID is None and label is not None: - logger.debug("Interface {0} not found, Add static route is not supported.".format(label)) + logger.debug(f"Interface {label} not found, Add static route is not supported.") return isamAppliance.create_return_object(changed=False) if maskOrPrefix is not None: @@ -102,13 +102,13 @@ def update(isamAppliance, address, new_address=None, enabled=True, maskOrPrefix= Updating a static route """ if isamAppliance.facts['model'] != requires_model: - warnings = ["API invoked requires model: {0}, appliance is of deployment model: {1}.".format(requires_model, isamAppliance.facts['model'])] + warnings = [f"API invoked requires model: {requires_model}, appliance is of deployment model: {isamAppliance.facts['model']}."] return isamAppliance.create_return_object(warnings=warnings) warnings = [] interfaceUUID = _get_interfaceUUID(isamAppliance, label, vlanId) if interfaceUUID is None and label is not None: - warnings.append("Interface {0} not found, Update static route is not supported.".format(label)) + warnings.append(f"Interface {label} not found, Update static route is not supported.") return isamAppliance.create_return_object(changed=False, warnings=warnings) if table.lower() != 'main': @@ -125,13 +125,13 @@ def update(isamAppliance, address, new_address=None, enabled=True, maskOrPrefix= if item['uuid'] == table: found_table = True if found_table is False: - logger.debug("Route table {0} is not found, Add static route is not supported.".format(table)) + logger.debug(f"Route table {table} is not found, Add static route is not supported.") return isamAppliance.create_return_object(changed=False) uuid = _get_uuid(isamAppliance, address, table, interfaceUUID) if uuid is None: - logger.info("Unable to find Static Route to modify: {0} / {1}".format(address, table)) + logger.info(f"Unable to find Static Route to modify: {address} / {table}") return isamAppliance.create_return_object() if new_label is not None: @@ -175,7 +175,7 @@ def update(isamAppliance, address, new_address=None, enabled=True, maskOrPrefix= else: return isamAppliance.invoke_put( "Updating a static route", - "/net/routes/{0}".format(uuid), json_data) + f"/net/routes/{uuid}", json_data) return isamAppliance.create_return_object() @@ -185,7 +185,7 @@ def set(isamAppliance, address, new_address=None, enabled=True, maskOrPrefix=Non force=False): if isamAppliance.facts['model'] != requires_model: - warnings = ["API invoked requires model: {0}, appliance is of deployment model: {1}.".format(requires_model, isamAppliance.facts['model'])] + warnings = [f"API invoked requires model: {requires_model}, appliance is of deployment model: {isamAppliance.facts['model']}."] return isamAppliance.create_return_object(warnings=warnings) if table != 'main': @@ -197,7 +197,7 @@ def set(isamAppliance, address, new_address=None, enabled=True, maskOrPrefix=Non warnings = [] interfaceUUID = _get_interfaceUUID(isamAppliance, label, vlanId) if interfaceUUID is None and label is not None: - warnings.append("Interface {0} not found, Update static route is not supported.".format(label)) + warnings.append(f"Interface {label} not found, Update static route is not supported.") return isamAppliance.create_return_object(changed=False, warnings=warnings) if _check(isamAppliance, address, table_uuid, interfaceUUID) is True: @@ -227,7 +227,7 @@ def _get_interfaceUUID(isamAppliance, label, vlanId=None): def _get_uuid(isamAppliance, address, table, interfaceUUID): ret_obj = get_all(isamAppliance) for sr in ret_obj['data']['staticRoutes']: - logger.debug("Scanning {0}/{1}/{2} in Static Routes: {3}".format(address, table, interfaceUUID, sr)) + logger.debug(f"Scanning {address}/{table}/{interfaceUUID} in Static Routes: {sr}") if sr['address'] == address and ( sr['interfaceUUID'] == interfaceUUID or (sr['interfaceUUID'] == '' and interfaceUUID is None)) and sr[ 'table'] == table: @@ -241,14 +241,14 @@ def delete(isamAppliance, address, table='main', label=None, vlanId=None, check_ Delete a static route """ if isamAppliance.facts['model'] != requires_model: - warnings = ["API invoked requires model: {0}, appliance is of deployment model: {1}.".format(requires_model, isamAppliance.facts['model'])] + warnings = [f"API invoked requires model: {requires_model}, appliance is of deployment model: {isamAppliance.facts['model']}."] return isamAppliance.create_return_object(warnings=warnings) warnings = [] interfaceUUID = _get_interfaceUUID(isamAppliance, label, vlanId) if interfaceUUID is None and label is not None: - warnings.append("Interface {0} not found, Delete static route is not supported.".format(label)) + warnings.append(f"Interface {label} not found, Delete static route is not supported.") return isamAppliance.create_return_object(changed=False, warnings=warnings) if table != 'main': @@ -265,7 +265,7 @@ def delete(isamAppliance, address, table='main', label=None, vlanId=None, check_ if item['uuid'] == table: found_table = True if found_table is False: - logger.debug("Route table {0} is not found, Add static route is not supported.".format(label)) + logger.debug(f"Route table {label} is not found, Add static route is not supported.") return isamAppliance.create_return_object(changed=False) uuid = _get_uuid(isamAppliance=isamAppliance, address=address, table=table, interfaceUUID=interfaceUUID) @@ -276,7 +276,7 @@ def delete(isamAppliance, address, table='main', label=None, vlanId=None, check_ else: return isamAppliance.invoke_delete( "Delete a static route", - "/net/routes/{0}".format(uuid)) + f"/net/routes/{uuid}") return isamAppliance.create_return_object() @@ -315,11 +315,11 @@ def compare(isamAppliance1, isamAppliance2): Compare static routes between 2 appliances """ if isamAppliance1.facts['model'] != requires_model: - warnings = ["API invoked requires model: {0}, appliance is of deployment model: {1}.".format(requires_model, isamAppliance1.facts['model'])] + warnings = [f"API invoked requires model: {requires_model}, appliance is of deployment model: {isamAppliance1.facts['model']}."] return isamAppliance1.create_return_object(warnings=warnings) if isamAppliance2.facts['model'] != requires_model: - warnings = ["API invoked requires model: {0}, appliance is of deployment model: {1}.".format(requires_model, isamAppliance2.facts['model'])] + warnings = [f"API invoked requires model: {requires_model}, appliance is of deployment model: {isamAppliance2.facts['model']}."] return isamAppliance2.create_return_object(warnings=warnings) ret_obj1 = get_all(isamAppliance1) diff --git a/ibmsecurity/isam/base/remote_syslog/forwarder.py b/ibmsecurity/isam/base/remote_syslog/forwarder.py index ef19bf9d..c9c895db 100644 --- a/ibmsecurity/isam/base/remote_syslog/forwarder.py +++ b/ibmsecurity/isam/base/remote_syslog/forwarder.py @@ -33,7 +33,7 @@ def _find_forwarder(ret_obj, server, port, protocol): for obj in ret_obj['data']: if obj['server'] == server and obj['port'] == port and obj['protocol'] == protocol: existing_forwarder = obj - logger.debug("Found Forwarder: {0}".format(obj)) + logger.debug(f"Found Forwarder: {obj}") break i += 1 @@ -53,7 +53,7 @@ def get(isamAppliance, server, port, protocol, check_mode=False, force=False): return_obj['data'], i = _find_forwarder(ret_obj, server, port, protocol) warnings = [] if return_obj['data'] == None: - warnings.append("No entry found for server {} port {} and protocol {}.".format(server, port, protocol)) + warnings.append(f"No entry found for server {server} port {port} and protocol {protocol}.") return_obj['warnings'] = warnings return return_obj @@ -113,10 +113,8 @@ def set(isamAppliance, server, port, protocol='udp', debug=False, keyfile=None, # Check of the given server/port/protocol exist - if not then we add it if existing_forwarder is None or force is True: if format is not None: - if ibmsecurity.utilities.tools.version_compare(isamAppliance.facts["version"], "10.0.2.0") < 0: - warnings.append( - "Appliance at version: {0}, format is not supported. Needs 10.0.2.0 or higher. Ignoring format for this call.".format( - isamAppliance.facts["version"])) + if ibmsecurity.utilities.tools.version_compare(isamAppliance.facts['version'], "10.0.2.0") < 0: + warnings.append(f"Appliance at version: {isamAppliance.facts['version']}, format requires 10.0.2.0") else: json_data["format"] = format json_to_post = ret_obj['data'] @@ -125,18 +123,16 @@ def set(isamAppliance, server, port, protocol='udp', debug=False, keyfile=None, warnings.append("existing_forwarder is None") else: if format is not None: - if ibmsecurity.utilities.tools.version_compare(isamAppliance.facts["version"], "10.0.2.0") < 0: - warnings.append( - "Appliance at version: {0}, format is not supported. Needs 10.0.2.0 or higher. Ignoring format for this call.".format( - isamAppliance.facts["version"])) + if ibmsecurity.utilities.tools.version_compare(isamAppliance.facts['version'], "10.0.2.0") < 0: + warnings.append(f"Appliance at version: {isamAppliance.facts['version']}, format requires 10.0.2.0") else: json_data["format"] = format elif 'format' in ret_obj['data'][i]: del ret_obj['data'][i]['format'] sorted_json_data = tools.json_sort(json_data) - logger.debug("Sorted input: {0}".format(sorted_json_data)) + logger.debug(f"Sorted input: {sorted_json_data}") sorted_ret_obj = tools.json_sort(existing_forwarder) - logger.debug("Sorted existing data: {0}".format(sorted_ret_obj)) + logger.debug(f"Sorted existing data: {sorted_ret_obj}") if sorted_ret_obj != sorted_json_data: logger.info("Changes detected, update needed.") ret_obj['data'][i] = json_data diff --git a/ibmsecurity/isam/base/remote_syslog/forwarder_sources.py b/ibmsecurity/isam/base/remote_syslog/forwarder_sources.py index 62f8256b..2092e24d 100644 --- a/ibmsecurity/isam/base/remote_syslog/forwarder_sources.py +++ b/ibmsecurity/isam/base/remote_syslog/forwarder_sources.py @@ -105,7 +105,7 @@ def set(isamAppliance, server, port, protocol, name, tag, facility, severity, ch warnings = [] update_required = False if existing_forwarder is None: - warnings.append("Unable to find forwarder for {} {} {}".format(server, port, protocol)) + warnings.append(f"Unable to find forwarder for {server} {port} {protocol}") else: if existing_forwarder_source is None: json_to_post = ret_obj['data'] @@ -113,9 +113,9 @@ def set(isamAppliance, server, port, protocol, name, tag, facility, severity, ch update_required = True else: sorted_json_data = tools.json_sort(json_data) - logger.debug("Sorted input: {0}".format(sorted_json_data)) + logger.debug(f"Sorted input: {sorted_json_data}") sorted_ret_obj = tools.json_sort(existing_forwarder_source) - logger.debug("Sorted existing data: {0}".format(sorted_ret_obj)) + logger.debug(f"Sorted existing data: {sorted_ret_obj}") if sorted_ret_obj != sorted_json_data: logger.info("Changes detected, update needed.") ret_obj['data'][i]['sources'][j] = json_data diff --git a/ibmsecurity/isam/base/runtime/cluster.py b/ibmsecurity/isam/base/runtime/cluster.py index 0e529e42..27a4b536 100644 --- a/ibmsecurity/isam/base/runtime/cluster.py +++ b/ibmsecurity/isam/base/runtime/cluster.py @@ -12,7 +12,7 @@ def get(isamAppliance, check_mode=False, force=False): Retrieving the status of the clustered runtime profiles """ return isamAppliance.invoke_get("Retrieving the status of the clustered runtime profiles", - "{0}".format(uri), + f"{uri}", requires_modules=requires_modules, requires_version=requires_version) @@ -29,7 +29,7 @@ def execute(isamAppliance, operation, check_mode=False, force=False): return isamAppliance.create_return_object(changed=True) else: return isamAppliance.invoke_put("Stopping, starting, restarting, or reloading the clustered runtime profiles", - "{0}".format(uri), + f"{uri}", { 'operation': operation }, diff --git a/ibmsecurity/isam/base/runtime/listening_interfaces.py b/ibmsecurity/isam/base/runtime/listening_interfaces.py index 8bfe360d..9f85dc46 100644 --- a/ibmsecurity/isam/base/runtime/listening_interfaces.py +++ b/ibmsecurity/isam/base/runtime/listening_interfaces.py @@ -64,11 +64,11 @@ def set_by_address(isamAppliance, address, port, secure, check_mode=False, force for intfc in ret_obj['data']['interfaces']: for intfc_adr in intfc['ipv4']['addresses']: if intfc_adr['address'] == address: - uuid = "{0}.{1}".format(intfc['uuid'], intfc_adr['uuid']) + uuid = f"{intfc['uuid']}.{intfc_adr['uuid']}" break for intfc_adr in intfc['ipv6']['addresses']: if intfc_adr['address'] == address: - uuid = "{0}.{1}".format(intfc['uuid'], intfc_adr['uuid']) + uuid = f"{intfc['uuid']}.{intfc_adr['uuid']}" break return set(isamAppliance, uuid, port, secure, check_mode, force) @@ -114,7 +114,7 @@ def delete(isamAppliance, interface, port, check_mode=False, force=False): if force is False: exists, secure, id, warnings = _check(isamAppliance, interface, port) else: - id = '{0}:{1}'.format(interface, port) + id = f'{interface}:{port}' if force is True or exists is True: if check_mode is True: @@ -122,7 +122,7 @@ def delete(isamAppliance, interface, port, check_mode=False, force=False): else: return isamAppliance.invoke_delete( "Delete a runtime listening interface", - "/mga/runtime_tuning/endpoints/{0}/v1".format(id), + f"/mga/runtime_tuning/endpoints/{id}/v1", requires_modules=requires_modules,requires_model=requires_model) return isamAppliance.create_return_object(warnings=warnings) diff --git a/ibmsecurity/isam/base/runtime/process.py b/ibmsecurity/isam/base/runtime/process.py index abe49c5e..9f7826ae 100644 --- a/ibmsecurity/isam/base/runtime/process.py +++ b/ibmsecurity/isam/base/runtime/process.py @@ -24,9 +24,9 @@ def execute(isamAppliance, operation="restart", check_mode=False, force=False): check_value, warnings = _check(isamAppliance,operation) # Reload function is new to ISAM v9.0.2.0 - if operation == "reload" and tools.version_compare(isamAppliance.facts["version"], "9.0.2.0") < 0: + if operation == "reload" and tools.version_compare(isamAppliance.facts['version'], "9.0.2.0") < 0: warnings.append( - "Appliance is at version {0}, reload requires atleast v9.0.2.0".format(isamAppliance.facts['version'])) + f"Appliance is at version {isamAppliance.facts['version']}, reload requires atleast v9.0.2.0") return isamAppliance.create_return_object(warnings=warnings) if force is True or check_value is True: @@ -63,6 +63,5 @@ def _check(isamAppliance, operation): return True,warnings else: logger.info( - "Executing {0} on Liberty Runtime process not required or will not work. Use force if needed.".format( - operation)) + f"Executing {operation} on Liberty Runtime process not required or will not work. Use force if needed.") return False,warnings diff --git a/ibmsecurity/isam/base/runtime/tuning_parameters.py b/ibmsecurity/isam/base/runtime/tuning_parameters.py index 7b689f2b..fc7c1f3f 100644 --- a/ibmsecurity/isam/base/runtime/tuning_parameters.py +++ b/ibmsecurity/isam/base/runtime/tuning_parameters.py @@ -25,7 +25,7 @@ def set(isamAppliance, option, value, check_mode=False, force=False): matches, exists, warnings = _check(isamAppliance, option, value) if exists is False: - warnings.append("Tuning Parameter {0} was not found. set() request will attempt anyway.".format(option)) + warnings.append(f"Tuning Parameter {option} was not found. set() request will attempt anyway.") if force is True or matches is False: if check_mode is True: @@ -33,7 +33,7 @@ def set(isamAppliance, option, value, check_mode=False, force=False): else: return isamAppliance.invoke_put( "Setting a runtime tuning parameter", - "/mga/runtime_tuning/{0}/v1".format(option), + f"/mga/runtime_tuning/{option}/v1", { 'value': value }, requires_modules=requires_modules, requires_model=requires_model) @@ -52,11 +52,11 @@ def _check(isamAppliance, option, value): exists = False try: if str(ret_obj['data'][option]) == str(value): - logger.info("Tuning parameter {0}/{1} already set.".format(option, value)) + logger.info(f"Tuning parameter {option}/{value} already set.") matches = True else: logger.info( - "Tuning parameter {0} value does not match {1} != {2}.".format(option, ret_obj['data'][option], value)) + f"Tuning parameter {option} value does not match {ret_obj['data'][option]} != {value}.") exists = True except Exception: logger.info("Runtime tuning parameter does not exist") @@ -80,10 +80,10 @@ def reset(isamAppliance, option, check_mode=False, force=False): else: return isamAppliance.invoke_delete( "Reset a runtime tuning parameter to default value", - "/mga/runtime_tuning/{0}/v1".format(option), + f"/mga/runtime_tuning/{option}/v1", requires_modules=requires_modules, requires_model=requires_model) elif exists is False and warnings == []: - warnings.append("Tuning Parameter {0} was not found. Skipping reset() request.".format(option)) + warnings.append(f"Tuning Parameter {option} was not found. Skipping reset() request.") return isamAppliance.create_return_object(warnings=warnings) diff --git a/ibmsecurity/isam/base/scheduled_security_updates.py b/ibmsecurity/isam/base/scheduled_security_updates.py index b35c652e..42267191 100644 --- a/ibmsecurity/isam/base/scheduled_security_updates.py +++ b/ibmsecurity/isam/base/scheduled_security_updates.py @@ -75,9 +75,9 @@ def _check(isamAppliance, enableAutoCheck, scheduleSettings, dailyFrequencySetti json_data['config']['dailyFrequencySettings'] = dailyFrequencySettings sorted_json_data = ibmsecurity.utilities.tools.json_sort(json_data) - logger.debug("Sorted input: {0}".format(sorted_json_data)) + logger.debug(f"Sorted input: {sorted_json_data}") sorted_ret_obj = ibmsecurity.utilities.tools.json_sort(ret_obj['data']) - logger.debug("Sorted existing data: {0}".format(sorted_ret_obj)) + logger.debug(f"Sorted existing data: {sorted_ret_obj}") if sorted_ret_obj != sorted_json_data: logger.info("Changes detected, update needed.") json_data["schedule_type"] = schedule_type diff --git a/ibmsecurity/isam/base/service_agreement.py b/ibmsecurity/isam/base/service_agreement.py index 0345dfed..f55636ed 100644 --- a/ibmsecurity/isam/base/service_agreement.py +++ b/ibmsecurity/isam/base/service_agreement.py @@ -35,14 +35,14 @@ def get_non_ibm(isamAppliance, offering, check_mode=False, force=False): Reading non-IBM the software license agreement terms """ return isamAppliance.invoke_get("Reading non-IBM the software license agreement terms", - "{0}/non_ibm_text/{1}".format(uri, offering)) + f"{uri}/non_ibm_text/{offering}") def get_terms(isamAppliance, check_mode=False, force=False): """ Reading the software license agreement terms """ - return isamAppliance.invoke_get("Reading the software license agreement terms", "{0}/".format(uri)) + return isamAppliance.invoke_get("Reading the software license agreement terms", f"{uri}/") def _check(isamAppliance): diff --git a/ibmsecurity/isam/base/silent_config.py b/ibmsecurity/isam/base/silent_config.py index 73b27457..608f181d 100644 --- a/ibmsecurity/isam/base/silent_config.py +++ b/ibmsecurity/isam/base/silent_config.py @@ -13,7 +13,7 @@ def get(isamAppliance, check_mode=False, force=False): """ Getting the silent configuration flag """ - return isamAppliance.invoke_get("Getting the silent configuration flag", "{}/flag".format(module_uri), + return isamAppliance.invoke_get("Getting the silent configuration flag", f"{module_uri}/flag", requires_version=requires_version, requires_modules=requires_modules, requires_model=requires_model) @@ -37,7 +37,7 @@ def update(isamAppliance, flag, check_mode=False, force=False): return isamAppliance.create_return_object(changed=True, warnings=warnings) else: json_data = {"flag": flag} - return isamAppliance.invoke_put("Setting the silent configuration flag", "{}/flag".format(module_uri), + return isamAppliance.invoke_put("Setting the silent configuration flag", f"{module_uri}/flag", json_data, requires_version=requires_version, requires_modules=requires_modules, requires_model=requires_model) @@ -70,7 +70,7 @@ def _export(isamAppliance, uri, network_hostname, filename, network_1_1_ipv4_add post_data = "" for k, value in json_data.items(): if value is not None: - post_data = "{0}{1}={2}&".format(post_data, k, value) + post_data = f"{post_data}{k}={value}&" # strip the last & added post_data = post_data[:-1] @@ -97,10 +97,10 @@ def export_iso(isamAppliance, network_hostname, filename=None, network_1_1_ipv4_ network_1_1_ipv6_prefix=None, network_1_1_ipv6_gateway=None, include_policy="false", check_mode=False, force=False): logger.info("Generating an ISO file for silent configuration.") - uri = "{0}/create/iso".format(module_uri) + uri = f"{module_uri}/create/iso" if filename is None: - filename = "{}.iso".format(network_hostname) - logger.debug("Using filename as: {}".format(filename)) + filename = f"{network_hostname}.iso" + logger.debug(f"Using filename as: {filename}") return _export(isamAppliance, uri, network_hostname, filename, network_1_1_ipv4_address, network_1_1_ipv4_netmask, network_1_1_ipv4_gateway, network_1_1_ipv6_address, network_1_1_ipv6_prefix, @@ -113,10 +113,10 @@ def export_img(isamAppliance, network_hostname, filename=None, network_1_1_ipv4_ force=False): logger.info("Generating an IMG file for silent configuration.") - uri = "{0}/create/usb".format(module_uri) + uri = f"{module_uri}/create/usb" if filename is None: - filename = "{}.img".format(network_hostname) - logger.debug("Using filename as: {}".format(filename)) + filename = f"{network_hostname}.img" + logger.debug(f"Using filename as: {filename}") return _export(isamAppliance, uri, network_hostname, filename, network_1_1_ipv4_address, network_1_1_ipv4_netmask, network_1_1_ipv4_gateway, network_1_1_ipv6_address, network_1_1_ipv6_prefix, diff --git a/ibmsecurity/isam/base/snapshots.py b/ibmsecurity/isam/base/snapshots.py index 3de729e6..605cf01f 100644 --- a/ibmsecurity/isam/base/snapshots.py +++ b/ibmsecurity/isam/base/snapshots.py @@ -35,7 +35,7 @@ def search(isamAppliance, comment, check_mode=False, force=False): for obj in ret_obj_all['data']: if comment in obj['comment']: - logger.debug("Snapshot comment \"{0}\" has this string \"{1}\" in it.".format(obj['comment'], comment)) + logger.debug(f"Snapshot comment \"{obj['comment']}\" has this string \"{comment}\" in it.") if ret_obj['data'] == {}: ret_obj['data'] = [obj['id']] else: @@ -73,12 +73,12 @@ def _check(isamAppliance, comment='', id=None): if id != None: for snaps in ret_obj['data']: if snaps['id'] == id: - logger.debug("Found id: {}".format(id)) + logger.debug(f"Found id: {id}") return True else: for snaps in ret_obj['data']: if snaps['comment'] == comment: - logger.debug("Found comment: {}".format(comment)) + logger.debug(f"Found comment: {comment}") return True return False @@ -103,7 +103,7 @@ def delete(isamAppliance, id=None, comment=None, check_mode=False, force=False): if ret_obj != {} and ret_obj['data'] != {}: delete_flag = True ids = ret_obj['data'] - logger.info("Deleting the following list of IDs: {}".format(ids)) + logger.info(f"Deleting the following list of IDs: {ids}") if force is True or delete_flag is True: if check_mode is True: return isamAppliance.create_return_object(changed=True) @@ -201,7 +201,7 @@ def download(isamAppliance, filename, id=None, comment=None, check_mode=False, f if ret_obj != {} and ret_obj['data'] != {}: download_flag = True ids = ret_obj['data'] - logger.info("Downloading the following list of IDs: {}".format(ids)) + logger.info(f"Downloading the following list of IDs: {ids}") if force is True or ( os.path.exists(filename) is False and download_flag is True): # Don't overwrite if not forced to diff --git a/ibmsecurity/isam/base/snmp_monitoring.py b/ibmsecurity/isam/base/snmp_monitoring.py index 361e21d7..22b9375a 100644 --- a/ibmsecurity/isam/base/snmp_monitoring.py +++ b/ibmsecurity/isam/base/snmp_monitoring.py @@ -88,9 +88,9 @@ def _check_all(isamAppliance, snmpv1v2c, snmpv3, port, enabled): import ibmsecurity.utilities.tools sorted_json_data = ibmsecurity.utilities.tools.json_sort(json_data) - logger.debug("Sorted input: {0}".format(sorted_json_data)) + logger.debug(f"Sorted input: {sorted_json_data}") sorted_ret_obj = ibmsecurity.utilities.tools.json_sort(ret_obj['data']) - logger.debug("Sorted existing data: {0}".format(sorted_ret_obj)) + logger.debug(f"Sorted existing data: {sorted_ret_obj}") if sorted_ret_obj != sorted_json_data: logger.info("Changes detected, update needed.") update_required = True diff --git a/ibmsecurity/isam/base/ssl_certificates/certificate_databases.py b/ibmsecurity/isam/base/ssl_certificates/certificate_databases.py index 521c081b..1b29870d 100644 --- a/ibmsecurity/isam/base/ssl_certificates/certificate_databases.py +++ b/ibmsecurity/isam/base/ssl_certificates/certificate_databases.py @@ -50,7 +50,7 @@ def get(isamAppliance, cert_dbase_id, check_mode=False, force=False): Retrieving the SSL certificate database details """ return isamAppliance.invoke_get("Retrieving the SSL certificate database details", - "/isam/ssl_certificates/{0}/details".format(cert_dbase_id), + f"/isam/ssl_certificates/{cert_dbase_id}/details", requires_model=requires_model) @@ -87,14 +87,14 @@ def create(isamAppliance, kdb_name, type='kdb', json_data[k] = v # new in 10.0.5 if k in certificate_database_new_10_05: - if ibmsecurity.utilities.tools.version_compare(isamAppliance.facts["version"], "10.0.8.0") < 0: - warnings.append( "Appliance at version: {0}, load_certificate: {1} is not supported. Needs 10.0.0.0 or higher. Ignoring load_certificate for this call.".format( isamAppliance.facts["version"], load_certificate)) + if ibmsecurity.utilities.tools.version_compare(isamAppliance.facts['version'], "10.0.8.0") < 0: + warnings.append( f"Appliance at version: {isamAppliance.facts['version']}, load_certificate: {load_certificate} is not supported. Needs 10.0.0.0 or higher. Ignoring load_certificate for this call.") else: json_data[k] = v # new in 10.0.8 if k in certificate_database_new_10_08: - if ibmsecurity.utilities.tools.version_compare(isamAppliance.facts["version"], "10.0.8.0") < 0: - warnings.append( "Appliance at version: {0}, load_certificate: {1} is not supported. Needs 10.0.0.0 or higher. Ignoring load_certificate for this call.".format( isamAppliance.facts["version"], load_certificate)) + if ibmsecurity.utilities.tools.version_compare(isamAppliance.facts['version'], "10.0.8.0") < 0: + warnings.append( f"Appliance at version: {isamAppliance.facts['version']}, load_certificate: {load_certificate} is not supported. Needs 10.0.0.0 or higher. Ignoring load_certificate for this call.") else: json_data[k] = v # Logic @@ -138,7 +138,7 @@ def delete(isamAppliance, cert_dbase_id, check_mode=False, force=False): else: return isamAppliance.invoke_delete( "Deleting a certificate database", - "/isam/ssl_certificates/{0}".format(cert_dbase_id)) + f"/isam/ssl_certificates/{cert_dbase_id}") return isamAppliance.create_return_object() @@ -153,7 +153,7 @@ def export_db(isamAppliance, cert_id, filename, check_mode=False, force=False): if check_mode is False: # No point downloading a file if in check_mode return isamAppliance.invoke_get_file( "Export a certificate database", - "/isam/ssl_certificates/{0}?export".format(cert_id), + f"/isam/ssl_certificates/{cert_id}?export", filename) return isamAppliance.create_return_object() @@ -214,7 +214,7 @@ def rename(isamAppliance, cert_id, new_name, check_mode=False, force=False): else: return isamAppliance.invoke_put( "Renaming a certificate database", - "/isam/ssl_certificates/{0}".format(cert_id), + f"/isam/ssl_certificates/{cert_id}", { "new_name": new_name }) @@ -241,7 +241,7 @@ def set(isamAppliance, cert_id, description, check_mode=False, force=False): else: return isamAppliance.invoke_put( "Set description for a certificate database", - "/isam/ssl_certificates/{0}".format(cert_id), + f"/isam/ssl_certificates/{cert_id}", { "description": description }) diff --git a/ibmsecurity/isam/base/ssl_certificates/certificate_requests.py b/ibmsecurity/isam/base/ssl_certificates/certificate_requests.py index 897ae61c..ed01a11a 100644 --- a/ibmsecurity/isam/base/ssl_certificates/certificate_requests.py +++ b/ibmsecurity/isam/base/ssl_certificates/certificate_requests.py @@ -10,7 +10,7 @@ def get_all(isamAppliance, kdb_id, check_mode=False, force=False): Retrieving certificate request names and details in a certificate database """ return isamAppliance.invoke_get("Retrieving certificate request names and details in a certificate database", - "/isam/ssl_certificates/{0}/cert_request".format(kdb_id)) + f"/isam/ssl_certificates/{kdb_id}/cert_request") def get(isamAppliance, kdb_id, cert_id, check_mode=False, force=False): @@ -18,7 +18,7 @@ def get(isamAppliance, kdb_id, cert_id, check_mode=False, force=False): Retrieving a certificate request from a certificate database """ return isamAppliance.invoke_get("Retrieving a certificate request from a certificate database", - "/isam/ssl_certificates/{0}/cert_request/{1}".format(kdb_id, cert_id)) + f"/isam/ssl_certificates/{kdb_id}/cert_request/{cert_id}") def add(isamAppliance, kdb_id, label, dn, size='1024', signature_algorithm='', check_mode=False, force=False): @@ -29,9 +29,8 @@ def add(isamAppliance, kdb_id, label, dn, size='1024', signature_algorithm='', c warnings = [] if signature_algorithm is not None: - if ibmsecurity.utilities.tools.version_compare(isamAppliance.facts["version"], "9.0.2.0") < 0: - warnings.append("Appliance at version: {0}, signature_algorithm is not supported. Needs 9.0.2.0 or higher. " - "Ignoring signature_algorithm for this call".format(isamAppliance.facts["version"])) + if ibmsecurity.utilities.tools.version_compare(isamAppliance.facts['version'], "9.0.2.0") < 0: + warnings.append(f"Appliance at version: {isamAppliance.facts['version']}, signature_algorithm is not supported. Needs 9.0.2.0 or higher. Ignoring signature_algorithm for this call") json_obj = { "label": label, "dn": dn, @@ -52,7 +51,7 @@ def add(isamAppliance, kdb_id, label, dn, size='1024', signature_algorithm='', c return isamAppliance.invoke_post( "Creating a certificate request in a certificate database", - "/isam/ssl_certificates/{0}/cert_request".format(kdb_id), + f"/isam/ssl_certificates/{kdb_id}/cert_request", json_obj, warnings=warnings) @@ -69,7 +68,7 @@ def delete(isamAppliance, kdb_id, cert_id, check_mode=False, force=False): else: return isamAppliance.invoke_delete( "Deleting a certificate request from a certificate database", - "/isam/ssl_certificates/{0}/cert_request/{1}".format(kdb_id, cert_id)) + f"/isam/ssl_certificates/{kdb_id}/cert_request/{cert_id}") return isamAppliance.create_return_object() @@ -82,7 +81,7 @@ def export_cert(isamAppliance, kdb_id, cert_id, filename, check_mode=False, forc if check_mode is False: # No point downloading a file if in check_mode return isamAppliance.invoke_get_file( "Exporting a certificate request from a certificate database", - "/isam/ssl_certificates/{0}/cert_request/{1}?export".format(kdb_id, cert_id), + f"/isam/ssl_certificates/{kdb_id}/cert_request/{cert_id}?export", filename) return isamAppliance.create_return_object() diff --git a/ibmsecurity/isam/base/ssl_certificates/personal_certificate.py b/ibmsecurity/isam/base/ssl_certificates/personal_certificate.py index 128819a2..8cf0f431 100644 --- a/ibmsecurity/isam/base/ssl_certificates/personal_certificate.py +++ b/ibmsecurity/isam/base/ssl_certificates/personal_certificate.py @@ -12,7 +12,7 @@ def get_all(isamAppliance, kdb_id, check_mode=False, force=False): """ return isamAppliance.invoke_get( "Retrieving personal certificate names and details in a certificate database", - "/isam/ssl_certificates/{0}/personal_cert".format(kdb_id) + f"/isam/ssl_certificates/{kdb_id}/personal_cert" ) @@ -22,7 +22,7 @@ def get(isamAppliance, kdb_id, cert_id, check_mode=False, force=False): """ return isamAppliance.invoke_get( "Retrieving a personal certificate from a certificate database", - "/isam/ssl_certificates/{0}/personal_cert/{1}".format(kdb_id, cert_id) + f"/isam/ssl_certificates/{kdb_id}/personal_cert/{cert_id}" ) @@ -34,9 +34,8 @@ def generate(isamAppliance, kdb_id, label, dn, expire='365', default='no', size= warnings = [] if signature_algorithm is not None: - if ibmsecurity.utilities.tools.version_compare(isamAppliance.facts["version"], "9.0.2.0") < 0: - warnings.append("Appliance at version: {0}, signature_algorithm is not supported. Needs 9.0.2.0 or higher. " - "Ignoring signature_algorithm for this call".format(isamAppliance.facts["version"])) + if ibmsecurity.utilities.tools.version_compare(isamAppliance.facts['version'], "9.0.2.0") < 0: + warnings.append(f"Appliance at version: {isamAppliance.facts['version']}, signature_algorithm is not supported. Needs 9.0.2.0 or higher. Ignoring signature_algorithm for this call") json_obj = { "operation": 'generate', "label": label, @@ -62,7 +61,7 @@ def generate(isamAppliance, kdb_id, label, dn, expire='365', default='no', size= else: return isamAppliance.invoke_post( "Generating a self-signed personal certificate in a certificate database", - "/isam/ssl_certificates/{0}/personal_cert".format(kdb_id), + f"/isam/ssl_certificates/{kdb_id}/personal_cert", json_obj, warnings=warnings ) @@ -77,7 +76,7 @@ def rename(isamAppliance, kdb_id, cert_id, new_id, """ warnings = [] - if ibmsecurity.utilities.tools.version_compare(isamAppliance.facts["version"], "10.0.7.0") < 0: + if ibmsecurity.utilities.tools.version_compare(isamAppliance.facts['version'], "10.0.7.0") < 0: warnings.append( f"Appliance is at version: {isamAppliance.facts['version']}. Renaming a certificate requires at least 10.0.7.0" ) @@ -102,7 +101,7 @@ def set(isamAppliance, kdb_id, cert_id, default='no', check_mode=False, force=Fa """ warnings = [] - if ibmsecurity.utilities.tools.version_compare(isamAppliance.facts["version"], "10.0.3.0") > 0: + if ibmsecurity.utilities.tools.version_compare(isamAppliance.facts['version'], "10.0.3.0") > 0: warnings.append( f"Appliance is at version: {isamAppliance.facts['version']}. Setting certificates as default is no longer supported." ) @@ -113,7 +112,7 @@ def set(isamAppliance, kdb_id, cert_id, default='no', check_mode=False, force=Fa else: return isamAppliance.invoke_put( "Setting a personal certificate as default in a certificate database", - "/isam/ssl_certificates/{0}/personal_cert/{1}".format(kdb_id, cert_id), + f"/isam/ssl_certificates/{kdb_id}/personal_cert/{cert_id}", { 'default': default }) @@ -131,7 +130,7 @@ def receive(isamAppliance, kdb_id, label, cert, default='no', check_mode=False, else: return isamAppliance.invoke_post_files( "Receiving a personal certificate into a certificate database", - "/isam/ssl_certificates/{0}/personal_cert".format(kdb_id), + f"/isam/ssl_certificates/{kdb_id}/personal_cert", [ { 'file_formfield': 'cert', @@ -170,7 +169,7 @@ def export_cert(isamAppliance, kdb_id, cert_id, filename, check_mode=False, forc if check_mode is False: # No point downloading a file if in check_mode return isamAppliance.invoke_get_file( "Exporting a personal certificate from a certificate database", - "/isam/ssl_certificates/{0}/personal_cert/{1}?export".format(kdb_id, cert_id), + f"/isam/ssl_certificates/{kdb_id}/personal_cert/{cert_id}?export", filename) return isamAppliance.create_return_object() @@ -186,7 +185,7 @@ def import_cert(isamAppliance, kdb_id, cert, label=None, password=None, check_mo if check_mode: return isamAppliance.create_return_object(changed=True) else: - iviaVersion = isamAppliance.facts["version"] + iviaVersion = isamAppliance.facts['version'] post_data = { 'file_formfield': 'cert', 'filename': cert, @@ -227,7 +226,7 @@ def extract_cert(isamAppliance, kdb_id, cert_id, password, filename, check_mode= else: ret_obj = isamAppliance.invoke_post( "Extracting a personal certificate from a certificate database", - "/isam/ssl_certificates/{0}/personal_cert/{1}".format(kdb_id, cert_id), + f"/isam/ssl_certificates/{kdb_id}/personal_cert/{cert_id}", { 'operation': 'extract', 'type': 'pkcs12', diff --git a/ibmsecurity/isam/base/ssl_certificates/signer_certificate.py b/ibmsecurity/isam/base/ssl_certificates/signer_certificate.py index 2736c266..18a948f0 100644 --- a/ibmsecurity/isam/base/ssl_certificates/signer_certificate.py +++ b/ibmsecurity/isam/base/ssl_certificates/signer_certificate.py @@ -11,7 +11,7 @@ def get_all(isamAppliance, kdb_id, check_mode=False, force=False): Retrieving signer certificate names and details in a certificate database """ return isamAppliance.invoke_get("Retrieving signer certificate names and details in a certificate database", - "/isam/ssl_certificates/{0}/signer_cert".format(kdb_id)) + f"/isam/ssl_certificates/{kdb_id}/signer_cert") def get(isamAppliance, kdb_id, cert_id, check_mode=False, force=False): @@ -19,7 +19,7 @@ def get(isamAppliance, kdb_id, cert_id, check_mode=False, force=False): Retrieving a signer certificate from a certificate database """ return isamAppliance.invoke_get("Retrieving a signer certificate from a certificate database", - "/isam/ssl_certificates/{0}/signer_cert/{1}".format(kdb_id, cert_id)) + f"/isam/ssl_certificates/{kdb_id}/signer_cert/{cert_id}") def load(isamAppliance, kdb_id, label, server, port, check_remote=False, check_mode=False, force=False): @@ -42,7 +42,7 @@ def load(isamAppliance, kdb_id, label, server, port, check_remote=False, check_m else: return isamAppliance.invoke_post( "Load a certificate from a server", - "/isam/ssl_certificates/{0}/signer_cert".format(kdb_id), + f"/isam/ssl_certificates/{kdb_id}/signer_cert", { "operation": 'load', "label": label, @@ -85,7 +85,7 @@ def _check_load(isamAppliance, kdb_id, label, server, port): cert_id = cert_data['id'] cert_pem = get(isamAppliance, kdb_id, cert_id)['data']['contents'] if cert_id == label: # label exists on appliance already - logger.debug("Comparing certificates: appliance[{0}] remote[{1}].".format(cert_pem,remote_cert_pem)) + logger.debug(f"Comparing certificates: appliance[{cert_pem}] remote[{remote_cert_pem}].") if cert_pem == remote_cert_pem: # certificate data is the same logger.debug("The certificate already exits on the appliance with the same label name and same content.") return True # both the labels and certificates match @@ -101,9 +101,7 @@ def _check_load(isamAppliance, kdb_id, label, server, port): else: if cert_pem == remote_cert_pem: # cert on the appliance, but with a different name logger.info( - "The certifcate is already on the appliance, but it has a different label name. " - "The existing label name is {label} and requested label name is {cert_id}".format( - label=label, cert_id=cert_id)) + f"The certifcate is already on the appliance, but it has a different label name. The existing label name is {label} and requested label name is {cert_id}") return True return False @@ -124,7 +122,7 @@ def delete(isamAppliance, kdb_id, cert_id, check_mode=False, force=False): from urllib import quote # URL being encoded primarily to handle spaces and other special characers in them - f_uri = "/isam/ssl_certificates/{0}/signer_cert/{1}".format(kdb_id, cert_id) + f_uri = f"/isam/ssl_certificates/{kdb_id}/signer_cert/{cert_id}" full_uri = quote(f_uri) return isamAppliance.invoke_delete( "Deleting a signer certificate from a certificate database", full_uri) @@ -142,7 +140,7 @@ def export_cert(isamAppliance, kdb_id, cert_id, filename, check_mode=False, forc if check_mode is False: # No point downloading a file if in check_mode return isamAppliance.invoke_get_file( "Export a certificate database", - "/isam/ssl_certificates/{0}/signer_cert/{1}?export".format(kdb_id, cert_id), + f"/isam/ssl_certificates/{kdb_id}/signer_cert/{cert_id}?export", filename) return isamAppliance.create_return_object() @@ -156,10 +154,10 @@ def import_cert(isamAppliance, kdb_id, cert, label, preserve_label='false', chec if check_mode is True: return isamAppliance.create_return_object(changed=True) else: - if version_compare(isamAppliance.facts["version"], "10.0.5.0") < 0: + if version_compare(isamAppliance.facts['version'], "10.0.5.0") < 0: return isamAppliance.invoke_post_files( "Importing a signer certificate into a certificate database", - "/isam/ssl_certificates/{0}/signer_cert".format(kdb_id), + f"/isam/ssl_certificates/{kdb_id}/signer_cert", [ { 'file_formfield': 'cert', @@ -171,7 +169,7 @@ def import_cert(isamAppliance, kdb_id, cert, label, preserve_label='false', chec else: return isamAppliance.invoke_post_files( "Importing a signer certificate into a certificate database", - "/isam/ssl_certificates/{0}/signer_cert".format(kdb_id), + f"/isam/ssl_certificates/{kdb_id}/signer_cert", [ { 'file_formfield': 'cert', @@ -204,7 +202,7 @@ def _check_import(isamAppliance, kdb_id, cert_id, filename, check_mode=False): the one stored in filename """ tmpdir = get_random_temp_dir() - orig_filename = '%s.cer' % cert_id + orig_filename = f'{cert_id}.cer' tmp_original_file = os.path.join(tmpdir, os.path.basename(orig_filename)) if _check(isamAppliance, kdb_id, cert_id): export_cert(isamAppliance, kdb_id, cert_id, tmp_original_file, check_mode=False, force=True) diff --git a/ibmsecurity/isam/base/support.py b/ibmsecurity/isam/base/support.py index 20de10e2..79e14885 100644 --- a/ibmsecurity/isam/base/support.py +++ b/ibmsecurity/isam/base/support.py @@ -21,7 +21,7 @@ def get_categories(isamAppliance, check_mode=False, force=False): Retrieving information about all the support categories """ return isamAppliance.invoke_get("Retrieving information about all the support categories", - "{0}/categories".format(uri)) + f"{uri}/categories") def get_instances(isamAppliance, name, check_mode=False, force=False): @@ -29,7 +29,7 @@ def get_instances(isamAppliance, name, check_mode=False, force=False): Retrieving information about all the instances for a specific support category """ return isamAppliance.invoke_get("Retrieving information about all the instances for a specific support category", - "{0}/categories/{1}/instances".format(uri, name)) + f"{uri}/categories/{name}/instances") def create(isamAppliance, comment='', wrp=None, isam_runtime=None, lmi=None, cluster=None, felb=None, @@ -72,7 +72,7 @@ def create(isamAppliance, comment='', wrp=None, isam_runtime=None, lmi=None, clu return isamAppliance.create_return_object(changed=True) else: return isamAppliance.invoke_post("Creating a new support file", - "{0}/".format(uri), + f"{uri}/", json_data, requires_modules=requires_modules, requires_version=requires_version) @@ -117,9 +117,9 @@ def delete(isamAppliance, id, check_mode=False, force=False): return isamAppliance.create_return_object(changed=True) else: if isinstance(id, list): - del_uri = "{0}/multi_destroy{1}".format(uri, tools.create_query_string(record_ids=','.join(id))) + del_uri = f"{uri}/multi_destroy{tools.create_query_string(record_ids=','.join(id))}" else: - del_uri = "{0}/{1}".format(uri, id) + del_uri = f"{uri}/{id}" return isamAppliance.invoke_delete("Deleting a support file", del_uri) return isamAppliance.create_return_object() @@ -133,7 +133,7 @@ def modify(isamAppliance, id, filename, comment, check_mode=False, force=False): if check_mode is True: return isamAppliance.create_return_object(changed=True) else: - return isamAppliance.invoke_put("Modifying snapshot", "{0}/{1}".format(uri, id), + return isamAppliance.invoke_put("Modifying snapshot", f"{uri}/{id}", { 'id': id, 'filename': filename, @@ -152,7 +152,7 @@ def download(isamAppliance, filename, id, check_mode=False, force=False): if check_mode is False: # No point downloading a file if in check_mode if isinstance(id, list): id = ','.join(id) - uri_download = "{0}/download{1}".format(uri, tools.create_query_string(record_ids=id)) + uri_download = f"{uri}/download{tools.create_query_string(record_ids=id)}" return isamAppliance.invoke_get_file("Downloading snapshots", uri_download, filename) return isamAppliance.create_return_object() diff --git a/ibmsecurity/isam/base/sysaccount/groups.py b/ibmsecurity/isam/base/sysaccount/groups.py index addc76a6..2e55fcbe 100644 --- a/ibmsecurity/isam/base/sysaccount/groups.py +++ b/ibmsecurity/isam/base/sysaccount/groups.py @@ -16,7 +16,7 @@ def get(isamAppliance, id, check_mode=False, force=False): """ Get information on particular group by id """ - return isamAppliance.invoke_get("Retrieving group", "/sysaccount/groups/{0}/v1".format(id)) + return isamAppliance.invoke_get("Retrieving group", f"/sysaccount/groups/{id}/v1") def create(isamAppliance, id, check_mode=False, force=False): @@ -61,7 +61,7 @@ def delete(isamAppliance, id, check_mode=False, force=False): if check_mode is True: return isamAppliance.create_return_object(changed=True) else: - return isamAppliance.invoke_delete("Deleting group", "/sysaccount/groups/{0}/v1".format(id)) + return isamAppliance.invoke_delete("Deleting group", f"/sysaccount/groups/{id}/v1") return isamAppliance.create_return_object() diff --git a/ibmsecurity/isam/base/sysaccount/users.py b/ibmsecurity/isam/base/sysaccount/users.py index 4576bfcc..36b95947 100644 --- a/ibmsecurity/isam/base/sysaccount/users.py +++ b/ibmsecurity/isam/base/sysaccount/users.py @@ -16,7 +16,7 @@ def get(isamAppliance, id, check_mode=False, force=False): """ Get information on particular user by id """ - return isamAppliance.invoke_get("Retrieving user", "/sysaccount/users/{0}/v1".format(id)) + return isamAppliance.invoke_get("Retrieving user", f"/sysaccount/users/{id}/v1") def create(isamAppliance, id, password, groups=[], check_mode=False, force=False): @@ -63,7 +63,7 @@ def delete(isamAppliance, id, check_mode=False, force=False): if check_mode is True: return isamAppliance.create_return_object(changed=True) else: - return isamAppliance.invoke_delete("Deleting user", "/sysaccount/users/{0}/v1".format(id)) + return isamAppliance.invoke_delete("Deleting user", f"/sysaccount/users/{id}/v1") return isamAppliance.create_return_object() @@ -79,7 +79,7 @@ def modify(isamAppliance, id, password, old_password=None, check_mode=False, for if check_mode is True: return isamAppliance.create_return_object(changed=True, warnings=warnings) else: - return isamAppliance.invoke_put("Change password", "/sysaccount/users/{0}/v1".format(id), + return isamAppliance.invoke_put("Change password", f"/sysaccount/users/{id}/v1", { 'password': password }, warnings=warnings) diff --git a/ibmsecurity/isam/base/system_alerts/alerts.py b/ibmsecurity/isam/base/system_alerts/alerts.py index 78497848..20ed22e9 100644 --- a/ibmsecurity/isam/base/system_alerts/alerts.py +++ b/ibmsecurity/isam/base/system_alerts/alerts.py @@ -41,7 +41,7 @@ def disable(isamAppliance, uuid, check_mode=False, force=False): else: return isamAppliance.invoke_delete( "Delete a system alert", - "/core/system_alerts/{0}".format(uuid)) + f"/core/system_alerts/{uuid}") return isamAppliance.create_return_object() diff --git a/ibmsecurity/isam/base/system_alerts/email.py b/ibmsecurity/isam/base/system_alerts/email.py index 8e8a0f97..5fe97caa 100644 --- a/ibmsecurity/isam/base/system_alerts/email.py +++ b/ibmsecurity/isam/base/system_alerts/email.py @@ -17,7 +17,7 @@ def get(isamAppliance, uuid, check_mode=False, force=False): Get a specific email object """ return isamAppliance.invoke_get("Get a specific email object", - "/core/rsp_email_objs/{0}".format(uuid)) + f"/core/rsp_email_objs/{uuid}") def add(isamAppliance, name, smtpServer, from_email, to_email, smtpPort=25, objType='email', @@ -59,7 +59,7 @@ def update(isamAppliance, uuid, name, smtpServer, from_email, to_email, smtpPort else: return isamAppliance.invoke_put( "Update a specific email object", - "/core/rsp_email_objs/{0}".format(uuid), + f"/core/rsp_email_objs/{uuid}", { 'name': name, 'uuid': uuid, @@ -84,7 +84,7 @@ def delete(isamAppliance, uuid, check_mode=False, force=False): else: return isamAppliance.invoke_delete( "Delete an email object", - "/core/rsp_email_objs/{0}".format(uuid)) + f"/core/rsp_email_objs/{uuid}") return isamAppliance.create_return_object() diff --git a/ibmsecurity/isam/base/system_alerts/logdb.py b/ibmsecurity/isam/base/system_alerts/logdb.py index c362676c..73bcdead 100644 --- a/ibmsecurity/isam/base/system_alerts/logdb.py +++ b/ibmsecurity/isam/base/system_alerts/logdb.py @@ -17,7 +17,7 @@ def get(isamAppliance, uuid, check_mode=False, force=False): Get a specific logdb object """ return isamAppliance.invoke_get("Get a specific logdb object", - "/core/rsp_logdb_objs/{0}".format(uuid)) + f"/core/rsp_logdb_objs/{uuid}") def add(isamAppliance, name, aclEventsAllocation, ipsEventsAllocation, sysEventsAllocation, objType='logdb', @@ -60,7 +60,7 @@ def update(isamAppliance, name, uuid, aclEventsAllocation, ipsEventsAllocation, else: return isamAppliance.invoke_put( "Update a specific logdb object", - "/core/rsp_logdb_objs/{0}".format(uuid), + f"/core/rsp_logdb_objs/{uuid}", { 'name': name, 'uuid': uuid, @@ -86,7 +86,7 @@ def delete(isamAppliance, uuid, check_mode=False, force=False): else: return isamAppliance.invoke_delete( "Delete a logdb object", - "/core/rsp_logdb_objs/{0}".format(uuid)) + f"/core/rsp_logdb_objs/{uuid}") return isamAppliance.create_return_object() diff --git a/ibmsecurity/isam/base/system_alerts/rsyslog.py b/ibmsecurity/isam/base/system_alerts/rsyslog.py index c30be26c..a417f25a 100644 --- a/ibmsecurity/isam/base/system_alerts/rsyslog.py +++ b/ibmsecurity/isam/base/system_alerts/rsyslog.py @@ -17,7 +17,7 @@ def get(isamAppliance, uuid, check_mode=False, force=False): Get a specific rsyslog object """ return isamAppliance.invoke_get("Get a specific rsyslog object", - "/core/rsp_rsyslog_objs/{0}".format(uuid)) + f"/core/rsp_rsyslog_objs/{uuid}") def add(isamAppliance, name, collector, collectorPort=514, collectorLeef=False, objType='rsyslog', comment='', @@ -58,7 +58,7 @@ def update(isamAppliance, uuid, name, collector, collectorPort=514, collectorLee else: return isamAppliance.invoke_put( "Update a specific rsyslog object", - "/core/rsp_rsyslog_objs/{0}".format(uuid), + f"/core/rsp_rsyslog_objs/{uuid}", { 'name': name, 'uuid': uuid, @@ -82,7 +82,7 @@ def delete(isamAppliance, uuid, check_mode=False, force=False): else: return isamAppliance.invoke_delete( "Delete a rsyslog object", - "/core/rsp_rsyslog_objs/{0}".format(uuid)) + f"/core/rsp_rsyslog_objs/{uuid}") return isamAppliance.create_return_object() diff --git a/ibmsecurity/isam/base/system_alerts/snmp.py b/ibmsecurity/isam/base/system_alerts/snmp.py index 9d488130..b061c80e 100644 --- a/ibmsecurity/isam/base/system_alerts/snmp.py +++ b/ibmsecurity/isam/base/system_alerts/snmp.py @@ -17,7 +17,7 @@ def get(isamAppliance, uuid, check_mode=False, force=False): Get a specific snmp object """ return isamAppliance.invoke_get("Get a specific snmp object", - "/core/rsp_snmp_objs/{0}".format(uuid)) + f"/core/rsp_snmp_objs/{uuid}") def add(isamAppliance, name, trapAddress, trapCommunity, trapNotificationType=None, trapVersion='V1', trapPort=162, @@ -78,7 +78,7 @@ def update(isamAppliance, uuid, name, trapAddress, trapCommunity, trapNotificati else: return isamAppliance.invoke_put( "Update a specific snmp object", - "/core/rsp_snmp_objs/{0}".format(uuid), + f"/core/rsp_snmp_objs/{uuid}", { 'name': name, 'uuid': uuid, @@ -113,7 +113,7 @@ def delete(isamAppliance, uuid, check_mode=False, force=False): else: return isamAppliance.invoke_delete( "Delete a snmp object", - "/core/rsp_snmp_objs/{0}".format(uuid)) + f"/core/rsp_snmp_objs/{uuid}") return isamAppliance.create_return_object() diff --git a/ibmsecurity/isam/base/update_servers.py b/ibmsecurity/isam/base/update_servers.py index 898fd64b..021c3a53 100644 --- a/ibmsecurity/isam/base/update_servers.py +++ b/ibmsecurity/isam/base/update_servers.py @@ -25,7 +25,7 @@ def get(isamAppliance, name, check_mode=False, force=False): us_id = ret_obj['data'] if us_id == {}: - logger.info("Update Server {0} had no match, skipping retrieval.".format(name)) + logger.info(f"Update Server {name} had no match, skipping retrieval.") return isamAppliance.create_return_object() else: return _get(isamAppliance, us_id) @@ -33,7 +33,7 @@ def get(isamAppliance, name, check_mode=False, force=False): def _get(isamAppliance, us_id): return isamAppliance.invoke_get("Retrieve a specific update server", - "{0}/{1}".format(uri, us_id)) + f"{uri}/{us_id}") def search(isamAppliance, name, force=False, check_mode=False): @@ -45,7 +45,7 @@ def search(isamAppliance, name, force=False, check_mode=False): for obj in ret_obj['data']['luServers']: if obj['name'] == name: - logger.info("Found Update Server {0} id: {1}".format(name, obj['uuid'])) + logger.info(f"Found Update Server {name} id: {obj['uuid']}") return_obj['data'] = obj['uuid'] return_obj['rc'] = 0 @@ -60,12 +60,12 @@ def set(isamAppliance, priority, name, enabled, hostName, port, trustLevel, useP """ if (search(isamAppliance, name=name))['data'] == {}: # Force the add - we already know update server does not exist - logger.info("Update Server {0} had no match, requesting to add new one.".format(name)) + logger.info(f"Update Server {name} had no match, requesting to add new one.") return add(isamAppliance, priority, name, enabled, hostName, port, trustLevel, useProxy, useProxyAuth, cert, proxyHost, proxyPort, proxyUser, proxyPwd, check_mode, True) else: # Update request - logger.info("Update Server {0} exists, requesting to update.".format(name)) + logger.info(f"Update Server {name} exists, requesting to update.") return update(isamAppliance, priority, name, enabled, hostName, port, trustLevel, useProxy, useProxyAuth, cert, proxyHost, proxyPort, proxyUser, proxyPwd, new_name, check_mode, force) @@ -114,7 +114,7 @@ def update(isamAppliance, priority, name, enabled, hostName, port, trustLevel, u if check_mode is True: return isamAppliance.create_return_object(changed=True) else: - return isamAppliance.invoke_put("Update an update server", "{0}/{1}".format(uri, us_id), json_data, + return isamAppliance.invoke_put("Update an update server", f"{uri}/{us_id}", json_data, requires_modules=requires_modules, requires_version=requires_version) @@ -149,9 +149,9 @@ def _check(isamAppliance, priority, name, enabled, hostName, port, trustLevel, u json_data['name'] = name del ret_obj['data']['uuid'] sorted_json_data = ibmsecurity.utilities.tools.json_sort(json_data) - logger.debug("Sorted input: {0}".format(sorted_json_data)) + logger.debug(f"Sorted input: {sorted_json_data}") sorted_ret_obj = ibmsecurity.utilities.tools.json_sort(ret_obj['data']) - logger.debug("Sorted existing data: {0}".format(sorted_ret_obj)) + logger.debug(f"Sorted existing data: {sorted_ret_obj}") if sorted_ret_obj != sorted_json_data: logger.info("Changes detected, update needed.") update_required = True @@ -167,7 +167,7 @@ def enable(isamAppliance, name, enabled, check_mode=False, force=False): ret_obj = get(isamAppliance=isamAppliance, name=name) if ret_obj['data'] == {}: - warnings.append("Update Server {0} not found.".format(name)) + warnings.append(f"Update Server {name} not found.") elif force is True or enabled != ret_obj['data']['enabled']: logger.debug("Enable flag needs to be updated!") return update(isamAppliance, priority=ret_obj['data']['priority'], name=name, enabled=enabled, @@ -192,9 +192,9 @@ def delete(isamAppliance, name, check_mode=False, force=False): if check_mode is True: return isamAppliance.create_return_object(changed=True) else: - return isamAppliance.invoke_delete("Delete an Update Server", "{0}/{1}".format(uri, ret_obj['data'])) + return isamAppliance.invoke_delete("Delete an Update Server", f"{uri}/{ret_obj['data']}") else: - logger.info("Update Server: {0} not found, delete skipped.".format(name)) + logger.info(f"Update Server: {name} not found, delete skipped.") return isamAppliance.create_return_object() From 76b8813d6569c71901f332167ff8b602377ca561 Mon Sep 17 00:00:00 2001 From: Tom Bosmans Date: Wed, 28 May 2025 16:26:45 +0200 Subject: [PATCH 45/54] fix: pylint --- ibmsecurity/utilities/tools.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ibmsecurity/utilities/tools.py b/ibmsecurity/utilities/tools.py index 9e7caf4e..9bbd9a23 100644 --- a/ibmsecurity/utilities/tools.py +++ b/ibmsecurity/utilities/tools.py @@ -9,6 +9,8 @@ from io import open import zipfile import json +import os +import tempfile logger = logging.getLogger(__name__) @@ -237,8 +239,6 @@ def get_random_temp_dir(): """ Create a temporary directory """ - import os - import tempfile tmpdir = tempfile.gettempdir() random_str = random_password(10, allow_special=False) tmpdir += '/%s' % random_str From 8ed4cbcf10c23f22146f0446946533ba3c8308e2 Mon Sep 17 00:00:00 2001 From: Tom Bosmans Date: Wed, 28 May 2025 16:28:31 +0200 Subject: [PATCH 46/54] fix: pylint format -> f-string --- ibmsecurity/utilities/tools.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/ibmsecurity/utilities/tools.py b/ibmsecurity/utilities/tools.py index 9bbd9a23..dc070809 100644 --- a/ibmsecurity/utilities/tools.py +++ b/ibmsecurity/utilities/tools.py @@ -176,9 +176,9 @@ def create_query_string(**kwargs): query_str = '?' else: query_str += '&' - query_str += "{0}={1}".format(key, kwargs[key]) + query_str += f"{key}={kwargs[key]}" - logger.debug("Query Parameter to be used: {0}".format(query_str)) + logger.debug(f"Query Parameter to be used: {query_str}") return query_str @@ -203,18 +203,18 @@ def files_same(original_file, new_file): def files_same_zip_content(original_file, new_file): identical = True - logger.debug("Comparing original_file[{}] vs new_file[{}]".format(original_file, new_file)) + logger.debug(f"Comparing original_file[{original_file}] vs new_file[{new_file}]") z1 = zipfile.ZipFile(original_file) z2 = zipfile.ZipFile(new_file) if len(z1.infolist()) != len(z2.infolist()): - logger.debug("number of archive elements differ: {} in {} vs {} from server".format(len(z1.infolist()), z1.filename, len(z2.infolist()))) + logger.debug(f"number of archive elements differ: {len(z1.infolist())} in {z1.filename} vs {len(z2.infolist())} from server") identical = False # Can stop comparison of zip files for perfomance return identical for zipentry in z1.infolist(): if zipentry.filename not in z2.namelist(): - logger.debug("no file named {} found in {}".format(zipentry.filename, z2.filename)) + logger.debug(f"no file named {zipentry.filename} found in {z2.filename}") identical = False else: with z1.open(zipentry.filename) as f: @@ -225,12 +225,12 @@ def files_same_zip_content(original_file, new_file): hash_new_file = hashlib.sha224(new_file_contents).hexdigest() if hash_original_file != hash_new_file: identical = False - logger.debug("content for zip file {} differs.".format(zipentry.filename)) + logger.debug(f"content for zip file {zipentry.filename} differs.") if identical: - logger.info("content for zip files {} and {} are the same.".format(original_file,new_file)) + logger.info(f"content for zip files {original_file} and {new_file} are the same.") else: - logger.info("content for zip files {} and {} are different.".format(original_file,new_file)) + logger.info(f"content for zip files {original_file} and {new_file} are different.") return identical @@ -241,7 +241,7 @@ def get_random_temp_dir(): """ tmpdir = tempfile.gettempdir() random_str = random_password(10, allow_special=False) - tmpdir += '/%s' % random_str + tmpdir += f'/{random_str}' os.mkdir(tmpdir) return tmpdir From 7ee13c9911396196764cf6f76b9f5559e0c198de Mon Sep 17 00:00:00 2001 From: Tom Bosmans Date: Wed, 28 May 2025 17:06:53 +0200 Subject: [PATCH 47/54] fix: ignore error --- ibmsecurity/isam/base/admin_ssh_keys.py | 28 +++++++++++++------------ ibmsecurity/pytest/__init__.py | 0 2 files changed, 15 insertions(+), 13 deletions(-) delete mode 100644 ibmsecurity/pytest/__init__.py diff --git a/ibmsecurity/isam/base/admin_ssh_keys.py b/ibmsecurity/isam/base/admin_ssh_keys.py index 0f722b70..5e0d34bb 100644 --- a/ibmsecurity/isam/base/admin_ssh_keys.py +++ b/ibmsecurity/isam/base/admin_ssh_keys.py @@ -13,13 +13,6 @@ def get_all(isamAppliance, check_mode=False, force=False): return isamAppliance.invoke_get("Retrieving keys", "/admin_cfg/ssh-keys/v1") -def get(isamAppliance, uuid, check_mode=False, force=False): - """ - Get specific ssh public key for the default admin user - """ - return isamAppliance.invoke_get("Retrieving key", f"/admin_cfg/ssh-keys/{uuid}/v1") - - def get(isamAppliance, name=None, uuid=None, check_mode=False, force=False): """ Get specific ssh key for admin user @@ -43,26 +36,35 @@ def get(isamAppliance, name=None, uuid=None, check_mode=False, force=False): raise IBMError("999", "Cannot get the ssh keys for the administrator. Provide exactly 1 of the parameters uuid or name") -def add(isamAppliance, key, name, check_mode=False, force=False): +def add(isamAppliance, key=None, name=None, check_mode=False, force=False): """ Import ssh public key for the default admin user """ + warnings = [] if force or not _check(isamAppliance, name): if check_mode: return isamAppliance.create_return_object(changed=True, warnings=warnings) else: - return isamAppliance.invoke_post( + retObj = isamAppliance.invoke_post( "Import ssh key", "/admin_cfg/ssh-keys/v1", { 'key': key, 'name': name - }) + }, + ignore_error=True), - return isamAppliance.create_return_object() + # On error 400, this message: A SSH Key with this fingerprint already exists. + + logger.debug(retObj) + + if retObj[0].get('rc', -1) == 400: + warnings.append(f"{retObj[0].get('data', {}).get('message', 'unknown error')}") + + return isamAppliance.create_return_object(warnings=warnings) create = add -def update(isamAppliance, key, name, check_mode=False, force=False): +def update(isamAppliance, key=None, name=None, check_mode=False, force=False): """ Update an existing key """ @@ -88,7 +90,7 @@ def update(isamAppliance, key, name, check_mode=False, force=False): return isamAppliance.create_return_object() -def set(isamAppliance, key, name, fingerprint=None, check_mode=False, force=False): +def set(isamAppliance, key=None, name=None, fingerprint=None, check_mode=False, force=False): """ Create key if it does not exist yet, update if it does. diff --git a/ibmsecurity/pytest/__init__.py b/ibmsecurity/pytest/__init__.py deleted file mode 100644 index e69de29b..00000000 From d2292fb6c2f7107d922d7ce2767e7a8dbc1a2fca Mon Sep 17 00:00:00 2001 From: Tom Bosmans Date: Wed, 28 May 2025 17:07:16 +0200 Subject: [PATCH 48/54] feature: test for admin ssh keys --- test/test_base_admin_ssh.py | 57 +++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 test/test_base_admin_ssh.py diff --git a/test/test_base_admin_ssh.py b/test/test_base_admin_ssh.py new file mode 100644 index 00000000..78e19fc5 --- /dev/null +++ b/test/test_base_admin_ssh.py @@ -0,0 +1,57 @@ +import logging + +import ibmsecurity.isam.base.admin_ssh_keys +import ibmsecurity.isam.appliance + +import pytest + +def getTestData(): + testdata = [ + { + "name": "workstation", + "key": "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILNvMjSUx0YEPNw0eAsHUERYl244CQfVWqCOTfo4joCe workstation" + }, + { + "name": "testuser", + "key": "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILNvMjSUx0YEPNw0eAsHUERYl244CQfVWqCOTfo4joCe workstation", + "fingerprint": "256 SHA256:kbJ4H0/nm7O5GdPNkXsNrG+oTlcaARU6ro64h3Y5WMY workstation (ED25519)" + } + ] + return testdata + + +def test_get_admin_sshkeys(iviaServer, caplog) -> None: + """Get sms protection""" + caplog.set_level(logging.DEBUG) + arg = {} + + returnValue = ibmsecurity.isam.base.admin_ssh_keys.get_all(iviaServer, + **arg + ) + logging.log(logging.INFO, returnValue) + + assert not returnValue.failed() + + +@pytest.mark.parametrize("items", getTestData()) +def test_set_admin_sshkeys(iviaServer, caplog, items) -> None: + """Set admin ssh keys""" + caplog.set_level(logging.DEBUG) + # items is a key-value pair + logging.log(logging.INFO, items) + arg = {} + for k, v in items.items(): + #if k == 'name': + # name = v + # continue + #if k == 'key': + # key = v + # continue + arg[k] = v + + returnValue = ibmsecurity.isam.base.admin_ssh_keys.set(iviaServer, **arg) + + logging.log(logging.INFO, returnValue) + + if returnValue is not None: + assert not returnValue.failed() From ddb5c94f9a8a8c6d9d739c60b77871085d1969be Mon Sep 17 00:00:00 2001 From: Tom Bosmans Date: Wed, 28 May 2025 17:18:37 +0200 Subject: [PATCH 49/54] fix: small updates, and test --- .../base/application_database_settings.py | 2 + ibmsecurity/isam/base/application_locale.py | 3 ++ test/test_base_application_locale.py | 51 +++++++++++++++++++ 3 files changed, 56 insertions(+) create mode 100644 test/test_base_application_locale.py diff --git a/ibmsecurity/isam/base/application_database_settings.py b/ibmsecurity/isam/base/application_database_settings.py index a0db9749..fc61c3e1 100644 --- a/ibmsecurity/isam/base/application_database_settings.py +++ b/ibmsecurity/isam/base/application_database_settings.py @@ -8,6 +8,8 @@ logger = logging.getLogger(__name__) +# TODO: DEPRECATED + # URI for this module uri = "/core/dca_updates_cfg" requires_modules = None diff --git a/ibmsecurity/isam/base/application_locale.py b/ibmsecurity/isam/base/application_locale.py index 8299ed86..5a608709 100644 --- a/ibmsecurity/isam/base/application_locale.py +++ b/ibmsecurity/isam/base/application_locale.py @@ -30,3 +30,6 @@ def update(isamAppliance, id, check_mode=False, force=False): ) return isamAppliance.create_return_object() + + +set = update diff --git a/test/test_base_application_locale.py b/test/test_base_application_locale.py new file mode 100644 index 00000000..a418687a --- /dev/null +++ b/test/test_base_application_locale.py @@ -0,0 +1,51 @@ +import logging + +import ibmsecurity.isam.base.application_locale +import ibmsecurity.isam.appliance + +import pytest + +def getTestData(): + testdata = [ + {"id": "en_US.utf8"} + + ] + return testdata + + +def test_get_log_language(iviaServer, caplog) -> None: + """Get sms protection""" + caplog.set_level(logging.DEBUG) + arg = {} + + returnValue = ibmsecurity.isam.base.application_locale.get(iviaServer, + **arg + ) + logging.log(logging.INFO, returnValue) + + assert not returnValue.failed() + + +@pytest.mark.parametrize("items", getTestData()) +def test_set_locale(iviaServer, caplog, items) -> None: + """Set admin ssh keys""" + caplog.set_level(logging.DEBUG) + # items is a key-value pair + logging.log(logging.INFO, items) + arg = {} + + for k, v in items.items(): + #if k == 'id': + # id = v + # continue + #if k == 'key': + # key = v + # continue + arg[k] = v + + returnValue = ibmsecurity.isam.base.application_locale.set(iviaServer, **arg) + + logging.log(logging.INFO, returnValue) + + if returnValue is not None: + assert not returnValue.failed() From cad55bec07e8b0961f93d2f82d34dd4f6165999a Mon Sep 17 00:00:00 2001 From: Tom Bosmans Date: Wed, 28 May 2025 17:19:51 +0200 Subject: [PATCH 50/54] documentation: update pylint and changelog --- changelog.md | 2 ++ pylintrc | 18 +++++++++++++----- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/changelog.md b/changelog.md index fc10a60e..be366e99 100644 --- a/changelog.md +++ b/changelog.md @@ -7,6 +7,8 @@ - feature: web/reverse_proxy/oauth_configuration.py - add new parameters in 10.0.8 - feature: web/reverse_proxy/oauth2_configuration.py - OAuth2 IBM Security Verify OIDC Provider configuration (new in 10.0.4) - feature: aac/server_connections/sms.py - SMS Server Connection (new in 10.0.8) +- fix: base/admin_ssh_keys.py - Ignore error when same ssh key exists under different name +- pylint: change format() to f-strings ## 2025.3.28.0 diff --git a/pylintrc b/pylintrc index 9572874e..493f67fd 100644 --- a/pylintrc +++ b/pylintrc @@ -290,7 +290,7 @@ exclude-too-few-public-methods= ignored-parents= # Maximum number of arguments for function / method. -max-args=5 +max-args=50 # Maximum number of attributes for a class (see R0902). max-attributes=7 @@ -302,13 +302,13 @@ max-bool-expr=5 max-branches=12 # Maximum number of locals for function / method body. -max-locals=15 +max-locals=25 # Maximum number of parents for a class (see R0901). max-parents=7 # Maximum number of positional arguments for function / method. -max-positional-arguments=5 +max-positional-arguments=50 # Maximum number of public methods for a class (see R0904). max-public-methods=20 @@ -320,7 +320,7 @@ max-returns=6 max-statements=50 # Minimum number of public methods for a class (see R0903). -min-public-methods=2 +min-public-methods=1 [EXCEPTIONS] @@ -453,7 +453,15 @@ disable=all # multiple time (only on the command line, not in the configuration file where # it should appear only once). See also the "--disable" option for examples. #enable=R1705 -enable=C0209 +enable=C0209, + W1304, + async, + design, + nonascii-checker, + imports + + + [METHOD_ARGS] From 10fe5b474b46aa671e0d4f3c81d6c5a50d990b90 Mon Sep 17 00:00:00 2001 From: Tom Bosmans Date: Wed, 28 May 2025 17:21:22 +0200 Subject: [PATCH 51/54] documentation: move changelog into docs --- changelog.md => docs/changelog.md | 0 mkdocs.yml | 2 ++ 2 files changed, 2 insertions(+) rename changelog.md => docs/changelog.md (100%) diff --git a/changelog.md b/docs/changelog.md similarity index 100% rename from changelog.md rename to docs/changelog.md diff --git a/mkdocs.yml b/mkdocs.yml index 4d01abe1..07860594 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -19,3 +19,5 @@ nav: - home: index.md - Developer Guide: - Contributing: contributing.md + - Changelog: + - Changelog: changelog.md From ac371fb0fbd295a4871162cbf5293973027913de Mon Sep 17 00:00:00 2001 From: Tom Bosmans Date: Wed, 28 May 2025 17:23:05 +0200 Subject: [PATCH 52/54] documentation: update .gitignore (exlcude reports) --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index ab125e3d..5083963e 100644 --- a/.gitignore +++ b/.gitignore @@ -44,6 +44,8 @@ nosetests.xml coverage.xml *,cover .hypothesis/ +report.txt +report_.*.txt # Translations *.mo From 8992db87ab108125909b72a854ca2c3765257bc5 Mon Sep 17 00:00:00 2001 From: Tom Bosmans Date: Wed, 28 May 2025 17:37:26 +0200 Subject: [PATCH 53/54] feature: tracing configuration (new in 10.0.8) --- docs/changelog.md | 1 + ibmsecurity/isam/base/tracing.py | 22 ++++++++++++++++++++++ test/test_base_tracing.py | 22 ++++++++++++++++++++++ 3 files changed, 45 insertions(+) create mode 100644 ibmsecurity/isam/base/tracing.py create mode 100644 test/test_base_tracing.py diff --git a/docs/changelog.md b/docs/changelog.md index be366e99..9bcb3f98 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -9,6 +9,7 @@ - feature: aac/server_connections/sms.py - SMS Server Connection (new in 10.0.8) - fix: base/admin_ssh_keys.py - Ignore error when same ssh key exists under different name - pylint: change format() to f-strings +- feature: base/tracing.py - Get tracing configuration (new in 10.0.8) ## 2025.3.28.0 diff --git a/ibmsecurity/isam/base/tracing.py b/ibmsecurity/isam/base/tracing.py new file mode 100644 index 00000000..db3c83bc --- /dev/null +++ b/ibmsecurity/isam/base/tracing.py @@ -0,0 +1,22 @@ +import logging +import ibmsecurity.utilities.tools + +logger = logging.getLogger(__name__) + +# URI for this module +uri = "/isam/tracing" +requires_modules = None +requires_version = "10.0.8.0" +warnings=[] + +def get(isamAppliance, full_list=False, deployed_policy=False, check_mode=False, force=False): + """ + Get tracing settings + """ + full_uri = uri + ibmsecurity.utilities.tools.create_query_string(full_list=str(full_list).lower(), deployed_policy=str(deployed_policy).lower()) + logger.debug(f"{full_uri}") + return isamAppliance.invoke_get("Get tracing", + full_uri, + requires_modules=requires_modules, + requires_version=requires_version, + warnings=warnings) diff --git a/test/test_base_tracing.py b/test/test_base_tracing.py new file mode 100644 index 00000000..278babe6 --- /dev/null +++ b/test/test_base_tracing.py @@ -0,0 +1,22 @@ +import logging + +import ibmsecurity.isam.base.tracing +import ibmsecurity.isam.appliance + +import pytest + + + + +def test_get_tracing(iviaServer, caplog) -> None: + """Get sms protection""" + caplog.set_level(logging.DEBUG) + arg = {} + + returnValue = ibmsecurity.isam.base.tracing.get(iviaServer, + full_list=True, + deployed_policy=True + ) + logging.log(logging.INFO, returnValue) + + assert not returnValue.failed() From 78c30e3e4af7ee6e98078b269cb6a879a5eac0b6 Mon Sep 17 00:00:00 2001 From: Tom Bosmans Date: Mon, 2 Jun 2025 08:52:45 +0200 Subject: [PATCH 54/54] documentation: wip --- docs/index.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/docs/index.md b/docs/index.md index 5924d452..2c6cd925 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,7 +1,5 @@ # IBMSecurity Documentation -## THIS IS WORK IN PROGRESS - ## About ibmsecurity This repository contains Python code to manage IBM Security Appliances using their respective REST APIs.