-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrefresh-static-group.exp
executable file
·218 lines (178 loc) · 5.15 KB
/
refresh-static-group.exp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
#!/usr/bin/expect
# read existing address objects
# delta results from new list
# create new objects
# redefine group object
# delete old objects
log_user 0
set timeout 45
set debug 0
set trace 0
proc help {} {
puts "PAN: refresh Panorama static group"
puts "Usage: $::argv0 <object-address-prefix> <object-address-group-name> <tag> < <stdio new>"
puts "example: $::argv0 WebEx WebEx-Networks CiscoWebex Webex < foo.txt"
exit 64
}
set path [file dirname [file normalize [info script]]]
source $path/inc/myexpect.exp
source $path/inc/common.tcl
if { [catch { source $path/config.tcl }] } {
puts "config.tcl does not exist, please create it from config.tcl.example"
exit 1
}
if { [llength $argv] != 3 } {
puts "Incorrect number of arguments"
[help]
}
## set hostname [string tolower [lindex $argv 0]]
set hostname $config(panorama)
set prefix [lindex $argv 0]
set group [lindex $argv 1]
set tag [lindex $argv 2]
# dry-run mode if passed in the "tag"
if { [string match "dry-run" $tag] } {
set dryrun 1
} else {
set dryrun 0
}
# used within object descriptions
set date [clock format [clock seconds] -format "%Y-%m-%d.%H:%M"]
###########
# read from stdio the new address list
foreach n [split [read stdin] "\n"] {
if { [string index $n 0] == "#" || [string length $n] == 0 } {
continue
}
lappend o_new [netmask $n]
}
# sanity check
if { ! [info exists o_new] } {
puts "exiting. unable to read new values from stdio"
exit 1
}
if {$trace} { foreach x $o_new { puts "# new input: $x" } }
###########
# spawn ssh connection
source $path/inc/ssh-init.exp
###########
# output config with set commands
send "set cli config-output-format set\r"
myexpect "$prompt>"
send "set cli pager off\r"
myexpect "$prompt>"
# enter config mode
send "configure\r"
myexpect "$prompt#"
###########
unset expect_out(buffer)
match_max 60000
# set shared address WebEx-170.72.0.0-16 ip-netmask 170.72.0.0/16
# set shared address WebEx-170.72.0.0-16 description CiscoWebExNetwork
# set shared address WebEx-170.72.0.0-16 tag WebEx
send "show shared address | match $prefix-\r"
expect -nocase "$prompt#"
set buffer [split $expect_out(buffer) "\n"]
# read currently configured address objects as old
set o_old {}
foreach l $buffer {
# reduce arbritrary whitespace
set l [list {*}[string map {\{ \\\{} $l]]
switch -glob -- $l {
"*ip-netmask*" {
# 170.72.0.0/16 WebEx-170.72.0.0-16
dict set o_old [lindex [split $l " "] 5] [lindex [split $l " "] 3]
}
}
}
# check if we have existing old entires to be removed
set o_rem {}
set o_existing {}
dict for {key value} $o_old {
if {$trace} { puts "# found old: $key\t$value" }
set x [lsearch $o_new $key]
if { $x == -1 } {
lappend o_rem $value
} else {
lappend o_existing $key
lappend group_members $value
}
}
if {$trace} { foreach x $o_existing { puts "# old: $x" } }
if {$debug} { foreach x $o_rem { puts "# rem: $x" } }
# check if we have new objects to add
set o_add {}
foreach n $o_new {
if { [llength o_existing] < 1 } {
continue
}
set x [lsearch $o_existing $n]
if { $x == -1 } {
lappend o_add $n
}
}
if {$debug} { foreach x $o_add { puts "# add: $x" } }
###########
# at this point lists o_add and o_rem should be ready for further processing
if { ([llength $o_add] < 1 && [llength $o_rem] < 1) } {
puts "$tag: no changes needed for $group"
exit 2
}
# process the ADDITIONS
foreach a $o_add {
# strip host entires and replace slash with dash
if { [string match "*/32" $a] } {
set object "$prefix-[lindex [split $a /] 0]"
} else {
set object "$prefix-[string map {/ -} $a]"
}
# remove ipv6 colons from object name
set object [string map {: -} $object]
log "info" "$tag: add $object for $group"
if { ! $dryrun } {
send "set shared address $object description \"Dynamically Updated $date No Touchy\" tag $tag ip-netmask $a\r"
myexpect "$prompt#"
}
lappend group_members $object
}
# redefine the GROUP
# this could be wrapped into the add loop and just add individual members
if {$debug} { puts "# group: $group_members" }
if { ! $dryrun } {
send "set shared address-group $group description \"Dynamically Updated $date No Touchy\" static \[ $group_members \]\r"
myexpect "$prompt#"
}
# process the REMOVALS
foreach r $o_rem {
log "info" "$tag: rem $r from $group"
if { ! $dryrun } {
send "delete shared address-group $group static $r\r"
myexpect "$prompt#"
send "delete shared address $r\r"
myexpect "$prompt#"
}
}
if { $dryrun } {
puts "dry-run: exiting without committing"
exit 2
}
###########
# commit
set timeout 120
send "commit description $config(commit_description) partial admin $config(username)\n"
myexpect "$prompt#"
# exit config mode
send "exit\r"
myexpect "$prompt>"
# commit-all to each template-stacks
foreach stack $config(templatestacks) {
send "commit-all template-stack description $config(commit_description) name $stack\r"
myexpect "$prompt>"
}
###########
# close goodbye
send "exit\r"
expect eof
puts "Success"
exit 0