salt.bash 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375
  1. # written by David Pravec
  2. # - feel free to /msg alekibango on IRC if you want to talk about this file
  3. # TODO: check if --config|-c was used and use configured config file for queries
  4. # TODO: solve somehow completion for salt -G pythonversion:[tab]
  5. # (not sure what to do with lists)
  6. # TODO: --range[tab] -- how?
  7. # TODO: --compound[tab] -- how?
  8. # TODO: use history to extract some words, esp. if ${cur} is empty
  9. # TODO: TEST EVERYTHING a lot
  10. # TODO: is it ok to use '--timeout 2' ?
  11. _salt_get_grains(){
  12. if [ "$1" = 'local' ] ; then
  13. salt-call --log-level=error --out=txt -- grains.ls | sed 's/^.*\[//' | tr -d ",']" |sed 's:\([a-z0-9]\) :\1\: :g'
  14. else
  15. salt '*' --timeout 2 --hide-timeout --log-level=error --out=txt -- grains.ls | sed 's/^.*\[//' | tr -d ",']" |sed 's:\([a-z0-9]\) :\1\: :g'
  16. fi
  17. }
  18. _salt_get_grain_values(){
  19. if [ "$1" = 'local' ] ; then
  20. salt-call --log-level=error --out=txt -- grains.item $1 |sed 's/^\S*:\s//' |grep -v '^\s*$'
  21. else
  22. salt '*' --timeout 2 --hide-timeout --log-level=error --out=txt -- grains.item $1 |sed 's/^\S*:\s//' |grep -v '^\s*$'
  23. fi
  24. }
  25. _salt_get_keys(){
  26. for type in $*; do
  27. # remove header from data:
  28. salt-key --no-color -l $type | tail -n+2
  29. done
  30. }
  31. _salt_list_functions(){
  32. # salt-call: get all functions on this minion
  33. # salt: get all functions on all minions
  34. # sed: remove all array overhead and convert to newline separated list
  35. # sort: chop out doubled entries, so overhead is minimal later during actual completion
  36. if [ "$1" = 'local' ] ; then
  37. salt-call --log-level=quiet --out=txt -- sys.list_functions \
  38. | sed "s/^.*\[//;s/[],']//g;s/ /\n/g" \
  39. | sort -u
  40. else
  41. salt '*' --timeout 2 --hide-timeout --log-level=quiet --out=txt -- sys.list_functions \
  42. | sed "s/^.*\[//;s/[],']//g;s/ /\n/g" \
  43. | sort -u
  44. fi
  45. }
  46. _salt_get_coms() {
  47. CACHE_DIR="$HOME/.cache/salt-${1}-comp-cache_functions"
  48. local _salt_cache_functions=${SALT_COMP_CACHE_FUNCTIONS:=$CACHE_DIR}
  49. local _salt_cache_timeout=${SALT_COMP_CACHE_TIMEOUT:='last hour'}
  50. if [ ! -d "$(dirname ${_salt_cache_functions})" ]; then
  51. mkdir -p "$(dirname ${_salt_cache_functions})"
  52. fi
  53. # Regenerate cache if timed out
  54. if [[ "$(stat --format=%Z ${_salt_cache_functions} 2>/dev/null)" -lt "$(date --date="${_salt_cache_timeout}" +%s)" ]]; then
  55. _salt_list_functions $1 > "${_salt_cache_functions}"
  56. fi
  57. # filter results, to only print the part to next dot (or end of function)
  58. sed 's/^\('${cur}'\(\.\|[^.]*\)\)\?.*/\1/' "${_salt_cache_functions}" | sort -u
  59. }
  60. _salt(){
  61. local cur prev opts _salt_grains _salt_coms pprev ppprev
  62. COMPREPLY=()
  63. cur="${COMP_WORDS[COMP_CWORD]}"
  64. prev="${COMP_WORDS[COMP_CWORD-1]}"
  65. if [ ${COMP_CWORD} -gt 2 ]; then
  66. pprev="${COMP_WORDS[COMP_CWORD-2]}"
  67. fi
  68. if [ ${COMP_CWORD} -gt 3 ]; then
  69. ppprev="${COMP_WORDS[COMP_CWORD-3]}"
  70. fi
  71. opts="-h --help -d --doc --documentation --version --versions-report -c \
  72. --config-dir= -v --verbose -t --timeout= -s --static -b --batch= \
  73. --batch-size= -E --pcre -L --list -G --grain --grain-pcre -N \
  74. --nodegroup -R --range -C --compound -I --pillar \
  75. --return= -a --auth= --eauth= --extended-auth= -T --make-token -S \
  76. --ipcidr --out=pprint --out=yaml --out=overstatestage --out=json \
  77. --out=raw --out=highstate --out=key --out=txt --no-color --out-indent= "
  78. if [[ "${cur}" == -* ]] ; then
  79. COMPREPLY=($(compgen -W "${opts}" -- ${cur}))
  80. return 0
  81. fi
  82. # 2 special cases for filling up grain values
  83. case "${pprev}" in
  84. -G|--grain|--grain-pcre)
  85. if [ "${cur}" = ":" ]; then
  86. COMPREPLY=($(compgen -W "`_salt_get_grain_values ${prev}`"))
  87. return 0
  88. fi
  89. ;;
  90. esac
  91. case "${ppprev}" in
  92. -G|--grain|--grain-pcre)
  93. if [ "${prev}" = ":" ]; then
  94. COMPREPLY=( $(compgen -W "`_salt_get_grain_values ${pprev}`" -- ${cur}) )
  95. return 0
  96. fi
  97. ;;
  98. esac
  99. if [ "${cur}" = "=" ] && [[ "${prev}" == --* ]]; then
  100. cur=""
  101. fi
  102. if [ "${prev}" = "=" ] && [[ "${pprev}" == --* ]]; then
  103. prev="${pprev}"
  104. fi
  105. case "${prev}" in
  106. -c|--config)
  107. COMPREPLY=($(compgen -f -- ${cur}))
  108. return 0
  109. ;;
  110. salt)
  111. COMPREPLY=($(compgen -W "\'*\' ${opts} $(_salt_get_keys acc)" -- ${cur}))
  112. return 0
  113. ;;
  114. -E|--pcre)
  115. COMPREPLY=($(compgen -W "$(_salt_get_keys acc)" -- ${cur}))
  116. return 0
  117. ;;
  118. -G|--grain|--grain-pcre)
  119. COMPREPLY=($(compgen -W "$(_salt_get_grains)" -- ${cur}))
  120. return 0
  121. ;;
  122. -C|--compound)
  123. COMPREPLY=() # TODO: finish this one? how?
  124. return 0
  125. ;;
  126. -t|--timeout)
  127. COMPREPLY=($( compgen -W "1 2 3 4 5 6 7 8 9 10 15 20 30 40 60 90 120 180" -- ${cur}))
  128. return 0
  129. ;;
  130. -b|--batch|--batch-size)
  131. COMPREPLY=($(compgen -W "1 2 3 4 5 6 7 8 9 10 15 20 30 40 50 60 70 80 90 100 120 150 200"))
  132. return 0
  133. ;;
  134. -N|--nodegroup)
  135. MASTER_CONFIG='/etc/salt/master'
  136. COMPREPLY=($(compgen -W "`awk -F ':' 'BEGIN {print_line = 0}; /^nodegroups/ {print_line = 1;getline } print_line && /^ */ {print $1} /^[^ ]/ {print_line = 0}' <${MASTER_CONFIG}`" -- ${cur}))
  137. return 0
  138. ;;
  139. esac
  140. _salt_coms=$(_salt_get_coms remote)
  141. # If there are still dots in the suggestion, do not append space
  142. grep "^${cur}.*\." "${_salt_coms}" &>/dev/null && compopt -o nospace
  143. all="${opts} ${_salt_coms}"
  144. COMPREPLY=( $(compgen -W "${all}" -- ${cur}) )
  145. return 0
  146. }
  147. complete -F _salt salt
  148. _saltkey(){
  149. local cur prev opts prev pprev
  150. COMPREPLY=()
  151. cur="${COMP_WORDS[COMP_CWORD]}"
  152. prev="${COMP_WORDS[COMP_CWORD-1]}"
  153. opts="-c --config-dir= -h --help --version --versions-report -q --quiet \
  154. -y --yes --gen-keys= --gen-keys-dir= --keysize= --key-logfile= \
  155. -l --list= -L --list-all -a --accept= -A --accept-all \
  156. -r --reject= -R --reject-all -p --print= -P --print-all \
  157. -d --delete= -D --delete-all -f --finger= -F --finger-all \
  158. --out=pprint --out=yaml --out=overstatestage --out=json --out=raw \
  159. --out=highstate --out=key --out=txt --no-color --out-indent= "
  160. if [ ${COMP_CWORD} -gt 2 ]; then
  161. pprev="${COMP_WORDS[COMP_CWORD-2]}"
  162. fi
  163. if [ ${COMP_CWORD} -gt 3 ]; then
  164. ppprev="${COMP_WORDS[COMP_CWORD-3]}"
  165. fi
  166. if [[ "${cur}" == -* ]] ; then
  167. COMPREPLY=($(compgen -W "${opts}" -- ${cur}))
  168. return 0
  169. fi
  170. if [ "${cur}" = "=" ] && [[ "${prev}" == --* ]]; then
  171. cur=""
  172. fi
  173. if [ "${prev}" = "=" ] && [[ "${pprev}" == --* ]]; then
  174. prev="${pprev}"
  175. fi
  176. case "${prev}" in
  177. -a|--accept)
  178. COMPREPLY=($(compgen -W "$(_salt_get_keys un rej)" -- ${cur}))
  179. return 0
  180. ;;
  181. -r|--reject)
  182. COMPREPLY=($(compgen -W "$(_salt_get_keys acc)" -- ${cur}))
  183. return 0
  184. ;;
  185. -d|--delete)
  186. COMPREPLY=($(compgen -W "$(_salt_get_keys acc un rej)" -- ${cur}))
  187. return 0
  188. ;;
  189. -c|--config)
  190. COMPREPLY=($(compgen -f -- ${cur}))
  191. return 0
  192. ;;
  193. --keysize)
  194. COMPREPLY=($(compgen -W "2048 3072 4096 5120 6144" -- ${cur}))
  195. return 0
  196. ;;
  197. --gen-keys)
  198. return 0
  199. ;;
  200. --gen-keys-dir)
  201. COMPREPLY=($(compgen -d -- ${cur}))
  202. return 0
  203. ;;
  204. -p|--print)
  205. COMPREPLY=($(compgen -W "$(_salt_get_keys acc un rej)" -- ${cur}))
  206. return 0
  207. ;;
  208. -l|--list)
  209. COMPREPLY=($(compgen -W "pre un acc accepted unaccepted rej rejected all" -- ${cur}))
  210. return 0
  211. ;;
  212. --accept-all)
  213. return 0
  214. ;;
  215. esac
  216. COMPREPLY=($(compgen -W "${opts} " -- ${cur}))
  217. return 0
  218. }
  219. complete -F _saltkey salt-key
  220. _saltcall(){
  221. local cur prev opts _salt_coms pprev ppprev
  222. COMPREPLY=()
  223. cur="${COMP_WORDS[COMP_CWORD]}"
  224. prev="${COMP_WORDS[COMP_CWORD-1]}"
  225. opts="-h --help -d --doc --documentation --version --versions-report \
  226. -m --module-dirs= -g --grains --return= --local -c --config-dir= -l --log-level= \
  227. --out=pprint --out=yaml --out=overstatestage --out=json --out=raw \
  228. --out=highstate --out=key --out=txt --no-color --out-indent= "
  229. if [ ${COMP_CWORD} -gt 2 ]; then
  230. pprev="${COMP_WORDS[COMP_CWORD-2]}"
  231. fi
  232. if [ ${COMP_CWORD} -gt 3 ]; then
  233. ppprev="${COMP_WORDS[COMP_CWORD-3]}"
  234. fi
  235. if [[ "${cur}" == -* ]] ; then
  236. COMPREPLY=($(compgen -W "${opts}" -- ${cur}))
  237. return 0
  238. fi
  239. if [ "${cur}" = "=" ] && [[ ${prev} == --* ]]; then
  240. cur=""
  241. fi
  242. if [ "${prev}" = "=" ] && [[ ${pprev} == --* ]]; then
  243. prev="${pprev}"
  244. fi
  245. case ${prev} in
  246. -m|--module-dirs)
  247. COMPREPLY=( $(compgen -d ${cur} ))
  248. return 0
  249. ;;
  250. -l|--log-level)
  251. COMPREPLY=( $(compgen -W "info none garbage trace warning error debug" -- ${cur}))
  252. return 0
  253. ;;
  254. -g|grains)
  255. return 0
  256. ;;
  257. salt-call)
  258. COMPREPLY=($(compgen -W "${opts}" -- ${cur}))
  259. return 0
  260. ;;
  261. esac
  262. _salt_coms=$(_salt_get_coms local)
  263. # If there are still dots in the suggestion, do not append space
  264. grep "^${cur}.*\." "${_salt_coms}" &>/dev/null && compopt -o nospace
  265. COMPREPLY=( $(compgen -W "${opts} ${_salt_coms}" -- ${cur} ))
  266. return 0
  267. }
  268. complete -F _saltcall salt-call
  269. _saltcp(){
  270. local cur prev opts target prefpart postpart helper filt pprev ppprev
  271. COMPREPLY=()
  272. cur="${COMP_WORDS[COMP_CWORD]}"
  273. prev="${COMP_WORDS[COMP_CWORD-1]}"
  274. opts="-t --timeout= -s --static -b --batch= --batch-size= \
  275. -h --help --version --versions-report -c --config-dir= \
  276. -E --pcre -L --list -G --grain --grain-pcre -N --nodegroup \
  277. -R --range -C --compound -I --pillar \
  278. --out=pprint --out=yaml --out=overstatestage --out=json --out=raw \
  279. --out=highstate --out=key --out=txt --no-color --out-indent= "
  280. if [[ "${cur}" == -* ]] ; then
  281. COMPREPLY=($(compgen -W "${opts}" -- ${cur}))
  282. return 0
  283. fi
  284. if [ "${cur}" = "=" ] && [[ "${prev}" == --* ]]; then
  285. cur=""
  286. fi
  287. if [ "${prev}" = "=" ] && [[ "${pprev}" == --* ]]; then
  288. prev=${pprev}
  289. fi
  290. case ${prev} in
  291. salt-cp)
  292. COMPREPLY=($(compgen -W "${opts} $(_salt_get_keys acc)" -- ${cur}))
  293. return 0
  294. ;;
  295. -t|--timeout)
  296. # those numbers are just a hint
  297. COMPREPLY=($(compgen -W "2 3 4 8 10 15 20 25 30 40 60 90 120 180 240 300" -- ${cur} ))
  298. return 0
  299. ;;
  300. -E|--pcre)
  301. COMPREPLY=($(compgen -W "$(_salt_get_keys acc)" -- ${cur}))
  302. return 0
  303. ;;
  304. -L|--list)
  305. # IMPROVEMENTS ARE WELCOME
  306. prefpart="${cur%,*},"
  307. postpart=${cur##*,}
  308. filt="^\($(echo ${cur}| sed 's:,:\\|:g')\)$"
  309. helper=($(_salt_get_keys acc | grep -v "${filt}" | sed "s/^/${prefpart}/"))
  310. COMPREPLY=($(compgen -W "${helper[*]}" -- ${cur}))
  311. return 0
  312. ;;
  313. -G|--grain|--grain-pcre)
  314. COMPREPLY=($(compgen -W "$(_salt_get_grains)" -- ${cur}))
  315. return 0
  316. ;;
  317. # FIXME
  318. -R|--range)
  319. # FIXME ??
  320. return 0
  321. ;;
  322. -C|--compound)
  323. # FIXME ??
  324. return 0
  325. ;;
  326. -c|--config)
  327. COMPREPLY=($(compgen -f -- ${cur}))
  328. return 0
  329. ;;
  330. esac
  331. # default is using opts:
  332. COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
  333. }
  334. complete -F _saltcp salt-cp