Skip to content

Commit

Permalink
Adds hash_data function (#373)
Browse files Browse the repository at this point in the history
* Adds hash_data function

* Fixes auto generated file

* Adds type annotations

* Adds documentation for hash
  • Loading branch information
joewesch authored Oct 26, 2023
1 parent a35a9cf commit ed680db
Show file tree
Hide file tree
Showing 7 changed files with 118 additions and 0 deletions.
5 changes: 5 additions & 0 deletions docs/dev/code_reference/hash.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Hash

::: netutils.hash
options:
show_submodules: True
1 change: 1 addition & 0 deletions docs/user/include_jinja_list.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
| paloalto_panos_brace_to_set | netutils.config.conversion.paloalto_panos_brace_to_set |
| fqdn_to_ip | netutils.dns.fqdn_to_ip |
| is_fqdn_resolvable | netutils.dns.is_fqdn_resolvable |
| hash_data | netutils.hash.hash_data |
| abbreviated_interface_name | netutils.interface.abbreviated_interface_name |
| abbreviated_interface_name_list | netutils.interface.abbreviated_interface_name_list |
| canonical_interface_name | netutils.interface.canonical_interface_name |
Expand Down
1 change: 1 addition & 0 deletions docs/user/lib_use_cases.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ Functions are grouped with like functions, such as IP or MAC address based funct
- Conversion - Provides the ability to convert between different syntax's within the same OS.
- Parsing - Provides the ability to parse configuration for the minor differences that are there.
- DNS - Provides the ability to work with DNS, such as validating that a FQDN is resolvable.
- Hash - Provide a convenience method for hashlib to be used in Jinja2
- Interface - Provides the ability to work with interface names, expanding, abbreviating, and splitting the names.
- IP Address - Provides the ability to work with IP addresses, primarily exposing Python `ipaddress` functionality.
- Library Helpers - Provides helpers to pull useful information, e.g. NAPALM getters.
Expand Down
1 change: 1 addition & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ nav:
- Banner: "dev/code_reference/banner.md"
- Configs: "dev/code_reference/configs.md"
- DNS: "dev/code_reference/dns.md"
- Hash: "dev/code_reference/hash.md"
- Interface: "dev/code_reference/interface.md"
- IP: "dev/code_reference/ip.md"
- Library Helpers: "dev/code_reference/lib_helpers.md"
Expand Down
39 changes: 39 additions & 0 deletions netutils/hash.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
"""Functions for hashing data."""
import hashlib
import typing as t


def hash_data(data: bytes, algorithm: str) -> t.Any:
"""Convenience function primarily built to expose hashlib to Jinja.
Args:
data (bytes): Data to hash.
algorithm (str): Hashing algorithm to use.
Returns:
bytes: Hashed data.
Raises:
AttributeError: Invalid algorithm specified.
Examples:
>>> from netutils.hash import hash_data
>>> hash_data("test", "md5")
'098f6bcd4621d373cade4e832627b4f6'
>>> from jinja2 import Environment
>>> from netutils.utils import jinja2_convenience_function
>>>
>>> env = Environment(trim_blocks=True, lstrip_blocks=True)
>>> env.filters.update(jinja2_convenience_function())
>>> template_str = "{{ 'test' | hash_data('md5') }}"
>>> template = env.from_string(template_str)
>>> result = template.render()
>>> print(result)
098f6bcd4621d373cade4e832627b4f6
"""
if not isinstance(data, bytes):
data = str(data).encode()
algorithm = algorithm.lower()
hasher = getattr(hashlib, algorithm)
return hasher(data).hexdigest()
1 change: 1 addition & 0 deletions netutils/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@
"get_napalm_getters": "lib_helpers.get_napalm_getters",
"paloalto_panos_brace_to_set": "config.conversion.paloalto_panos_brace_to_set",
"get_upgrade_path": "os_version.get_upgrade_path",
"hash_data": "hash.hash_data",
}


Expand Down
70 changes: 70 additions & 0 deletions tests/unit/test_hash.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
"""Tests for the hash functions."""
import pytest

from netutils.hash import hash_data


EXPECTED_HASHES = [
(
"md5",
"b31be8e621f7d7cb80289c3634a2463f",
),
(
"sha1",
"696de4dae5e77515f0460c78dc712f9b055ae7f2",
),
(
"sha224",
"bead2aad3706b211e825f5919db78dceca775cae4bd5b58078652ad2",
),
(
"sha256",
"a9675e13424e5009161f7b7da6c1bb7e091f1401459176e8efce23c0f1fc5ba9",
),
(
"sha384",
"4476744d8167497e9cbc85901a753be7bef5a33a1ce36926c5a21b68c7c2d420daa6cd347d515dd21af1e93927c7ba5c",
),
(
"sha512",
"75dc2cbd4b2e025f8c0a1f495bc321343eef8d5561dfa02e29f77b32b9685f7add41169e7f9fb085f5110ac4635de286437c758c115b8eadacc20f086e39cc28",
),
(
"blake2b",
"82a094789746f0a0405845ced806282e1bd6f317dd8a9464b6e660105e16108f6582c0f091d787a833c8d8fd5c53004dac2571113045fefe25d1f159f8c1f934",
),
(
"blake2s",
"b8fecb4ff8b866c7638985eb66d4ba9cb5f908d0b1a25def4c593ba140b791af",
),
(
"sha3_224",
"f0b2b40e360489e0e2da83094238e9591677e1d304d70a1feb1188f2",
),
(
"sha3_256",
"308a5dd839eb055ee84f0b2c99344526a716c58a14dffb704b6784437aee91ba",
),
(
"sha3_384",
"80e4d0e43bf447ef4d3a6dcd1a795a3573bc6f34d42b81ee78bb757bd86ed6bc9210d752797fd62bfbdb6fc17eb52ed1",
),
(
"sha3_512",
"13dddfadbe95282b6b0da1c7c3c7dc28c086cdcc3de39baafb1fb45913ac39c0d9744927c10fb1d858ab257069d3ef367c8913553e7f7eabb1f4ffe6480e5924",
),
]


@pytest.mark.parametrize("algorithm,expected", EXPECTED_HASHES)
def test_hash_data(algorithm, expected):
"""Test the hash_data function."""
data = "Network To Code"
assert hash_data(data, algorithm) == expected


def test_hash_data_invalid_algorithm():
"""Test the hash_data function with an invalid algorithm."""
data = "Network To Code"
with pytest.raises(AttributeError):
hash_data(data, "invalid")

0 comments on commit ed680db

Please sign in to comment.