Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 18 additions & 22 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,30 +1,26 @@
ARG PYTHON_VER
ARG PYTHON_VER="3.10"

FROM python:${PYTHON_VER}-slim

RUN apt-get update && \
apt-get upgrade -y && \
apt-get install --no-install-recommends -y curl gcc python3-dev && \
apt-get autoremove -y && \
apt-get clean all && \
rm -rf /var/lib/apt/lists/* && \
pip --no-cache-dir install --upgrade pip wheel

RUN pip install --upgrade pip

RUN curl -sSL https://install.python-poetry.org -o /tmp/install-poetry.py && \
python /tmp/install-poetry.py --version 1.6.0 && \
rm -f /tmp/install-poetry.py
# Install Poetry manually via its installer script;
# if we instead used "pip install poetry" it would install its own dependencies globally which may conflict with ours.
# https://python-poetry.org/docs/master/#installing-with-the-official-installer
# This also makes it so that Poetry will *not* be included in the "final" image since it's not installed to /usr/local/
ARG POETRY_HOME=/opt/poetry
ARG POETRY_INSTALLER_PARALLEL=true
ARG POETRY_VERSION=2.1.3
ARG POETRY_VIRTUALENVS_CREATE=false
ADD https://install.python-poetry.org /tmp/install-poetry.py
RUN python /tmp/install-poetry.py

# Add poetry install location to the $PATH
ENV PATH="${PATH}:/root/.local/bin"
ENV PATH="${POETRY_HOME}/bin:${PATH}"

WORKDIR /local
COPY pyproject.toml poetry.lock /local/
RUN poetry config virtualenvs.create ${POETRY_VIRTUALENVS_CREATE} && \
poetry config installer.parallel "${POETRY_INSTALLER_PARALLEL}"

RUN poetry config virtualenvs.create false \
&& poetry install --no-interaction --no-ansi
WORKDIR /local
COPY . /local

# Do not break dependency caching before installing project
COPY . .
RUN poetry install
# Install the app
RUN poetry install --with dev --all-extras
1 change: 1 addition & 0 deletions docs/conf.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Configuration file for sphinx documentation."""

# pylint: disable-all
# Configuration file for the Sphinx documentation builder.
#
Expand Down
15 changes: 9 additions & 6 deletions docs/user/lib_getting_started.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,15 @@ These include:

The plugin comes with tasks that expose the basic pyntc functionality.

- [pyntc_config](https://github.com/networktocode/pyntc#config-commands) - Pass configuration commands to a network device.
- [pyntc_file_copy](https://github.com/networktocode/pyntc#copying-files) - Copy a file to a network device.
- [pyntc_install_os](https://github.com/networktocode/pyntc#installing-operating-systems) - Install an operating system.
- [pyntc_reboot](https://github.com/networktocode/pyntc#reboot) - Reboot a network device.
- [pyntc_save](https://github.com/networktocode/pyntc#save-configs) - Save the running configuration of a network device.
- [pyntc_show](https://github.com/networktocode/pyntc#sending-show-commands) - Send a single `show` command to a network device.
- [pyntc_config](https://pyntc.readthedocs.io/en/latest/user/lib_getting_started/#config-commands) - Pass configuration commands to a network device.
- [pyntc_file_copy](https://pyntc.readthedocs.io/en/latest/user/lib_getting_started/#copying-files) - Copy a file to a network device.
- [pyntc_remote_file_copy](https://pyntc.readthedocs.io/en/latest/user/lib_getting_started/#remote-file-copy-download-to-device) - Uses device copy command to retrieve a file.
- [pyntc_install_os](https://pyntc.readthedocs.io/en/latest/user/lib_getting_started/#installing-operating-systems) - Install an operating system.
- [pyntc_reboot](https://pyntc.readthedocs.io/en/latest/user/lib_getting_started/#reboot) - Reboot a network device.
- [pyntc_save](https://pyntc.readthedocs.io/en/latest/user/lib_getting_started/#save-configss) - Save the running configuration of a network device.
- [pyntc_show](https://pyntc.readthedocs.io/en/latest/user/lib_getting_started/#sending-show-commands) - Send a single `show` command to a network device.
- pyntc_verify_file - Verify a file exists on the device and verify the checksum of the file.
- pyntc_check_file_exists - Check if a file exists on the device.

## Basic Usage

Expand Down
1 change: 1 addition & 0 deletions nornir_pyntc/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Initialize Connection and Tasks."""

from importlib import metadata
from nornir_pyntc.connections import CONNECTION_NAME, Pyntc
from nornir_pyntc.tasks import pyntc_config, pyntc_file_copy, pyntc_install_os, pyntc_reboot, pyntc_save, pyntc_show
Expand Down
23 changes: 23 additions & 0 deletions nornir_pyntc/tasks/pyntc_check_file_exists.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
"""Copy file to device."""

from typing import Any

from nornir.core.task import Result, Task
from nornir_pyntc.connections import CONNECTION_NAME


def pyntc_check_file_exists(task: Task, filename: str, **kwargs: Any) -> Result:
"""Check if file exists on device.

Args:
task (Task): Nornir Task object.
filename (str): Name of the file.
kwargs (Any): Additional keyword args.
Comment thread
smk4664 marked this conversation as resolved.

Returns:
Result object with:
* (bool): True if file exists, False otherwise.
"""
pyntc_connection = task.host.get_connection(CONNECTION_NAME, task.nornir.config)
result = pyntc_connection.check_file_exists(filename, **kwargs)
return Result(host=task.host, result=result, changed=False)
1 change: 1 addition & 0 deletions nornir_pyntc/tasks/pyntc_config.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Send configuration commands."""

from typing import List

from nornir.core.task import Result, Task
Expand Down
1 change: 1 addition & 0 deletions nornir_pyntc/tasks/pyntc_file_copy.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Copy file to device."""

from typing import Any

from nornir.core.task import Result, Task
Expand Down
1 change: 1 addition & 0 deletions nornir_pyntc/tasks/pyntc_install_os.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Installs the prescribed Network OS."""

from typing import Any

from nornir.core.task import Result, Task
Expand Down
1 change: 1 addition & 0 deletions nornir_pyntc/tasks/pyntc_reboot.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Reboot device."""

from requests.exceptions import ConnectionError, ReadTimeout # pylint: disable=redefined-builtin

from nornir.core.task import Result, Task
Expand Down
26 changes: 26 additions & 0 deletions nornir_pyntc/tasks/pyntc_remote_file_copy.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
"""Copy file to device, using the device's copy command."""

from typing import Any

from nornir.core.task import Result, Task
from pyntc.utils.models import FileCopyModel
from nornir_pyntc.connections import CONNECTION_NAME


def pyntc_remote_file_copy(task: Task, src: FileCopyModel, **kwargs: Any) -> Result:
"""Execute the file copy command on a remote device using the device's native copy command.

Args:
task (Task): Nornir Task object.
src (FileCopyModel): Source of file.
kwargs (Any): Additional keyword args.
Comment thread
smk4664 marked this conversation as resolved.

Returns:
Result object with:
* (bool): True if save is successful.
"""
pyntc_connection = task.host.get_connection(CONNECTION_NAME, task.nornir.config)
result = pyntc_connection.remote_file_copy(src=src, **kwargs)
if result:
return Result(host=task.host, result=result, changed=True)
return Result(host=task.host, result=result, changed=False)
1 change: 1 addition & 0 deletions nornir_pyntc/tasks/pyntc_save.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Save a device's running configuration."""

from typing import Any

from nornir.core.task import Result, Task
Expand Down
1 change: 1 addition & 0 deletions nornir_pyntc/tasks/pyntc_show.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Send a non-configuration command."""

from typing import Any, Union

from nornir.core.task import Result, Task
Expand Down
33 changes: 33 additions & 0 deletions nornir_pyntc/tasks/pyntc_verify_file.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
"""Copy file to device."""

from typing import Any

from nornir.core.task import Result, Task
from nornir_pyntc.connections import CONNECTION_NAME


def pyntc_verify_file(
task: Task,
checksum: str,
filename: str,
hashing_algorithm: str = "md5",
**kwargs: Any,
) -> Result:
"""Check if file exists on device and the checksum matches the provided value.

Args:
task (Task): Nornir Task object.
checksum (str): Expected checksum of the file.
filename (str): Name of the file.
hashing_algorithm (str): Hashing algorithm to use for checksum verification (default: "md5").
kwargs (Any): Additional keyword args.
Comment thread
smk4664 marked this conversation as resolved.

Returns:
Result object with:
* (bool): True if file exists and checksum matches, False otherwise.
"""
pyntc_connection = task.host.get_connection(CONNECTION_NAME, task.nornir.config)
result = pyntc_connection.verify_file(
filename, checksum, hashing_algorithm, **kwargs
)
return Result(host=task.host, result=result, changed=False)
Loading
Loading