Skip to content

Commit 0e38fa7

Browse files
committed
feat: add kubernetes cluster access and listing crds in the cluster
Signed-off-by: Gergely Brautigam <[email protected]>
1 parent ac25dd3 commit 0e38fa7

File tree

5 files changed

+98
-1
lines changed

5 files changed

+98
-1
lines changed

README.md

+15
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,21 @@ cty generate crd -r folder
140140

141141
Any other flag will work as before.
142142

143+
### Kubernetes Config
144+
145+
Use `cty` to search for a resource in an existing Kubernetes Cluster.
146+
147+
```
148+
cty generate crd -k krokcommands.delivery.krok.app
149+
```
150+
151+
This will look for this CRD in the cluster and generate a sample file for it. If you wish to use a different resource
152+
that supports `openAPIV3Schema` you can configure the group/version/resource `cty` is looking for.
153+
154+
```
155+
cty generate crd -k xxtstorageaccounts.crossplane.fnietoga.me --resource CompositeResourceDefinition --group apiextensions.crossplane.io --version v1
156+
```
157+
143158
### Config File
144159
145160
It's possible to define a config file that designates groups for various rendered CRDs.

cmd/crd.go

+7
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,13 @@ func constructHandler(args *rootArgs) (Handler, error) {
128128
var crdHandler Handler
129129

130130
switch {
131+
case args.kubeCluster != "":
132+
crdHandler = &KubeHandler{
133+
crd: args.kubeCluster,
134+
resourceGroup: args.group,
135+
resourceVersion: args.version,
136+
resource: args.resource,
137+
}
131138
case args.stdin:
132139
crdHandler = &StdInHandler{}
133140
case args.fileLocation != "":

cmd/generate.go

+9-1
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,12 @@ type rootArgs struct {
1515
tag string
1616
caBundle string
1717
privSSHKey string
18-
useSSHAgent bool
1918
gitURL string
19+
kubeCluster string
20+
group string
21+
version string
22+
resource string
23+
useSSHAgent bool
2024
stdin bool
2125
}
2226

@@ -36,6 +40,7 @@ func init() {
3640
f := generateCmd.PersistentFlags()
3741
f.BoolVarP(&args.stdin, "stdin", "i", false, "Take CRD content from stdin.")
3842
f.StringVarP(&args.fileLocation, "crd", "c", "", "The CRD file to generate a yaml from.")
43+
f.StringVarP(&args.kubeCluster, "kube", "k", "", "Try to access the local cluster and fetch CRD content from there.")
3944
f.StringVarP(&args.folderLocation, "folder", "r", "", "A folder from which to parse a series of CRDs.")
4045
f.StringVarP(&args.url, "url", "u", "", "If provided, will use this URL to fetch CRD YAML content from.")
4146
f.StringVarP(&args.gitURL, "git-url", "g", "", "If provided, CRDs will be discovered using a git repository.")
@@ -47,4 +52,7 @@ func init() {
4752
f.StringVar(&args.caBundle, "ca-bundle-file", "", "Additional certificate bundle to load. Should the name of the file.")
4853
f.StringVar(&args.privSSHKey, "private-ssh-key-file", "", "Private key to use for cloning. Should the name of the file.")
4954
f.BoolVar(&args.useSSHAgent, "ssh-agent", false, "If set, the configured SSH agent will be used to clone the repository..")
55+
f.StringVar(&args.group, "group", "apiextensions.k8s.io", "If set, it will look for this group when using Kubernetes Config.")
56+
f.StringVar(&args.version, "version", "v1", "If set, it will look for this version when using Kubernetes Config.")
57+
f.StringVar(&args.resource, "resource", "customresourcedefinitions", "If set, it will look for this version when using Kubernetes Config.")
5058
}

cmd/kube_handler.go

+65
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package cmd
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"os"
7+
"path/filepath"
8+
9+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
10+
"k8s.io/apimachinery/pkg/runtime/schema"
11+
"k8s.io/client-go/dynamic"
12+
"k8s.io/client-go/tools/clientcmd"
13+
"k8s.io/client-go/util/homedir"
14+
15+
"github.com/Skarlso/crd-to-sample-yaml/pkg"
16+
)
17+
18+
type KubeHandler struct {
19+
crd string
20+
group string
21+
resourceGroup string
22+
resourceVersion string
23+
resource string
24+
}
25+
26+
func (h *KubeHandler) CRDs() ([]*pkg.SchemaType, error) {
27+
kubeconfig := os.Getenv("KUBECONFIG")
28+
if kubeconfig == "" {
29+
kubeconfig = filepath.Join(homedir.HomeDir(), ".kube", "config")
30+
}
31+
32+
config, err := clientcmd.BuildConfigFromFlags("", kubeconfig)
33+
if err != nil {
34+
return nil, fmt.Errorf("error building config from flags: %w", err)
35+
}
36+
cliSet, err := dynamic.NewForConfig(config)
37+
if err != nil {
38+
return nil, fmt.Errorf("error creating dynamic client: %w", err)
39+
}
40+
ctx := context.Background()
41+
42+
result, err := cliSet.Resource(schema.GroupVersionResource{
43+
Group: h.resourceGroup,
44+
Version: h.resourceVersion,
45+
Resource: h.resource,
46+
}).Get(ctx, h.crd, metav1.GetOptions{})
47+
if err != nil {
48+
return nil, fmt.Errorf("error getting CRD: %w", err)
49+
}
50+
51+
schemaType, err := pkg.ExtractSchemaType(result)
52+
if err != nil {
53+
return nil, fmt.Errorf("failed to extract schema type: %w", err)
54+
}
55+
56+
if schemaType == nil {
57+
return nil, nil
58+
}
59+
60+
if h.group != "" {
61+
schemaType.Rendering = pkg.Rendering{Group: h.group}
62+
}
63+
64+
return []*pkg.SchemaType{schemaType}, nil
65+
}

go.mod

+2
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ require (
1616
github.com/stretchr/testify v1.10.0
1717
k8s.io/apiextensions-apiserver v0.32.2
1818
k8s.io/apimachinery v0.32.2
19+
k8s.io/client-go v0.32.2
1920
)
2021

2122
require (
@@ -78,6 +79,7 @@ require (
7879
golang.org/x/net v0.35.0 // indirect
7980
golang.org/x/oauth2 v0.24.0 // indirect
8081
golang.org/x/sys v0.30.0 // indirect
82+
golang.org/x/term v0.29.0 // indirect
8183
golang.org/x/text v0.22.0 // indirect
8284
golang.org/x/time v0.8.0 // indirect
8385
google.golang.org/genproto/googleapis/api v0.0.0-20240826202546-f6391c0de4c7 // indirect

0 commit comments

Comments
 (0)