kdebug 0.2.3__py3-none-any.whl → 0.3.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
kdebug/cli.py CHANGED
@@ -8,7 +8,7 @@ interactive shell access and backup capabilities.
8
8
 
9
9
  Usage Examples:
10
10
  # Interactive session with controller
11
- ./kdebug.py -n kubecost --controller sts --controller-name aggregator --container aggregator --cmd bash
11
+ ./kdebug.py -n kubecost --controller sts/aggregator --container aggregator --cmd bash
12
12
 
13
13
  # Interactive session with direct pod
14
14
  ./kdebug.py -n kubecost --pod aggregator-0 --container aggregator
@@ -17,10 +17,11 @@ Usage Examples:
17
17
  ./kdebug.py -n kubecost --pod aggregator-0 --container aggregator --backup /var/configs
18
18
 
19
19
  # Using deployment
20
- ./kdebug.py -n myapp --controller deployment --controller-name frontend --cmd sh
20
+ ./kdebug.py -n myapp --controller deploy/frontend --cmd sh
21
21
  """
22
22
 
23
23
  import argparse
24
+ import importlib.resources
24
25
  import json
25
26
  import os
26
27
  import subprocess
@@ -455,18 +456,12 @@ def select_pod(args) -> Optional[Dict]:
455
456
 
456
457
  # Controller-based selection
457
458
  if args.controller:
458
- if not args.controller_name:
459
- print(
460
- "Error: --controller-name is required when using --controller",
461
- file=sys.stderr,
462
- )
463
- return None
464
-
465
- pods = get_pods_by_controller(args.controller, args.controller_name, namespace)
459
+ controller_type, controller_name = args.controller
460
+ pods = get_pods_by_controller(controller_type, controller_name, namespace)
466
461
 
467
462
  if not pods:
468
463
  print(
469
- f"No pods found for {args.controller} '{args.controller_name}'",
464
+ f"No pods found for {controller_type} '{controller_name}'",
470
465
  file=sys.stderr,
471
466
  )
472
467
  return None
@@ -998,246 +993,43 @@ def cleanup_debug_container(
998
993
  return True
999
994
 
1000
995
 
1001
- def generate_bash_completion() -> str:
1002
- """Generate bash completion script."""
1003
- return """# kdebug bash completion
1004
- # Source this file or add to ~/.bashrc:
1005
- # source <(kdebug --completions bash)
1006
- # Or:
1007
- # source /path/to/completions/kdebug.bash
1008
-
1009
- _kdebug_get_contexts() {
1010
- kubectl config get-contexts -o name 2>/dev/null
1011
- }
1012
-
1013
- _kdebug_get_namespaces() {
1014
- local kubectl_args=$(_kdebug_get_kubectl_args)
1015
- kubectl $kubectl_args get namespaces -o jsonpath='{.items[*].metadata.name}' 2>/dev/null
1016
- }
1017
-
1018
- _kdebug_get_pods() {
1019
- local ns="${1:-default}"
1020
- local kubectl_args=$(_kdebug_get_kubectl_args)
1021
- kubectl $kubectl_args get pods -n "$ns" -o jsonpath='{.items[*].metadata.name}' 2>/dev/null
1022
- }
1023
-
1024
- _kdebug_get_controllers() {
1025
- local ns="${1:-default}"
1026
- local controller_type="$2"
1027
- local kubectl_args=$(_kdebug_get_kubectl_args)
1028
- case "$controller_type" in
1029
- deployment|deploy)
1030
- kubectl $kubectl_args get deployments -n "$ns" -o jsonpath='{.items[*].metadata.name}' 2>/dev/null
1031
- ;;
1032
- statefulset|sts)
1033
- kubectl $kubectl_args get statefulsets -n "$ns" -o jsonpath='{.items[*].metadata.name}' 2>/dev/null
1034
- ;;
1035
- daemonset|ds)
1036
- kubectl $kubectl_args get daemonsets -n "$ns" -o jsonpath='{.items[*].metadata.name}' 2>/dev/null
1037
- ;;
1038
- esac
1039
- }
1040
-
1041
- _kdebug_get_kubectl_args() {
1042
- local i args=""
1043
- for ((i=1; i < ${#COMP_WORDS[@]}; i++)); do
1044
- case "${COMP_WORDS[i]}" in
1045
- --context)
1046
- if [[ $((i+1)) -lt ${#COMP_WORDS[@]} ]]; then
1047
- args="$args --context=${COMP_WORDS[$((i+1))]}"
1048
- fi
1049
- ;;
1050
- --context=*)
1051
- args="$args ${COMP_WORDS[i]}"
1052
- ;;
1053
- --kubeconfig)
1054
- if [[ $((i+1)) -lt ${#COMP_WORDS[@]} ]]; then
1055
- args="$args --kubeconfig=${COMP_WORDS[$((i+1))]}"
1056
- fi
1057
- ;;
1058
- --kubeconfig=*)
1059
- args="$args ${COMP_WORDS[i]}"
1060
- ;;
1061
- esac
1062
- done
1063
- echo "$args"
1064
- }
1065
-
1066
- _kdebug_get_namespace_from_args() {
1067
- local i
1068
- for ((i=1; i < ${#COMP_WORDS[@]}; i++)); do
1069
- case "${COMP_WORDS[i]}" in
1070
- -n|--namespace)
1071
- if [[ $((i+1)) -lt ${#COMP_WORDS[@]} ]]; then
1072
- echo "${COMP_WORDS[$((i+1))]}"
1073
- return
1074
- fi
1075
- ;;
1076
- -n=*|--namespace=*)
1077
- echo "${COMP_WORDS[i]#*=}"
1078
- return
1079
- ;;
1080
- esac
1081
- done
1082
- local kubectl_args=$(_kdebug_get_kubectl_args)
1083
- kubectl $kubectl_args config view --minify -o jsonpath='{..namespace}' 2>/dev/null || echo "default"
1084
- }
1085
-
1086
- _kdebug_get_controller_from_args() {
1087
- local i
1088
- for ((i=1; i < ${#COMP_WORDS[@]}; i++)); do
1089
- case "${COMP_WORDS[i]}" in
1090
- --controller)
1091
- if [[ $((i+1)) -lt ${#COMP_WORDS[@]} ]]; then
1092
- echo "${COMP_WORDS[$((i+1))]}"
1093
- return
1094
- fi
1095
- ;;
1096
- --controller=*)
1097
- echo "${COMP_WORDS[i]#*=}"
1098
- return
1099
- ;;
1100
- esac
1101
- done
1102
- }
1103
-
1104
- _kdebug() {
1105
- local cur prev words cword
1106
- _init_completion || return
1107
-
1108
- local opts="--pod --controller --controller-name -n --namespace --context --kubeconfig
1109
- --container --debug-image --cmd --cd-into --backup --compress --as-root
1110
- --debug --completions -V --version --help -h"
1111
-
1112
- local controller_types="deployment deploy statefulset sts daemonset ds"
1113
-
1114
- case "$prev" in
1115
- -n|--namespace)
1116
- COMPREPLY=($(compgen -W "$(_kdebug_get_namespaces)" -- "$cur"))
1117
- return
1118
- ;;
1119
- --context)
1120
- COMPREPLY=($(compgen -W "$(_kdebug_get_contexts)" -- "$cur"))
1121
- return
1122
- ;;
1123
- --kubeconfig)
1124
- _filedir
1125
- return
1126
- ;;
1127
- --pod)
1128
- local ns=$(_kdebug_get_namespace_from_args)
1129
- COMPREPLY=($(compgen -W "$(_kdebug_get_pods "$ns")" -- "$cur"))
1130
- return
1131
- ;;
1132
- --controller)
1133
- COMPREPLY=($(compgen -W "$controller_types" -- "$cur"))
1134
- return
1135
- ;;
1136
- --controller-name)
1137
- local ns=$(_kdebug_get_namespace_from_args)
1138
- local ct=$(_kdebug_get_controller_from_args)
1139
- if [[ -n "$ct" ]]; then
1140
- COMPREPLY=($(compgen -W "$(_kdebug_get_controllers "$ns" "$ct")" -- "$cur"))
1141
- fi
1142
- return
1143
- ;;
1144
- --container|--debug-image|--cmd|--cd-into|--backup)
1145
- # These take arbitrary values, no completion
1146
- return
1147
- ;;
1148
- --completions)
1149
- COMPREPLY=($(compgen -W "bash zsh" -- "$cur"))
1150
- return
1151
- ;;
1152
- esac
1153
-
1154
- if [[ "$cur" == -* ]]; then
1155
- COMPREPLY=($(compgen -W "$opts" -- "$cur"))
1156
- return
1157
- fi
1158
- }
1159
-
1160
- complete -F _kdebug kdebug
1161
- """
1162
-
1163
-
1164
- def generate_zsh_completion() -> str:
1165
- """Generate zsh completion script."""
1166
- return """#compdef kdebug
1167
- # kdebug zsh completion
1168
- # Install: kdebug --completions zsh > ~/.zsh/completions/_kdebug
1169
- # Or: source <(kdebug --completions zsh)
1170
-
1171
- _kdebug_kubectl_args() {
1172
- local args=""
1173
- [[ -n "${opt_args[--context]}" ]] && args="$args --context=${opt_args[--context]}"
1174
- [[ -n "${opt_args[--kubeconfig]}" ]] && args="$args --kubeconfig=${opt_args[--kubeconfig]}"
1175
- echo "$args"
1176
- }
1177
-
1178
- _kdebug_contexts() {
1179
- local -a contexts
1180
- contexts=(${(f)"$(kubectl config get-contexts -o name 2>/dev/null)"})
1181
- _describe 'context' contexts
1182
- }
1183
-
1184
- _kdebug_namespaces() {
1185
- local kubectl_args=$(_kdebug_kubectl_args)
1186
- local -a namespaces
1187
- namespaces=(${(f)"$(kubectl $kubectl_args get namespaces -o jsonpath='{range .items[*]}{.metadata.name}{"\\n"}{end}' 2>/dev/null)"})
1188
- _describe 'namespace' namespaces
1189
- }
996
+ def _output_completion_script(shell: str) -> None:
997
+ """Output the shell completion script and exit."""
998
+ files = {"bash": "kdebug.bash", "zsh": "_kdebug", "fish": "kdebug.fish"}
999
+ filename = files.get(shell)
1000
+ if not filename:
1001
+ print(f"Unknown shell: {shell}", file=sys.stderr)
1002
+ sys.exit(1)
1190
1003
 
1191
- _kdebug_pods() {
1192
- local ns="${opt_args[-n]:-${opt_args[--namespace]:-default}}"
1193
- local kubectl_args=$(_kdebug_kubectl_args)
1194
- local -a pods
1195
- pods=(${(f)"$(kubectl $kubectl_args get pods -n "$ns" -o jsonpath='{range .items[*]}{.metadata.name}{"\\n"}{end}' 2>/dev/null)"})
1196
- _describe 'pod' pods
1197
- }
1004
+ try:
1005
+ completions_pkg = importlib.resources.files("kdebug.completions")
1006
+ script = (completions_pkg / filename).read_text()
1007
+ print(script)
1008
+ except Exception as e:
1009
+ print(f"Error reading completion script: {e}", file=sys.stderr)
1010
+ sys.exit(1)
1198
1011
 
1199
- _kdebug_controller_names() {
1200
- local ns="${opt_args[-n]:-${opt_args[--namespace]:-default}}"
1201
- local ct="${opt_args[--controller]:-deployment}"
1202
- local kubectl_args=$(_kdebug_kubectl_args)
1203
- local resource
1204
- case "$ct" in
1205
- deployment|deploy) resource="deployments" ;;
1206
- statefulset|sts) resource="statefulsets" ;;
1207
- daemonset|ds) resource="daemonsets" ;;
1208
- *) resource="deployments" ;;
1209
- esac
1210
- local -a names
1211
- names=(${(f)"$(kubectl $kubectl_args get "$resource" -n "$ns" -o jsonpath='{range .items[*]}{.metadata.name}{"\\n"}{end}' 2>/dev/null)"})
1212
- _describe 'controller name' names
1213
- }
1214
1012
 
1215
- _kdebug() {
1216
- local -a args
1217
- args=(
1218
- '(-V --version)'{-V,--version}'[Show version and exit]'
1219
- '(-h --help)'{-h,--help}'[Show help message]'
1220
- '--pod[Pod name for direct selection]:pod:_kdebug_pods'
1221
- '--controller[Controller type]:type:(deployment deploy statefulset sts daemonset ds)'
1222
- '--controller-name[Controller name]:name:_kdebug_controller_names'
1223
- '(-n --namespace)'{-n,--namespace}'[Kubernetes namespace]:namespace:_kdebug_namespaces'
1224
- '--context[Kubernetes context to use]:context:_kdebug_contexts'
1225
- '--kubeconfig[Path to kubeconfig file]:path:_files'
1226
- '--container[Target container for process namespace sharing]:container:'
1227
- '--debug-image[Debug container image]:image:'
1228
- '--cmd[Command to run in debug container]:command:'
1229
- '--cd-into[Change to directory on start]:directory:_files -/'
1230
- '--backup[Copy path from pod to local backups]:path:'
1231
- '--compress[Compress backup as tar.gz]'
1232
- '--as-root[Run debug container as root]'
1233
- '--debug[Show kubectl commands being executed]'
1234
- '--completions[Output shell completion script]:shell:(bash zsh)'
1235
- )
1236
- _arguments -s $args
1237
- }
1013
+ def parse_controller_arg(value: str) -> Tuple[str, str]:
1014
+ """Parse --controller TYPE/NAME format and return (controller_type, controller_name).
1238
1015
 
1239
- _kdebug "$@"
1240
- """
1016
+ Raises argparse.ArgumentTypeError on invalid input.
1017
+ """
1018
+ if "/" not in value:
1019
+ raise argparse.ArgumentTypeError(
1020
+ f"Invalid format '{value}'. Expected TYPE/NAME (e.g. sts/myapp, deploy/frontend)."
1021
+ )
1022
+ controller_type, controller_name = value.split("/", 1)
1023
+ if not controller_name:
1024
+ raise argparse.ArgumentTypeError(
1025
+ f"Missing controller name after '/'. Expected TYPE/NAME (e.g. sts/myapp)."
1026
+ )
1027
+ if controller_type.lower() not in CONTROLLER_ALIASES:
1028
+ valid_types = ", ".join(sorted(CONTROLLER_ALIASES.keys()))
1029
+ raise argparse.ArgumentTypeError(
1030
+ f"Unknown controller type '{controller_type}'. Valid types: {valid_types}"
1031
+ )
1032
+ return (controller_type, controller_name)
1241
1033
 
1242
1034
 
1243
1035
  class KdebugHelpFormatter(argparse.RawDescriptionHelpFormatter):
@@ -1258,12 +1050,13 @@ def main():
1258
1050
  Usage:
1259
1051
  kdebug [options] Interactive TUI mode
1260
1052
  kdebug --pod POD [options] Direct pod selection
1261
- kdebug --controller TYPE --controller-name NAME Controller selection""",
1053
+ kdebug --controller TYPE/NAME [options] Controller selection""",
1262
1054
  formatter_class=KdebugHelpFormatter,
1263
1055
  epilog="""Examples:
1264
1056
  kdebug # Interactive TUI
1265
1057
  kdebug -n prod --pod api-0 # Direct pod
1266
- kdebug --controller sts --controller-name db # StatefulSet pod
1058
+ kdebug --controller sts/db # StatefulSet pod
1059
+ kdebug --controller deploy/frontend --cmd sh # Deployment pod
1267
1060
  kdebug --pod web-0 --backup /app/config # Backup files""",
1268
1061
  )
1269
1062
 
@@ -1279,14 +1072,9 @@ Usage:
1279
1072
  )
1280
1073
  target_group.add_argument(
1281
1074
  "--controller",
1282
- choices=list(CONTROLLER_ALIASES.keys()),
1283
- metavar="TYPE",
1284
- help="Controller type: deployment, sts, ds (or full names)",
1285
- )
1286
- target_group.add_argument(
1287
- "--controller-name",
1288
- metavar="NAME",
1289
- help="Controller name (required with --controller)",
1075
+ type=parse_controller_arg,
1076
+ metavar="TYPE/NAME",
1077
+ help="Controller as TYPE/NAME (e.g. sts/myapp, deploy/frontend)",
1290
1078
  )
1291
1079
 
1292
1080
  # Options arguments
@@ -1349,7 +1137,7 @@ Usage:
1349
1137
  )
1350
1138
  util_group.add_argument(
1351
1139
  "--completions",
1352
- choices=["bash", "zsh"],
1140
+ choices=["bash", "zsh", "fish"],
1353
1141
  metavar="SHELL",
1354
1142
  help="Output shell completion script",
1355
1143
  )
@@ -1358,10 +1146,7 @@ Usage:
1358
1146
 
1359
1147
  # Handle --completions early
1360
1148
  if args.completions:
1361
- if args.completions == "bash":
1362
- print(generate_bash_completion())
1363
- else:
1364
- print(generate_zsh_completion())
1149
+ _output_completion_script(args.completions)
1365
1150
  sys.exit(0)
1366
1151
 
1367
1152
  # Set debug mode and kubectl global options
@@ -1370,10 +1155,6 @@ Usage:
1370
1155
  KUBECTL_CONTEXT = args.context
1371
1156
  KUBECTL_KUBECONFIG = args.kubeconfig
1372
1157
 
1373
- # Validate arguments - allow interactive mode if no pod/controller specified
1374
- if args.controller and not args.controller_name:
1375
- parser.error("--controller-name is required when using --controller")
1376
-
1377
1158
  # Select pod
1378
1159
  pod = select_pod(args)
1379
1160
  if not pod:
File without changes
@@ -0,0 +1,94 @@
1
+ #compdef kdebug
2
+ # kdebug zsh completion
3
+ # Install: kdebug --completions zsh > ~/.zsh/completions/_kdebug
4
+ # Or: source <(kdebug --completions zsh)
5
+
6
+ _kdebug_kubectl_args() {
7
+ local args=""
8
+ [[ -n "${opt_args[--context]}" ]] && args="$args --context=${opt_args[--context]}"
9
+ [[ -n "${opt_args[--kubeconfig]}" ]] && args="$args --kubeconfig=${opt_args[--kubeconfig]}"
10
+ echo "$args"
11
+ }
12
+
13
+ _kdebug_contexts() {
14
+ local -a contexts
15
+ contexts=(${(f)"$(kubectl config get-contexts -o name 2>/dev/null)"})
16
+ _describe 'context' contexts
17
+ }
18
+
19
+ _kdebug_namespaces() {
20
+ local kubectl_args=$(_kdebug_kubectl_args)
21
+ local -a namespaces
22
+ namespaces=(${(f)"$(kubectl $kubectl_args get namespaces -o jsonpath='{range .items[*]}{.metadata.name}{"\n"}{end}' 2>/dev/null)"})
23
+ _describe 'namespace' namespaces
24
+ }
25
+
26
+ _kdebug_pods() {
27
+ local ns="${opt_args[-n]:-${opt_args[--namespace]:-default}}"
28
+ local kubectl_args=$(_kdebug_kubectl_args)
29
+ local -a pods
30
+ pods=(${(f)"$(kubectl $kubectl_args get pods -n "$ns" -o jsonpath='{range .items[*]}{.metadata.name}{"\n"}{end}' 2>/dev/null)"})
31
+ _describe 'pod' pods
32
+ }
33
+
34
+ _kdebug_controllers() {
35
+ local ns="${opt_args[-n]:-${opt_args[--namespace]:-default}}"
36
+ local kubectl_args=$(_kdebug_kubectl_args)
37
+ local cur_word="${words[CURRENT]}"
38
+
39
+ if [[ "$cur_word" == */* ]]; then
40
+ # User typed TYPE/ - complete the name
41
+ local ct="${cur_word%%/*}"
42
+ local resource
43
+ case "$ct" in
44
+ deployment|deploy) resource="deployments" ;;
45
+ statefulset|sts) resource="statefulsets" ;;
46
+ daemonset|ds) resource="daemonsets" ;;
47
+ *) resource="deployments" ;;
48
+ esac
49
+ local -a names
50
+ names=(${(f)"$(kubectl $kubectl_args get "$resource" -n "$ns" -o jsonpath='{range .items[*]}{.metadata.name}{"\n"}{end}' 2>/dev/null)"})
51
+ local -a completions
52
+ for name in "${names[@]}"; do
53
+ completions+=("${ct}/${name}")
54
+ done
55
+ compadd -Q -- "${completions[@]}"
56
+ else
57
+ # Complete the type prefix
58
+ local -a prefixes
59
+ prefixes=(
60
+ 'deployment/:Deployment'
61
+ 'deploy/:Deployment (short)'
62
+ 'statefulset/:StatefulSet'
63
+ 'sts/:StatefulSet (short)'
64
+ 'daemonset/:DaemonSet'
65
+ 'ds/:DaemonSet (short)'
66
+ )
67
+ _describe 'controller type' prefixes -S ''
68
+ fi
69
+ }
70
+
71
+ _kdebug() {
72
+ local -a args
73
+ args=(
74
+ '(-V --version)'{-V,--version}'[Show version and exit]'
75
+ '(-h --help)'{-h,--help}'[Show help message]'
76
+ '--pod[Pod name for direct selection]:pod:_kdebug_pods'
77
+ '--controller[Controller as TYPE/NAME]:controller:_kdebug_controllers'
78
+ '(-n --namespace)'{-n,--namespace}'[Kubernetes namespace]:namespace:_kdebug_namespaces'
79
+ '--context[Kubernetes context to use]:context:_kdebug_contexts'
80
+ '--kubeconfig[Path to kubeconfig file]:path:_files'
81
+ '--container[Target container for process namespace sharing]:container:'
82
+ '--debug-image[Debug container image]:image:'
83
+ '--cmd[Command to run in debug container]:command:'
84
+ '--cd-into[Change to directory on start]:directory:_files -/'
85
+ '--backup[Copy path from pod to local backups]:path:'
86
+ '--compress[Compress backup as tar.gz]'
87
+ '--as-root[Run debug container as root]'
88
+ '--debug[Show kubectl commands being executed]'
89
+ '--completions[Output shell completion script]:shell:(bash zsh fish)'
90
+ )
91
+ _arguments -s $args
92
+ }
93
+
94
+ _kdebug "$@"
@@ -0,0 +1,146 @@
1
+ # kdebug bash completion
2
+ # Source this file or add to ~/.bashrc:
3
+ # source <(kdebug --completions bash)
4
+ # Or:
5
+ # source /path/to/completions/kdebug.bash
6
+
7
+ _kdebug_get_contexts() {
8
+ kubectl config get-contexts -o name 2>/dev/null
9
+ }
10
+
11
+ _kdebug_get_namespaces() {
12
+ local kubectl_args=$(_kdebug_get_kubectl_args)
13
+ kubectl $kubectl_args get namespaces -o jsonpath='{.items[*].metadata.name}' 2>/dev/null
14
+ }
15
+
16
+ _kdebug_get_pods() {
17
+ local ns="${1:-default}"
18
+ local kubectl_args=$(_kdebug_get_kubectl_args)
19
+ kubectl $kubectl_args get pods -n "$ns" -o jsonpath='{.items[*].metadata.name}' 2>/dev/null
20
+ }
21
+
22
+ _kdebug_get_controllers() {
23
+ local ns="${1:-default}"
24
+ local controller_type="$2"
25
+ local kubectl_args=$(_kdebug_get_kubectl_args)
26
+ case "$controller_type" in
27
+ deployment|deploy)
28
+ kubectl $kubectl_args get deployments -n "$ns" -o jsonpath='{.items[*].metadata.name}' 2>/dev/null
29
+ ;;
30
+ statefulset|sts)
31
+ kubectl $kubectl_args get statefulsets -n "$ns" -o jsonpath='{.items[*].metadata.name}' 2>/dev/null
32
+ ;;
33
+ daemonset|ds)
34
+ kubectl $kubectl_args get daemonsets -n "$ns" -o jsonpath='{.items[*].metadata.name}' 2>/dev/null
35
+ ;;
36
+ esac
37
+ }
38
+
39
+ _kdebug_get_kubectl_args() {
40
+ local i args=""
41
+ for ((i=1; i < ${#COMP_WORDS[@]}; i++)); do
42
+ case "${COMP_WORDS[i]}" in
43
+ --context)
44
+ if [[ $((i+1)) -lt ${#COMP_WORDS[@]} ]]; then
45
+ args="$args --context=${COMP_WORDS[$((i+1))]}"
46
+ fi
47
+ ;;
48
+ --context=*)
49
+ args="$args ${COMP_WORDS[i]}"
50
+ ;;
51
+ --kubeconfig)
52
+ if [[ $((i+1)) -lt ${#COMP_WORDS[@]} ]]; then
53
+ args="$args --kubeconfig=${COMP_WORDS[$((i+1))]}"
54
+ fi
55
+ ;;
56
+ --kubeconfig=*)
57
+ args="$args ${COMP_WORDS[i]}"
58
+ ;;
59
+ esac
60
+ done
61
+ echo "$args"
62
+ }
63
+
64
+ _kdebug_get_namespace_from_args() {
65
+ local i
66
+ for ((i=1; i < ${#COMP_WORDS[@]}; i++)); do
67
+ case "${COMP_WORDS[i]}" in
68
+ -n|--namespace)
69
+ if [[ $((i+1)) -lt ${#COMP_WORDS[@]} ]]; then
70
+ echo "${COMP_WORDS[$((i+1))]}"
71
+ return
72
+ fi
73
+ ;;
74
+ -n=*|--namespace=*)
75
+ echo "${COMP_WORDS[i]#*=}"
76
+ return
77
+ ;;
78
+ esac
79
+ done
80
+ local kubectl_args=$(_kdebug_get_kubectl_args)
81
+ kubectl $kubectl_args config view --minify -o jsonpath='{..namespace}' 2>/dev/null || echo "default"
82
+ }
83
+
84
+ _kdebug() {
85
+ local cur prev words cword
86
+ _init_completion || return
87
+
88
+ local opts="--pod --controller -n --namespace --context --kubeconfig
89
+ --container --debug-image --cmd --cd-into --backup --compress --as-root
90
+ --debug --completions -V --version --help -h"
91
+
92
+ local controller_prefixes="deployment/ deploy/ statefulset/ sts/ daemonset/ ds/"
93
+
94
+ case "$prev" in
95
+ -n|--namespace)
96
+ COMPREPLY=($(compgen -W "$(_kdebug_get_namespaces)" -- "$cur"))
97
+ return
98
+ ;;
99
+ --context)
100
+ COMPREPLY=($(compgen -W "$(_kdebug_get_contexts)" -- "$cur"))
101
+ return
102
+ ;;
103
+ --kubeconfig)
104
+ _filedir
105
+ return
106
+ ;;
107
+ --pod)
108
+ local ns=$(_kdebug_get_namespace_from_args)
109
+ COMPREPLY=($(compgen -W "$(_kdebug_get_pods "$ns")" -- "$cur"))
110
+ return
111
+ ;;
112
+ --controller)
113
+ # Complete TYPE/NAME - if cur contains /, complete the name part
114
+ if [[ "$cur" == */* ]]; then
115
+ local ct="${cur%%/*}"
116
+ local ns=$(_kdebug_get_namespace_from_args)
117
+ local names=$(_kdebug_get_controllers "$ns" "$ct")
118
+ local completions=""
119
+ for name in $names; do
120
+ completions="$completions ${ct}/${name}"
121
+ done
122
+ COMPREPLY=($(compgen -W "$completions" -- "$cur"))
123
+ else
124
+ COMPREPLY=($(compgen -W "$controller_prefixes" -- "$cur"))
125
+ # Don't add trailing space after type prefix
126
+ compopt -o nospace
127
+ fi
128
+ return
129
+ ;;
130
+ --container|--debug-image|--cmd|--cd-into|--backup)
131
+ # These take arbitrary values, no completion
132
+ return
133
+ ;;
134
+ --completions)
135
+ COMPREPLY=($(compgen -W "bash zsh fish" -- "$cur"))
136
+ return
137
+ ;;
138
+ esac
139
+
140
+ if [[ "$cur" == -* ]]; then
141
+ COMPREPLY=($(compgen -W "$opts" -- "$cur"))
142
+ return
143
+ fi
144
+ }
145
+
146
+ complete -F _kdebug kdebug
@@ -0,0 +1,121 @@
1
+ # kdebug fish completion
2
+ # Install: kdebug --completions fish | source
3
+ # Or: kdebug --completions fish > ~/.config/fish/completions/kdebug.fish
4
+
5
+ function __kdebug_get_kubectl_args
6
+ set -l tokens (commandline -opc)
7
+ set -l args
8
+ set -l i 2
9
+ while test $i -le (count $tokens)
10
+ switch $tokens[$i]
11
+ case --context
12
+ set -l next (math $i + 1)
13
+ if test $next -le (count $tokens)
14
+ set -a args --context=$tokens[$next]
15
+ end
16
+ case '--context=*'
17
+ set -a args $tokens[$i]
18
+ case --kubeconfig
19
+ set -l next (math $i + 1)
20
+ if test $next -le (count $tokens)
21
+ set -a args --kubeconfig=$tokens[$next]
22
+ end
23
+ case '--kubeconfig=*'
24
+ set -a args $tokens[$i]
25
+ end
26
+ set i (math $i + 1)
27
+ end
28
+ echo $args
29
+ end
30
+
31
+ function __kdebug_get_namespace_from_args
32
+ set -l tokens (commandline -opc)
33
+ set -l i 2
34
+ while test $i -le (count $tokens)
35
+ switch $tokens[$i]
36
+ case -n --namespace
37
+ set -l next (math $i + 1)
38
+ if test $next -le (count $tokens)
39
+ echo $tokens[$next]
40
+ return
41
+ end
42
+ case '-n=*' '--namespace=*'
43
+ string replace -r '^[^=]+=' '' $tokens[$i]
44
+ return
45
+ end
46
+ set i (math $i + 1)
47
+ end
48
+ set -l kubectl_args (__kdebug_get_kubectl_args)
49
+ set -l ns (kubectl $kubectl_args config view --minify -o jsonpath='{..namespace}' 2>/dev/null)
50
+ if test -n "$ns"
51
+ echo $ns
52
+ else
53
+ echo default
54
+ end
55
+ end
56
+
57
+ function __kdebug_get_contexts
58
+ kubectl config get-contexts -o name 2>/dev/null
59
+ end
60
+
61
+ function __kdebug_get_namespaces
62
+ set -l kubectl_args (__kdebug_get_kubectl_args)
63
+ kubectl $kubectl_args get namespaces -o jsonpath='{range .items[*]}{.metadata.name}{"\n"}{end}' 2>/dev/null
64
+ end
65
+
66
+ function __kdebug_get_pods
67
+ set -l ns (__kdebug_get_namespace_from_args)
68
+ set -l kubectl_args (__kdebug_get_kubectl_args)
69
+ kubectl $kubectl_args get pods -n "$ns" -o jsonpath='{range .items[*]}{.metadata.name}{"\n"}{end}' 2>/dev/null
70
+ end
71
+
72
+ function __kdebug_get_controllers
73
+ set -l ns (__kdebug_get_namespace_from_args)
74
+ set -l kubectl_args (__kdebug_get_kubectl_args)
75
+ set -l cur (commandline -ct)
76
+
77
+ if string match -q '*/*' -- "$cur"
78
+ # User typed TYPE/ - complete the name part
79
+ set -l ct (string replace -r '/.*' '' -- "$cur")
80
+ set -l resource
81
+ switch $ct
82
+ case deployment deploy
83
+ set resource deployments
84
+ case statefulset sts
85
+ set resource statefulsets
86
+ case daemonset ds
87
+ set resource daemonsets
88
+ case '*'
89
+ return
90
+ end
91
+ for name in (kubectl $kubectl_args get "$resource" -n "$ns" -o jsonpath='{range .items[*]}{.metadata.name}{"\n"}{end}' 2>/dev/null)
92
+ echo "$ct/$name"
93
+ end
94
+ else
95
+ # Complete type prefixes
96
+ printf '%s\n' deployment/ deploy/ statefulset/ sts/ daemonset/ ds/
97
+ end
98
+ end
99
+
100
+ # Disable file completions for kdebug
101
+ complete -c kdebug -f
102
+
103
+ # Target selection
104
+ complete -c kdebug -l pod -d 'Pod name for direct selection' -xa '(__kdebug_get_pods)'
105
+ complete -c kdebug -l controller -d 'Controller as TYPE/NAME' -xa '(__kdebug_get_controllers)'
106
+
107
+ # Options
108
+ complete -c kdebug -s n -l namespace -d 'Kubernetes namespace' -xa '(__kdebug_get_namespaces)'
109
+ complete -c kdebug -l context -d 'Kubernetes context to use' -xa '(__kdebug_get_contexts)'
110
+ complete -c kdebug -l kubeconfig -d 'Path to kubeconfig file' -rF
111
+ complete -c kdebug -l container -d 'Target container for process namespace sharing' -x
112
+ complete -c kdebug -l debug-image -d 'Debug container image' -x
113
+ complete -c kdebug -l cmd -d 'Command to run in debug container' -x
114
+ complete -c kdebug -l cd-into -d 'Change to directory on start' -rF
115
+ complete -c kdebug -l backup -d 'Copy path from pod to local backups' -x
116
+ complete -c kdebug -l compress -d 'Compress backup as tar.gz'
117
+ complete -c kdebug -l as-root -d 'Run debug container as root'
118
+ complete -c kdebug -l debug -d 'Show kubectl commands being executed'
119
+ complete -c kdebug -l completions -d 'Output shell completion script' -xa 'bash zsh fish'
120
+ complete -c kdebug -s V -l version -d 'Show version and exit'
121
+ complete -c kdebug -s h -l help -d 'Show help message'
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kdebug
3
- Version: 0.2.3
3
+ Version: 0.3.1
4
4
  Summary: Universal Kubernetes Debug Container Utility
5
5
  Project-URL: Homepage, https://github.com/jessegoodier/kdebug
6
6
  Project-URL: Repository, https://github.com/jessegoodier/kdebug
@@ -13,7 +13,7 @@ Classifier: License :: OSI Approved :: MIT License
13
13
  Classifier: Operating System :: MacOS
14
14
  Classifier: Operating System :: POSIX :: Linux
15
15
  Classifier: Programming Language :: Python :: 3
16
- Requires-Python: >=3.8
16
+ Requires-Python: >=3.9
17
17
  Description-Content-Type: text/markdown
18
18
 
19
19
  # kdebug - Universal Kubernetes Debug and File Copy Container Utility
@@ -0,0 +1,10 @@
1
+ kdebug/__init__.py,sha256=OOhp8y3zVAw6RzVcSq4wtyeAzPneUnVw-b2OIXtjgTc,182
2
+ kdebug/cli.py,sha256=c6dWkjD2d-c7lEDjUX9x0MTirHaxIYIrNV_Lg9umMJw,42047
3
+ kdebug/completions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
+ kdebug/completions/_kdebug,sha256=xa4h4pE-awN3Kb5HA7GMBuu8vTMrKg_6PKy9Q0X3iXE,3539
5
+ kdebug/completions/kdebug.bash,sha256=HkNrBKLIDojWrWPq9QXA9sd6k79LnUBEqW8Es2Rf5FE,4731
6
+ kdebug/completions/kdebug.fish,sha256=kzJ4ww0-IyXduYqEHFTNKLLHSZ9Jad9oOEAoweYjKuU,4469
7
+ kdebug-0.3.1.dist-info/METADATA,sha256=tSCzCfUkE37yoFYP9OCFXnofcsFnbk8HlIZHYodD99I,10044
8
+ kdebug-0.3.1.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
9
+ kdebug-0.3.1.dist-info/entry_points.txt,sha256=SSMhCgTQLJEK7RwCvlEiskLgk3_zXzTssTu6d-1_sJo,43
10
+ kdebug-0.3.1.dist-info/RECORD,,
@@ -1,6 +0,0 @@
1
- kdebug/__init__.py,sha256=OOhp8y3zVAw6RzVcSq4wtyeAzPneUnVw-b2OIXtjgTc,182
2
- kdebug/cli.py,sha256=OBeBwem1AzinYYn-90XgFOpOemB1R09XxlS48o9r84M,49147
3
- kdebug-0.2.3.dist-info/METADATA,sha256=7RCK9i9IPq5Sw9eipFHrDB2Z0j9UOKJAjkNQ_BPmU4o,10044
4
- kdebug-0.2.3.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
5
- kdebug-0.2.3.dist-info/entry_points.txt,sha256=SSMhCgTQLJEK7RwCvlEiskLgk3_zXzTssTu6d-1_sJo,43
6
- kdebug-0.2.3.dist-info/RECORD,,
File without changes