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