191 lines
5.8 KiB
Text
191 lines
5.8 KiB
Text
#compdef knife
|
|
|
|
# These flags should be available everywhere according to the knife man page.
|
|
knife_general_flags=(
|
|
--help
|
|
--server-url
|
|
--key
|
|
--config
|
|
--editor
|
|
--format
|
|
--log_level
|
|
--logfile
|
|
--no-editor
|
|
--user
|
|
--print-after
|
|
--version
|
|
--yes
|
|
)
|
|
|
|
# Knife has a very special syntax, some example calls are:
|
|
# knife status
|
|
# knife cookbook list
|
|
# knife role show ROLENAME
|
|
# knife data bag show DATABAGNAME
|
|
# knife role show ROLENAME --attribute ATTRIBUTENAME
|
|
# knife cookbook show COOKBOOKNAME COOKBOOKVERSION recipes
|
|
|
|
# The -Q switch in compadd allows for completion of things like "data bag" without
|
|
# having to go through two rounds of completion and avoids ZSH inserting a '\' for
|
|
# escaping spaces.
|
|
function _knife() {
|
|
local curcontext="$curcontext" state line
|
|
typeset -A opt_args
|
|
cloudproviders=(bluebox ec2 rackspace slicehost terremark)
|
|
_arguments \
|
|
'1: :->knifecmd'\
|
|
'2: :->knifesubcmd'\
|
|
'3: :->knifesubcmd2' \
|
|
'4: :->knifesubcmd3' \
|
|
'5: :->knifesubcmd4' \
|
|
'6: :->knifesubcmd5'
|
|
|
|
case $state in
|
|
(knifecmd)
|
|
compadd -Q "$@" bootstrap client configure cookbook "cookbook site" "data bag" exec index node recipe role search ssh status windows $cloudproviders
|
|
;;
|
|
(knifesubcmd)
|
|
case $words[2] in
|
|
(bluebox|ec2|rackspace|slicehost|terremark)
|
|
compadd "$@" server images
|
|
;;
|
|
(client)
|
|
compadd -Q "$@" "bulk delete" list create show delete edit reregister
|
|
;;
|
|
(configure)
|
|
compadd "$@" client
|
|
;;
|
|
(cookbook)
|
|
compadd -Q "$@" test list create download delete "metadata from" show "bulk delete" metadata upload
|
|
;;
|
|
(node)
|
|
compadd -Q "$@" "from file" create show edit delete list run_list "bulk delete"
|
|
;;
|
|
(recipe)
|
|
compadd "$@" list
|
|
;;
|
|
(role)
|
|
compadd -Q "$@" "bulk delete" create delete edit "from file" list show
|
|
;;
|
|
(windows)
|
|
compadd "$@" bootstrap
|
|
;;
|
|
(*)
|
|
_arguments '2:Subsubcommands:($(_knife_options1))'
|
|
esac
|
|
;;
|
|
(knifesubcmd2)
|
|
case $words[3] in
|
|
(server)
|
|
compadd "$@" list create delete
|
|
;;
|
|
(images)
|
|
compadd "$@" list
|
|
;;
|
|
(site)
|
|
compadd "$@" vendor show share search download list unshare
|
|
;;
|
|
(show|delete|edit)
|
|
_arguments '3:Subsubcommands:($(_chef_$words[2]s_remote))'
|
|
;;
|
|
(upload|test)
|
|
_arguments '3:Subsubcommands:($(_chef_$words[2]s_local) --all)'
|
|
;;
|
|
(list)
|
|
compadd -a "$@" knife_general_flags
|
|
;;
|
|
(bag)
|
|
compadd -Q "$@" show edit list "from file" create delete
|
|
;;
|
|
(*)
|
|
_arguments '3:Subsubcommands:($(_knife_options2))'
|
|
esac
|
|
;;
|
|
(knifesubcmd3)
|
|
case $words[3] in
|
|
(show)
|
|
case $words[2] in
|
|
(cookbook)
|
|
versioncomp=1
|
|
_arguments '4:Cookbookversions:($(_cookbook_versions) latest)'
|
|
;;
|
|
(node|client|role)
|
|
compadd "$@" --attribute
|
|
esac
|
|
esac
|
|
case $words[4] in
|
|
(show|edit)
|
|
_arguments '4:Subsubsubcommands:($(_chef_$words[2]_$words[3]s_remote))'
|
|
;;
|
|
(file)
|
|
_arguments '*:file or directory:_files -g "*.(rb|json)"'
|
|
;;
|
|
(list)
|
|
compadd -a "$@" knife_general_flags
|
|
;;
|
|
(*)
|
|
_arguments '*:Subsubcommands:($(_knife_options3))'
|
|
esac
|
|
;;
|
|
(knifesubcmd4)
|
|
if (( versioncomp > 0 )); then
|
|
compadd "$@" attributes definitions files libraries providers recipes resources templates
|
|
else
|
|
_arguments '*:Subsubcommands:($(_knife_options2))'
|
|
fi
|
|
;;
|
|
(knifesubcmd5)
|
|
_arguments '*:Subsubcommands:($(_knife_options3))'
|
|
esac
|
|
}
|
|
|
|
# Helper functions to provide the argument completion for several depths of commands
|
|
function _knife_options1() {
|
|
( for line in $( knife $words[2] --help | grep -v "^knife" ); do echo $line | grep "\-\-"; done )
|
|
}
|
|
|
|
function _knife_options2() {
|
|
( for line in $( knife $words[2] $words[3] --help | grep -v "^knife" ); do echo $line | grep "\-\-"; done )
|
|
}
|
|
|
|
function _knife_options3() {
|
|
( for line in $( knife $words[2] $words[3] $words[4] --help | grep -v "^knife" ); do echo $line | grep "\-\-"; done )
|
|
}
|
|
|
|
# The chef_x_remote functions use knife to get a list of objects of type x on the server
|
|
function _chef_roles_remote() {
|
|
(knife role list | grep \" | awk '{print $1}' | awk -F"," '{print $1}' | awk -F"\"" '{print $2}')
|
|
}
|
|
|
|
function _chef_clients_remote() {
|
|
(knife client list | grep \" | awk '{print $1}' | awk -F"," '{print $1}' | awk -F"\"" '{print $2}')
|
|
}
|
|
|
|
function _chef_nodes_remote() {
|
|
(knife node list | grep \" | awk '{print $1}' | awk -F"," '{print $1}' | awk -F"\"" '{print $2}')
|
|
}
|
|
|
|
function _chef_cookbooks_remote() {
|
|
(knife cookbook list | grep \" | awk '{print $1}' | awk -F"," '{print $1}' | awk -F"\"" '{print $2}')
|
|
}
|
|
|
|
function _chef_sitecookbooks_remote() {
|
|
(knife cookbook site list | grep \" | awk '{print $1}' | awk -F"," '{print $1}' | awk -F"\"" '{print $2}')
|
|
}
|
|
|
|
function _chef_data_bags_remote() {
|
|
(knife data bag list | grep \" | awk '{print $1}' | awk -F"," '{print $1}' | awk -F"\"" '{print $2}')
|
|
}
|
|
|
|
# The chef_x_local functions use the knife config to find the paths of relevant objects x to be uploaded to the server
|
|
function _chef_cookbooks_local() {
|
|
(for i in $( grep cookbook_path $HOME/.chef/knife.rb | awk 'BEGIN {FS = "[" }; {print $2}' | sed 's/\,//g' | sed "s/'//g" | sed 's/\(.*\)]/\1/' ); do ls $i; done)
|
|
}
|
|
|
|
# This function extracts the available cookbook versions on the chef server
|
|
function _cookbook_versions() {
|
|
(knife cookbook show $words[4] | grep -v $words[4] | grep -v -E '\]|\[|\{|\}' | sed 's/ //g' | sed 's/"//g')
|
|
}
|
|
|
|
function _knife "$@"
|
|
|