Parent directory

_knife

7860 bytes
  1#compdef knife
  2
  3# You can override the path to knife.rb and your cookbooks by setting
  4# KNIFE_CONF_PATH=/path/to/my/.chef/knife.rb
  5# KNIFE_COOKBOOK_PATH=/path/to/my/chef/cookbooks
  6# If you want your local cookbooks path to be calculated relative to where you are then
  7# set the below option
  8# KNIFE_RELATIVE_PATH=true
  9# Read around where these are used for more detail.
 10
 11# These flags should be available everywhere according to man knife
 12knife_general_flags=(--help --server-url --key --config --editor --format --log_level --logfile --no-editor --user --print-after --version --yes)
 13
 14# knife has a very special syntax, some example calls are:
 15# knife status
 16# knife cookbook list
 17# knife role show ROLENAME
 18# knife data bag show DATABAGNAME
 19# knife role show ROLENAME --attribute ATTRIBUTENAME
 20# knife cookbook show COOKBOOKNAME COOKBOOKVERSION recipes
 21
 22# The -Q switch in compadd allow for completions of things like "data bag" without having to go through two rounds of completion and avoids zsh inserting a \ for escaping spaces
 23_knife() {
 24  local curcontext="$curcontext" state line
 25  typeset -A opt_args
 26  cloudproviders=(bluebox ec2 rackspace slicehost terremark)
 27  _arguments \
 28    '1: :->knifecmd' \
 29    '2: :->knifesubcmd' \
 30    '3: :->knifesubcmd2' \
 31    '4: :->knifesubcmd3' \
 32    '5: :->knifesubcmd4' \
 33    '6: :->knifesubcmd5'
 34
 35  case $state in
 36  knifecmd)
 37    compadd -Q "$@" bootstrap client configure cookbook "cookbook site" "data bag" diff exec environment index node recipe role search solo ssh status upload vault windows $cloudproviders
 38    ;;
 39  knifesubcmd)
 40    case $words[2] in
 41    bluebox|ec2|rackspace|slicehost|terremark)
 42      compadd "$@" server images
 43      ;;
 44    client)
 45      compadd -Q "$@" "bulk delete" list create show delete edit reregister
 46      ;;
 47    configure)
 48      compadd "$@" client
 49      ;;
 50    cookbook)
 51      compadd -Q "$@" test list create download delete "metadata from" show "bulk delete" metadata upload
 52      ;;
 53    diff)
 54      _arguments '*:file or directory:_files -g "*"'
 55      ;;
 56    environment)
 57      compadd -Q "$@" list create delete edit show "from file"
 58      ;;
 59    node)
 60      compadd -Q "$@" "from file" create show edit delete list run_list "bulk delete"
 61      ;;
 62    recipe)
 63      compadd "$@" list
 64      ;;
 65    role)
 66      compadd -Q "$@" "bulk delete" create delete edit "from file" list show
 67      ;;
 68    solo)
 69      compadd "$@" bootstrap clean cook init prepare
 70      ;;
 71    upload)
 72      _arguments '*:file or directory:_files -g "*"'
 73      ;;
 74    vault)
 75      compadd -Q "$@" create decrypt delete edit remove "rotate all keys" "rotate keys" show update
 76      ;;
 77    windows)
 78      compadd "$@" bootstrap
 79      ;;
 80    *)
 81      _arguments '2:Subsubcommands:($(_knife_options1))'
 82      ;;
 83    esac
 84    ;;
 85  knifesubcmd2)
 86    case $words[3] in
 87    server)
 88      compadd "$@" list create delete
 89      ;;
 90    images)
 91      compadd "$@" list
 92      ;;
 93    site)
 94      compadd "$@" vendor show share search download list unshare
 95      ;;
 96    show|delete|edit)
 97      _arguments '3:Subsubcommands:($(_chef_$words[2]s_remote))'
 98      ;;
 99    upload|test)
100      _arguments '3:Subsubcommands:($(_chef_$words[2]s_local) --all)'
101      ;;
102    list)
103      compadd -a "$@" knife_general_flags
104      ;;
105    bag)
106      compadd -Q "$@" show edit list "from file" create delete
107      ;;
108    bootstrap|clean|cook|prepare)
109      compadd "$@" nodes/*.json(N:t:r)
110      ;;
111    init)
112      compadd "$@" ./*(/N:t)
113      ;;
114    *)
115      _arguments '3:Subsubcommands:($(_knife_options2))'
116      ;;
117    esac
118    ;;
119  knifesubcmd3)
120    case $words[3] in
121    show)
122      case $words[2] in
123      cookbook)
124        versioncomp=1
125        _arguments '4:Cookbookversions:($(_cookbook_versions) latest)'
126        ;;
127      node|client|role)
128        compadd "$@" --attribute
129        ;;
130      esac
131      ;;
132    esac
133    case $words[4] in
134    show|edit)
135      _arguments '4:Subsubsubcommands:($(_chef_$words[2]_$words[3]s_remote))'
136      ;;
137    file)
138      case $words[2] in
139      environment)
140        _arguments '*:files:_path_files -g "*.(rb|json)" -W "$(_chef_root)/environments"'
141        ;;
142      node)
143        _arguments '*:files:_path_files -g "*.(rb|json)" -W "$(_chef_root)/nodes"'
144        ;;
145      role)
146        _arguments '*:files:_path_files -g "*.(rb|json)" -W "$(_chef_root)/roles"'
147        ;;
148      *)
149        _arguments '*:Subsubcommands:($(_knife_options3))'
150        ;;
151      esac
152      ;;
153    list)
154      compadd -a "$@" knife_general_flags
155      ;;
156    *)
157      _arguments '*:Subsubcommands:($(_knife_options3))'
158      ;;
159    esac
160    ;;
161  knifesubcmd4)
162    if ((versioncomp > 0)); then
163      compadd "$@" attributes definitions files libraries providers recipes resources templates
164    else
165      case $words[5] in
166      file)
167        _arguments '*:directory:_path_files -/ -W "$(_chef_root)/data_bags" -qS \ '
168        ;;
169      *) _arguments '*:Subsubcommands:($(_knife_options2))' ;;
170      esac
171    fi
172    ;;
173  knifesubcmd5)
174    case $words[5] in
175    file)
176      _arguments '*:files:_path_files -g "*.json" -W "$(_chef_root)/data_bags/$words[6]"'
177      ;;
178    *)
179      _arguments '*:Subsubcommands:($(_knife_options3))'
180      ;;
181    esac
182    ;;
183  esac
184}
185
186# Helper functions to provide the argument completion for several depths of commands
187_knife_options1() {
188  (for line in $(knife $words[2] --help | grep -v "^knife"); do echo $line | grep "\-\-"; done)
189}
190
191_knife_options2() {
192  (for line in $(knife $words[2] $words[3] --help | grep -v "^knife"); do echo $line | grep "\-\-"; done)
193}
194
195_knife_options3() {
196  (for line in $(knife $words[2] $words[3] $words[4] --help | grep -v "^knife"); do echo $line | grep "\-\-"; done)
197}
198
199# The chef_x_remote functions use knife to get a list of objects of type x on the server
200_chef_roles_remote() {
201  (knife role list --format json | grep \" | awk '{print $1}' | awk -F"," '{print $1}' | awk -F"\"" '{print $2}')
202}
203
204_chef_clients_remote() {
205  (knife client list --format json | grep \" | awk '{print $1}' | awk -F"," '{print $1}' | awk -F"\"" '{print $2}')
206}
207
208_chef_nodes_remote() {
209  (knife node list --format json | grep \" | awk '{print $1}' | awk -F"," '{print $1}' | awk -F"\"" '{print $2}')
210}
211
212_chef_cookbooks_remote() {
213  (knife cookbook list --format json | grep \" | awk '{print $1}' | awk -F"," '{print $1}' | awk -F"\"" '{print $2}')
214}
215
216_chef_sitecookbooks_remote() {
217  (knife cookbook site list --format json | grep \" | awk '{print $1}' | awk -F"," '{print $1}' | awk -F"\"" '{print $2}')
218}
219
220_chef_data_bags_remote() {
221  (knife data bag list --format json | grep \" | awk '{print $1}' | awk -F"," '{print $1}' | awk -F"\"" '{print $2}')
222}
223
224_chef_environments_remote() {
225  (knife environment list | awk '{print $1}')
226}
227
228# The chef_x_local functions use the knife config to find the paths of relevant objects x to be uploaded to the server
229_chef_cookbooks_local() {
230  if [ $KNIFE_RELATIVE_PATH ]; then
231    local cookbook_path="$(_chef_root)/cookbooks"
232  else
233    local knife_rb=${KNIFE_CONF_PATH:-${HOME}/.chef/knife.rb}
234    if [ -f ./.chef/knife.rb ]; then
235      knife_rb="./.chef/knife.rb"
236    fi
237    local cookbook_path=${KNIFE_COOKBOOK_PATH:-$(grep cookbook_path $knife_rb | awk 'BEGIN {FS = "[" }; {print $2}' | sed 's/\,//g' | sed "s/'//g" | sed 's/\(.*\)]/\1/')}
238  fi
239  (for i in $cookbook_path; do ls $i; done)
240}
241
242# This function extracts the available cookbook versions on the chef server
243_cookbook_versions() {
244  (knife cookbook show $words[4] | grep -v $words[4] | grep -v -E '\]|\[|\{|\}' | sed 's/ //g' | sed 's/"//g')
245}
246
247# Searches up from current directory to find the closest folder that has a .chef folder
248# Useful for the knife upload/from file commands
249_chef_root() {
250  directory="$PWD"
251  while [ $directory != '/' ]; do
252    test -e "$directory/.chef" && echo "$directory" && return
253    directory="${directory:h}"
254  done
255}
256
257_knife "$@"