Skip to content

Commit d7b6c2d

Browse files
committedJun 16, 2022
adding overaly parser to the repo list ...
1 parent 8de5d80 commit d7b6c2d

File tree

3 files changed

+318
-0
lines changed

3 files changed

+318
-0
lines changed
 

‎cfgs/README.md

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
#### Required folder structure

‎lsts/README.md

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
#### Required folder structure

‎oparser.sh

+316
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,316 @@
1+
#!/usr/bin/env bash
2+
3+
# Author: Salvatore Cuzzilla
4+
# em@il: salvatore@cuzzilla.org
5+
# Starting date: 07-01-2021
6+
# Last change date: 19-01-2020
7+
# Release date: TBD
8+
# Description: extract L3VPN overlay cfg from an MPLS router
9+
10+
11+
set -o errexit
12+
set -o nounset
13+
set -o pipefail
14+
15+
work_dir=$(dirname "$(readlink --canonicalize-existing "${0}" 2> /dev/null)")
16+
17+
readonly epoch=$(date +'%s')
18+
readonly error_validating_input=79
19+
readonly error_reading_file=80
20+
readonly error_parsing_options=81
21+
readonly error_missing_options=82
22+
readonly error_unknown_options=83
23+
readonly error_missing_options_arg=84
24+
readonly error_unimplemented_options=85
25+
readonly readonly script_name="${0##*/}"
26+
27+
f_option_flag=0
28+
i_option_flag=0
29+
h_option_flag=0
30+
31+
trap clean_up ERR SIGINT SIGTERM
32+
33+
usage() {
34+
cat <<MAN
35+
Usage: ${script_name} [-f <ARG> ] [ -i <ARG> ] || [-h]
36+
37+
DESCRIPTION:
38+
this tool can be used the extract the overaly configuration (MPLS-L3VPN)
39+
from MPLS-PE routers based on CISCO-XR OS
40+
41+
OPTIONS:
42+
-h
43+
Print this help and exit
44+
-f
45+
[mandatory] Specify the MPLS-PE configuration file - Must be in 'cisco/formal' format
46+
-i
47+
[mandatory] Specify Bundle-Ethernet interface/s
48+
(Examples:
49+
- Bundle-Ether7 is considering all sub-if belonging to bundle number 7
50+
- Bundle-Ether7.100 is considering only sub-if 100)
51+
MAN
52+
}
53+
54+
clean_up() {
55+
if [[ -d "${work_dir}/lsts/${pe_hostname}_${epoch}" ]]; then
56+
echo -e "Deleting: ${work_dir}/lsts/${pe_hostname}_${epoch} ..."
57+
rm -rf "${work_dir}/lsts/${pe_hostname}_${epoch}"
58+
fi
59+
60+
if [[ -d "${work_dir}/cfgs/${pe_hostname}_${epoch}" ]]; then
61+
echo -e "Deleting: ${work_dir}/cfgs/${pe_hostname}_${epoch} ..."
62+
rm -rf "${work_dir}/cfgs/${pe_hostname}_${epoch}"
63+
fi
64+
}
65+
66+
die() {
67+
local -r msg="${1}"
68+
local -r code="${2:-90}"
69+
echo "${msg}" >&2
70+
exit "${code}"
71+
}
72+
73+
parse_user_options() {
74+
while getopts ":f:i:h" opts; do
75+
case "${opts}" in
76+
f)
77+
f_option_flag=1
78+
readonly f_arg="${OPTARG}"
79+
;;
80+
i)
81+
i_option_flag=1
82+
readonly i_arg="${OPTARG}"
83+
;;
84+
h)
85+
h_option_flag=1
86+
;;
87+
:)
88+
die "error - mind your options/arguments - [ -h ] to know more" "${error_unknown_options}"
89+
;;
90+
\?)
91+
die "error - mind your options/arguments - [ -h ] to know more" "${error_missing_options_arg}"
92+
;;
93+
*)
94+
die "error - mind your options/arguments - [ -h ] to know more" "${error_unimplemented_options}"
95+
;;
96+
esac
97+
done
98+
}
99+
shift $((OPTIND -1))
100+
101+
# Generating the lst "bundle-if,vrf" main source to be able to extract the level2 lst & the level1 cf
102+
# Input: $f_arg && $i_arg
103+
# Output: $level1_lst
104+
gen_level1_lst_rgx1() {
105+
echo -e "Generating ${level1_lst} from ${pe_formal_cf} ..."
106+
$(egrep "^interface ${pe_bundle_if}\svrf" "${pe_formal_cf}" | awk -F " " '{print $2","$4}' > "${level1_lst}")
107+
}
108+
109+
gen_level1_lst_rgx2() {
110+
echo -e "Generating ${level1_lst} from ${pe_formal_cf} ..."
111+
$(egrep "^interface ${pe_bundle_if}.*\svrf" "${pe_formal_cf}" | awk -F " " '{print $2","$4}' > "${level1_lst}")
112+
}
113+
114+
# Generating the lst for policy-maps & route-policies to be able to extract the associated overaly cf
115+
# Input: $f_arg && $level1_lst
116+
# Output: $level2_pm_lst && $level2_rpl_lst
117+
gen_level2_lst() {
118+
if [[ ! -f "${level1_lst}" ]]; then
119+
die "error - reading file: ${level1_lst}" "${error_reading_file}"
120+
fi
121+
122+
echo -e "Generating ${level2_pm_lst} && ${level2_rpl_lst} from ${pe_formal_cf} ..."
123+
124+
while read -r line
125+
do
126+
local be_if="$(echo "${line}" | awk -F "," '{print $1}')"
127+
local vrf_if="$(echo "${line}" | awk -F "," '{print $2}')"
128+
# to be able to distinguish between rpl-00 & rpl-01
129+
local vrf_if_rpl="${vrf_if::-3}"
130+
# workaround to cover rpl name unmatching the vrf name
131+
local vrf_if_rpl_unmatch="${vrf_if_rpl#"NGDCS-"}"
132+
133+
if [[ ${vrf_if} != "hsrp" ]]; then
134+
local policy_map=$(egrep "${vrf_if}|${be_if}$be_if_pad" "${pe_formal_cf}" | egrep "^policy-map.*")
135+
#local route_policy=$(egrep "${vrf_if_rpl}|${be_if}$be_if_pad" "${pe_formal_cf}" | egrep "^route-policy.*")
136+
# workaround to cover rpl name unmatching the vrf name
137+
local route_policy=$(egrep "${vrf_if_rpl_unmatch}|${be_if}$be_if_pad" "${pe_formal_cf}" | egrep "^route-policy.*")
138+
139+
if [[ ! -z "${policy_map}" ]]; then
140+
echo -e "${policy_map}" >> "${level2_pm_lst}"
141+
else
142+
echo -e "pm empty for line ${be_if},${vrf_if}" >> "${level2_pm_empty_lst}"
143+
fi
144+
145+
if [[ ! -z "${route_policy}" ]]; then
146+
echo -e "${route_policy}" >> "${level2_rpl_lst}"
147+
else
148+
echo -e "rpl empty for line ${be_if},${vrf_if}" >> "${level2_rpl_empty_lst}"
149+
fi
150+
fi
151+
done < "${level1_lst}"
152+
}
153+
154+
# Generating level1 cf ( vrf, if, router_[bgp|static|hsrp] )
155+
# Input: $f_arg && $level1_lst
156+
# Output: $level1_vrf_cf && $level1_if_cf && $level1_rbgp_cf && $level1_rstatic_cf && $level1_hsrp_cf
157+
gen_level1_cf() {
158+
while read -r line
159+
do
160+
local be_if="$(echo "${line}" | awk -F "," '{print $1}')"
161+
local vrf_if="$(echo "${line}" | awk -F "," '{print $2}')"
162+
163+
if [[ ${vrf_if} != "hsrp" ]]; then
164+
local vrf=$(egrep "${vrf_if}|${be_if}$be_if_pad" "${pe_formal_cf}" | egrep "^vrf.*")
165+
local interface=$(egrep "${vrf_if}|${be_if}$be_if_pad" "${pe_formal_cf}" | egrep "^interface.*")
166+
local router_bgp=$(egrep "${vrf_if}|${be_if}$be_if_pad" "${pe_formal_cf}" | egrep "^router\sbgp.*")
167+
local router_static=$(egrep "${vrf_if}|${be_if}$be_if_pad" "${pe_formal_cf}" | egrep "^router\sstatic.*")
168+
local router_hsrp=$(egrep "${vrf_if}|${be_if}$be_if_pad" "${pe_formal_cf}" | egrep "^router\shsrp.*")
169+
170+
echo -e "Extracting Level1 MPLS-PEs overlay configrations for ${be_if} ..."
171+
172+
if [[ ! -z "${vrf}" ]]; then
173+
echo -e "${vrf}" >> "${level1_vrf_cf}"
174+
else
175+
echo -e "vrf empty for line ${be_if},${vrf_if}" >> "${level1_vrf_empty_cf}"
176+
fi
177+
178+
if [[ ! -z "${interface}" ]]; then
179+
echo -e "${interface}" >> "${level1_if_cf}"
180+
else
181+
echo -e "interface empty for line ${be_if},${vrf_if}" >> "${level1_if_empty_cf}"
182+
fi
183+
184+
if [[ ! -z "${router_bgp}" ]]; then
185+
echo -e "${router_bgp}" >> "${level1_rbgp_cf}"
186+
else
187+
echo -e "router_bgp empty for line ${be_if},${vrf_if}" >> "${level1_rbgp_empty_cf}"
188+
fi
189+
190+
if [[ ! -z "${router_static}" ]]; then
191+
echo -e "${router_static}" >> "${level1_rstatic_cf}"
192+
else
193+
echo -e "router_static empty for line ${be_if},${vrf_if}" >> "${level1_rstatic_empty_cf}"
194+
fi
195+
196+
if [[ ! -z "${router_hsrp}" ]]; then
197+
echo -e "${router_hsrp}" >> "${level1_hsrp_cf}"
198+
else
199+
echo -e "router_hsrp empty for line ${be_if},${vrf_if}" >> "${level1_router_hsrp_empty_cf}"
200+
fi
201+
fi
202+
done < "${level1_lst}"
203+
}
204+
205+
# Generating level2 cf ( policy_map, route_policy )
206+
# Input: $f_arg && $level2_pm_lst && $level2_rpl_lst
207+
# Output: $level2_pm_cf && $level2_rpl_cf
208+
gen_level2_cf() {
209+
if [[ ! -f "${level2_rpl_lst}" ]]; then
210+
die "error - reading file: ${level2_rpl_lst}" "${error_reading_file}"
211+
fi
212+
213+
if [[ ! -f "${level2_pm_lst}" ]]; then
214+
die "error - reading file: ${level2_pm_lst}" "${error_reading_file}"
215+
fi
216+
217+
while read -r line
218+
do
219+
if [[ ! -z "${line}" ]]; then
220+
rpl=$(sed -n "/^${line}/,/end-policy/p" "${pe_formal_cf}")
221+
222+
echo -e "Extracting Level2 MPLS-PEs overlay configrations for ${line} ..."
223+
224+
if [[ ! -z "${rpl}" ]]; then
225+
echo -e "${rpl}" >> "${level2_rpl_cf}"
226+
echo -e "!" >> "${level2_rpl_cf}"
227+
else
228+
echo -e "rpl empty for line ${be_if},${vrf_if}" >> "${level2_rpl_empty_cf}"
229+
fi
230+
fi
231+
done < "${level2_rpl_lst}"
232+
233+
while read -r line
234+
do
235+
if [[ ! -z "${line}" ]]; then
236+
pm=$(sed -n "/^${line}/,/end-policy-map/p" "${pe_formal_cf}")
237+
238+
echo -e "Extracting Level2 MPLS-PEs overlay configrations for ${line} ..."
239+
240+
if [[ ! -z "${pm}" ]]; then
241+
echo -e "${pm}" >> "${level2_pm_cf}"
242+
echo -e "!" >> "${level2_pm_cf}"
243+
else
244+
echo -e "pm empty for line ${be_if},${vrf_if}" >> "${level2_pm_empty_cf}"
245+
fi
246+
fi
247+
done < "${level2_pm_lst}"
248+
}
249+
250+
parse_user_options "${@}"
251+
252+
if ((h_option_flag)); then
253+
usage
254+
exit 0
255+
fi
256+
257+
if ((f_option_flag)) && ((i_option_flag)); then
258+
readonly pe_hostname=$(echo "${f_arg}" | awk -F "." '{print $1}')
259+
readonly pe_formal_cf="${work_dir}/${f_arg}"
260+
readonly pe_bundle_if="${i_arg}"
261+
readonly be_if_pad=" "
262+
readonly level1_lst="${work_dir}/lsts/${pe_hostname}_${epoch}/level1.lst"
263+
readonly level2_lst="${work_dir}/lsts/${pe_hostname}_${epoch}/level2.lst"
264+
readonly level2_pm_lst="${work_dir}/lsts/${pe_hostname}_${epoch}/level2_pm.lst"
265+
readonly level2_rpl_lst="${work_dir}/lsts/${pe_hostname}_${epoch}/level2_rpl.lst"
266+
readonly level1_vrf_cf="${work_dir}/cfgs/${pe_hostname}_${epoch}/level1_vrf.cf"
267+
readonly level1_if_cf="${work_dir}/cfgs/${pe_hostname}_${epoch}/level1_if.cf"
268+
readonly level1_rbgp_cf="${work_dir}/cfgs/${pe_hostname}_${epoch}/level1_rbgp.cf"
269+
readonly level1_rstatic_cf="${work_dir}/cfgs/${pe_hostname}_${epoch}/level1_rstatic.cf"
270+
readonly level1_hsrp_cf="${work_dir}/cfgs/${pe_hostname}_${epoch}/level1_hsrp.cf"
271+
readonly level2_rpl_cf="${work_dir}/cfgs/${pe_hostname}_${epoch}/level2_rpl.cf"
272+
readonly level2_pm_cf="${work_dir}/cfgs/${pe_hostname}_${epoch}/level2_pm.cf"
273+
274+
readonly level2_pm_empty_lst="${work_dir}/lsts/${pe_hostname}_${epoch}/level2_pm_empty.lst"
275+
readonly level2_rpl_empty_lst="${work_dir}/lsts/${pe_hostname}_${epoch}/level2_rpl_empty.lst"
276+
readonly level1_vrf_empty_cf="${work_dir}/cfgs/${pe_hostname}_${epoch}/level1_vrf_empty.cf"
277+
readonly level1_if_empty_cf="${work_dir}/cfgs/${pe_hostname}_${epoch}/level1_if_empty.cf"
278+
readonly level1_rbgp_empty_cf="${work_dir}/cfgs/${pe_hostname}_${epoch}/level1_rbgp_empty.cf"
279+
readonly level1_rstatic_empty_cf="${work_dir}/cfgs/${pe_hostname}_${epoch}/level1_rstatic_empty.cf"
280+
readonly level1_hsrp_empty_cf="${work_dir}/cfgs/${pe_hostname}_${epoch}/level1_hsrp_empty.cf"
281+
readonly level2_rpl_empty_cf="${work_dir}/cfgs/${pe_hostname}_${epoch}/level2_rpl_empty.cf"
282+
readonly level2_pm_empty_cf="${work_dir}/cfgs/${pe_hostname}_${epoch}/level2_pm_empty.cf"
283+
284+
readonly pe_bundle_if_rgx1="^Bundle-Ether[0-9]{1,5}\.[0-9]{1,5}$"
285+
readonly pe_bundle_if_rgx2="^Bundle-Ether[0-9]{1,5}$"
286+
287+
if [[ ! -f "${pe_formal_cf}" ]]; then
288+
die "error - file reading failed: ${pe_formal_cf}" "${error_reading_file}"
289+
fi
290+
291+
if [[ ! "${pe_bundle_if}" =~ ${pe_bundle_if_rgx1} ]] | [[ ! "${pe_bundle_if}" =~ ${pe_bundle_if_rgx2} ]]; then
292+
die "error - input validation failed: ${pe_bundle_if}" "${error_validating_input}"
293+
fi
294+
295+
if [[ ! -d "${work_dir}/lsts/${pe_hostname}_${epoch}" ]]; then
296+
mkdir -p "${work_dir}/lsts/${pe_hostname}_${epoch}"
297+
fi
298+
299+
if [[ ! -d "${work_dir}/cfgs/${pe_hostname}_${epoch}" ]]; then
300+
mkdir -p "${work_dir}/cfgs/${pe_hostname}_${epoch}"
301+
fi
302+
303+
if [[ "${pe_bundle_if}" =~ ${pe_bundle_if_rgx1} ]]; then
304+
gen_level1_lst_rgx1
305+
elif [[ "${pe_bundle_if}" =~ ${pe_bundle_if_rgx2} ]]; then
306+
gen_level1_lst_rgx2
307+
fi
308+
309+
gen_level2_lst
310+
gen_level1_cf
311+
gen_level2_cf
312+
else
313+
die "error - mind your options/arguments - [ -h ] to know more" "${error_missing_options}"
314+
fi
315+
316+
exit 0

0 commit comments

Comments
 (0)
Please sign in to comment.