Skip to content

Commit eab1884

Browse files
authored
Bulk encryption utility for .netmiko.yml (#3506)
1 parent 9211005 commit eab1884

File tree

5 files changed

+714
-603
lines changed

5 files changed

+714
-603
lines changed
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
#!/usr/bin/env python3
2+
import argparse
3+
import sys
4+
from pathlib import Path
5+
from ruamel.yaml import YAML
6+
7+
from netmiko.encryption_handling import encrypt_value, get_encryption_key
8+
9+
yaml = YAML()
10+
yaml.preserve_quotes = True
11+
yaml.indent(mapping=2, sequence=4, offset=2)
12+
13+
14+
def encrypt_netmiko_yml(
15+
input_file: str, output_file: str | None, encryption_type: str
16+
) -> None:
17+
# Read the input YAML file
18+
input_path = Path(input_file).expanduser()
19+
with input_path.open("r") as f:
20+
config = yaml.load(f)
21+
22+
# Get the encryption key
23+
key = get_encryption_key()
24+
25+
# Encrypt password and secret for each device
26+
for device, params in config.items():
27+
if isinstance(params, dict):
28+
if "password" in params:
29+
encrypted_value = encrypt_value(
30+
params["password"], key, encryption_type
31+
)
32+
params["password"] = encrypted_value
33+
if "secret" in params:
34+
encrypted_value = encrypt_value(params["secret"], key, encryption_type)
35+
params["secret"] = encrypted_value
36+
37+
# Write the updated config to the output file or stdout
38+
if output_file:
39+
output_path = Path(output_file)
40+
with output_path.open("w") as f:
41+
yaml.dump(config, f)
42+
else:
43+
yaml.dump(config, sys.stdout)
44+
45+
46+
def main_ep():
47+
sys.exit(main())
48+
49+
50+
def main():
51+
parser = argparse.ArgumentParser(
52+
description="Encrypt passwords in .netmiko.yml file"
53+
)
54+
parser.add_argument(
55+
"--input_file",
56+
default="~/.netmiko.yml",
57+
help="Input .netmiko.yml file (default: ~/.netmiko.yml)",
58+
)
59+
parser.add_argument(
60+
"--output_file",
61+
help="Output .netmiko.yml file with encrypted passwords (default: stdout)",
62+
)
63+
parser.add_argument(
64+
"--encryption-type",
65+
choices=["fernet", "aes128"],
66+
default="fernet",
67+
help="Encryption type to use (default: fernet)",
68+
)
69+
70+
args = parser.parse_args()
71+
72+
encrypt_netmiko_yml(args.input_file, args.output_file, args.encryption_type)
73+
74+
if args.output_file:
75+
print(
76+
f"Encrypted .netmiko.yml file has been written to {Path(args.output_file).resolve()}",
77+
file=sys.stderr,
78+
)
79+
80+
return 0
81+
82+
83+
if __name__ == "__main__":
84+
sys.exit(main())

netmiko/cli_tools/netmiko_encrypt.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
11
#!/usr/bin/env python3
22
import os
3+
import sys
34
import argparse
45
from getpass import getpass
56

67
from netmiko.utilities import load_netmiko_yml
78
from netmiko.encryption_handling import encrypt_value
89

910

11+
def main_ep():
12+
sys.exit(main())
13+
14+
1015
def main():
1116
parser = argparse.ArgumentParser(
1217
description="Encrypt data using Netmiko's encryption."
@@ -56,6 +61,8 @@ def main():
5661
encrypted_data = encrypt_value(data, key, encryption_type)
5762
print(f"\nEncrypted data: {encrypted_data}\n")
5863

64+
return 0
65+
5966

6067
if __name__ == "__main__":
61-
main()
68+
sys.exit(main())

0 commit comments

Comments
 (0)