diff --git a/cmd/pulumi-gen-kubernetes/main.go b/cmd/pulumi-gen-kubernetes/main.go index ed30079493..8b89ea69e8 100644 --- a/cmd/pulumi-gen-kubernetes/main.go +++ b/cmd/pulumi-gen-kubernetes/main.go @@ -131,6 +131,10 @@ func writePythonClient(data map[string]interface{}, outdir, templateDir string) func(group, version, kind, kindPy string) error { path := fmt.Sprintf("%s/pulumi_kubernetes/%s/%s/%s.py", outdir, group, version, kind) return ioutil.WriteFile(path, []byte(kindPy), 0777) + }, + func(casingPy string) error { + return ioutil.WriteFile( + fmt.Sprintf("%s/pulumi_kubernetes/tables.py", outdir), []byte(casingPy), 0777) }) if err != nil { panic(err) diff --git a/pkg/gen/python-templates/casing.py.mustache b/pkg/gen/python-templates/casing.py.mustache new file mode 100644 index 0000000000..966e8032a9 --- /dev/null +++ b/pkg/gen/python-templates/casing.py.mustache @@ -0,0 +1,10 @@ +_CASING_FORWARD_TABLE = { +{{#properties}} + "{{name}}": "{{casedName}}", +{{/properties}} +} +_CASING_BACKWARD_TABLE = { +{{#properties}} + "{{casedName}}": "{{name}}", +{{/properties}} +} diff --git a/pkg/gen/python.go b/pkg/gen/python.go index eee04c24da..4551fac05f 100644 --- a/pkg/gen/python.go +++ b/pkg/gen/python.go @@ -35,9 +35,28 @@ func PythonClient( groupInit func(group, initPy string) error, versionInit func(group, version, initPy string) error, kindFile func(group, version, kind, kindPy string) error, + casingFile func(casingPy string) error, ) error { definitions := swagger["definitions"].(map[string]interface{}) + // Generate casing tables from property names. + // { properties: [ {name: fooBar, casedName: foo_bar}, ]} + properties := allCamelCasePropertyNames(definitions, pythonProvider()) + cases := map[string][]map[string]string{"properties": make([]map[string]string, 0)} + for _, name := range properties { + cases["properties"] = append(cases["properties"], + map[string]string{"name": name, "casedName": pyName(name)}) + } + casingPy, err := mustache.RenderFile( + fmt.Sprintf("%s/casing.py.mustache", templateDir), cases) + if err != nil { + return err + } + err = casingFile(casingPy) + if err != nil { + return err + } + groupsSlice := createGroups(definitions, pythonProvider()) rootInitPy, err := mustache.RenderFile( diff --git a/pkg/gen/typegen.go b/pkg/gen/typegen.go index e58b560b4e..b27d2dc518 100644 --- a/pkg/gen/typegen.go +++ b/pkg/gen/typegen.go @@ -16,6 +16,7 @@ package gen import ( "fmt" + "regexp" "strings" linq "github.com/ahmetb/go-linq" @@ -418,6 +419,42 @@ func nodeJSProvider() groupOpts { return groupOpts{generatorType: provider, lang func pythonProvider() groupOpts { return groupOpts{generatorType: provider, language: python} } +func allCamelCasePropertyNames(definitionsJSON map[string]interface{}, opts groupOpts) []string { + // Map definition JSON object -> `definition` with metadata. + definitions := make([]*definition, 0) + linq.From(definitionsJSON). + WhereT(func(kv linq.KeyValue) bool { + // Skip these objects, special case. They're deprecated and empty. + defName := kv.Key.(string) + return !strings.HasPrefix(defName, "io.k8s.kubernetes.pkg") + }). + SelectT(func(kv linq.KeyValue) *definition { + defName := kv.Key.(string) + return &definition{ + gvk: gvkFromRef(defName), + name: defName, + data: definitionsJSON[defName].(map[string]interface{}), + } + }). + ToSlice(&definitions) + + properties := sets.String{} + // Only select camel-cased property names + re := regexp.MustCompile(`[a-z]+[A-Z]`) + for _, d := range definitions { + if pmap, exists := d.data["properties"]; exists { + ps := pmap.(map[string]interface{}) + for p := range ps { + if re.MatchString(p) { + properties.Insert(p) + } + } + } + } + + return properties.List() +} + func createGroups(definitionsJSON map[string]interface{}, opts groupOpts) []*GroupConfig { // Map definition JSON object -> `definition` with metadata. definitions := []*definition{} diff --git a/sdk/python/pulumi_kubernetes/tables.py b/sdk/python/pulumi_kubernetes/tables.py index b3fa423aa7..3c27afbf40 100644 --- a/sdk/python/pulumi_kubernetes/tables.py +++ b/sdk/python/pulumi_kubernetes/tables.py @@ -101,6 +101,8 @@ "downwardAPI": "downward_api", "dryRun": "dry_run", "emptyDir": "empty_dir", + "enableServiceLinks": "enable_service_links", + "endpointsNamespace": "endpoints_namespace", "envFrom": "env_from", "evaluationError": "evaluation_error", "eventTime": "event_time", @@ -384,6 +386,7 @@ "volumesAttached": "volumes_attached", "volumesInUse": "volumes_in_use", "vsphereVolume": "vsphere_volume", + "webhookClientConfig": "webhook_client_config", "workingDir": "working_dir", } _CASING_BACKWARD_TABLE = { @@ -489,6 +492,8 @@ "downward_api": "downwardAPI", "dry_run": "dryRun", "empty_dir": "emptyDir", + "enable_service_links": "enableServiceLinks", + "endpoints_namespace": "endpointsNamespace", "env_from": "envFrom", "evaluation_error": "evaluationError", "event_time": "eventTime", @@ -772,5 +777,6 @@ "volumes_attached": "volumesAttached", "volumes_in_use": "volumesInUse", "vsphere_volume": "vsphereVolume", + "webhook_client_config": "webhookClientConfig", "working_dir": "workingDir", -} \ No newline at end of file +}