Commit b382bfa3aa3f8ef3b35d06c286b09bf9b19a5793
1 parent
dee510b3
add system information gathering, in cfengine speek this will create our hard classes
Showing
1 changed file
with
315 additions
and
0 deletions
system_information.sh
0 → 100755
1 | +#!/bin/dash | |
2 | + | |
3 | +## | |
4 | +# This is a first test what static informations I can gather from a | |
5 | +# system. The minimal requirement are the IP addresses because | |
6 | +# on these I build up my classes. | |
7 | +# The system type is also important...we might need to be running | |
8 | +# on variuous UNIX flavours. (But for now we focus on various linux | |
9 | +# flavours and maybe FreeBSD. | |
10 | +# | |
11 | + | |
12 | + | |
13 | +# Function calculates number of bit in a netmask | |
14 | +# | |
15 | +mask2cidr() { | |
16 | + local NBITS=0 | |
17 | + local OLDIFS="${IFS}" | |
18 | + IFS=. | |
19 | + | |
20 | + for DEC in $1 | |
21 | + do | |
22 | + case ${DEC} in | |
23 | + 255) NBITS=$((NBITS+8));; | |
24 | + 254) NBITS=$((NBITS+7));; | |
25 | + 252) NBITS=$((NBITS+6));; | |
26 | + 248) NBITS=$((NBITS+5));; | |
27 | + 240) NBITS=$((NBITS+4));; | |
28 | + 224) NBITS=$((NBITS+3));; | |
29 | + 192) NBITS=$((NBITS+2));; | |
30 | + 128) NBITS=$((NBITS+1));; | |
31 | + 0);; | |
32 | + *) NBITS=0; IFS="${OLDIFS}"; return 1 | |
33 | + esac | |
34 | + done | |
35 | + IFS="${OLDIFS}" | |
36 | + ${ECHO} "${NBITS}" | |
37 | +} | |
38 | + | |
39 | +cidr2mask() { | |
40 | + local MASK="" | |
41 | + local FULL_OCTETS=$((${1}/8)) | |
42 | + local PARTIAL_OCTET=$((${1}%8)) | |
43 | + | |
44 | + for I in 0 1 2 3 | |
45 | + do | |
46 | + if [ ${I} -lt ${FULL_OCTETS} ] | |
47 | + then | |
48 | + MASK="${MASK}255" | |
49 | + elif [ ${I} -eq ${FULL_OCTETS} ] | |
50 | + then | |
51 | + MASK="${MASK}$((256-(1<<(8-${PARTIAL_OCTET}))))" | |
52 | + else | |
53 | + MASK="${MASK}0" | |
54 | + fi | |
55 | + ${TEST} ${I} -lt 3 && MASK="${MASK}." | |
56 | + done | |
57 | + | |
58 | + ${ECHO} ${MASK} | |
59 | +} | |
60 | + | |
61 | +## | |
62 | +# retrieve interfaces. I prefer using ip if it is | |
63 | +# available, else I fallback to ifconfig... don't know | |
64 | +# how to retrieve this information on other systems. | |
65 | +# | |
66 | +get_if_data() { | |
67 | + if [ ${IP} ] | |
68 | + then | |
69 | + eval $(${IP} -o link | ${AWK} '{ | |
70 | + sub(/:/,"",$1); | |
71 | + no=$1; | |
72 | + sub(/:/,"",$2); | |
73 | + name=$2; | |
74 | + for (i=3; i<NF; i++) { | |
75 | + if ($i == "state") { | |
76 | + i++; state=$i | |
77 | + } | |
78 | + if ($i ~ /link/) { | |
79 | + i++; mac=$i; | |
80 | + classes=classes mac " " | |
81 | + } | |
82 | + } | |
83 | + print "IF" no "_NAME=" name ";IF" no "_STATE=" state ";IF" no "_MAC=" mac ";"; | |
84 | + if ("UP" == state) classes=classes mac " " | |
85 | + } | |
86 | + BEGIN { | |
87 | + classes="" | |
88 | + } | |
89 | + END { | |
90 | + print "CLASSES=\"${CLASSES}" classes " \";"; | |
91 | + print "NINTERFACES=" FNR ";" | |
92 | + }') | |
93 | + | |
94 | + eval $(${IP} -o addr | ${AWK} '{ | |
95 | + sub(/:/,"",$1); | |
96 | + no=$1; | |
97 | + if ($3 == "inet") { | |
98 | + sub(/[\/%].*/,"",$4); | |
99 | + print "IF" no "_IPV4=\"${IF" no "_IPV4}" $4 " \";"; | |
100 | + classes=classes $4 " " | |
101 | + } | |
102 | + if ($3 == "inet6") { | |
103 | + sub(/[\/%].*/,"",$4); | |
104 | + print "IF" no "_IPV6=\"${IF" no "_IPV6}" $4 " \";"; | |
105 | + classes=classes $4 " " | |
106 | + } | |
107 | + } | |
108 | + BEGIN { | |
109 | + classes="" | |
110 | + } | |
111 | + END { | |
112 | + print "CLASSES=\"${CLASSES}" classes " \";" | |
113 | + }') | |
114 | + else | |
115 | + if [ ${IFCONFIG} ] | |
116 | + then | |
117 | + #eval $(${IFCONFIG} -a | ${AWK} '{ | |
118 | + eval $(ifconfig -a | awk ' | |
119 | + /ether/ { mac=$2 } | |
120 | + /inet / { ipv4=ipv4 $2 " " } | |
121 | + /inet6/ { ipv6=ipv6 $2 " " } | |
122 | + /^[^ \t]/ { | |
123 | + if ("" != ipv4 || "" != ipv6) state="UP"; else state="DOWN"; | |
124 | + if ("" != name) { | |
125 | + print "IF" no "_NAME=" name ";IF" no "_STATE=" state ";IF" no "_MAC=" mac ";" \ | |
126 | + "IF" no "_IPV4=\"${IF" no "_IPV4}" ipv4 " \";" \ | |
127 | + "IF" no "_IPV6=\"${IF" no "_IPV6}" ipv6 " \";"; | |
128 | + no++; | |
129 | + } | |
130 | + ipv4=ipv6=""; | |
131 | + sub(/:/,"",$1); | |
132 | + name=$1 | |
133 | + } | |
134 | + BEGIN { | |
135 | + no=1; | |
136 | + } | |
137 | + END { | |
138 | + if ("" != ipv4 || "" != ipv6) state="UP"; else state="DOWN"; | |
139 | + print "IF" no "_NAME=" name ";IF" no "_STATE=" state ";IF" no "_MAC=" mac ";" \ | |
140 | + "IF" no "_IPV4=\"${IF" no "_IPV4}" ipv4 " \";" \ | |
141 | + "IF" no "_IPV6=\"${IF" no "_IPV6}" ipv6 " \";"; | |
142 | + print "NINTERFACES=" no | |
143 | + }') | |
144 | + else | |
145 | + ${LOGGER} -p local0.warn 'Found no way to retrieve interface information.' | |
146 | + fi | |
147 | + fi | |
148 | +} | |
149 | + | |
150 | +## | |
151 | +# start guessing the system type | |
152 | +# 1. get informations via uname | |
153 | +# | |
154 | +get_host_info() { | |
155 | + OS="$(${UNAME} -o)" | |
156 | + KERNEL="$(${UNAME} -s)" | |
157 | + VERSION="$(${UNAME} -r)" | |
158 | + PLATFORM="$(${UNAME} -m)" | |
159 | + HOSTNAME="$(${UNAME} -n)" | |
160 | + CLASSES="$(${ECHO} -e "${OS}\n${KERNEL}\n${VERSION}\n${PLATFORM}\n${HOSTNAME}" |\ | |
161 | + ${SORT} -u | ${TR} "\n" " ")" | |
162 | +} | |
163 | + | |
164 | +## | |
165 | +# if we are on a linux try to figure out wich distribution we are | |
166 | +# running. | |
167 | +# First look what kind of realease file we have: | |
168 | +# | |
169 | +# 00 01 - Novell SuSE ---> /etc/SuSE-release | |
170 | +# 00 02 - Red Hat ---> /etc/redhat-release, /etc/redhat_version | |
171 | +# 00 04 - Fedora ---> /etc/fedora-release | |
172 | +# 00 08 - Slackware ---> /etc/slackware-release, /etc/slackware-version | |
173 | +# 00 10 - Debian ---> /etc/debian_release, /etc/debian_version | |
174 | +# 00 20 - Mandrake ---> /etc/mandrake-release | |
175 | +# 00 40 - Yellow dog ---> /etc/yellowdog-release | |
176 | +# 00 80 - Sun JDS ---> /etc/sun-release | |
177 | +# 01 00 - Solaris/Sparc ---> /etc/release | |
178 | +# 02 00 - Gentoo ---> /etc/gentoo-release | |
179 | +# | |
180 | +# Here I follow a pessimistic way because I prefere to have no | |
181 | +# identification at all over a wrong one...so I check for all these files. | |
182 | +# If I can't find any or find multiple of them I assume this system | |
183 | +# as unidentified. Anyway when I found one I still check the content... | |
184 | +# Here I need some help as I don't know the valid content of these files. | |
185 | +# For now I assume that at least the name of the distribution is in | |
186 | +# the file. | |
187 | +# | |
188 | +get_dist_info() { | |
189 | + if [ -z "${KERNEL}" ] | |
190 | + then | |
191 | + get_host_info | |
192 | + fi | |
193 | + | |
194 | + if [ "Linux" = "${KERNEL}" ] | |
195 | + then | |
196 | + local SUSE=1 | |
197 | + local REDHAT=2 | |
198 | + local FEDORA=4 | |
199 | + local SLACKWARE=8 | |
200 | + local DEBIAN=16 | |
201 | + local MANDRAKE=32 | |
202 | + local YELLOWDOG=64 | |
203 | + local SUNJDS=128 | |
204 | + local GENTOO=256 | |
205 | + local SOLARIS=512 | |
206 | + | |
207 | + local LAST=${SOLARIS} | |
208 | + | |
209 | + local CHK=$((SUSE|REDHAT|FEDORA|SLACKWARE|DEBIAN|MANDRAKE|\ | |
210 | + YELLOWDOG|SUNJDS|GENTOO|SOLARIS)) | |
211 | + | |
212 | + eval local FILES_${SUSE}=\'/etc/SuSE-release\' | |
213 | + eval local FILES_${REDHAT}=\'/etc/redhat-release /etc/redhat_version\' | |
214 | + eval local FILES_${FEDORA}=\'/etc/fedora-release\' | |
215 | + eval local FILES_${SLACKWARE}=\'/etc/slackware-release /etc/slackware-version\' | |
216 | + eval local FILES_${DEBIAN}=\'/etc/debian_release /etc/debian_version\' | |
217 | + eval local FILES_${MANDRAKE}=\'/etc/mandrake-release\' | |
218 | + eval local FILES_${YELLOWDOG}=\'/etc/yellowdog-release\' | |
219 | + eval local FILES_${SUNJDS}=\'/etc/sun-release\' | |
220 | + eval local FILES_${GENTOO}=\'/etc/gentoo-release\' | |
221 | + eval local FILES_${SOLARIS}=\'/etc/release\' | |
222 | + | |
223 | + local CUR=1 | |
224 | + while [ ${CUR} -le ${LAST} ] | |
225 | + do | |
226 | + local DIR | |
227 | + | |
228 | + eval local FILES=\"\${FILES_${CUR}}\" | |
229 | + | |
230 | + for DIR in ${FILES} | |
231 | + do | |
232 | + ${TEST} -f ${DIR} || CHK=$((CHK&~CUR)) | |
233 | + done | |
234 | + | |
235 | + CUR=$((CUR*2)) | |
236 | + done | |
237 | + | |
238 | + DIST="Unknown" | |
239 | + | |
240 | + ${TEST} ${CHK} -eq ${SUSE} && DIST="Suse" | |
241 | + ${TEST} ${CHK} -eq ${REDHAT} && DIST="Redhat" | |
242 | + ${TEST} ${CHK} -eq ${FEDORA} && DIST="Fedora" | |
243 | + ${TEST} ${CHK} -eq ${SLACKWARE} && DIST="Slakware" | |
244 | + ${TEST} ${CHK} -eq ${DEBIAN} && DIST="Debian" | |
245 | + ${TEST} ${CHK} -eq ${MANDRAKE} && DIST="Mandrake" | |
246 | + ${TEST} ${CHK} -eq ${YELLOWDOG} && DIST="Yellowdog" | |
247 | + ${TEST} ${CHK} -eq ${SUNJDS} && DIST="Sun" | |
248 | + ${TEST} ${CHK} -eq ${GENTOO} && DIST="Gentoo" | |
249 | + ${TEST} ${CHK} -eq ${SOLARIS} && DIST="Solaris" | |
250 | + | |
251 | + if [ 'Unknown' != "${DIST}" ] | |
252 | + then | |
253 | + eval ${GREP} -iq ${DIST} \${FILES_${CHK}} || DIST="Unknown" | |
254 | + fi | |
255 | + | |
256 | + CLASSES="${CLASSES}${DIST} " | |
257 | + else | |
258 | + DIST="${OS}" | |
259 | + fi | |
260 | +} | |
261 | + | |
262 | +## | |
263 | +# Here now starts the usage of the functions defined above. | |
264 | +# | |
265 | + | |
266 | +## | |
267 | +# first specify some programs | |
268 | +# | |
269 | +WHICH="/usr/bin/which" | |
270 | +UNAME="$(${WHICH} uname)" | |
271 | +TEST="$(${WHICH} test)" | |
272 | +GREP="$(${WHICH} grep)" | |
273 | +AWK="$(${WHICH} awk)" | |
274 | +ECHO="$(${WHICH} echo)" | |
275 | +SORT="$(${WHICH} sort)" | |
276 | +TR="$(${WHICH} tr)" | |
277 | +PRINTF="$(${WHICH} printf)" | |
278 | +LOGGER="$(${WHICH} logger)" | |
279 | +IP="$(${WHICH} ip)" | |
280 | +IFCONFIG="$(${WHICH} ifconfig)" | |
281 | + | |
282 | +get_dist_info | |
283 | +get_if_data | |
284 | + | |
285 | +## | |
286 | +# report everysthing | |
287 | +# | |
288 | + | |
289 | +${PRINTF} "%15s : %s\n" "OS" "${OS}" | |
290 | +${PRINTF} "%15s : %s\n" "KERNEL" "${KERNEL}" | |
291 | +${PRINTF} "%15s : %s\n" "VERSION" "${VERSION}" | |
292 | +${PRINTF} "%15s : %s\n" "PLATFORM" "${PLATFORM}" | |
293 | +${PRINTF} "%15s : %s\n" "DIST" "${DIST}" | |
294 | +${PRINTF} "%15s : %s\n" "HOSTNAME" "${HOSTNAME}" | |
295 | +${PRINTF} "%15s : %s\n" "# INTERFACES" "${NINTERFACES}" | |
296 | + | |
297 | +NO=1 | |
298 | +while [ ${NO} -le ${NINTERFACES:=0} ] | |
299 | +do | |
300 | + eval printf \"%15s : %s\\\n\" \"IF${NO}_NAME\" \"\${IF${NO}_NAME}\" | |
301 | + eval printf \"%15s : %s\\\n\" \"IF${NO}_MAC\" \"\${IF${NO}_MAC}\" | |
302 | + eval printf \"%15s : %s\\\n\" \"IF${NO}_STATE\" \"\${IF${NO}_STATE}\" | |
303 | + eval printf \"%15s : %s\\\n\" \"IF${NO}_IPV4\" \"\${IF${NO}_IPV4}\" | |
304 | + eval printf \"%15s : %s\\\n\" \"IF${NO}_IPV6\" \"\${IF${NO}_IPV6}\" | |
305 | + NO=$((NO+1)) | |
306 | +done | |
307 | + | |
308 | +${PRINTF} "%15s : %s\n" "CLASSES" "${CLASSES}" | |
309 | + | |
310 | +echo | |
311 | +echo $(mask2cidr 255.255.128.0) | |
312 | +echo $(cidr2mask 17) | |
313 | +eval echo \$\(cidr2mask $(mask2cidr 255.255.128.0)\) | |
314 | + | |
315 | +# vim: set ts=4 sw=4: | ... | ... |
Please
register
or
login
to post a comment