ttp_templates 0.1.0__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.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2020 apraksim
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,246 @@
1
+ Metadata-Version: 2.1
2
+ Name: ttp_templates
3
+ Version: 0.1.0
4
+ Summary: Template Text Parser Templates collections
5
+ Home-page: https://github.com/dmulyalin/ttp_templates
6
+ Author: Denis Mulyalin
7
+ Author-email: d.mulyalin@gmail.com
8
+ License: UNKNOWN
9
+ Description: # Template Text Parser Templates
10
+
11
+ This repository contains a collection of [TTP](https://github.com/dmulyalin/ttp) templates.
12
+
13
+ If you solved a problem using TTP and feel that your work can be
14
+ useful to other people, feel free to raise an issue or submit pull request to
15
+ include your template(s) in this repository.
16
+
17
+ ## Sample usage
18
+
19
+ This example demonstrates how to parse `Test Platform` output for `show run | sec interface` command using `platform/test_platform_show_run_pipe_sec_interface.txt` template.
20
+ <details><summary>Code</summary>
21
+
22
+ ```python
23
+ from ttp_templates import parse_output
24
+ import pprint
25
+
26
+ data = """
27
+ interface GigabitEthernet1/3.251
28
+ description Customer #32148
29
+ encapsulation dot1q 251
30
+ ip address 172.16.33.10 255.255.255.128
31
+ shutdown
32
+ !
33
+ interface GigabitEthernet1/3.251
34
+ description Customer #32148
35
+ encapsulation dot1q 251
36
+ ip address 172.16.33.10 255.255.255.128
37
+ shutdown
38
+ """
39
+
40
+ result = parse_output(
41
+ data=data,
42
+ platform="Test Platform",
43
+ command="show run | sec interface"
44
+ )
45
+
46
+ pprint.pprint(result)
47
+
48
+ # prints:
49
+ # [[[{'description': 'Customer #32148',
50
+ # 'disabled': True,
51
+ # 'dot1q': '251',
52
+ # 'interface': 'GigabitEthernet1/3.251',
53
+ # 'ip': '172.16.33.10',
54
+ # 'mask': '255.255.255.128'},
55
+ # {'description': 'Customer #32148',
56
+ # 'disabled': True,
57
+ # 'dot1q': '251',
58
+ # 'interface': 'GigabitEthernet1/3.251',
59
+ # 'ip': '172.16.33.10',
60
+ # 'mask': '255.255.255.128'}]]]
61
+ ```
62
+ </details>
63
+
64
+ Sample code to parse `Cisco IOS` output in a structure compatible with `ietf-interfaces` YANG module.
65
+ <details><summary>Code</summary>
66
+
67
+ ```python
68
+ from ttp_templates import get_template
69
+ from ttp import ttp
70
+ import pprint
71
+
72
+ data1 = """
73
+ interface GigabitEthernet1/3.251
74
+ description Customer #32148
75
+ encapsulation dot1q 251
76
+ ip address 172.16.33.10 255.255.255.128
77
+ shutdown
78
+ !
79
+ interface GigabitEthernet1/4
80
+ description vCPEs access control
81
+ ip address 172.16.33.10 255.255.255.128
82
+ !
83
+ """
84
+ data2 = """
85
+ interface GigabitEthernet1/5
86
+ description Works data
87
+ ip mtu 9000
88
+ !
89
+ interface GigabitEthernet1/7
90
+ description Works data v6
91
+ ipv6 address 2001::1/64
92
+ ipv6 address 2001:1::1/64
93
+ """
94
+
95
+ template = get_template(yang="ietf-interfaces", platform="cisco_ios")
96
+ parser = ttp(template=template)
97
+
98
+ parser.add_input(data1)
99
+ parser.add_input(data2)
100
+
101
+ parser.parse()
102
+ res = parser.result()
103
+ pprint.pprint(res)
104
+
105
+ # prints:
106
+ # [{'comment': '',
107
+ # 'exception': {},
108
+ # 'result': [{'ietf-interfaces:interfaces': {'interface': [{'admin-status': 'down',
109
+ # 'description': 'Customer '
110
+ # '#32148',
111
+ # 'enabled': False,
112
+ # 'ietf-ip:ipv4': {'address': [{'ip': '172.16.33.10',
113
+ # 'netmask': '255.255.255.128',
114
+ # 'origin': 'static'}]},
115
+ # 'if-index': 1,
116
+ # 'link-up-down-trap-enable': 'enabled',
117
+ # 'name': 'GigabitEthernet1/3.251',
118
+ # 'oper-status': 'unknown',
119
+ # 'statistics': {'discontinuity-time': '1970-01-01T00:00:00+00:00'},
120
+ # 'type': 'iana-if-type:ethernetCsmacd'},
121
+ # {'admin-status': 'up',
122
+ # 'description': 'vCPEs '
123
+ # 'access '
124
+ # 'control',
125
+ # 'enabled': True,
126
+ # 'ietf-ip:ipv4': {'address': [{'ip': '172.16.33.10',
127
+ # 'netmask': '255.255.255.128',
128
+ # 'origin': 'static'}]},
129
+ # 'if-index': 1,
130
+ # 'link-up-down-trap-enable': 'enabled',
131
+ # 'name': 'GigabitEthernet1/4',
132
+ # 'oper-status': 'unknown',
133
+ # 'statistics': {'discontinuity-time': '1970-01-01T00:00:00+00:00'},
134
+ # 'type': 'iana-if-type:ethernetCsmacd'}]}},
135
+ # {'ietf-interfaces:interfaces': {'interface': [{'admin-status': 'up',
136
+ # 'description': 'Works '
137
+ # 'data',
138
+ # 'enabled': True,
139
+ # 'ietf-ip:ipv4': {'mtu': 9000},
140
+ # 'if-index': 1,
141
+ # 'link-up-down-trap-enable': 'enabled',
142
+ # 'name': 'GigabitEthernet1/5',
143
+ # 'oper-status': 'unknown',
144
+ # 'statistics': {'discontinuity-time': '1970-01-01T00:00:00+00:00'},
145
+ # 'type': 'iana-if-type:ethernetCsmacd'},
146
+ # {'admin-status': 'up',
147
+ # 'description': 'Works '
148
+ # 'data '
149
+ # 'v6',
150
+ # 'enabled': True,
151
+ # 'ietf-ip:ipv6': {'address': [{'ip': '2001::1',
152
+ # 'origin': 'static',
153
+ # 'prefix-length': 64},
154
+ # {'ip': '2001:1::1',
155
+ # 'origin': 'static',
156
+ # 'prefix-length': 64}]},
157
+ # 'if-index': 1,
158
+ # 'link-up-down-trap-enable': 'enabled',
159
+ # 'name': 'GigabitEthernet1/7',
160
+ # 'oper-status': 'unknown',
161
+ # 'statistics': {'discontinuity-time': '1970-01-01T00:00:00+00:00'},
162
+ # 'type': 'iana-if-type:ethernetCsmacd'}]}}],
163
+ # 'valid': {0: True, 1: True}}]
164
+ ```
165
+ </details>
166
+
167
+
168
+ # How templates collections structured
169
+
170
+ This repository contains three collections of templates corresponding to folder names:
171
+
172
+ * `platform` collection - mimics [ntc-templates](https://github.com/networktocode/ntc-templates) API and follows same naming rule
173
+ * `yang` collection - contains templates capable of producing YANG compatible structures out of text data
174
+ * `misc` collection - miscellaneous templates for various use cases organized in folders
175
+
176
+ **Platform collection templates files naming rule**
177
+
178
+ `{{ vendor_os }}_{{ command_with_underscores }}.txt` - lower case only
179
+
180
+ **YANG collection templates files naming rule**
181
+
182
+ `{{ YANG module name }}_{{ platform_name }}.txt` - lower case only
183
+
184
+ **Misc collection templates files naming rule**
185
+
186
+ `{{ usecase folder }}/{{ template name }}.txt` - upper or lower case
187
+
188
+ # API reference
189
+
190
+ `ttp_templates.parse_output`: Function to load template text and parse data provided
191
+
192
+ **Attributes**
193
+
194
+ * data (str) - data to parse
195
+ * path (str) - OS path to template to load
196
+ * platform (str) - name of the platform to load template for
197
+ * command (str) - command to load template for
198
+ * yang (str) - name of YANG module to load template for
199
+ * misc (str) - OS path to template within repository misc folder
200
+ * structure (str) - results structure list, dictionary or flat_list
201
+ * template_vars (dict) - variables to load in template object
202
+
203
+ **Valid combinations of template location**
204
+
205
+ ``path`` attribute is always more preferred
206
+
207
+ * ``path="./misc/foo/bar.txt"``
208
+ * ``platfrom="cisco_ios", command="show version"``
209
+ * ``yang="ietf-interfaces", platform="cisco_ios"``
210
+ * ``misc="foo_folder/bar_template.txt"``
211
+
212
+
213
+ `ttp_templates.get_template`: Function to locate template file and return it's content
214
+
215
+ **Attributes**
216
+
217
+ * path (str) - OS path to template to load
218
+ * platform (str) - name of the platform to load template for
219
+ * command (str) - command to load template for
220
+ * yang (str) - name of YANG module to load template for
221
+ * misc (str) - OS path to template within repository misc folder
222
+
223
+ **Valid combinations of template location**
224
+
225
+ ``path`` attribute is always more preferred
226
+
227
+ * ``path="./misc/foo/bar.txt"``
228
+ * ``platfrom="cisco_ios", command="show version"``
229
+ * ``yang="ietf-interfaces", platform="cisco_ios"``
230
+ * ``misc="foo_folder/bar_template.txt"``
231
+
232
+
233
+ # Contributions
234
+ Feel free to submit an issue, report a bug or ask a question, feature requests are welcomed.
235
+
236
+ It is always good idea to document as much as you can and give context on the problem you was
237
+ trying to solve. TTP templates have ``<doc>`` tag exactly for that.
238
+ Platform: UNKNOWN
239
+ Classifier: Topic :: Utilities
240
+ Classifier: Programming Language :: Python :: 2.7
241
+ Classifier: Programming Language :: Python :: 3.5
242
+ Classifier: Programming Language :: Python :: 3.6
243
+ Classifier: Programming Language :: Python :: 3.7
244
+ Classifier: License :: OSI Approved :: MIT License
245
+ Classifier: Operating System :: OS Independent
246
+ Description-Content-Type: text/markdown
@@ -0,0 +1,229 @@
1
+ # Template Text Parser Templates
2
+
3
+ This repository contains a collection of [TTP](https://github.com/dmulyalin/ttp) templates.
4
+
5
+ If you solved a problem using TTP and feel that your work can be
6
+ useful to other people, feel free to raise an issue or submit pull request to
7
+ include your template(s) in this repository.
8
+
9
+ ## Sample usage
10
+
11
+ This example demonstrates how to parse `Test Platform` output for `show run | sec interface` command using `platform/test_platform_show_run_pipe_sec_interface.txt` template.
12
+ <details><summary>Code</summary>
13
+
14
+ ```python
15
+ from ttp_templates import parse_output
16
+ import pprint
17
+
18
+ data = """
19
+ interface GigabitEthernet1/3.251
20
+ description Customer #32148
21
+ encapsulation dot1q 251
22
+ ip address 172.16.33.10 255.255.255.128
23
+ shutdown
24
+ !
25
+ interface GigabitEthernet1/3.251
26
+ description Customer #32148
27
+ encapsulation dot1q 251
28
+ ip address 172.16.33.10 255.255.255.128
29
+ shutdown
30
+ """
31
+
32
+ result = parse_output(
33
+ data=data,
34
+ platform="Test Platform",
35
+ command="show run | sec interface"
36
+ )
37
+
38
+ pprint.pprint(result)
39
+
40
+ # prints:
41
+ # [[[{'description': 'Customer #32148',
42
+ # 'disabled': True,
43
+ # 'dot1q': '251',
44
+ # 'interface': 'GigabitEthernet1/3.251',
45
+ # 'ip': '172.16.33.10',
46
+ # 'mask': '255.255.255.128'},
47
+ # {'description': 'Customer #32148',
48
+ # 'disabled': True,
49
+ # 'dot1q': '251',
50
+ # 'interface': 'GigabitEthernet1/3.251',
51
+ # 'ip': '172.16.33.10',
52
+ # 'mask': '255.255.255.128'}]]]
53
+ ```
54
+ </details>
55
+
56
+ Sample code to parse `Cisco IOS` output in a structure compatible with `ietf-interfaces` YANG module.
57
+ <details><summary>Code</summary>
58
+
59
+ ```python
60
+ from ttp_templates import get_template
61
+ from ttp import ttp
62
+ import pprint
63
+
64
+ data1 = """
65
+ interface GigabitEthernet1/3.251
66
+ description Customer #32148
67
+ encapsulation dot1q 251
68
+ ip address 172.16.33.10 255.255.255.128
69
+ shutdown
70
+ !
71
+ interface GigabitEthernet1/4
72
+ description vCPEs access control
73
+ ip address 172.16.33.10 255.255.255.128
74
+ !
75
+ """
76
+ data2 = """
77
+ interface GigabitEthernet1/5
78
+ description Works data
79
+ ip mtu 9000
80
+ !
81
+ interface GigabitEthernet1/7
82
+ description Works data v6
83
+ ipv6 address 2001::1/64
84
+ ipv6 address 2001:1::1/64
85
+ """
86
+
87
+ template = get_template(yang="ietf-interfaces", platform="cisco_ios")
88
+ parser = ttp(template=template)
89
+
90
+ parser.add_input(data1)
91
+ parser.add_input(data2)
92
+
93
+ parser.parse()
94
+ res = parser.result()
95
+ pprint.pprint(res)
96
+
97
+ # prints:
98
+ # [{'comment': '',
99
+ # 'exception': {},
100
+ # 'result': [{'ietf-interfaces:interfaces': {'interface': [{'admin-status': 'down',
101
+ # 'description': 'Customer '
102
+ # '#32148',
103
+ # 'enabled': False,
104
+ # 'ietf-ip:ipv4': {'address': [{'ip': '172.16.33.10',
105
+ # 'netmask': '255.255.255.128',
106
+ # 'origin': 'static'}]},
107
+ # 'if-index': 1,
108
+ # 'link-up-down-trap-enable': 'enabled',
109
+ # 'name': 'GigabitEthernet1/3.251',
110
+ # 'oper-status': 'unknown',
111
+ # 'statistics': {'discontinuity-time': '1970-01-01T00:00:00+00:00'},
112
+ # 'type': 'iana-if-type:ethernetCsmacd'},
113
+ # {'admin-status': 'up',
114
+ # 'description': 'vCPEs '
115
+ # 'access '
116
+ # 'control',
117
+ # 'enabled': True,
118
+ # 'ietf-ip:ipv4': {'address': [{'ip': '172.16.33.10',
119
+ # 'netmask': '255.255.255.128',
120
+ # 'origin': 'static'}]},
121
+ # 'if-index': 1,
122
+ # 'link-up-down-trap-enable': 'enabled',
123
+ # 'name': 'GigabitEthernet1/4',
124
+ # 'oper-status': 'unknown',
125
+ # 'statistics': {'discontinuity-time': '1970-01-01T00:00:00+00:00'},
126
+ # 'type': 'iana-if-type:ethernetCsmacd'}]}},
127
+ # {'ietf-interfaces:interfaces': {'interface': [{'admin-status': 'up',
128
+ # 'description': 'Works '
129
+ # 'data',
130
+ # 'enabled': True,
131
+ # 'ietf-ip:ipv4': {'mtu': 9000},
132
+ # 'if-index': 1,
133
+ # 'link-up-down-trap-enable': 'enabled',
134
+ # 'name': 'GigabitEthernet1/5',
135
+ # 'oper-status': 'unknown',
136
+ # 'statistics': {'discontinuity-time': '1970-01-01T00:00:00+00:00'},
137
+ # 'type': 'iana-if-type:ethernetCsmacd'},
138
+ # {'admin-status': 'up',
139
+ # 'description': 'Works '
140
+ # 'data '
141
+ # 'v6',
142
+ # 'enabled': True,
143
+ # 'ietf-ip:ipv6': {'address': [{'ip': '2001::1',
144
+ # 'origin': 'static',
145
+ # 'prefix-length': 64},
146
+ # {'ip': '2001:1::1',
147
+ # 'origin': 'static',
148
+ # 'prefix-length': 64}]},
149
+ # 'if-index': 1,
150
+ # 'link-up-down-trap-enable': 'enabled',
151
+ # 'name': 'GigabitEthernet1/7',
152
+ # 'oper-status': 'unknown',
153
+ # 'statistics': {'discontinuity-time': '1970-01-01T00:00:00+00:00'},
154
+ # 'type': 'iana-if-type:ethernetCsmacd'}]}}],
155
+ # 'valid': {0: True, 1: True}}]
156
+ ```
157
+ </details>
158
+
159
+
160
+ # How templates collections structured
161
+
162
+ This repository contains three collections of templates corresponding to folder names:
163
+
164
+ * `platform` collection - mimics [ntc-templates](https://github.com/networktocode/ntc-templates) API and follows same naming rule
165
+ * `yang` collection - contains templates capable of producing YANG compatible structures out of text data
166
+ * `misc` collection - miscellaneous templates for various use cases organized in folders
167
+
168
+ **Platform collection templates files naming rule**
169
+
170
+ `{{ vendor_os }}_{{ command_with_underscores }}.txt` - lower case only
171
+
172
+ **YANG collection templates files naming rule**
173
+
174
+ `{{ YANG module name }}_{{ platform_name }}.txt` - lower case only
175
+
176
+ **Misc collection templates files naming rule**
177
+
178
+ `{{ usecase folder }}/{{ template name }}.txt` - upper or lower case
179
+
180
+ # API reference
181
+
182
+ `ttp_templates.parse_output`: Function to load template text and parse data provided
183
+
184
+ **Attributes**
185
+
186
+ * data (str) - data to parse
187
+ * path (str) - OS path to template to load
188
+ * platform (str) - name of the platform to load template for
189
+ * command (str) - command to load template for
190
+ * yang (str) - name of YANG module to load template for
191
+ * misc (str) - OS path to template within repository misc folder
192
+ * structure (str) - results structure list, dictionary or flat_list
193
+ * template_vars (dict) - variables to load in template object
194
+
195
+ **Valid combinations of template location**
196
+
197
+ ``path`` attribute is always more preferred
198
+
199
+ * ``path="./misc/foo/bar.txt"``
200
+ * ``platfrom="cisco_ios", command="show version"``
201
+ * ``yang="ietf-interfaces", platform="cisco_ios"``
202
+ * ``misc="foo_folder/bar_template.txt"``
203
+
204
+
205
+ `ttp_templates.get_template`: Function to locate template file and return it's content
206
+
207
+ **Attributes**
208
+
209
+ * path (str) - OS path to template to load
210
+ * platform (str) - name of the platform to load template for
211
+ * command (str) - command to load template for
212
+ * yang (str) - name of YANG module to load template for
213
+ * misc (str) - OS path to template within repository misc folder
214
+
215
+ **Valid combinations of template location**
216
+
217
+ ``path`` attribute is always more preferred
218
+
219
+ * ``path="./misc/foo/bar.txt"``
220
+ * ``platfrom="cisco_ios", command="show version"``
221
+ * ``yang="ietf-interfaces", platform="cisco_ios"``
222
+ * ``misc="foo_folder/bar_template.txt"``
223
+
224
+
225
+ # Contributions
226
+ Feel free to submit an issue, report a bug or ask a question, feature requests are welcomed.
227
+
228
+ It is always good idea to document as much as you can and give context on the problem you was
229
+ trying to solve. TTP templates have ``<doc>`` tag exactly for that.
@@ -0,0 +1,11 @@
1
+ [metadata]
2
+ description-file = README.md
3
+ license_files = LICENSE
4
+
5
+ [bdist_wheel]
6
+ universal = 1
7
+
8
+ [egg_info]
9
+ tag_build =
10
+ tag_date = 0
11
+
@@ -0,0 +1,37 @@
1
+ from setuptools import setup, find_packages
2
+
3
+ with open("README.md", "r") as f:
4
+ long_description = f.read()
5
+
6
+ __author__ = "Denis Mulyalin <d.mulyalin@gmail.com>"
7
+
8
+ setup(
9
+ name="ttp_templates",
10
+ version="0.1.0",
11
+ author="Denis Mulyalin",
12
+ author_email="d.mulyalin@gmail.com",
13
+ description="Template Text Parser Templates collections",
14
+ long_description=long_description,
15
+ long_description_content_type="text/markdown",
16
+ url="https://github.com/dmulyalin/ttp_templates",
17
+ packages=find_packages(),
18
+ extras_require={},
19
+ include_package_data=True,
20
+ package_data={
21
+ "ttp_templates": [
22
+ "platform/*.txt",
23
+ "yang/*.txt",
24
+ "misc/*/*.txt"
25
+ ]
26
+ },
27
+ data_files=[('', ['LICENSE'])],
28
+ classifiers=[
29
+ "Topic :: Utilities",
30
+ "Programming Language :: Python :: 2.7",
31
+ "Programming Language :: Python :: 3.5",
32
+ "Programming Language :: Python :: 3.6",
33
+ "Programming Language :: Python :: 3.7",
34
+ "License :: OSI Approved :: MIT License",
35
+ "Operating System :: OS Independent",
36
+ ]
37
+ )
@@ -0,0 +1,85 @@
1
+ import sys
2
+ import pprint
3
+ sys.path.insert(0,'..')
4
+
5
+ from ttp_templates import get_template
6
+ from ttp_templates import parse_output
7
+
8
+
9
+ def test_get_template():
10
+ template = get_template(path="yang/ietf-interfaces_cisco_ios.txt")
11
+ # print(template)
12
+ assert isinstance(template, str)
13
+
14
+ # test_get_template()
15
+
16
+ def test_parse_output_platform():
17
+ data = """
18
+ interface GigabitEthernet1/3.251
19
+ description Customer #32148
20
+ encapsulation dot1q 251
21
+ ip address 172.16.33.10 255.255.255.128
22
+ shutdown
23
+ !
24
+ interface GigabitEthernet1/3.251
25
+ description Customer #32148
26
+ encapsulation dot1q 251
27
+ ip address 172.16.33.10 255.255.255.128
28
+ shutdown
29
+ """
30
+ result = parse_output(
31
+ data=data,
32
+ platform="Test Platform",
33
+ command="show run | sec interface"
34
+ )
35
+ # pprint.pprint(result)
36
+ assert result == [[[{'description': 'Customer #32148',
37
+ 'disabled': True,
38
+ 'dot1q': '251',
39
+ 'interface': 'GigabitEthernet1/3.251',
40
+ 'ip': '172.16.33.10',
41
+ 'mask': '255.255.255.128'},
42
+ {'description': 'Customer #32148',
43
+ 'disabled': True,
44
+ 'dot1q': '251',
45
+ 'interface': 'GigabitEthernet1/3.251',
46
+ 'ip': '172.16.33.10',
47
+ 'mask': '255.255.255.128'}]]]
48
+
49
+ # test_parse_output()
50
+
51
+ def test_parse_output_misc():
52
+ data = """
53
+ r1# show run | sec interfaces
54
+ interface GigabitEthernet1
55
+ vrf forwarding MGMT
56
+ ip address 10.223.89.55 255.255.255.0
57
+ negotiation auto
58
+ no mop enabled
59
+ interface GigabitEthernet1
60
+ vrf forwarding MGMT
61
+ ip address 10.223.89.56 255.255.255.0
62
+ negotiation auto
63
+ no mop enabled
64
+ no mop sysid
65
+ """
66
+ result = parse_output(
67
+ data=data,
68
+ misc="ttp_templates_tests/cisco_ios_interfaces_cfg_per_ip.txt"
69
+ )
70
+ # pprint.pprint(result)
71
+ assert result == [[{'description': 'description',
72
+ 'hostname': 'r1',
73
+ 'interface': 'GigabitEthernet1',
74
+ 'ip': '10.223.89.55',
75
+ 'mask': '255.255.255.0',
76
+ 'vrf': 'MGMT'},
77
+ {'description': 'description',
78
+ 'hostname': 'r1',
79
+ 'interface': 'GigabitEthernet1',
80
+ 'ip': '10.223.89.56',
81
+ 'mask': '255.255.255.0',
82
+ 'vrf': 'MGMT'}]]
83
+
84
+
85
+ # test_parse_output_misc()
@@ -0,0 +1,99 @@
1
+ import sys
2
+ import pprint
3
+ sys.path.insert(0,'..')
4
+
5
+ from ttp_templates import get_template
6
+ from ttp import ttp
7
+
8
+
9
+ def test_cisco_ios():
10
+ data1 = """
11
+ interface GigabitEthernet1/3.251
12
+ description Customer #32148
13
+ encapsulation dot1q 251
14
+ ip address 172.16.33.10 255.255.255.128
15
+ shutdown
16
+ !
17
+ interface GigabitEthernet1/4
18
+ description vCPEs access control
19
+ ip address 172.16.33.10 255.255.255.128
20
+ !
21
+ """
22
+ data2 = """
23
+ interface GigabitEthernet1/5
24
+ description Works data
25
+ ip mtu 9000
26
+ !
27
+ interface GigabitEthernet1/7
28
+ description Works data v6
29
+ ipv6 address 2001::1/64
30
+ ipv6 address 2001:1::1/64
31
+ """
32
+ template = get_template(yang="ietf-interfaces", platform="cisco_ios")
33
+ # print(template)
34
+ parser = ttp(template=template)
35
+ parser.add_input(data1)
36
+ parser.add_input(data2)
37
+ parser.parse()
38
+ res = parser.result()
39
+ # pprint.pprint(res)
40
+ assert res == [{'comment': '',
41
+ 'exception': {},
42
+ 'result': [{'ietf-interfaces:interfaces': {'interface': [{'admin-status': 'down',
43
+ 'description': 'Customer '
44
+ '#32148',
45
+ 'enabled': False,
46
+ 'ietf-ip:ipv4': {'address': [{'ip': '172.16.33.10',
47
+ 'netmask': '255.255.255.128',
48
+ 'origin': 'static'}]},
49
+ 'if-index': 1,
50
+ 'link-up-down-trap-enable': 'enabled',
51
+ 'name': 'GigabitEthernet1/3.251',
52
+ 'oper-status': 'unknown',
53
+ 'statistics': {'discontinuity-time': '1970-01-01T00:00:00+00:00'},
54
+ 'type': 'iana-if-type:ethernetCsmacd'},
55
+ {'admin-status': 'up',
56
+ 'description': 'vCPEs '
57
+ 'access '
58
+ 'control',
59
+ 'enabled': True,
60
+ 'ietf-ip:ipv4': {'address': [{'ip': '172.16.33.10',
61
+ 'netmask': '255.255.255.128',
62
+ 'origin': 'static'}]},
63
+ 'if-index': 1,
64
+ 'link-up-down-trap-enable': 'enabled',
65
+ 'name': 'GigabitEthernet1/4',
66
+ 'oper-status': 'unknown',
67
+ 'statistics': {'discontinuity-time': '1970-01-01T00:00:00+00:00'},
68
+ 'type': 'iana-if-type:ethernetCsmacd'}]}},
69
+ {'ietf-interfaces:interfaces': {'interface': [{'admin-status': 'up',
70
+ 'description': 'Works '
71
+ 'data',
72
+ 'enabled': True,
73
+ 'ietf-ip:ipv4': {'mtu': 9000},
74
+ 'if-index': 1,
75
+ 'link-up-down-trap-enable': 'enabled',
76
+ 'name': 'GigabitEthernet1/5',
77
+ 'oper-status': 'unknown',
78
+ 'statistics': {'discontinuity-time': '1970-01-01T00:00:00+00:00'},
79
+ 'type': 'iana-if-type:ethernetCsmacd'},
80
+ {'admin-status': 'up',
81
+ 'description': 'Works '
82
+ 'data '
83
+ 'v6',
84
+ 'enabled': True,
85
+ 'ietf-ip:ipv6': {'address': [{'ip': '2001::1',
86
+ 'origin': 'static',
87
+ 'prefix-length': 64},
88
+ {'ip': '2001:1::1',
89
+ 'origin': 'static',
90
+ 'prefix-length': 64}]},
91
+ 'if-index': 1,
92
+ 'link-up-down-trap-enable': 'enabled',
93
+ 'name': 'GigabitEthernet1/7',
94
+ 'oper-status': 'unknown',
95
+ 'statistics': {'discontinuity-time': '1970-01-01T00:00:00+00:00'},
96
+ 'type': 'iana-if-type:ethernetCsmacd'}]}}],
97
+ 'valid': {0: True, 1: True}}]
98
+
99
+ # test_cisco_ios()
@@ -0,0 +1,2 @@
1
+ from .ttp_templates import get_template
2
+ from .ttp_templates import parse_output
@@ -0,0 +1,109 @@
1
+ import os
2
+ from ttp import ttp
3
+ from typing import Optional, List, Dict
4
+
5
+ def get_template(
6
+ platform: Optional[str] = None,
7
+ command: Optional[str] = None,
8
+ yang: Optional[str] = None,
9
+ misc: Optional[str] = None,
10
+ path: Optional[str] = None
11
+ ):
12
+ """
13
+ Function to locate template file and return it's content
14
+
15
+ **Attributes**
16
+
17
+ * path (str) - OS path to template to load
18
+ * platform (str) - name of the platform to load template for
19
+ * command (str) - command to load template for
20
+ * yang (str) - name of YANG module to load template for
21
+ * misc (str) - OS path to template within repository misc folder
22
+
23
+ **Valid combinations of template location**
24
+
25
+ ``path`` attribute is always more preferred
26
+
27
+ * ``path="./misc/foo/bar.txt"``
28
+ * ``platfrom="cisco_ios", command="show version"``
29
+ * ``yang="ietf-interfaces", platform="cisco_ios"``
30
+ * ``misc="foo_folder/bar_template.txt"``
31
+ """
32
+ # form path to template file
33
+ if path:
34
+ pass
35
+ elif platform and command:
36
+ platform = platform.lower()
37
+ command = command.lower()
38
+ command = command.replace("|", "pipe")
39
+ for symbol in [" "]:
40
+ platform = platform.replace(symbol, "_")
41
+ command = command.replace(symbol, "_")
42
+ path = "platform/{}_{}.txt".format(platform, command)
43
+ elif platform and yang:
44
+ platform = platform.lower()
45
+ yang = yang.lower()
46
+ for symbol in [" "]:
47
+ platform = platform.replace(symbol, "_")
48
+ yang = yang.replace(symbol, "_")
49
+ path = "yang/{}_{}.txt".format(yang, platform)
50
+ elif misc:
51
+ path = "misc/{}".format(misc)
52
+ else:
53
+ return None
54
+
55
+ template_filename = os.path.join(os.path.dirname(__file__), path)
56
+
57
+ # open template file and return content
58
+ with open(template_filename, "r") as f:
59
+ return f.read()
60
+
61
+
62
+ def parse_output(
63
+ data: str,
64
+ platform: Optional[str] = None,
65
+ command: Optional[str] = None,
66
+ path: Optional[str] = None,
67
+ yang: Optional[str] = None,
68
+ misc: Optional[str] = None,
69
+ structure: Optional[str] = "list",
70
+ template_vars: Optional[Dict] = {}
71
+ ):
72
+ """
73
+ Function to load template text and parse data provided
74
+
75
+ **Attributes**
76
+
77
+ * data (str) - data to parse
78
+ * path (str) - OS path to template to load
79
+ * platform (str) - name of the platform to load template for
80
+ * command (str) - command to load template for
81
+ * yang (str) - name of YANG module to load template for
82
+ * misc (str) - OS path to template within repository misc folder
83
+ * structure (str) - results structure list, dictionary or flat_list
84
+ * template_vars (dict) - variables to load in template object
85
+
86
+ **Valid combinations of template location**
87
+
88
+ ``path`` attribute is always more preferred
89
+
90
+ * ``path="./misc/foo/bar.txt"``
91
+ * ``platfrom="cisco_ios", command="show version"``
92
+ * ``yang="ietf-interfaces", platform="cisco_ios"``
93
+ * ``misc="foo_folder/bar_template.txt"``
94
+ """
95
+ # get template text
96
+ template = get_template(
97
+ platform=platform,
98
+ command=command,
99
+ path=path,
100
+ yang=yang,
101
+ misc=misc
102
+ )
103
+
104
+ # create parser object
105
+ parser = ttp(data=data, template=template, vars=template_vars)
106
+
107
+ # parse and return results
108
+ parser.parse(one=True)
109
+ return parser.result(structure=structure)
@@ -0,0 +1,246 @@
1
+ Metadata-Version: 2.1
2
+ Name: ttp-templates
3
+ Version: 0.1.0
4
+ Summary: Template Text Parser Templates collections
5
+ Home-page: https://github.com/dmulyalin/ttp_templates
6
+ Author: Denis Mulyalin
7
+ Author-email: d.mulyalin@gmail.com
8
+ License: UNKNOWN
9
+ Description: # Template Text Parser Templates
10
+
11
+ This repository contains a collection of [TTP](https://github.com/dmulyalin/ttp) templates.
12
+
13
+ If you solved a problem using TTP and feel that your work can be
14
+ useful to other people, feel free to raise an issue or submit pull request to
15
+ include your template(s) in this repository.
16
+
17
+ ## Sample usage
18
+
19
+ This example demonstrates how to parse `Test Platform` output for `show run | sec interface` command using `platform/test_platform_show_run_pipe_sec_interface.txt` template.
20
+ <details><summary>Code</summary>
21
+
22
+ ```python
23
+ from ttp_templates import parse_output
24
+ import pprint
25
+
26
+ data = """
27
+ interface GigabitEthernet1/3.251
28
+ description Customer #32148
29
+ encapsulation dot1q 251
30
+ ip address 172.16.33.10 255.255.255.128
31
+ shutdown
32
+ !
33
+ interface GigabitEthernet1/3.251
34
+ description Customer #32148
35
+ encapsulation dot1q 251
36
+ ip address 172.16.33.10 255.255.255.128
37
+ shutdown
38
+ """
39
+
40
+ result = parse_output(
41
+ data=data,
42
+ platform="Test Platform",
43
+ command="show run | sec interface"
44
+ )
45
+
46
+ pprint.pprint(result)
47
+
48
+ # prints:
49
+ # [[[{'description': 'Customer #32148',
50
+ # 'disabled': True,
51
+ # 'dot1q': '251',
52
+ # 'interface': 'GigabitEthernet1/3.251',
53
+ # 'ip': '172.16.33.10',
54
+ # 'mask': '255.255.255.128'},
55
+ # {'description': 'Customer #32148',
56
+ # 'disabled': True,
57
+ # 'dot1q': '251',
58
+ # 'interface': 'GigabitEthernet1/3.251',
59
+ # 'ip': '172.16.33.10',
60
+ # 'mask': '255.255.255.128'}]]]
61
+ ```
62
+ </details>
63
+
64
+ Sample code to parse `Cisco IOS` output in a structure compatible with `ietf-interfaces` YANG module.
65
+ <details><summary>Code</summary>
66
+
67
+ ```python
68
+ from ttp_templates import get_template
69
+ from ttp import ttp
70
+ import pprint
71
+
72
+ data1 = """
73
+ interface GigabitEthernet1/3.251
74
+ description Customer #32148
75
+ encapsulation dot1q 251
76
+ ip address 172.16.33.10 255.255.255.128
77
+ shutdown
78
+ !
79
+ interface GigabitEthernet1/4
80
+ description vCPEs access control
81
+ ip address 172.16.33.10 255.255.255.128
82
+ !
83
+ """
84
+ data2 = """
85
+ interface GigabitEthernet1/5
86
+ description Works data
87
+ ip mtu 9000
88
+ !
89
+ interface GigabitEthernet1/7
90
+ description Works data v6
91
+ ipv6 address 2001::1/64
92
+ ipv6 address 2001:1::1/64
93
+ """
94
+
95
+ template = get_template(yang="ietf-interfaces", platform="cisco_ios")
96
+ parser = ttp(template=template)
97
+
98
+ parser.add_input(data1)
99
+ parser.add_input(data2)
100
+
101
+ parser.parse()
102
+ res = parser.result()
103
+ pprint.pprint(res)
104
+
105
+ # prints:
106
+ # [{'comment': '',
107
+ # 'exception': {},
108
+ # 'result': [{'ietf-interfaces:interfaces': {'interface': [{'admin-status': 'down',
109
+ # 'description': 'Customer '
110
+ # '#32148',
111
+ # 'enabled': False,
112
+ # 'ietf-ip:ipv4': {'address': [{'ip': '172.16.33.10',
113
+ # 'netmask': '255.255.255.128',
114
+ # 'origin': 'static'}]},
115
+ # 'if-index': 1,
116
+ # 'link-up-down-trap-enable': 'enabled',
117
+ # 'name': 'GigabitEthernet1/3.251',
118
+ # 'oper-status': 'unknown',
119
+ # 'statistics': {'discontinuity-time': '1970-01-01T00:00:00+00:00'},
120
+ # 'type': 'iana-if-type:ethernetCsmacd'},
121
+ # {'admin-status': 'up',
122
+ # 'description': 'vCPEs '
123
+ # 'access '
124
+ # 'control',
125
+ # 'enabled': True,
126
+ # 'ietf-ip:ipv4': {'address': [{'ip': '172.16.33.10',
127
+ # 'netmask': '255.255.255.128',
128
+ # 'origin': 'static'}]},
129
+ # 'if-index': 1,
130
+ # 'link-up-down-trap-enable': 'enabled',
131
+ # 'name': 'GigabitEthernet1/4',
132
+ # 'oper-status': 'unknown',
133
+ # 'statistics': {'discontinuity-time': '1970-01-01T00:00:00+00:00'},
134
+ # 'type': 'iana-if-type:ethernetCsmacd'}]}},
135
+ # {'ietf-interfaces:interfaces': {'interface': [{'admin-status': 'up',
136
+ # 'description': 'Works '
137
+ # 'data',
138
+ # 'enabled': True,
139
+ # 'ietf-ip:ipv4': {'mtu': 9000},
140
+ # 'if-index': 1,
141
+ # 'link-up-down-trap-enable': 'enabled',
142
+ # 'name': 'GigabitEthernet1/5',
143
+ # 'oper-status': 'unknown',
144
+ # 'statistics': {'discontinuity-time': '1970-01-01T00:00:00+00:00'},
145
+ # 'type': 'iana-if-type:ethernetCsmacd'},
146
+ # {'admin-status': 'up',
147
+ # 'description': 'Works '
148
+ # 'data '
149
+ # 'v6',
150
+ # 'enabled': True,
151
+ # 'ietf-ip:ipv6': {'address': [{'ip': '2001::1',
152
+ # 'origin': 'static',
153
+ # 'prefix-length': 64},
154
+ # {'ip': '2001:1::1',
155
+ # 'origin': 'static',
156
+ # 'prefix-length': 64}]},
157
+ # 'if-index': 1,
158
+ # 'link-up-down-trap-enable': 'enabled',
159
+ # 'name': 'GigabitEthernet1/7',
160
+ # 'oper-status': 'unknown',
161
+ # 'statistics': {'discontinuity-time': '1970-01-01T00:00:00+00:00'},
162
+ # 'type': 'iana-if-type:ethernetCsmacd'}]}}],
163
+ # 'valid': {0: True, 1: True}}]
164
+ ```
165
+ </details>
166
+
167
+
168
+ # How templates collections structured
169
+
170
+ This repository contains three collections of templates corresponding to folder names:
171
+
172
+ * `platform` collection - mimics [ntc-templates](https://github.com/networktocode/ntc-templates) API and follows same naming rule
173
+ * `yang` collection - contains templates capable of producing YANG compatible structures out of text data
174
+ * `misc` collection - miscellaneous templates for various use cases organized in folders
175
+
176
+ **Platform collection templates files naming rule**
177
+
178
+ `{{ vendor_os }}_{{ command_with_underscores }}.txt` - lower case only
179
+
180
+ **YANG collection templates files naming rule**
181
+
182
+ `{{ YANG module name }}_{{ platform_name }}.txt` - lower case only
183
+
184
+ **Misc collection templates files naming rule**
185
+
186
+ `{{ usecase folder }}/{{ template name }}.txt` - upper or lower case
187
+
188
+ # API reference
189
+
190
+ `ttp_templates.parse_output`: Function to load template text and parse data provided
191
+
192
+ **Attributes**
193
+
194
+ * data (str) - data to parse
195
+ * path (str) - OS path to template to load
196
+ * platform (str) - name of the platform to load template for
197
+ * command (str) - command to load template for
198
+ * yang (str) - name of YANG module to load template for
199
+ * misc (str) - OS path to template within repository misc folder
200
+ * structure (str) - results structure list, dictionary or flat_list
201
+ * template_vars (dict) - variables to load in template object
202
+
203
+ **Valid combinations of template location**
204
+
205
+ ``path`` attribute is always more preferred
206
+
207
+ * ``path="./misc/foo/bar.txt"``
208
+ * ``platfrom="cisco_ios", command="show version"``
209
+ * ``yang="ietf-interfaces", platform="cisco_ios"``
210
+ * ``misc="foo_folder/bar_template.txt"``
211
+
212
+
213
+ `ttp_templates.get_template`: Function to locate template file and return it's content
214
+
215
+ **Attributes**
216
+
217
+ * path (str) - OS path to template to load
218
+ * platform (str) - name of the platform to load template for
219
+ * command (str) - command to load template for
220
+ * yang (str) - name of YANG module to load template for
221
+ * misc (str) - OS path to template within repository misc folder
222
+
223
+ **Valid combinations of template location**
224
+
225
+ ``path`` attribute is always more preferred
226
+
227
+ * ``path="./misc/foo/bar.txt"``
228
+ * ``platfrom="cisco_ios", command="show version"``
229
+ * ``yang="ietf-interfaces", platform="cisco_ios"``
230
+ * ``misc="foo_folder/bar_template.txt"``
231
+
232
+
233
+ # Contributions
234
+ Feel free to submit an issue, report a bug or ask a question, feature requests are welcomed.
235
+
236
+ It is always good idea to document as much as you can and give context on the problem you was
237
+ trying to solve. TTP templates have ``<doc>`` tag exactly for that.
238
+ Platform: UNKNOWN
239
+ Classifier: Topic :: Utilities
240
+ Classifier: Programming Language :: Python :: 2.7
241
+ Classifier: Programming Language :: Python :: 3.5
242
+ Classifier: Programming Language :: Python :: 3.6
243
+ Classifier: Programming Language :: Python :: 3.7
244
+ Classifier: License :: OSI Approved :: MIT License
245
+ Classifier: Operating System :: OS Independent
246
+ Description-Content-Type: text/markdown
@@ -0,0 +1,12 @@
1
+ LICENSE
2
+ README.md
3
+ setup.cfg
4
+ setup.py
5
+ test/test_ttp_templates_methods.py
6
+ test/test_yang_ietf_interfaces.py
7
+ ttp_templates/__init__.py
8
+ ttp_templates/ttp_templates.py
9
+ ttp_templates.egg-info/PKG-INFO
10
+ ttp_templates.egg-info/SOURCES.txt
11
+ ttp_templates.egg-info/dependency_links.txt
12
+ ttp_templates.egg-info/top_level.txt
@@ -0,0 +1 @@
1
+ ttp_templates