k8s kubectl autocomplete is great, until you want to run a command for multiple things.
For example, I want to delete 2 pods, I can run:
k delete pod foo-12345 bar-67890
But I can only autocomplete with foo. What about bar<tab>?
It is in the best case a partial workaround. After a few test, I can say that your goal can be achieved, but it have some cons. There might be a 3rd party solution but I am not aware of any.
bash-completion
'bash-completion' package is required for making kubectl shell completion work as expected. You can install it using apt-get install bash-completionmo
. More information can be found in Kubernetes Documentation Optional kubectl configurations.
Debugging
Bash-completion has it's own syntax and functions. For debugging purpose you can run export BASH_COMP_DEBUG_FILE=$HOME/compdebug.txt
. It will create compdebug
text file and send all debug output from kubectl shell
completion functions to it. Example output below:
__kubectl_parse_get: get completion by kubectl get -o template --template="{{ range .items }}{{ .metadata.name }} {{ end }}" "first-deployment-85b75bf4f9-mn8zh"
__kubectl_handle_word: c is 0 words[c] is kubectl
__kubectl_handle_command: c is 0 words[c] is kubectl
__kubectl_handle_command: looking for _kubectl_root_command
__kubectl_handle_word: c is 1 words[c] is get
__kubectl_handle_command: c is 1 words[c] is get
__kubectl_handle_command: looking for _kubectl_get
__kubectl_handle_word: c is 2 words[c] is pod
__kubectl_handle_noun: c is 2 words[c] is pod
__kubectl_handle_reply
__kubectl_parse_get: get completion by kubectl get -o template --template="{{ range .items }}{{ .metadata.name }} {{ end }}" "pod"
How it works
kubectl
doesn't complete more than one object, because it's autocomplete function runs sub-request kubectl get argN
to get list of objects, and argN
is the previous arguments of the existing command line. When you use it first time, it takes arguments from kubectl command pod->argN
and run kubectl get pod
. The second time it takes arguments from kubectl command pod podname1->argN
, so the sub-request looks like kubectl get podname1
instead of kubectl get pod
which cause en error and empty output instead of list of the objects.
Test Scenario
To achieve this script you can use command kubectl completion bash > k8scompletion.sh
.
It's good to create second completion script that you can rollback to default settings - kubectl completion bash > k8scompletion-copy.sh
.
$ vi k8scompletion.sh
In function __kubectl_get_resource()
I've edited __kubectl_parse_get "${nouns[${#nouns[@]} -1]}"
to __kubectl_parse_get "${nouns[0]}"
__kubectl_get_resource()
{
if [[ ${#nouns[@]} -eq 0 ]]; then
local kubectl_out
if kubectl_out=$(__kubectl_debug_out "kubectl api-resources $(__kubectl_override_flags) -o name --cached --request-timeout=5s --verbs=get"); then
COMPREPLY=( $( compgen -W "${kubectl_out[*]}" -- "$cur" ) )
return 0
fi
return 1
fi
__kubectl_parse_get "${nouns[0]}"
}
Script adjustment overview
Adjusted script allows you to complete kubernetes resources and all objects from this resource. The following workaround is enough for demonstration and solving the mentioned in the question problem, but can cause some side effects, so please pay attention to the results you get.
Side Note
Shell completion script varies from one kubectl
version to another, thus it is hard to create universal patch.
Test Output
$ kubectl delete <TAB>
apiservices.apiregistration.k8s.io nodes.metrics.k8s.io
backendconfigs.cloud.google.com persistentvolumeclaims
certificatesigningrequests.certificates.k8s.io persistentvolumes
clusterrolebindings.rbac.authorization.k8s.io poddisruptionbudgets.policy
clusterroles.rbac.authorization.k8s.io pods
componentstatuses podsecuritypolicies.policy
configmaps pods.metrics.k8s.io
controllerrevisions.apps podtemplates
cronjobs.batch priorityclasses.scheduling.k8s.io
csidrivers.storage.k8s.io replicasets.apps
... and few others
$ kubectl delete pod<TAB>
poddisruptionbudgets.policy pods podsecuritypolicies.policy pods.metrics.k8s.io podtemplates
$ kubectl delete pod <TAB><TAB>
httpd-deploy-1-6c4b998b99-jk876 httpd-deploy-6867dfd79c-tr648 nginx2 nginx-deploy-2-94985d7bd-bdb4d
httpd-deploy-2-64dc95c468-s7vt2 nginx nginx-deploy-1-5494687955-sm5lh nginx-deploy-85df977897-44lcn
$ kubectl get pod nginx<TAB>
nginx nginx2 nginx-deploy-1-5494687955-sm5lh nginx-deploy-2-94985d7bd-bdb4d nginx-deploy-85df977897-44lcn
$ kubectl get pod nginx-deploy-<TAB>
nginx-deploy-1-5494687955-sm5lh nginx-deploy-2-94985d7bd-bdb4d nginx-deploy-85df977897-44lcn
$ kubectl get pod nginx-deploy-1<TAB>
###It autocomplete below after clicking on tab to nginx-deploy-1-5494687955-sm5lh
$ kubectl get pod nginx-deploy-1-5494687955-sm5lh <TAB>
httpd-deploy-1-6c4b998b99-jk876 httpd-deploy-6867dfd79c-tr648 nginx2 nginx-deploy-2-94985d7bd-bdb4d
httpd-deploy-2-64dc95c468-s7vt2 nginx nginx-deploy-1-5494687955-sm5lh nginx-deploy-85df977897-44lcn
$ kubectl delete pod nginx-deploy-1-5494687955-sm5lh nginx<TAB>
nginx nginx2 nginx-deploy-1-5494687955-29vqs nginx-deploy-2-94985d7bd-bdb4d nginx-deploy-85df977897-44lcn
$ kubectl delete pod nginx-deploy-1-5494687955-sm5lh nginx2 <TAB>
httpd-deploy-1-6c4b998b99-jk876 httpd-deploy-6867dfd79c-tr648 nginx2 nginx-deploy-2-94985d7bd-bdb4d
httpd-deploy-2-64dc95c468-s7vt2 nginx nginx-deploy-1-5494687955-29vqs nginx-deploy-85df977897-44lcn
$ kubectl delete pod nginx-deploy-1-5494687955-sm5lh nginx2
Rollback changes
To apply this specific completion script, you have to use source
command - source k8scompletion.sh
or source k8scompletion-copy.sh
.