Skip to content

Commit 995d2e4

Browse files
authored
Merge pull request #18 from cybozu-go/bash-completion
Implement completion
2 parents 10f88e5 + 43751d7 commit 995d2e4

File tree

12 files changed

+155
-29
lines changed

12 files changed

+155
-29
lines changed

cmd/npv/app/dump.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ var dumpCmd = &cobra.Command{
2424
RunE: func(cmd *cobra.Command, args []string) error {
2525
return runDump(context.Background(), cmd.OutOrStdout(), args[0])
2626
},
27+
ValidArgsFunction: completePods,
2728
}
2829

2930
func runDump(ctx context.Context, w io.Writer, name string) error {

cmd/npv/app/helper.go

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import (
1717
"k8s.io/apimachinery/pkg/types"
1818
"k8s.io/client-go/dynamic"
1919
"k8s.io/client-go/kubernetes"
20-
"k8s.io/client-go/rest"
20+
ctrl "sigs.k8s.io/controller-runtime"
2121
)
2222

2323
var cachedCiliumClients map[string]*client.Client
@@ -27,7 +27,7 @@ func init() {
2727
}
2828

2929
func createK8sClients() (*kubernetes.Clientset, *dynamic.DynamicClient, error) {
30-
config, err := rest.InClusterConfig()
30+
config, err := ctrl.GetConfig()
3131
if err != nil {
3232
return nil, nil, err
3333
}
@@ -121,6 +121,26 @@ func getPodIdentity(ctx context.Context, d *dynamic.DynamicClient, namespace, na
121121
return identity, nil
122122
}
123123

124+
func listRelevantPods(ctx context.Context, c *kubernetes.Clientset, namespace string) ([]corev1.Pod, error) {
125+
pods, err := c.CoreV1().Pods(namespace).List(ctx, metav1.ListOptions{})
126+
if err != nil {
127+
return nil, err
128+
}
129+
130+
ret := make([]corev1.Pod, 0)
131+
for _, p := range pods.Items {
132+
// Skip non-relevant pods
133+
if p.Spec.HostNetwork {
134+
continue
135+
}
136+
if p.Status.Phase != corev1.PodRunning {
137+
continue
138+
}
139+
ret = append(ret, p)
140+
}
141+
return ret, nil
142+
}
143+
124144
// key: identity number
125145
// value: CiliumIdentity resource
126146
func getIdentityResourceMap(ctx context.Context, d *dynamic.DynamicClient) (map[int]*unstructured.Unstructured, error) {

cmd/npv/app/helper_completion.go

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package app
2+
3+
import (
4+
"context"
5+
6+
"github.com/spf13/cobra"
7+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
8+
)
9+
10+
func completeNamespaces(cmd *cobra.Command, args []string, toComplete string) (ret []string, directive cobra.ShellCompDirective) {
11+
ret = make([]string, 0)
12+
directive = cobra.ShellCompDirectiveNoFileComp
13+
14+
clientset, _, err := createK8sClients()
15+
if err != nil {
16+
return
17+
}
18+
19+
nss, err := clientset.CoreV1().Namespaces().List(context.Background(), metav1.ListOptions{})
20+
if err != nil {
21+
return
22+
}
23+
24+
for _, ns := range nss.Items {
25+
ret = append(ret, ns.Name)
26+
}
27+
return
28+
}
29+
30+
func completePods(cmd *cobra.Command, args []string, toComplete string) (ret []string, directive cobra.ShellCompDirective) {
31+
ret = make([]string, 0)
32+
directive = cobra.ShellCompDirectiveNoFileComp
33+
34+
clientset, _, err := createK8sClients()
35+
if err != nil {
36+
return
37+
}
38+
39+
pods, err := listRelevantPods(context.Background(), clientset, rootOptions.namespace)
40+
if err != nil {
41+
return
42+
}
43+
44+
for _, p := range pods {
45+
ret = append(ret, p.Name)
46+
}
47+
return
48+
}

cmd/npv/app/inspect.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ var inspectCmd = &cobra.Command{
3333
RunE: func(cmd *cobra.Command, args []string) error {
3434
return runInspect(context.Background(), cmd.OutOrStdout(), args[0])
3535
},
36+
ValidArgsFunction: completePods,
3637
}
3738

3839
type policyEntryKey struct {

cmd/npv/app/list.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ var listCmd = &cobra.Command{
3636
RunE: func(cmd *cobra.Command, args []string) error {
3737
return runList(context.Background(), cmd.OutOrStdout(), args[0])
3838
},
39+
ValidArgsFunction: completePods,
3940
}
4041

4142
type derivedFromEntry struct {

cmd/npv/app/root.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,12 @@ func init() {
2626
rootCmd.PersistentFlags().Uint16Var(&rootOptions.proxyPort, "proxy-port", 8080, "port number of the proxy endpoints")
2727
rootCmd.PersistentFlags().StringVarP(&rootOptions.output, "output", "o", OutputSimple, "output format")
2828
rootCmd.PersistentFlags().BoolVar(&rootOptions.noHeaders, "no-headers", false, "stop printing header")
29+
rootCmd.RegisterFlagCompletionFunc("namespace", completeNamespaces)
2930
}
3031

31-
var rootCmd = &cobra.Command{}
32+
var rootCmd = &cobra.Command{
33+
Use: "npv",
34+
}
3235

3336
func Execute() {
3437
if err := rootCmd.Execute(); err != nil {

cmd/npv/app/summary.go

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@ import (
77
"strings"
88

99
"github.com/spf13/cobra"
10-
corev1 "k8s.io/api/core/v1"
11-
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1210
)
1311

1412
func init() {
@@ -50,24 +48,16 @@ func runSummary(ctx context.Context, w io.Writer) error {
5048
}
5149

5250
summary := make([]summaryEntry, 0)
53-
pods, err := clientset.CoreV1().Pods(rootOptions.namespace).List(ctx, metav1.ListOptions{})
51+
pods, err := listRelevantPods(ctx, clientset, rootOptions.namespace)
5452
if err != nil {
5553
return err
5654
}
5755

58-
for _, p := range pods.Items {
56+
for _, p := range pods {
5957
var entry summaryEntry
6058
entry.Namespace = p.Namespace
6159
entry.Name = p.Name
6260

63-
// Skip non-relevant pods
64-
if p.Spec.HostNetwork {
65-
continue
66-
}
67-
if p.Status.Phase != corev1.PodRunning {
68-
continue
69-
}
70-
7161
policies, err := queryPolicyMap(ctx, clientset, dynamicClient, rootOptions.namespace, p.Name)
7262
if err != nil {
7363
return err

e2e/Makefile

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,11 +72,19 @@ install-test-pod:
7272
install-policy-viewer:
7373
$(MAKE) -C ../ build
7474
PODNAME=$$(kubectl get po -l app=ubuntu -o name | cut -d'/' -f2); \
75+
kubectl cp testdata/onboard $${PODNAME}:/tmp/; \
76+
kubectl exec $${PODNAME} -- chmod +x /tmp/onboard; \
77+
kubectl exec $${PODNAME} -- /tmp/onboard; \
7578
kubectl cp $(POLICY_VIEWER) $${PODNAME}:/tmp/; \
7679
kubectl exec $${PODNAME} -- chmod +x /tmp/npv; \
7780
kubectl cp $$(aqua which kubectl) $${PODNAME}:/tmp/; \
7881
kubectl exec $${PODNAME} -- chmod +x /tmp/kubectl
7982

83+
.PHONY: pilot
84+
pilot:
85+
@PODNAME=$$(kubectl get po -l app=ubuntu -o name | cut -d'/' -f2); \
86+
kubectl exec -it $${PODNAME} -- bash
87+
8088
.PHONY: test
8189
test:
8290
go test -v -race . -ginkgo.v -ginkgo.fail-fast

e2e/testdata/onboard

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#!/bin/bash
2+
3+
if ! grep boarded /root/.bashrc > /dev/null 2>&1; then
4+
echo '. /usr/share/bash-completion/bash_completion' >> /root/.bashrc
5+
echo 'export PATH=${PATH}:/tmp' >> /root/.bashrc
6+
echo '. <(npv completion bash)' >> /root/.bashrc
7+
echo '# boarded' >> /root/.bashrc
8+
fi

e2e/testdata/ubuntu.yaml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ rules:
1212
- apiGroups:
1313
- ""
1414
resources:
15+
- namespaces
1516
- pods
1617
verbs:
1718
- get
@@ -58,9 +59,6 @@ spec:
5859
app: ubuntu
5960
spec:
6061
serviceAccountName: ubuntu
61-
securityContext:
62-
runAsUser: 1000
63-
runAsGroup: 1000
6462
containers:
6563
- name: ubuntu
6664
args:

go.mod

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,18 @@ require (
1111
k8s.io/api v0.31.2
1212
k8s.io/apimachinery v0.31.2
1313
k8s.io/client-go v0.31.2
14+
sigs.k8s.io/controller-runtime v0.19.3
1415
sigs.k8s.io/yaml v1.4.0
1516
)
1617

1718
require (
1819
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
20+
github.com/beorn7/perks v1.0.1 // indirect
1921
github.com/blang/semver/v4 v4.0.0 // indirect
22+
github.com/cespare/xxhash/v2 v2.3.0 // indirect
2023
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
2124
github.com/emicklei/go-restful/v3 v3.11.2 // indirect
25+
github.com/evanphx/json-patch/v5 v5.9.0 // indirect
2226
github.com/fsnotify/fsnotify v1.7.0 // indirect
2327
github.com/fxamacker/cbor/v2 v2.7.0 // indirect
2428
github.com/go-logr/logr v1.4.2 // indirect
@@ -36,6 +40,7 @@ require (
3640
github.com/go-openapi/validate v0.22.3 // indirect
3741
github.com/go-task/slim-sprig/v3 v3.0.0 // indirect
3842
github.com/gogo/protobuf v1.3.2 // indirect
43+
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
3944
github.com/golang/protobuf v1.5.4 // indirect
4045
github.com/google/gnostic-models v0.6.8 // indirect
4146
github.com/google/go-cmp v0.6.0 // indirect
@@ -44,6 +49,7 @@ require (
4449
github.com/google/uuid v1.6.0 // indirect
4550
github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
4651
github.com/hashicorp/hcl v1.0.0 // indirect
52+
github.com/imdario/mergo v0.3.16 // indirect
4753
github.com/inconshreveable/mousetrap v1.1.0 // indirect
4854
github.com/josharian/intern v1.0.0 // indirect
4955
github.com/json-iterator/go v1.1.12 // indirect
@@ -58,7 +64,12 @@ require (
5864
github.com/opentracing/opentracing-go v1.2.1-0.20220228012449-10b1cf09e00b // indirect
5965
github.com/pelletier/go-toml/v2 v2.1.0 // indirect
6066
github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 // indirect
67+
github.com/pkg/errors v0.9.1 // indirect
6168
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
69+
github.com/prometheus/client_golang v1.19.1 // indirect
70+
github.com/prometheus/client_model v0.6.1 // indirect
71+
github.com/prometheus/common v0.55.0 // indirect
72+
github.com/prometheus/procfs v0.15.1 // indirect
6273
github.com/sagikazarmark/locafero v0.4.0 // indirect
6374
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
6475
github.com/sasha-s/go-deadlock v0.3.1 // indirect
@@ -77,9 +88,9 @@ require (
7788
github.com/x448/float16 v0.8.4 // indirect
7889
github.com/yusufpapurcu/wmi v1.2.3 // indirect
7990
go.mongodb.org/mongo-driver v1.13.1 // indirect
80-
go.opentelemetry.io/otel v1.21.0 // indirect
81-
go.opentelemetry.io/otel/metric v1.21.0 // indirect
82-
go.opentelemetry.io/otel/trace v1.21.0 // indirect
91+
go.opentelemetry.io/otel v1.28.0 // indirect
92+
go.opentelemetry.io/otel/metric v1.28.0 // indirect
93+
go.opentelemetry.io/otel/trace v1.28.0 // indirect
8394
go.uber.org/multierr v1.11.0 // indirect
8495
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba // indirect
8596
golang.org/x/net v0.30.0 // indirect
@@ -90,11 +101,13 @@ require (
90101
golang.org/x/text v0.19.0 // indirect
91102
golang.org/x/time v0.5.0 // indirect
92103
golang.org/x/tools v0.26.0 // indirect
104+
gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect
93105
google.golang.org/protobuf v1.35.1 // indirect
94106
gopkg.in/inf.v0 v0.9.1 // indirect
95107
gopkg.in/ini.v1 v1.67.0 // indirect
96108
gopkg.in/yaml.v2 v2.4.0 // indirect
97109
gopkg.in/yaml.v3 v3.0.1 // indirect
110+
k8s.io/apiextensions-apiserver v0.31.0 // indirect
98111
k8s.io/klog/v2 v2.130.1 // indirect
99112
k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 // indirect
100113
k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 // indirect

0 commit comments

Comments
 (0)