junoscfg 0.5.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. junoscfg-0.5.1/.github/workflows/publish.yml +34 -0
  2. junoscfg-0.5.1/.gitignore +23 -0
  3. junoscfg-0.5.1/LICENSE +21 -0
  4. junoscfg-0.5.1/PKG-INFO +126 -0
  5. junoscfg-0.5.1/README.md +91 -0
  6. junoscfg-0.5.1/private_test_data/.gitignore +4 -0
  7. junoscfg-0.5.1/private_test_data/README.md +5 -0
  8. junoscfg-0.5.1/pyproject.toml +89 -0
  9. junoscfg-0.5.1/src/junoscfg/__init__.py +558 -0
  10. junoscfg-0.5.1/src/junoscfg/anonymize/__init__.py +146 -0
  11. junoscfg-0.5.1/src/junoscfg/anonymize/config.py +258 -0
  12. junoscfg-0.5.1/src/junoscfg/anonymize/path_filter.py +65 -0
  13. junoscfg-0.5.1/src/junoscfg/anonymize/revert.py +109 -0
  14. junoscfg-0.5.1/src/junoscfg/anonymize/rules/__init__.py +98 -0
  15. junoscfg-0.5.1/src/junoscfg/anonymize/rules/as_number.py +145 -0
  16. junoscfg-0.5.1/src/junoscfg/anonymize/rules/community.py +88 -0
  17. junoscfg-0.5.1/src/junoscfg/anonymize/rules/description.py +68 -0
  18. junoscfg-0.5.1/src/junoscfg/anonymize/rules/group.py +95 -0
  19. junoscfg-0.5.1/src/junoscfg/anonymize/rules/identity.py +86 -0
  20. junoscfg-0.5.1/src/junoscfg/anonymize/rules/ip.py +149 -0
  21. junoscfg-0.5.1/src/junoscfg/anonymize/rules/password.py +290 -0
  22. junoscfg-0.5.1/src/junoscfg/anonymize/rules/sensitive_word.py +93 -0
  23. junoscfg-0.5.1/src/junoscfg/anonymize/rules/ssh_key.py +119 -0
  24. junoscfg-0.5.1/src/junoscfg/anonymize/walker.py +189 -0
  25. junoscfg-0.5.1/src/junoscfg/cli.py +830 -0
  26. junoscfg-0.5.1/src/junoscfg/convert/__init__.py +132 -0
  27. junoscfg-0.5.1/src/junoscfg/convert/field_validator.py +569 -0
  28. junoscfg-0.5.1/src/junoscfg/convert/input/__init__.py +41 -0
  29. junoscfg-0.5.1/src/junoscfg/convert/input/json_input.py +24 -0
  30. junoscfg-0.5.1/src/junoscfg/convert/input/set_input.py +517 -0
  31. junoscfg-0.5.1/src/junoscfg/convert/input/structured_input.py +18 -0
  32. junoscfg-0.5.1/src/junoscfg/convert/input/xml_input.py +26 -0
  33. junoscfg-0.5.1/src/junoscfg/convert/input/yaml_input.py +46 -0
  34. junoscfg-0.5.1/src/junoscfg/convert/ir.py +32 -0
  35. junoscfg-0.5.1/src/junoscfg/convert/output/__init__.py +41 -0
  36. junoscfg-0.5.1/src/junoscfg/convert/output/dict_walker.py +581 -0
  37. junoscfg-0.5.1/src/junoscfg/convert/output/json_output.py +17 -0
  38. junoscfg-0.5.1/src/junoscfg/convert/output/set_output.py +47 -0
  39. junoscfg-0.5.1/src/junoscfg/convert/output/structured_output.py +80 -0
  40. junoscfg-0.5.1/src/junoscfg/convert/output/xml_output.py +13 -0
  41. junoscfg-0.5.1/src/junoscfg/convert/output/yaml_output.py +23 -0
  42. junoscfg-0.5.1/src/junoscfg/display/__init__.py +63 -0
  43. junoscfg-0.5.1/src/junoscfg/display/config_store.py +436 -0
  44. junoscfg-0.5.1/src/junoscfg/display/constants.py +194 -0
  45. junoscfg-0.5.1/src/junoscfg/display/path_filter.py +45 -0
  46. junoscfg-0.5.1/src/junoscfg/display/set_converter.py +224 -0
  47. junoscfg-0.5.1/src/junoscfg/display/to_json.py +33 -0
  48. junoscfg-0.5.1/src/junoscfg/display/to_yaml.py +270 -0
  49. junoscfg-0.5.1/src/junoscfg/display/value_format.py +24 -0
  50. junoscfg-0.5.1/src/junoscfg/display/xml_helpers.py +25 -0
  51. junoscfg-0.5.1/src/junoscfg/edityaml/__init__.py +23 -0
  52. junoscfg-0.5.1/src/junoscfg/edityaml/ansibilize.py +321 -0
  53. junoscfg-0.5.1/src/junoscfg/edityaml/path_walker.py +180 -0
  54. junoscfg-0.5.1/src/junoscfg/edityaml/rules.py +110 -0
  55. junoscfg-0.5.1/src/junoscfg/edityaml/transforms.py +79 -0
  56. junoscfg-0.5.1/src/junoscfg/input.py +78 -0
  57. junoscfg-0.5.1/src/junoscfg/py.typed +0 -0
  58. junoscfg-0.5.1/src/junoscfg/validate/__init__.py +47 -0
  59. junoscfg-0.5.1/src/junoscfg/validate/artifact_builder.py +309 -0
  60. junoscfg-0.5.1/src/junoscfg/validate/grammar_generator.py +216 -0
  61. junoscfg-0.5.1/src/junoscfg/validate/json_yaml_validator.py +130 -0
  62. junoscfg-0.5.1/src/junoscfg/validate/schema_generator.py +187 -0
  63. junoscfg-0.5.1/src/junoscfg/validate/schema_node.py +101 -0
  64. junoscfg-0.5.1/src/junoscfg/validate/set_validator.py +99 -0
  65. junoscfg-0.5.1/src/junoscfg/validate/structured_validator.py +47 -0
  66. junoscfg-0.5.1/src/junoscfg/validate/validator.py +174 -0
  67. junoscfg-0.5.1/src/junoscfg/validate/xml_validator.py +96 -0
  68. junoscfg-0.5.1/src/junoscfg/validate/xsd_extractor.py +62 -0
  69. junoscfg-0.5.1/src/junoscfg/validate/xsd_fixes.py +929 -0
  70. junoscfg-0.5.1/src/junoscfg/validate/xsd_parser.py +436 -0
@@ -0,0 +1,34 @@
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - "v*"
7
+
8
+ jobs:
9
+ build:
10
+ runs-on: ubuntu-latest
11
+ steps:
12
+ - uses: actions/checkout@v4
13
+ - uses: astral-sh/setup-uv@v4
14
+ - run: uv build
15
+
16
+ - uses: actions/upload-artifact@v4
17
+ with:
18
+ name: dist
19
+ path: dist/
20
+
21
+ publish:
22
+ needs: build
23
+ runs-on: ubuntu-latest
24
+ environment: pypi
25
+ permissions:
26
+ id-token: write
27
+ steps:
28
+ - uses: actions/download-artifact@v4
29
+ with:
30
+ name: dist
31
+ path: dist/
32
+
33
+ - uses: astral-sh/setup-uv@v4
34
+ - run: uv publish --trusted-publishing always
@@ -0,0 +1,23 @@
1
+ __pycache__/
2
+ *.py[cod]
3
+ *$py.class
4
+ *.egg-info/
5
+ dist/
6
+ build/
7
+ .eggs/
8
+ *.egg
9
+ .mypy_cache/
10
+ .ruff_cache/
11
+ .pytest_cache/
12
+ .venv/
13
+ .claude/
14
+ tmp/
15
+ site/
16
+ run.sh
17
+ data/xml-schema-from-device*.xml
18
+ data/*.json
19
+ data/*.yaml
20
+ data/*.yaml_edit
21
+ data/*.conf
22
+ data/*.md
23
+ data/*.schema
junoscfg-0.5.1/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 junoscfg contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,126 @@
1
+ Metadata-Version: 2.4
2
+ Name: junoscfg
3
+ Version: 0.5.1
4
+ Summary: Convert Junos configurations between XML, JSON, structured, and display set formats
5
+ Project-URL: Homepage, https://github.com/dg-i/junoscfg
6
+ Project-URL: Repository, https://github.com/dg-i/junoscfg
7
+ Project-URL: Documentation, https://github.com/dg-i/junoscfg#readme
8
+ Project-URL: Issues, https://github.com/dg-i/junoscfg/issues
9
+ Author-email: Manon Goo <manon.goo@dg-i.net>
10
+ License-Expression: MIT
11
+ License-File: LICENSE
12
+ Keywords: anonymization,ansible,configuration,converter,json,juniper,junos,network,set,validation,xml,yaml
13
+ Classifier: Development Status :: 4 - Beta
14
+ Classifier: Intended Audience :: System Administrators
15
+ Classifier: Intended Audience :: Telecommunications Industry
16
+ Classifier: License :: OSI Approved :: MIT License
17
+ Classifier: Operating System :: OS Independent
18
+ Classifier: Programming Language :: Python :: 3
19
+ Classifier: Programming Language :: Python :: 3.10
20
+ Classifier: Programming Language :: Python :: 3.11
21
+ Classifier: Programming Language :: Python :: 3.12
22
+ Classifier: Programming Language :: Python :: 3.13
23
+ Classifier: Topic :: System :: Networking
24
+ Classifier: Topic :: Utilities
25
+ Classifier: Typing :: Typed
26
+ Requires-Python: >=3.10
27
+ Requires-Dist: click>=8.0
28
+ Requires-Dist: ipanon>=0.2.2
29
+ Requires-Dist: jsonschema>=4.0
30
+ Requires-Dist: lark>=1.1
31
+ Requires-Dist: lxml>=4.9
32
+ Requires-Dist: netutils>=1.17.1
33
+ Requires-Dist: pyyaml>=6.0
34
+ Description-Content-Type: text/markdown
35
+
36
+ # Junoscfg (Python)
37
+
38
+ Convert and validate Junos configurations between JSON, structured, YAML, and display set formats.
39
+
40
+ Originally inspired by the [Ruby Junoser gem](https://github.com/codeout/junoser), now a comprehensive Junos configuration toolkit.
41
+
42
+ ## Installation
43
+
44
+ ```bash
45
+ pip install junoscfg
46
+ ```
47
+
48
+ ## Usage
49
+
50
+ ### CLI
51
+
52
+ ```bash
53
+ # Convert structured config to set commands
54
+ junoscfg -i structured -e set config.conf
55
+
56
+ # Convert JSON to set commands
57
+ junoscfg -i json -e set config.json
58
+
59
+ # Convert to structured format
60
+ junoscfg -e structured config.set
61
+
62
+ # Read from stdin
63
+ echo '{"configuration":{"system":{"host-name":"test"}}}' | junoscfg -i json -e set
64
+
65
+ # Transform YAML for Ansible (literal extraction)
66
+ junoscfg edityaml ansibilize -p "addr:interfaces.interface[*].name" config.yaml
67
+
68
+ # Offset mode for multi-router deployments (generates ipmath expressions)
69
+ junoscfg edityaml ansibilize -P "addr:interfaces.interface[*].unit[*].family.*.address[*].name" config.yaml
70
+
71
+ # Anonymize all sensitive data
72
+ junoscfg -i json -e set --anonymize-all config.json
73
+
74
+ # Anonymize with regex patterns (e.g. match site codes)
75
+ junoscfg -e set --anonymize-sensitive-patterns 'LAX\d+' config.json
76
+
77
+ # Retrieve XSD dump and generate schema artifacts
78
+ echo "<rpc> <get-xnm-information> <type>xml-schema</type> <namespace>junos-configuration</namespace> </get-xnm-information> </rpc>" | ssh -Csp 830 router.example.com netconf > netconf.xml
79
+ junoscfg schema generate netconf.xml -o ./artifacts/
80
+ ```
81
+
82
+ ### Python API
83
+
84
+ ```python
85
+ from junoscfg import convert_config, Format, validate_json
86
+
87
+ # Convert between any format pair
88
+ result = convert_config(
89
+ '{"configuration":{"system":{"host-name":"test"}}}',
90
+ from_format=Format.JSON, to_format=Format.SET,
91
+ )
92
+
93
+ # Validate a JSON config
94
+ result = validate_json('{"configuration":{"system":{"host-name":"test"}}}')
95
+ print(result.valid) # True
96
+
97
+ # Convert with strict field-level validation (raises on invalid enum/pattern/IP values)
98
+ result = convert_config(source, from_format=Format.JSON, to_format=Format.SET, strict=True)
99
+
100
+ # Anonymize a configuration
101
+ from junoscfg.anonymize import anonymize
102
+ from junoscfg.anonymize.config import AnonymizeConfig
103
+
104
+ config = AnonymizeConfig(ips=True, passwords=True, salt="my-salt")
105
+ config.expand_all()
106
+ ir = {"configuration": {"system": {"host-name": "router1", "name-server": [{"name": "8.8.8.8"}]}}}
107
+ result = anonymize(ir, config)
108
+ ```
109
+
110
+ ## Documentation
111
+
112
+ For full documentation, install the docs dependencies and run:
113
+
114
+ ```bash
115
+ uv sync --group docs
116
+ uv run mkdocs serve
117
+ ```
118
+
119
+ Then open [http://127.0.0.1:8000](http://127.0.0.1:8000).
120
+
121
+ Key sections:
122
+
123
+ - **Getting Started** — Installation and usage examples
124
+ - **User Guide** — Conversion, validation, and CLI reference
125
+ - **API Reference** — Auto-generated Python API docs
126
+ - **Architecture** — Design decisions and schema internals
@@ -0,0 +1,91 @@
1
+ # Junoscfg (Python)
2
+
3
+ Convert and validate Junos configurations between JSON, structured, YAML, and display set formats.
4
+
5
+ Originally inspired by the [Ruby Junoser gem](https://github.com/codeout/junoser), now a comprehensive Junos configuration toolkit.
6
+
7
+ ## Installation
8
+
9
+ ```bash
10
+ pip install junoscfg
11
+ ```
12
+
13
+ ## Usage
14
+
15
+ ### CLI
16
+
17
+ ```bash
18
+ # Convert structured config to set commands
19
+ junoscfg -i structured -e set config.conf
20
+
21
+ # Convert JSON to set commands
22
+ junoscfg -i json -e set config.json
23
+
24
+ # Convert to structured format
25
+ junoscfg -e structured config.set
26
+
27
+ # Read from stdin
28
+ echo '{"configuration":{"system":{"host-name":"test"}}}' | junoscfg -i json -e set
29
+
30
+ # Transform YAML for Ansible (literal extraction)
31
+ junoscfg edityaml ansibilize -p "addr:interfaces.interface[*].name" config.yaml
32
+
33
+ # Offset mode for multi-router deployments (generates ipmath expressions)
34
+ junoscfg edityaml ansibilize -P "addr:interfaces.interface[*].unit[*].family.*.address[*].name" config.yaml
35
+
36
+ # Anonymize all sensitive data
37
+ junoscfg -i json -e set --anonymize-all config.json
38
+
39
+ # Anonymize with regex patterns (e.g. match site codes)
40
+ junoscfg -e set --anonymize-sensitive-patterns 'LAX\d+' config.json
41
+
42
+ # Retrieve XSD dump and generate schema artifacts
43
+ echo "<rpc> <get-xnm-information> <type>xml-schema</type> <namespace>junos-configuration</namespace> </get-xnm-information> </rpc>" | ssh -Csp 830 router.example.com netconf > netconf.xml
44
+ junoscfg schema generate netconf.xml -o ./artifacts/
45
+ ```
46
+
47
+ ### Python API
48
+
49
+ ```python
50
+ from junoscfg import convert_config, Format, validate_json
51
+
52
+ # Convert between any format pair
53
+ result = convert_config(
54
+ '{"configuration":{"system":{"host-name":"test"}}}',
55
+ from_format=Format.JSON, to_format=Format.SET,
56
+ )
57
+
58
+ # Validate a JSON config
59
+ result = validate_json('{"configuration":{"system":{"host-name":"test"}}}')
60
+ print(result.valid) # True
61
+
62
+ # Convert with strict field-level validation (raises on invalid enum/pattern/IP values)
63
+ result = convert_config(source, from_format=Format.JSON, to_format=Format.SET, strict=True)
64
+
65
+ # Anonymize a configuration
66
+ from junoscfg.anonymize import anonymize
67
+ from junoscfg.anonymize.config import AnonymizeConfig
68
+
69
+ config = AnonymizeConfig(ips=True, passwords=True, salt="my-salt")
70
+ config.expand_all()
71
+ ir = {"configuration": {"system": {"host-name": "router1", "name-server": [{"name": "8.8.8.8"}]}}}
72
+ result = anonymize(ir, config)
73
+ ```
74
+
75
+ ## Documentation
76
+
77
+ For full documentation, install the docs dependencies and run:
78
+
79
+ ```bash
80
+ uv sync --group docs
81
+ uv run mkdocs serve
82
+ ```
83
+
84
+ Then open [http://127.0.0.1:8000](http://127.0.0.1:8000).
85
+
86
+ Key sections:
87
+
88
+ - **Getting Started** — Installation and usage examples
89
+ - **User Guide** — Conversion, validation, and CLI reference
90
+ - **API Reference** — Auto-generated Python API docs
91
+ - **Architecture** — Design decisions and schema internals
@@ -0,0 +1,4 @@
1
+ # Ignore everything in this directory except this .gitignore and the README
2
+ *
3
+ !.gitignore
4
+ !README.md
@@ -0,0 +1,5 @@
1
+ # Private Test Data
2
+
3
+ Place private/real-world router configurations here for integration testing.
4
+ All files in this directory (except this README) are gitignored.
5
+
@@ -0,0 +1,89 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "junoscfg"
7
+ version = "0.5.1"
8
+ description = "Convert Junos configurations between XML, JSON, structured, and display set formats"
9
+ readme = "README.md"
10
+ requires-python = ">=3.10"
11
+ license = "MIT"
12
+ authors = [
13
+ { name = "Manon Goo", email = "manon.goo@dg-i.net" },
14
+ ]
15
+ classifiers = [
16
+ "Development Status :: 4 - Beta",
17
+ "Intended Audience :: System Administrators",
18
+ "Intended Audience :: Telecommunications Industry",
19
+ "License :: OSI Approved :: MIT License",
20
+ "Operating System :: OS Independent",
21
+ "Programming Language :: Python :: 3",
22
+ "Programming Language :: Python :: 3.10",
23
+ "Programming Language :: Python :: 3.11",
24
+ "Programming Language :: Python :: 3.12",
25
+ "Programming Language :: Python :: 3.13",
26
+ "Topic :: System :: Networking",
27
+ "Topic :: Utilities",
28
+ "Typing :: Typed",
29
+ ]
30
+ keywords = ["junos", "juniper", "network", "configuration", "converter", "validation", "anonymization", "ansible", "set", "json", "xml", "yaml"]
31
+ dependencies = [
32
+ "click>=8.0",
33
+ "lxml>=4.9",
34
+ "pyyaml>=6.0",
35
+ "jsonschema>=4.0",
36
+ "lark>=1.1",
37
+ "ipanon>=0.2.2",
38
+ "netutils>=1.17.1",
39
+ ]
40
+
41
+ [project.urls]
42
+ Homepage = "https://github.com/dg-i/junoscfg"
43
+ Repository = "https://github.com/dg-i/junoscfg"
44
+ Documentation = "https://github.com/dg-i/junoscfg#readme"
45
+ Issues = "https://github.com/dg-i/junoscfg/issues"
46
+
47
+ [project.scripts]
48
+ junoscfg = "junoscfg.cli:main"
49
+
50
+ [tool.pytest.ini_options]
51
+ testpaths = ["tests"]
52
+
53
+ [tool.ruff]
54
+ target-version = "py310"
55
+ line-length = 100
56
+
57
+ [tool.ruff.lint]
58
+ select = ["E", "F", "W", "I", "N", "UP", "B", "A", "SIM", "TCH"]
59
+
60
+ [tool.mypy]
61
+ python_version = "3.10"
62
+ strict = true
63
+ warn_return_any = true
64
+ warn_unused_configs = true
65
+
66
+ [tool.hatch.build.targets.sdist]
67
+ exclude = [
68
+ "CLAUDE.md",
69
+ ".claude/",
70
+ "mkdocs.yml",
71
+ "docs/",
72
+ "tests/",
73
+ "uv.lock",
74
+ "data/",
75
+ ]
76
+
77
+ [tool.hatch.build.targets.wheel]
78
+ packages = ["src/junoscfg"]
79
+
80
+ [dependency-groups]
81
+ dev = [
82
+ "pytest>=7.0",
83
+ "ruff>=0.4",
84
+ ]
85
+ docs = [
86
+ "mkdocs>=1.6",
87
+ "mkdocs-material>=9.5",
88
+ "mkdocstrings[python]>=0.25",
89
+ ]