Skip to content

Commit 8e580d4

Browse files
committed
Add augerctl get
Signed-off-by: Shiming Zhang <[email protected]>
1 parent 2433600 commit 8e580d4

13 files changed

+1138
-0
lines changed

augerctl/README.md

+136
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
# augerctl
2+
3+
`augerctl` is a command line client for [Kubernetes][kubernetes] specific [etcd][etcd],
4+
and as close as possible to [kubectl][kubectl].
5+
It can be used in scripts or for administrators to explore an etcd cluster.
6+
7+
## Getting augerctl
8+
9+
The latest release is not yet available as a binary on [Github][github-release],
10+
the next release will be available.
11+
12+
so that it can be built from source.
13+
14+
``` bash
15+
git clone https://github.com/etcd-io/auger
16+
cd auger
17+
go install ./augerctl
18+
```
19+
20+
or
21+
22+
``` bash
23+
go install github.com/etcd-io/auger/augerctl@main
24+
```
25+
26+
and the binary will be available in the path `$GOBIN` or `$GOPATH/bin`
27+
28+
## Configuration
29+
30+
### --endpoints
31+
+ gRPC endpoints of etcd cluster
32+
+ default: `"http://127.0.0.1:2379"`
33+
34+
### --cert
35+
+ path to the etcd client TLS cert file
36+
+ default: none
37+
38+
### --key
39+
+ path to the etcd client TLS key file
40+
+ default: none
41+
42+
### --cacert
43+
+ path to the etcd client TLS CA cert file
44+
+ default: none
45+
46+
### --user
47+
+ username for authentication, provide username[:password]
48+
+ default: none
49+
50+
### --password
51+
+ password for authentication, only available if --user has no password
52+
+ default: none
53+
54+
## Usage
55+
56+
### Setting a resource
57+
58+
TODO
59+
60+
### Retrieving a resource
61+
62+
List a single service with namespace `default` and name `kubernetes`
63+
64+
``` bash
65+
augerctl get services -n default kubernetes
66+
67+
# Nearly equivalent
68+
kubectl get services -n default kubernetes -o yaml
69+
```
70+
71+
List a single resource of type `priorityclasses` and name `system-node-critical` without namespaced
72+
73+
``` bash
74+
augerctl get priorityclasses system-node-critical
75+
76+
# Nearly equivalent
77+
kubectl get priorityclasses system-node-critical -o yaml
78+
```
79+
80+
List all leases with namespace `kube-system`
81+
82+
``` bash
83+
augerctl get leases -n kube-system
84+
85+
# Nearly equivalent
86+
kubectl get leases -n kube-system -o yaml
87+
```
88+
89+
List a single resource of type `apiservices.apiregistration.k8s.io` and name `v1.apps`
90+
91+
``` bash
92+
augerctl get apiservices.apiregistration.k8s.io v1.apps
93+
94+
# Nearly equivalent
95+
kubectl get apiservices.apiregistration.k8s.io v1.apps -o yaml
96+
```
97+
98+
List all resources
99+
100+
``` bash
101+
augerctl get
102+
103+
# Nearly equivalent
104+
kubectl get $(kubectl api-resources --verbs=list --output=name | paste -s -d, - ) -A -o yaml
105+
```
106+
107+
### Deleting a resource
108+
109+
TODO
110+
111+
### Watching for changes
112+
113+
TODO
114+
115+
## Endpoint
116+
117+
If the etcd cluster isn't available on `http://127.0.0.1:2379`, specify a `--endpoints` flag.
118+
119+
## Project Details
120+
121+
### Versioning
122+
123+
augerctl uses [semantic versioning][semver].
124+
Releases will follow with the [Kubernetes][kubernetes] release cycle as possible (need API updates),
125+
but the version numbers will be not.
126+
127+
### License
128+
129+
augerctl is under the Apache 2.0 license. See the [LICENSE][license] file for details.
130+
131+
[kubernetes]: https://kubernetes.io/
132+
[kubectl]: https://kubectl.sigs.k8s.io/
133+
[etcd]: https://github.com/etcd-io/etcd
134+
[github-release]: https://github.com/etcd-io/auger/releases/
135+
[license]: ../LICENSE
136+
[semver]: http://semver.org/

augerctl/command/ctl.go

+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/*
2+
Copyright 2024 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
// Package command is a simple command line client for directly accessing data objects stored in etcd by Kubernetes.
18+
package command
19+
20+
import (
21+
"github.com/spf13/cobra"
22+
23+
"go.etcd.io/etcd/client/pkg/v3/transport"
24+
)
25+
26+
type flagpole struct {
27+
Endpoints []string
28+
29+
InsecureSkipVerify bool
30+
InsecureDiscovery bool
31+
TLS transport.TLSInfo
32+
33+
User string
34+
Password string
35+
}
36+
37+
// NewCtlCommand returns a new cobra.Command for use ctl
38+
func NewCtlCommand() *cobra.Command {
39+
flags := &flagpole{}
40+
41+
cmd := &cobra.Command{
42+
Use: "augerctl",
43+
Short: "A simple command line client for directly accessing data objects stored in etcd by Kubernetes.",
44+
}
45+
cmd.PersistentFlags().StringSliceVar(&flags.Endpoints, "endpoints", []string{"127.0.0.1:2379"}, "gRPC endpoints of etcd cluster")
46+
47+
cmd.PersistentFlags().BoolVar(&flags.InsecureDiscovery, "insecure-discovery", true, "accept insecure SRV records describing cluster endpoints")
48+
cmd.PersistentFlags().BoolVar(&flags.InsecureSkipVerify, "insecure-skip-tls-verify", false, "skip server certificate verification")
49+
cmd.PersistentFlags().StringVar(&flags.TLS.CertFile, "cert", "", "path to the etcd client TLS cert file")
50+
cmd.PersistentFlags().StringVar(&flags.TLS.KeyFile, "key", "", "path to the etcd client TLS key file")
51+
cmd.PersistentFlags().StringVar(&flags.TLS.TrustedCAFile, "cacert", "", "path to the etcd client TLS CA cert file")
52+
cmd.PersistentFlags().StringVar(&flags.User, "user", "", "username for authentication, provide username[:password]")
53+
cmd.PersistentFlags().StringVar(&flags.Password, "password", "", "password for authentication, only available if --user has no password")
54+
55+
cmd.AddCommand(
56+
newCtlGetCommand(flags),
57+
)
58+
return cmd
59+
}

augerctl/command/get_command.go

+137
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
/*
2+
Copyright 2024 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package command
18+
19+
import (
20+
"context"
21+
"fmt"
22+
"os"
23+
24+
"github.com/etcd-io/auger/pkg/client"
25+
"github.com/spf13/cobra"
26+
"k8s.io/apimachinery/pkg/runtime/schema"
27+
)
28+
29+
type getFlagpole struct {
30+
Namespace string
31+
Output string
32+
ChunkSize int64
33+
Prefix string
34+
}
35+
36+
var (
37+
getExample = `
38+
# List a single service with namespace "default" and name "kubernetes"
39+
augerctl get services -n default kubernetes
40+
# Nearly equivalent
41+
kubectl get services -n default kubernetes -o yaml
42+
43+
# List a single resource of type "priorityclasses" and name "system-node-critical" without namespaced
44+
augerctl get priorityclasses system-node-critical
45+
# Nearly equivalent
46+
kubectl get priorityclasses system-node-critical -A -o yaml
47+
48+
# List all leases with namespace "kube-system"
49+
augerctl get leases -n kube-system
50+
# Nearly equivalent
51+
kubectl get leases -n kube-system -o yaml
52+
53+
# List a single resource of type "apiservices.apiregistration.k8s.io" and name "v1.apps"
54+
augerctl get apiservices.apiregistration.k8s.io v1.apps
55+
# Nearly equivalent
56+
kubectl get apiservices.apiregistration.k8s.io v1.apps -o yaml
57+
58+
# List all resources
59+
augerctl get
60+
# Nearly equivalent
61+
kubectl get $(kubectl api-resources --verbs=list --output=name | paste -s -d, - ) -A -o yaml
62+
`
63+
)
64+
65+
func newCtlGetCommand(f *flagpole) *cobra.Command {
66+
flags := &getFlagpole{}
67+
68+
cmd := &cobra.Command{
69+
Args: cobra.RangeArgs(0, 2),
70+
Use: "get [resource] [name]",
71+
Short: "Gets the resource of Kubernetes in etcd",
72+
Example: getExample,
73+
RunE: func(cmd *cobra.Command, args []string) error {
74+
etcdclient, err := clientFromCmd(f)
75+
if err != nil {
76+
return err
77+
}
78+
err = getCommand(cmd.Context(), etcdclient, flags, args)
79+
80+
if err != nil {
81+
return fmt.Errorf("%v: %w", args, err)
82+
}
83+
return nil
84+
},
85+
}
86+
87+
cmd.Flags().StringVarP(&flags.Output, "output", "o", "yaml", "output format. One of: (yaml).")
88+
cmd.Flags().StringVarP(&flags.Namespace, "namespace", "n", "", "namespace of resource")
89+
cmd.Flags().Int64Var(&flags.ChunkSize, "chunk-size", 500, "chunk size of the list pager")
90+
cmd.Flags().StringVar(&flags.Prefix, "prefix", "/registry", "prefix to prepend to the resource")
91+
92+
return cmd
93+
}
94+
95+
func getCommand(ctx context.Context, etcdclient client.Client, flags *getFlagpole, args []string) error {
96+
var targetGr schema.GroupResource
97+
var targetName string
98+
var targetNamespace string
99+
if len(args) != 0 {
100+
// TODO: Support get information from CRD and scheme.Codecs
101+
// Support short name
102+
// Check for namespaced
103+
104+
gr := schema.ParseGroupResource(args[0])
105+
if gr.Empty() {
106+
return fmt.Errorf("invalid resource %q", args[0])
107+
}
108+
targetGr = gr
109+
targetNamespace = flags.Namespace
110+
if len(args) >= 2 {
111+
targetName = args[1]
112+
}
113+
}
114+
115+
printer := NewPrinter(os.Stdout, flags.Output)
116+
if printer == nil {
117+
return fmt.Errorf("invalid output format: %q", flags.Output)
118+
}
119+
120+
opOpts := []client.OpOption{
121+
client.WithName(targetName, targetNamespace),
122+
client.WithGroupResource(targetGr),
123+
client.WithChunkSize(flags.ChunkSize),
124+
client.WithResponse(printer.Print),
125+
}
126+
127+
// TODO: Support watch
128+
129+
_, err := etcdclient.Get(ctx, flags.Prefix,
130+
opOpts...,
131+
)
132+
if err != nil {
133+
return err
134+
}
135+
136+
return nil
137+
}

0 commit comments

Comments
 (0)