network/library/network_state.py
Rich Megginson e4d499763c ci: Use supported ansible-lint action; run ansible-lint against the collection
The old ansible-community ansible-lint is deprecated.  There is a
new ansible-lint github action.  The new ansible-lint has several checks
related to ansible-test and the ignore files.  Many of our ignore settings
are not allowed any more and are required to be fixed or addressed in the
Ansible preferred way.

The python imports have to be wrapped in a try/except ImportError, and
where possible, an error must be returned from the module explaining
what was not able to be imported.

The module documentation must comply with the Ansible standards.  One
aspect of this is the `version_added` must be a valid ansible-core
version in X.Y.Z format.  Note that this version isn't really used
anywhere, so it doesn't matter for users of the role, it is purely
an `ansible-test` and import gating issue.

The result of this is that the .sanity files can be reduced to the
bare minimum which will greatly reduce the maintenance burden of
those files, make it easier to support newer versions of Ansible,
and make it easier to import the system roles collection into Galaxy
and Automation Hub.

The latest Ansible repo gating tests run ansible-lint against
the collection format instead of against individual roles.
We have to convert the role to collection format before running
ansible-test.

Role developers can run this locally using
`tox -e collection,ansible-lint-collection`
See https://github.com/linux-system-roles/tox-lsr/pull/125

Add `---` doc start to .markdownlint.yaml

The file `examples/down_profile+delete_interface.yml`
was not used and was causing ansible-lint errors.

ansible-lint enforces the order of keywords in plays - `name`,
then `hosts`, then `vars`, then `tasks`.

Signed-off-by: Rich Megginson <rmeggins@redhat.com>
2024-01-05 17:36:07 -07:00

112 lines
2.7 KiB
Python

#!/usr/bin/python
# -*- coding: utf-8 -*-
# SPDX-License-Identifier: BSD-3-Clause
from __future__ import absolute_import, division, print_function
__metaclass__ = type
DOCUMENTATION = r"""
---
module: network_state
version_added: "2.13.0"
short_description: module for network role to apply network state configuration
description:
- This module allows to apply the network state configuration through nmstate,
https://github.com/nmstate/nmstate
options:
desired_state:
description: Nmstate state definition
required: true
type: dict
author: "Wen Liang (@liangwen12year)"
"""
EXAMPLES = r"""
network_state:
desired_state:
dns-resolver:
config:
search:
- example.com
- example.org
server:
- 2001:4860:4860::8888
- 8.8.8.8
"""
RETURN = r"""
state:
description: Network state after running the module
type: dict
returned: always
"""
import traceback
from ansible.module_utils.basic import AnsibleModule, missing_required_lib
try:
import libnmstate # pylint: disable=import-error
except ImportError:
NETWORK_HAS_NMSTATE = False
NETWORK_NMSTATE_IMPORT_ERROR = traceback.format_exc()
else:
NETWORK_HAS_NMSTATE = True
NETWORK_NMSTATE_IMPORT_ERROR = None
class NetworkState:
def __init__(self, module, module_name):
self.module = module
self.params = module.params
self.result = dict(changed=False)
self.module_name = module_name
self.previous_state = self.get_state_config()
def run(self):
desired_state = self.params["desired_state"]
libnmstate.apply(desired_state)
current_state = self.get_state_config()
if current_state != self.previous_state:
self.result["changed"] = True
self.result["state"] = current_state
self.module.exit_json(**self.result)
def get_state_config(self):
if hasattr(libnmstate, "show_running_config") and callable(
getattr(libnmstate, "show_running_config")
):
state_config = libnmstate.show_running_config()
else:
state_config = libnmstate.show()
return state_config
def run_module():
module_args = dict(
desired_state=dict(type="dict", required=True),
)
module = AnsibleModule(
argument_spec=module_args,
)
if not NETWORK_HAS_NMSTATE:
module.fail_json(
msg=missing_required_lib("libnmstate"),
exception=NETWORK_NMSTATE_IMPORT_ERROR,
)
network_state_module = NetworkState(module, "network_state")
network_state_module.run()
def main():
run_module()
if __name__ == "__main__":
main()