Skip to content

Commit

Permalink
bump to 0.20.0
Browse files Browse the repository at this point in the history
  • Loading branch information
dmulyalin committed Aug 13, 2023
1 parent e1c9441 commit d3767ce
Show file tree
Hide file tree
Showing 13 changed files with 1,536 additions and 1,129 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -130,4 +130,4 @@ dmypy.json

# mine
private/
tests/tofile_outputs/
tests/tofile_outputs/*
2 changes: 1 addition & 1 deletion nornir_salt/plugins/functions/InventoryFun.py
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,7 @@ def _delete_host(nr, name):

for n in names:
_ = nr.inventory.hosts.pop(n, None)
ret[name] = True
ret[n] = True

return ret

Expand Down
18 changes: 10 additions & 8 deletions nornir_salt/plugins/tasks/connections.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ def conn_list(task, conn_name: str = "all") -> list:
{
"connection_name": conn,
"connection_plugin": str(type(conn_obj)).split(" ")[1].strip(">"),
"connection_action": "list",
}
for conn, conn_obj in task.host.connections.items()
if conn_name == "all" or conn == conn_name
Expand All @@ -115,7 +116,7 @@ def conn_close(task, conn_name: str = "all") -> list:
for conn in list(task.host.connections.keys()):
if conn_name != "all" and conn != conn_name:
continue
ret.append({"connection_name": conn})
ret.append({"connection_name": conn, "connection_action": "close"})
try:
task.host.close_connection(conn)
except:
Expand Down Expand Up @@ -365,6 +366,11 @@ def conn_open(
in connection options.
"""
reconnect = reconnect or []
info = {
"connection_name": conn_name,
"connection_options": via or conn_name,
"connection_action": "open",
}
ret = {}
host = host or task.host
close_open = True if via else close_open
Expand All @@ -374,7 +380,7 @@ def conn_open(
if close_open:
host.close_connection(conn_name)
else:
return Result(host=host, result="Connection already open")
return Result(host=host, result="Connection already open", **info)

if via:
via_conn_opts = host._get_connection_options_recursively(via)
Expand Down Expand Up @@ -472,7 +478,7 @@ def conn_open(
if ret.get("exception") and raise_on_error:
raise RuntimeError(ret["exception"])

return Result(host=host, **ret)
return Result(host=host, **info, **ret)


@ValidateFuncArgs(model_connections)
Expand All @@ -491,11 +497,7 @@ def connections(task, call, **kwargs):
* close - calls conn_close task
* open - calls conn_open task
"""
if "conn_name" in kwargs:
task.name = "connections:{}:{}".format(call, kwargs["conn_name"])
else:
task.name = "connections:{}".format(call)

task.name = "connections"
dispatcher = {"ls": conn_list, "close": conn_close, "open": conn_open}

return dispatcher[call](task, **kwargs)
18 changes: 9 additions & 9 deletions nornir_salt/plugins/tasks/netmiko_send_command_ps.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,15 +90,15 @@
def send_command_ps(
self,
command_string: str,
read_timeout:int=30,
timeout:int=120,
inter_loop_sleep:float=0.1,
initial_sleep:float=0.1,
strip_prompt:bool=True,
strip_command:bool=True,
normalize:bool=True,
cutoff:float=0.6,
nowait:bool=False,
read_timeout: int = 30,
timeout: int = 120,
inter_loop_sleep: float = 0.1,
initial_sleep: float = 0.1,
strip_prompt: bool = True,
strip_command: bool = True,
normalize: bool = True,
cutoff: float = 0.6,
nowait: bool = False,
):
"""
Execute command_string_ps on the SSH channel using promptless (ps) approach. Can be used
Expand Down
47 changes: 45 additions & 2 deletions nornir_salt/plugins/tasks/network.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,13 @@
except ImportError:
HAS_DNS = False

try:
import pythonping

HAS_PYTHONPING = True
except ImportError:
HAS_PYTHONPING = False

from typing import Optional, Any, Dict, Union
from nornir.core.task import Result
from nornir_salt.utils.pydantic_models import model_network, model_network_resolve_dns
Expand All @@ -65,7 +72,7 @@ def resolve_dns(
:param server: list or comma separated string of IP addresses or FQDNs
of DNS servers to use
:param use_host_name: if True resolves host's name instead of host's hostname
:param use_host_name: if True resolves host's ``name`` instead of host's ``hostname``
:param timeout: number of seconds to wait for response from DNS server
:param ipv4: resolve 'A' record
:param ipv6: resolve 'AAAA' record
Expand Down Expand Up @@ -123,6 +130,42 @@ def resolve_dns(
)


def icmp_ping(task, use_host_name: bool = False, **kwargs) -> Result:
"""
Functiont to ping host using ICMP.
Requires `pythonping <https://github.com/alessandromaggio/pythonping>_`
library.
:param use_host_name: if True pings host's ``name`` instead of host's ``hostname``
:param kwargs: any additional arguments for ``pythonping.ping`` call
"""
ret = {}
task.name = "ping"

if not HAS_PYTHONPING:
return Result(
host=task.host,
failed=True,
result="Failed importing pythonping, is it installed?",
)

# source target to ping
if use_host_name:
target = task.host.name
else:
target = task.host.hostname

try:
ret["result"] = pythonping.ping(target, **kwargs)
except:
ret["result"] = None
ret["failed"] = True
ret["exception"] = traceback.format_exc()

return Result(host=task.host, **ret)


@ValidateFuncArgs(model_network)
def network(task, call, **kwargs) -> Result:
"""
Expand All @@ -138,8 +181,8 @@ def network(task, call, **kwargs) -> Result:
"""
dispatcher = {
"resolve_dns": resolve_dns,
"ping": icmp_ping,
# "reverse_dns": reverse_dns,
# "ping": ping,
# traceroute
# connect
}
Expand Down
11 changes: 9 additions & 2 deletions nornir_salt/utils/cli_form_commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,15 @@ def cli_form_commands(
commands = task.host.data["__task__"]["filename"]

# normalize commands to a list
if isinstance(commands, str) and split_lines:
commands = commands.splitlines()
if split_lines:
if isinstance(commands, str):
commands = commands.splitlines()
# handle a list of multiline command strings
elif isinstance(commands, list):
temp = []
for i in commands:
temp.extend(i.splitlines())
commands = temp
elif isinstance(commands, str) and not split_lines:
commands = [commands]

Expand Down
19 changes: 12 additions & 7 deletions nornir_salt/utils/pydantic_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -514,6 +514,7 @@ class TestsProcessorTestFunctions(str, Enum):
CustomFunctionTest = "CustomFunctionTest"
EvalTest = "EvalTest"


class EnumSaltTestAllowedExecFunctions(str, Enum):
nr_cli = "nr.cli"
nr_tping = "nr.tping"
Expand All @@ -524,13 +525,15 @@ class EnumSaltTestAllowedExecFunctions(str, Enum):
nr_network = "nr.network"
nr_file = "nr.file"
nr_snmp = "nr.snmp"



class modelSaltTestsArgs(BaseModel):
function: Optional[EnumSaltTestAllowedExecFunctions] = None

class Config:
extra = "allow"



class modelTestsProcessorTest(BaseModel):
"""Model for TestsProcessor single test dictionary item"""

Expand Down Expand Up @@ -564,7 +567,7 @@ class modelTestsProcessorTest(BaseModel):
globs: Optional[Dict] = None
# SALT related argumetns
salt: Optional[modelSaltTestsArgs] = None

class Config:
extra = "allow"

Expand Down Expand Up @@ -594,7 +597,8 @@ class modelTestsProcessorTests(BaseModel):
tests: Union[
List[List[StrictStr]], List[Dict], List[StrictStr], Dict[StrictStr, List[Dict]]
]



class modelTestsProcessorSuite(BaseModel):
"""Model for TestsProcessor tests suite"""

Expand All @@ -617,14 +621,15 @@ class modelTestsProcessorSuite(BaseModel):
],
],
]



class NornirInventoryConnection(BaseModel):
"""Nornir Inventory Connection Options Model"""

hostname: Optional[StrictStr] = None
port: Optional[
Union[None, int]
] = None # using Union[None, StrictInt] throws error if port is None
] = None # using Union[None, StrictInt] throws error if port is None
username: Optional[StrictStr] = None
password: Optional[StrictStr] = None
platform: Optional[StrictStr] = None
Expand Down

0 comments on commit d3767ce

Please sign in to comment.