Skip to content

Commit

Permalink
PoC generating CRDs programmatically
Browse files Browse the repository at this point in the history
  • Loading branch information
patrykorwat committed Aug 20, 2024
1 parent e150841 commit e6dc0dd
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 57 deletions.
17 changes: 10 additions & 7 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,18 @@ require (
github.com/k3s-io/kine v0.11.12
github.com/spf13/cobra v1.8.1
github.com/stretchr/testify v1.9.0
k8s.io/apimachinery v0.28.6
k8s.io/apiserver v0.0.0-20240725212559-c8097e3f30c7
k8s.io/apimachinery v0.31.0
k8s.io/apiserver v0.31.0
k8s.io/client-go v10.0.0+incompatible
k8s.io/code-generator v0.0.0-20240727175048-b53d16e2b339
k8s.io/component-base v0.0.0-20240726211132-95f30f136fb2
k8s.io/code-generator v0.31.0
k8s.io/component-base v0.31.0
k8s.io/klog/v2 v2.130.1
k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340
k8s.io/utils v0.0.0-20240711033017-18e509b52bc8
sigs.k8s.io/structured-merge-diff/v4 v4.4.1
)

require github.com/zclconf/go-cty v1.15.0
require github.com/zclconf/go-cty v1.15.0 // indirect

require (
cloud.google.com/go v0.115.0 // indirect
Expand Down Expand Up @@ -130,9 +130,11 @@ require (
github.com/mitchellh/hashstructure v1.0.0 // indirect
github.com/mitchellh/mapstructure v1.1.2 // indirect
github.com/mitchellh/reflectwalk v1.0.0 // indirect
github.com/moby/spdystream v0.4.0 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect
github.com/nats-io/jsm.go v0.0.31-0.20220317133147-fe318f464eee // indirect
github.com/nats-io/jwt/v2 v2.5.5 // indirect
github.com/nats-io/nats-server/v2 v2.10.12 // indirect
Expand Down Expand Up @@ -203,9 +205,10 @@ require (
gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
k8s.io/api v0.28.6 // indirect
k8s.io/api v0.31.0 // indirect
k8s.io/apiextensions-apiserver v0.31.0
k8s.io/gengo/v2 v2.0.0-20240228010128-51d4e06bde70 // indirect
k8s.io/kms v0.0.0-20240707024556-6e3528fa4c33 // indirect
k8s.io/kms v0.31.0 // indirect
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.30.3 // indirect
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
sigs.k8s.io/yaml v1.4.0 // indirect
Expand Down
32 changes: 20 additions & 12 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmV
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
github.com/armon/go-radix v1.0.0 h1:F4z6KzEeeQIMeLFa97iZU6vupzoecKdU5TX24SNppXI=
github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a h1:idn718Q4B6AGu/h5Sxe66HYVdqdGu2l9Iebqhi/AEoA=
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
github.com/aws/aws-sdk-go v1.15.78/go.mod h1:E3/ieXAlvM0XWO57iftYVDLLvQ824smPP3ATZkfNZeM=
Expand Down Expand Up @@ -442,6 +444,8 @@ github.com/mitchellh/panicwrap v1.0.0/go.mod h1:pKvZHwWrZowLUzftuFq7coarnxbBXU4a
github.com/mitchellh/prefixedio v0.0.0-20190213213902-5733675afd51/go.mod h1:kB1naBgV9ORnkiTVeyJOI1DavaJkG4oNIq0Af6ZVKUo=
github.com/mitchellh/reflectwalk v1.0.0 h1:9D+8oIskB4VJBN5SFlmc27fSlIBZaov1Wpk/IfikLNY=
github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
github.com/moby/spdystream v0.4.0 h1:Vy79D6mHeJJjiPdFEL2yku1kl0chZpJfZcPpb16BRl8=
github.com/moby/spdystream v0.4.0/go.mod h1:xBAYlnt/ay+11ShkdFKNAG7LsyK/tmNBVvVOwrfMgdI=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
Expand All @@ -452,6 +456,8 @@ github.com/mozillazg/go-httpheader v0.2.1/go.mod h1:jJ8xECTlalr6ValeXYdOF8fFUISe
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J1GEMiLbxo1LJaP8RfCpH6pymGZus=
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
github.com/nats-io/jsm.go v0.0.31-0.20220317133147-fe318f464eee h1:+l6i7zS8N1LOokm7dzShezI9STRGrzp0O49Pw8Jetdk=
github.com/nats-io/jsm.go v0.0.31-0.20220317133147-fe318f464eee/go.mod h1:EKSYvbvWAoh0hIfuZ+ieWm8u0VOTRTeDfuQvNPKRqEg=
github.com/nats-io/jwt/v2 v2.2.1-0.20220113022732-58e87895b296/go.mod h1:0tqz9Hlu6bCBFLWAASKhE5vUA4c24L9KPUUgvwumE/k=
Expand Down Expand Up @@ -897,24 +903,26 @@ honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWh
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
k8s.io/api v0.0.0-20240725200553-fb1fc3084c0e h1:zSGnlOF57ubuWLnmPjHd1c9XRaXJeXdcVsszq+wm17o=
k8s.io/api v0.0.0-20240725200553-fb1fc3084c0e/go.mod h1:ytlEzqC2wOTwYET71W7+J+k7O2V7vrDuzmNLBSpgT+k=
k8s.io/apimachinery v0.0.0-20240720202316-95b78024e3fe h1:V9MwpYUwbKlfLKVrhpVuKWiat/LBIhm1pGB9/xdHm5Q=
k8s.io/apimachinery v0.0.0-20240720202316-95b78024e3fe/go.mod h1:rsPdaZJfTfLsNJSQzNHQvYoTmxhoOEofxtOsF3rtsMo=
k8s.io/apiserver v0.0.0-20240725212559-c8097e3f30c7 h1:1KjC5c9Fq4TAoapUQTKyxZUT4+AkmN6kijB5ZV/TGs4=
k8s.io/apiserver v0.0.0-20240725212559-c8097e3f30c7/go.mod h1:Yx6hfOx0hAkjazWikJ0LTcqTvKJEnxxK0HvnaRRmJR8=
k8s.io/api v0.31.0 h1:b9LiSjR2ym/SzTOlfMHm1tr7/21aD7fSkqgD/CVJBCo=
k8s.io/api v0.31.0/go.mod h1:0YiFF+JfFxMM6+1hQei8FY8M7s1Mth+z/q7eF1aJkTE=
k8s.io/apiextensions-apiserver v0.31.0 h1:fZgCVhGwsclj3qCw1buVXCV6khjRzKC5eCFt24kyLSk=
k8s.io/apiextensions-apiserver v0.31.0/go.mod h1:b9aMDEYaEe5sdK+1T0KU78ApR/5ZVp4i56VacZYEHxk=
k8s.io/apimachinery v0.31.0 h1:m9jOiSr3FoSSL5WO9bjm1n6B9KROYYgNZOb4tyZ1lBc=
k8s.io/apimachinery v0.31.0/go.mod h1:rsPdaZJfTfLsNJSQzNHQvYoTmxhoOEofxtOsF3rtsMo=
k8s.io/apiserver v0.31.0 h1:p+2dgJjy+bk+B1Csz+mc2wl5gHwvNkC9QJV+w55LVrY=
k8s.io/apiserver v0.31.0/go.mod h1:KI9ox5Yu902iBnnyMmy7ajonhKnkeZYJhTZ/YI+WEMk=
k8s.io/client-go v0.0.0-20240727175048-71959c526d54 h1:HqBqgDLNI1YVvxu4ShJEoyJpdVRrCxT0f0HPAe6LgEY=
k8s.io/client-go v0.0.0-20240727175048-71959c526d54/go.mod h1:SORxrGJjz+pQkGtVEBP5ilXUslm+iXOJRgvngcKr6+Q=
k8s.io/code-generator v0.0.0-20240727175048-b53d16e2b339 h1:hUQUJfAKvCSI58b71N32zYLfg+4eT2DPzD55MZCsYAA=
k8s.io/code-generator v0.0.0-20240727175048-b53d16e2b339/go.mod h1:EUn13T3A/CaDKcstPAAr74dTsuy2Fzz63w8+i/ghW0c=
k8s.io/component-base v0.0.0-20240726211132-95f30f136fb2 h1:WboNx0wmEPs9STUc0rzvjZDGwQehkG9IG5iZZzACSGE=
k8s.io/component-base v0.0.0-20240726211132-95f30f136fb2/go.mod h1:f+bznChUGzOQayYeb6iDjbWSgV/69bOcWqS2qGVD3YQ=
k8s.io/code-generator v0.31.0 h1:w607nrMi1KeDKB3/F/J4lIoOgAwc+gV9ZKew4XRfMp8=
k8s.io/code-generator v0.31.0/go.mod h1:84y4w3es8rOJOUUP1rLsIiGlO1JuEaPFXQPA9e/K6U0=
k8s.io/component-base v0.31.0 h1:/KIzGM5EvPNQcYgwq5NwoQBaOlVFrghoVGr8lG6vNRs=
k8s.io/component-base v0.31.0/go.mod h1:TYVuzI1QmN4L5ItVdMSXKvH7/DtvIuas5/mm8YT3rTo=
k8s.io/gengo/v2 v2.0.0-20240228010128-51d4e06bde70 h1:NGrVE502P0s0/1hudf8zjgwki1X/TByhmAoILTarmzo=
k8s.io/gengo/v2 v2.0.0-20240228010128-51d4e06bde70/go.mod h1:VH3AT8AaQOqiGjMF9p0/IM1Dj+82ZwjfxUP1IxaHE+8=
k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
k8s.io/kms v0.0.0-20240707024556-6e3528fa4c33 h1:Wd/sRvKMgzuCdkZ/WQg2rg/j6NLW8eyw0RK8AhV9Hak=
k8s.io/kms v0.0.0-20240707024556-6e3528fa4c33/go.mod h1:x2EJv5lkGE18ijjE04e8W0fVyRPfAx5flo9WdY7a1Hw=
k8s.io/kms v0.31.0 h1:KchILPfB1ZE+ka7223mpU5zeFNkmb45jl7RHnlImUaI=
k8s.io/kms v0.31.0/go.mod h1:OZKwl1fan3n3N5FFxnW5C4V3ygrah/3YXeJWS3O6+94=
k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 h1:BZqlfIlq5YbRMFko6/PM7FjZpUb45WallggurYhKGag=
k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340/go.mod h1:yD4MZYeKMBwQKVht279WycxKyM84kkAx2DPrTXaeb98=
k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 h1:pUdcCO1Lk/tbT5ztQWOBi5HBgbBP1J8+AsQnQCKsi8A=
Expand Down
108 changes: 70 additions & 38 deletions pkg/registry/hykube/provider/strategy.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,19 +23,22 @@ import (
"fmt"
"github.com/go-resty/resty/v2"
"github.com/hashicorp/terraform/providers"
"github.com/zclconf/go-cty/cty"
"hykube.io/apiserver/pkg/apis/hykube"
"io"
"k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset"
"k8s.io/client-go/rest"
"k8s.io/klog/v2"
"os"
"os/exec"
"time"

apiextensionv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"

"github.com/hashicorp/go-hclog"
"github.com/hashicorp/go-plugin"
tfplugin "github.com/hashicorp/terraform/plugin"
tfversion "github.com/hashicorp/terraform/version"

"hykube.io/apiserver/pkg/apis/hykube/validation"
"k8s.io/apimachinery/pkg/fields"
"k8s.io/apimachinery/pkg/labels"
Expand Down Expand Up @@ -95,34 +98,42 @@ func (providerStrategy) NamespaceScoped() bool {
}

func (p providerStrategy) PrepareForCreate(ctx context.Context, obj runtime.Object) {
fullURLFile := "https://releases.hashicorp.com/terraform-provider-aws/5.62.0/terraform-provider-aws_5.62.0_darwin_arm64.zip"
go func() { // TODO: move to events post created
fullURLFile := "https://releases.hashicorp.com/terraform-provider-aws/5.62.0/terraform-provider-aws_5.62.0_linux_amd64.zip" // TODO: detect latest version by default

jj, _ := json.Marshal(obj)
klog.Info(string(jj))
jj, _ := json.Marshal(obj)
klog.Info(string(jj))

filename := "aws-provider.zip"
_, err := p.client.R().
SetOutput(filename).
Get(fullURLFile)
if err != nil {
klog.ErrorS(err, "Couldn't download file")
return
}
filename := "aws-provider.zip"
_, err := p.client.R().
SetOutput(filename).
Get(fullURLFile)
if err != nil {
klog.ErrorS(err, "Couldn't download file")
return
}

klog.Infof("Downloaded a provider from: %s", fullURLFile)
klog.Infof("Downloaded a provider from: %s", fullURLFile)

providerFilename, err := p.extractFile(err, filename)
if err != nil {
klog.ErrorS(err, "Couldn't extract file")
return
}
schema, err := p.getProviderSchema(providerFilename, true)
if err != nil {
klog.ErrorS(err, "Couldn't get provider schema")
return
}
providerFilename, err := p.extractFile(err, filename)
if err != nil {
klog.ErrorS(err, "Couldn't extract file")
return
}

os.Setenv("AWS_ACCESS_KEY_ID", "dummy")
os.Setenv("AWS_SECRET_ACCESS_KEY", "dummy")

klog.Infof("%v", schema)
schema, err := p.getProviderSchema(providerFilename, false)
if err != nil {
klog.ErrorS(err, "Couldn't get provider schema")
return
}

err = p.addCDRs(schema)

klog.Infof("%v", schema)
}()
}

func (p providerStrategy) extractFile(err error, filename string) (string, error) {
Expand Down Expand Up @@ -171,7 +182,7 @@ func (p providerStrategy) getProviderSchema(providerFilename string, verbose boo
logger := hclog.New(&options)
client := plugin.NewClient(
&plugin.ClientConfig{
Cmd: exec.Command(providerFilename),
Cmd: exec.Command("/" + providerFilename),
HandshakeConfig: tfplugin.Handshake,
VersionedPlugins: tfplugin.VersionedPlugins,
Managed: true,
Expand All @@ -192,21 +203,42 @@ func (p providerStrategy) getProviderSchema(providerFilename string, verbose boo

schema := provider.GetSchema()

config, err := schema.Provider.Block.CoerceValue(cty.ObjectVal(map[string]cty.Value{
"region": cty.StringVal(""),
"skip_region_validation": cty.True,
}))
client.Kill()

return &schema, nil
}

func (p providerStrategy) addCDRs(schema *providers.GetSchemaResponse) error {
config, err := rest.InClusterConfig()
if err != nil {
return nil, err
return err
}
provider.Configure(providers.ConfigureRequest{
TerraformVersion: tfversion.Version,
Config: config,
})

client.Kill()
crdClient, err := clientset.NewForConfig(config)

CRDPlural := "VPCs"
CRDGroup := "aws.hykube.io"
CRDVersion := "v1alpha1"
FullCRDName := CRDPlural + "." + CRDGroup

crd := &apiextensionv1beta1.CustomResourceDefinition{
ObjectMeta: meta_v1.ObjectMeta{Name: FullCRDName},
Spec: apiextensionv1beta1.CustomResourceDefinitionSpec{
Group: CRDGroup,
Version: CRDVersion,
Scope: apiextensionv1beta1.NamespaceScoped,
Names: apiextensionv1beta1.CustomResourceDefinitionNames{
Plural: CRDPlural,
Kind: "VPC",
},
},
}

return &schema, nil
_, err = crdClient.ApiextensionsV1beta1().CustomResourceDefinitions().Create(context.TODO(), crd, meta_v1.CreateOptions{})
if err != nil && apierrors.IsAlreadyExists(err) {
return nil
}
return err
}

func (providerStrategy) PrepareForUpdate(ctx context.Context, obj, old runtime.Object) {
Expand Down

0 comments on commit e6dc0dd

Please sign in to comment.