varlink: Drop varlink support
As part of our efforts to reduce dependencies, we would like to drop the support of varlink. This is going to be dropped but if we get user requests we can introduce it again. Signed-off-by: Fernando Fernandez Mancera <ffmancera@riseup.net>
This commit is contained in:
parent
3a9825ffe8
commit
ce1a4b82d8
@ -37,7 +37,7 @@ querying network status and applying network states.
|
||||
|
||||
- `./libnmstate/schemas/` Contains the API schema file.
|
||||
|
||||
- `./nmstatectl/` - Contains command lines tools and varlink service.
|
||||
- `./nmstatectl/` - Contains command lines tools.
|
||||
|
||||
- `./packaging/` - Contains packaging utilities.
|
||||
|
||||
|
@ -21,7 +21,6 @@ nmstatectl \- A nmstate command line tool
|
||||
.br
|
||||
.B nmstatectl version
|
||||
.br
|
||||
.B nmstatectl varlink \fR[\fIUNIX_FILE_SOCKET_PATH\fR]
|
||||
.SH DESCRIPTION
|
||||
.B nmstatectl\fR is created for users who want to try out nmstate without using
|
||||
\fIlibnmstate\fR.
|
||||
@ -113,15 +112,6 @@ checkpoint if not defined as argument.
|
||||
displays nmstate version.
|
||||
.RE
|
||||
.PP
|
||||
.B varlink
|
||||
.RS
|
||||
Initates the nmstate-varlink service in the specified unix file socket path
|
||||
supporting the libnmstate functions (Show, Apply, Commit and Rollback).
|
||||
This enables functions to be accessed via varlink command-line tool and client implementations.
|
||||
Currently the service is limited to using unix file socket address only.
|
||||
.PP
|
||||
example: nmstatectl varlink /run/nmstate.so &
|
||||
.PP
|
||||
.RE
|
||||
.SH OPTIONS
|
||||
.B --json
|
||||
|
@ -1,154 +0,0 @@
|
||||
# Varlink support for libnmstate
|
||||
Varlink protocol ([Varlink.org](https://varlink.org/)) can used to communicate with libnmstate via stdin/out and varlink client implementation ([Existing Language binding](https://varlink.org/Language-Bindings#how-to-test-new-language-bindings)). Varlink protocol encodes all messages as JSON object and communicates over unix and tcp socket connections. Nmstate service is defined in io.nmstate interface address and libnmstate functions should called in as specified in varlink interface defination file `io.nmstate.varlink`. This implementation supports python3-varlink version 29.0.0 and unix socket connection only.
|
||||
|
||||
|
||||
## Initiate nmstate varlink service
|
||||
User can initate nmstate-varlink services using ```nmstatectl``` command-line tool by defining the unix socket address path. The current nmstate-varlink implementation limits only using unix sockets connection.
|
||||
|
||||
unix socket connection
|
||||
```bash
|
||||
$ sudo nmstatectl varlink /run/nmstate.so &
|
||||
```
|
||||
|
||||
Nmstate-varlink systemd services default listening address is ```unix:/run/nmstate/nmstate.so```
|
||||
systemd service initiation
|
||||
|
||||
```bash
|
||||
$ sudo systemctl start nmstate-varlink.service
|
||||
```
|
||||
|
||||
After the `io.nmstate` interface is resolved using varlink resolver. Methods can be called directly via stdin/out without specifying the connection.
|
||||
`varlink call io.nmstate.Show`
|
||||
|
||||
## Nmstate basic operations using varlink
|
||||
The basic functions from libnmstate (show, apply, commit and rollback) are called via varlink interface. Passing inputs to the functions only support JSON format. Below are the examples for each basic functions using varlink stdin/out and varlink client.
|
||||
|
||||
Using libnmstate show function via varlink (query network state)
|
||||
|
||||
Required for varlink stdin/out operation
|
||||
|
||||
```bash
|
||||
$ sudo dnf install libvarlink-util
|
||||
```
|
||||
|
||||
Varlink stdin/out:
|
||||
```bash
|
||||
$ sudo varlink call unix:/run/nmstate.so/io.nmstate.Show
|
||||
```
|
||||
|
||||
Varlink python client:
|
||||
```python
|
||||
import varlink
|
||||
|
||||
with varlink.Client("unix:/run/nmstate.so").open("io.nmstate") as nmstate:
|
||||
nmstate.Show()
|
||||
```
|
||||
|
||||
JSON output: libnmstate current network is reported under "state" object.
|
||||
```json
|
||||
{
|
||||
"log": [
|
||||
{
|
||||
"level": "DEBUG",
|
||||
"message": "Async action: Retrieve applied config: foo started",
|
||||
"time": "2020-08-05 10:22:19"
|
||||
},
|
||||
{
|
||||
"level": "DEBUG",
|
||||
"message": "Async action: Retrieve applied config: foo finished",
|
||||
"time": "2020-08-05 10:22:19"
|
||||
}
|
||||
|
||||
],
|
||||
"state": {
|
||||
"dns-resolver": {
|
||||
"config": {
|
||||
"search": [],
|
||||
"server": []
|
||||
},
|
||||
"running": {}
|
||||
},
|
||||
"interfaces": [
|
||||
{
|
||||
"ipv4": {
|
||||
"enabled": false
|
||||
},
|
||||
"ipv6": {
|
||||
"enabled": false
|
||||
},
|
||||
"lldp": {
|
||||
"enabled": false
|
||||
},
|
||||
"mac-address": "36:66:98:1D:6A:C8",
|
||||
"mtu": 1500,
|
||||
"name": "eth0",
|
||||
"state": "down",
|
||||
"type": "ethernet"
|
||||
},
|
||||
],
|
||||
"route-rules": {
|
||||
"config": []
|
||||
},
|
||||
"routes": {
|
||||
"config": [],
|
||||
"running": []
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Using libnmstate apply function via varlink (query network state)
|
||||
|
||||
Varlink stdin/out:
|
||||
```bash
|
||||
$ sudo varlink call unix:/run/nmstate.so/io.nmstate.Apply '{"arguments": {"desired_state": {"interfaces": [{"name": "foo", "type": "dummy", "state": "up", "ipv4": {"enabled": false}, "ipv6": {"enabled": false}}]} } }'
|
||||
```
|
||||
* When using the varlink client it is not requried specify the "argument" parameter.
|
||||
|
||||
Varlink python client:
|
||||
```python
|
||||
import varlink
|
||||
|
||||
state = {'desired_state': {'interfaces': [{'name': 'foo', 'type': 'dummy', 'state': 'up', 'ipv4': {'enabled': False}, 'ipv6': {'enabled': False}}]} }
|
||||
|
||||
with varlink.Client("unix:/run/nmstate.so").open("io.nmstate") as nmstate:
|
||||
nmstate.Apply(state)
|
||||
```
|
||||
|
||||
## Error response
|
||||
All error nmstate messages are encoded as JSON object format. Errors are identified with specified varlink interface description
|
||||
|
||||
* Example shows format of the error raised via varlink stdin/out and varlink client calling Commit method with null value.
|
||||
|
||||
Varlink stdin/out:
|
||||
```bash
|
||||
Call failed with error: NmstateValueError
|
||||
{
|
||||
"error_message": "No checkpoint specified or found",
|
||||
"log": [
|
||||
{
|
||||
"level": "ERROR",
|
||||
"message": "No checkpoint specified or found",
|
||||
"name": "root",
|
||||
"time": "2020-07-31 15:16:22"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Varlink python client:
|
||||
```python
|
||||
varlink.error.VarlinkError: {
|
||||
'error': 'NmstateValueError',
|
||||
'parameters': {
|
||||
'error_message': 'No checkpoint specified or found',
|
||||
'log': [
|
||||
{
|
||||
'time': '2020-07-31 15:18:06',
|
||||
'level': 'ERROR',
|
||||
'message': 'No checkpoint specified or found'
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
@ -1,35 +0,0 @@
|
||||
#
|
||||
# Copyright (c) 2020 Red Hat, Inc.
|
||||
#
|
||||
# This file is part of nmstate
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation, either version 2.1 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
[Unit]
|
||||
Description= Varlink service of nmstate
|
||||
Documentation=https://www.nmstate.io/devel/libnmstate-varlink.html
|
||||
After=multi-user.target
|
||||
Requires=NetworkManager.service
|
||||
ConditionPathExists=/usr/bin/nmstatectl
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=root
|
||||
RuntimeDirectory=nmstate
|
||||
ExecStart=/usr/bin/nmstatectl varlink /run/nmstate/nmstate.so
|
||||
Restart=on-failure
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
@ -1,284 +0,0 @@
|
||||
#
|
||||
# Copyright (c) 2020 Red Hat, Inc.
|
||||
#
|
||||
# This file is part of nmstate
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation, either version 2.1 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
from contextlib import contextmanager
|
||||
import errno
|
||||
import logging
|
||||
import os
|
||||
|
||||
import libnmstate
|
||||
import libnmstate.error as libnmError
|
||||
|
||||
try:
|
||||
import varlink
|
||||
except ModuleNotFoundError:
|
||||
raise libnmError.NmstateDependencyError("python3 varlink module not found")
|
||||
|
||||
|
||||
class NmstateVarlinkLogHandler(logging.Handler):
|
||||
def __init__(self):
|
||||
self._log_records = list()
|
||||
super().__init__()
|
||||
|
||||
def filter(self, record):
|
||||
return True
|
||||
|
||||
def emit(self, record):
|
||||
self._log_records.append(record)
|
||||
|
||||
@property
|
||||
def logs(self):
|
||||
"""
|
||||
Return a list of dict, example:
|
||||
[
|
||||
{
|
||||
"time": "2003-07-08 16:49:45,896",
|
||||
"level": "DEBUG",
|
||||
"message": "foo is changed",
|
||||
}
|
||||
]
|
||||
"""
|
||||
return [
|
||||
{
|
||||
"time": record.asctime,
|
||||
"level": record.levelname,
|
||||
"message": record.message,
|
||||
}
|
||||
for record in self._log_records
|
||||
]
|
||||
|
||||
|
||||
@contextmanager
|
||||
def nmstate_varlink_logger():
|
||||
logger = logging.getLogger()
|
||||
logger.setLevel(logging.DEBUG)
|
||||
handler = NmstateVarlinkLogHandler()
|
||||
handler.setLevel(logging.DEBUG)
|
||||
logger.addHandler(handler)
|
||||
try:
|
||||
yield handler
|
||||
finally:
|
||||
logger.removeHandler(handler)
|
||||
|
||||
|
||||
def validate_method_arguments(user_args, method_args):
|
||||
"""
|
||||
Returns dictionary with validated arguments values.
|
||||
"""
|
||||
kwargs = {}
|
||||
for arg in user_args.keys():
|
||||
if arg not in method_args or user_args[arg] == {}:
|
||||
raise varlink.InvalidParameter(arg)
|
||||
if user_args[arg] is not None:
|
||||
kwargs[arg] = user_args[arg]
|
||||
return kwargs
|
||||
|
||||
|
||||
def gen_varlink_server(address):
|
||||
"""
|
||||
Returns varlink server object
|
||||
Checks if the varlink address already in use.
|
||||
"""
|
||||
address = "unix:" + address
|
||||
server = varlink.ThreadingServer(
|
||||
address, ServiceRequestHandler, bind_and_activate=False
|
||||
)
|
||||
server.allow_reuse_address = True
|
||||
try:
|
||||
server.server_bind()
|
||||
server.server_activate()
|
||||
except OSError as exception:
|
||||
server.shutdown()
|
||||
server.server_close()
|
||||
if exception.errno == errno.EADDRINUSE:
|
||||
server = varlink.ThreadingServer(
|
||||
address, ServiceRequestHandler, bind_and_activate=True
|
||||
)
|
||||
else:
|
||||
logging.error(exception.strerror)
|
||||
raise exception
|
||||
return server
|
||||
|
||||
|
||||
def start_varlink_server(address):
|
||||
"""
|
||||
Runs the varlink server in the specified the file path
|
||||
"""
|
||||
varlink_server = gen_varlink_server(address)
|
||||
try:
|
||||
with varlink_server as server:
|
||||
server.serve_forever()
|
||||
except Exception as exception:
|
||||
logging.error(str(exception))
|
||||
varlink_server.shutdown()
|
||||
finally:
|
||||
varlink_server.server_close()
|
||||
|
||||
|
||||
class NmstateError(varlink.VarlinkError):
|
||||
def __init__(self, message, logs):
|
||||
varlink.VarlinkError.__init__(
|
||||
self,
|
||||
{
|
||||
"error": self.__class__.__name__,
|
||||
"parameters": {
|
||||
"error_message": message,
|
||||
"log": logs,
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
class NmstateValueError(NmstateError):
|
||||
pass
|
||||
|
||||
|
||||
class NmstatePermissionError(NmstateError):
|
||||
pass
|
||||
|
||||
|
||||
class NmstateConflictError(NmstateError):
|
||||
pass
|
||||
|
||||
|
||||
class NmstateLibnmError(NmstateError):
|
||||
pass
|
||||
|
||||
|
||||
class NmstateVerificationError(NmstateError):
|
||||
pass
|
||||
|
||||
|
||||
class NmstateNotImplementedError(NmstateError):
|
||||
pass
|
||||
|
||||
|
||||
class NmstateInternalError(NmstateError):
|
||||
pass
|
||||
|
||||
|
||||
class NmstateDependencyError(NmstateError):
|
||||
pass
|
||||
|
||||
|
||||
class ServiceRequestHandler(varlink.RequestHandler):
|
||||
service = varlink.Service(
|
||||
vendor="Red Hat",
|
||||
product="Nmstate",
|
||||
version=libnmstate.__version__,
|
||||
url="https://www.nmstate.io",
|
||||
interface_dir=os.path.dirname(__file__),
|
||||
namespaced=False,
|
||||
)
|
||||
|
||||
|
||||
@ServiceRequestHandler.service.interface("io.nmstate")
|
||||
class NmstateVarlinkService:
|
||||
def Show(self, arguments):
|
||||
"""
|
||||
Reports the state data on the system
|
||||
"""
|
||||
with nmstate_varlink_logger() as log_handler:
|
||||
method_args = ["include_status_data"]
|
||||
show_kwargs = validate_method_arguments(arguments, method_args)
|
||||
try:
|
||||
configured_state = libnmstate.show(**show_kwargs)
|
||||
return {"state": configured_state, "log": log_handler.logs}
|
||||
except libnmstate.error.NmstateValueError as exception:
|
||||
logging.error(str(exception))
|
||||
raise NmstateValueError(str(exception), log_handler.logs)
|
||||
|
||||
def ShowRunningConfig(self, arguments):
|
||||
with nmstate_varlink_logger() as log_handler:
|
||||
method_args = []
|
||||
validate_method_arguments(arguments, method_args)
|
||||
try:
|
||||
configured_state = libnmstate.show_running_config()
|
||||
return {"state": configured_state, "log": log_handler.logs}
|
||||
except libnmstate.error.NmstateValueError as exception:
|
||||
logging.error(str(exception))
|
||||
raise NmstateValueError(str(exception), log_handler.logs)
|
||||
|
||||
def Apply(self, arguments):
|
||||
"""
|
||||
Apply desired state declared in json format
|
||||
which is parsed as dictionary
|
||||
"""
|
||||
with nmstate_varlink_logger() as log_handler:
|
||||
method_args = [
|
||||
"desired_state",
|
||||
"verify_change",
|
||||
"commit",
|
||||
"rollback_timeout",
|
||||
"save_to_disk",
|
||||
]
|
||||
apply_kwargs = validate_method_arguments(arguments, method_args)
|
||||
if "desired_state" not in apply_kwargs.keys():
|
||||
logging.error("Desired_state not specified")
|
||||
raise NmstateValueError(
|
||||
"desired_state: No state specified", log_handler.logs
|
||||
)
|
||||
try:
|
||||
libnmstate.apply(**apply_kwargs)
|
||||
return {"log": log_handler.logs}
|
||||
except TypeError as exception:
|
||||
logging.error(str(exception), log_handler.logs)
|
||||
raise varlink.InvalidParameter(exception)
|
||||
except libnmstate.error.NmstatePermissionError as exception:
|
||||
logging.error(str(exception))
|
||||
raise NmstatePermissionError(str(exception), log_handler.logs)
|
||||
except libnmstate.error.NmstateValueError as exception:
|
||||
logging.error(str(exception))
|
||||
raise NmstateValueError(str(exception), log_handler.logs)
|
||||
except libnmstate.error.NmstateConflictError as exception:
|
||||
logging.error(str(exception))
|
||||
raise NmstateConflictError(str(exception), log_handler.logs)
|
||||
except libnmstate.error.NmstateVerificationError as exception:
|
||||
logging.error(str(exception))
|
||||
raise NmstateVerificationError(
|
||||
str(exception), log_handler.logs
|
||||
)
|
||||
|
||||
def Commit(self, arguments):
|
||||
"""
|
||||
Commits the checkpoint
|
||||
"""
|
||||
with nmstate_varlink_logger() as log_handler:
|
||||
method_args = ["checkpoint"]
|
||||
commit_kwargs = validate_method_arguments(arguments, method_args)
|
||||
try:
|
||||
libnmstate.commit(**commit_kwargs)
|
||||
return {"log": log_handler.logs}
|
||||
except libnmstate.error.NmstateValueError as exception:
|
||||
logging.error(str(exception))
|
||||
raise NmstateValueError(str(exception), log_handler.logs)
|
||||
|
||||
def Rollback(self, arguments):
|
||||
"""
|
||||
Roll back to the checkpoint
|
||||
"""
|
||||
with nmstate_varlink_logger() as log_handler:
|
||||
method_args = ["checkpoint"]
|
||||
rollback_kwargs = validate_method_arguments(arguments, method_args)
|
||||
try:
|
||||
libnmstate.rollback(**rollback_kwargs)
|
||||
return {"log": log_handler.logs}
|
||||
except libnmstate.error.NmstateValueError as exception:
|
||||
logging.error(str(exception))
|
||||
raise NmstateValueError(str(exception), log_handler.logs)
|
@ -38,7 +38,6 @@ from libnmstate.schema import Interface
|
||||
from libnmstate.schema import InterfaceIP
|
||||
from libnmstate.schema import Route
|
||||
from libnmstate.schema import RouteRule
|
||||
from nmstatectl.nmstate_varlink import start_varlink_server
|
||||
|
||||
|
||||
def main():
|
||||
@ -57,7 +56,6 @@ def main():
|
||||
setup_subcommand_apply(subparsers)
|
||||
setup_subcommand_show(subparsers)
|
||||
setup_subcommand_version(subparsers)
|
||||
setup_subcommand_varlink(subparsers)
|
||||
setup_subcommand_gen_config(subparsers)
|
||||
parser.add_argument(
|
||||
"--version", action="store_true", help="Display nmstate version"
|
||||
@ -244,16 +242,6 @@ def setup_subcommand_version(subparsers):
|
||||
parser_version.set_defaults(func=version)
|
||||
|
||||
|
||||
def setup_subcommand_varlink(subparsers):
|
||||
parser_varlink = subparsers.add_parser(
|
||||
"varlink", help="Varlink support for libnmstate"
|
||||
)
|
||||
parser_varlink.add_argument(
|
||||
"address", type=str, help="Unix socket address e.g: /run/nmstate"
|
||||
)
|
||||
parser_varlink.set_defaults(func=run_varlink_server)
|
||||
|
||||
|
||||
def setup_subcommand_gen_config(subparsers):
|
||||
parser_gc = subparsers.add_parser("gc", help="Generate configurations")
|
||||
parser_gc.add_argument(
|
||||
@ -358,13 +346,6 @@ def apply(args):
|
||||
return 1
|
||||
|
||||
|
||||
def run_varlink_server(args):
|
||||
try:
|
||||
start_varlink_server(args.address)
|
||||
except Exception as exception:
|
||||
logging.exception(exception)
|
||||
|
||||
|
||||
def run_gen_config(args):
|
||||
if args.file:
|
||||
for statefile in args.file:
|
||||
|
@ -31,8 +31,6 @@ RUN dnf update -y && \
|
||||
python3-requests \
|
||||
python3-docopt \
|
||||
python3-nispor \
|
||||
python3-varlink \
|
||||
libvarlink-util \
|
||||
tcpreplay \
|
||||
wpa_supplicant \
|
||||
hostapd \
|
||||
|
@ -31,9 +31,7 @@ RUN dnf -y install dnf-plugins-core epel-release && \
|
||||
python3-requests \
|
||||
python3-docopt \
|
||||
python3-nispor \
|
||||
python3-varlink \
|
||||
tcpreplay \
|
||||
libvarlink-util \
|
||||
wpa_supplicant \
|
||||
hostapd \
|
||||
&& \
|
||||
|
@ -37,8 +37,6 @@ RUN dnf -y install dnf-plugins-core && \
|
||||
gobject-introspection-devel \
|
||||
python3-devel \
|
||||
python3-nispor \
|
||||
python3-varlink \
|
||||
libvarlink-util \
|
||||
make && \
|
||||
\
|
||||
dnf clean all && \
|
||||
|
@ -58,20 +58,11 @@ This package contains the nmstate plugin for OVS database manipulation.
|
||||
%prep
|
||||
%setup -q
|
||||
|
||||
%preun
|
||||
%systemd_preun nmstate-varlink.service
|
||||
|
||||
%build
|
||||
%py3_build
|
||||
|
||||
%install
|
||||
%py3_install
|
||||
mkdir -p %{buildroot}%{_unitdir}
|
||||
install -p -m 644 %{buildroot}%{python3_sitelib}/nmstatectl/nmstate-varlink.service \
|
||||
%{buildroot}%{_unitdir}/nmstate-varlink.service
|
||||
|
||||
%post
|
||||
%systemd_post nmstate-varlink.service
|
||||
|
||||
%files
|
||||
%doc README.md
|
||||
@ -86,7 +77,6 @@ install -p -m 644 %{buildroot}%{python3_sitelib}/nmstatectl/nmstate-varlink.serv
|
||||
%{python3_sitelib}/%{libname}
|
||||
%exclude %{python3_sitelib}/%{libname}/plugins/nmstate_plugin_*
|
||||
%exclude %{python3_sitelib}/%{libname}/plugins/__pycache__/nmstate_plugin_*
|
||||
%{_unitdir}/nmstate-varlink.service
|
||||
|
||||
%files -n nmstate-plugin-ovsdb
|
||||
%{python3_sitelib}/%{libname}/plugins/nmstate_plugin_ovsdb*
|
||||
|
@ -9,5 +9,4 @@ jsonschema
|
||||
PyGObject
|
||||
PyYAML
|
||||
setuptools
|
||||
varlink
|
||||
nispor>=1.1.0
|
||||
|
1
setup.py
1
setup.py
@ -51,7 +51,6 @@ setup(
|
||||
},
|
||||
package_data={
|
||||
"libnmstate": ["schemas/operational-state.yaml", "VERSION"],
|
||||
"nmstatectl": ["io.nmstate.varlink", "nmstate-varlink.service"],
|
||||
},
|
||||
data_files=gen_manpage(),
|
||||
)
|
||||
|
@ -1,176 +0,0 @@
|
||||
#
|
||||
# Copyright (c) 2020 Red Hat, Inc.
|
||||
#
|
||||
# This file is part of nmstate
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation, either version 2.1 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
#
|
||||
import pytest
|
||||
import varlink
|
||||
import threading
|
||||
import subprocess
|
||||
import sys
|
||||
import json
|
||||
import libnmstate
|
||||
import os
|
||||
import time
|
||||
|
||||
from nmstatectl.nmstate_varlink import gen_varlink_server
|
||||
from libnmstate.schema import Interface
|
||||
from libnmstate.schema import InterfaceType
|
||||
from libnmstate.schema import InterfaceState
|
||||
from libnmstate.schema import InterfaceIPv4
|
||||
from libnmstate.schema import InterfaceIPv6
|
||||
|
||||
|
||||
VARLINK_INTERFACE = "io.nmstate"
|
||||
|
||||
APPLY_STATE = {
|
||||
Interface.KEY: [
|
||||
{
|
||||
Interface.NAME: "varlink_test",
|
||||
Interface.TYPE: InterfaceType.DUMMY,
|
||||
Interface.STATE: InterfaceState.UP,
|
||||
Interface.IPV4: {InterfaceIPv4.ENABLED: False},
|
||||
Interface.IPV6: {InterfaceIPv6.ENABLED: False},
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@pytest.fixture(
|
||||
params=["/run/nmstate"],
|
||||
ids=["unix_socket_connection"],
|
||||
)
|
||||
def server(request):
|
||||
server = gen_varlink_server(request.param)
|
||||
thread_server = threading.Thread(target=server.serve_forever, daemon=True)
|
||||
thread_server.start()
|
||||
yield server
|
||||
server.shutdown()
|
||||
server.server_close()
|
||||
|
||||
|
||||
@pytest.fixture(
|
||||
params=["unix:/run/nmstate/nmstate.so"],
|
||||
ids=["systemd_unix_connection"],
|
||||
)
|
||||
def systemd_service(request):
|
||||
if os.system("systemctl is-active nmstate-varlink.service") != 0:
|
||||
os.system("systemctl start nmstate-varlink.service")
|
||||
time.sleep(1)
|
||||
yield request.param
|
||||
os.system("systemctl stop nmstate-varlink.service")
|
||||
|
||||
|
||||
def _format_address(server_address):
|
||||
return f"unix:{server_address}"
|
||||
|
||||
|
||||
def test_varlink_show(server):
|
||||
lib_state = libnmstate.show()
|
||||
with varlink.Client(_format_address(server.server_address)).open(
|
||||
VARLINK_INTERFACE, namespaced=False
|
||||
) as con:
|
||||
varlink_state = con._call("Show")
|
||||
assert varlink_state["state"] == lib_state
|
||||
|
||||
|
||||
def test_varlink_show_running_config(server):
|
||||
lib_state = libnmstate.show_running_config()
|
||||
with varlink.Client(_format_address(server.server_address)).open(
|
||||
VARLINK_INTERFACE, namespaced=False
|
||||
) as con:
|
||||
varlink_state = con._call("ShowRunningConfig")
|
||||
assert varlink_state["state"] == lib_state
|
||||
|
||||
|
||||
def test_varlink_apply_state(server):
|
||||
with varlink.Client(_format_address(server.server_address)).open(
|
||||
VARLINK_INTERFACE, namespaced=False
|
||||
) as con:
|
||||
con._call("Apply", {"desired_state": APPLY_STATE})
|
||||
lib_state = libnmstate.show()
|
||||
assert any(
|
||||
interface
|
||||
for interface in lib_state[Interface.KEY]
|
||||
if interface[Interface.NAME]
|
||||
== APPLY_STATE[Interface.KEY][0][Interface.NAME]
|
||||
)
|
||||
APPLY_STATE[Interface.KEY][0][Interface.STATE] = InterfaceState.DOWN
|
||||
libnmstate.apply(APPLY_STATE)
|
||||
|
||||
|
||||
def test_varlink_apply_with_none_state(server):
|
||||
apply_state = {"desired_state": {}}
|
||||
with varlink.Client(_format_address(server.server_address)).open(
|
||||
VARLINK_INTERFACE, namespaced=False
|
||||
) as con:
|
||||
with pytest.raises(varlink.InvalidParameter):
|
||||
con._call("Apply", apply_state)
|
||||
|
||||
|
||||
def test_varlink_commit_error(server):
|
||||
with varlink.Client(_format_address(server.server_address)).open(
|
||||
VARLINK_INTERFACE, namespaced=False
|
||||
) as con:
|
||||
with pytest.raises(varlink.VarlinkError):
|
||||
con._call("Commit", None)
|
||||
|
||||
|
||||
def test_varlink_rollback_error(server):
|
||||
with varlink.Client(_format_address(server.server_address)).open(
|
||||
VARLINK_INTERFACE, namespaced=False
|
||||
) as con:
|
||||
with pytest.raises(varlink.VarlinkError):
|
||||
con._call("Rollback", None)
|
||||
|
||||
|
||||
def test_varlink_activation_mode():
|
||||
lib_state = libnmstate.show()
|
||||
command = (
|
||||
"varlink --activate='nmstatectl varlink /run/nmstate' "
|
||||
+ "call io.nmstate.Show"
|
||||
)
|
||||
output = subprocess.check_output(command, shell=True).decode(
|
||||
sys.stdout.encoding
|
||||
)
|
||||
parsed_out = json.loads(output)
|
||||
assert parsed_out["state"] == lib_state
|
||||
|
||||
|
||||
def test_systemd_varlink_show(systemd_service):
|
||||
lib_state = libnmstate.show()
|
||||
with varlink.Client(systemd_service).open(
|
||||
VARLINK_INTERFACE, namespaced=False
|
||||
) as con:
|
||||
varlink_state = con._call("Show")
|
||||
assert varlink_state["state"] == lib_state
|
||||
|
||||
|
||||
def test_systemd_varlink_apply_state(systemd_service):
|
||||
APPLY_STATE[Interface.KEY][0][Interface.STATE] = InterfaceState.UP
|
||||
with varlink.Client(systemd_service).open(
|
||||
VARLINK_INTERFACE, namespaced=False
|
||||
) as con:
|
||||
con._call("Apply", {"desired_state": APPLY_STATE})
|
||||
lib_state = libnmstate.show()
|
||||
assert any(
|
||||
interface
|
||||
for interface in lib_state[Interface.KEY]
|
||||
if interface[Interface.NAME]
|
||||
== APPLY_STATE[Interface.KEY][0][Interface.NAME]
|
||||
)
|
||||
APPLY_STATE[Interface.KEY][0][Interface.STATE] = InterfaceState.DOWN
|
||||
libnmstate.apply(APPLY_STATE)
|
Loading…
x
Reference in New Issue
Block a user