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