From 8bb53a18d07775eb280c87e864792b0468824c34 Mon Sep 17 00:00:00 2001 From: Ian Wahbe Date: Tue, 19 Dec 2023 15:39:00 -0800 Subject: [PATCH] Add token mapping and maxItemOne tracking (#279) --- .ci-mgmt.yaml | 1 - .../pulumi-resource-kong/bridge-metadata.json | 343 ++++++++++++++++++ provider/resources.go | 68 ++-- 3 files changed, 364 insertions(+), 48 deletions(-) create mode 100644 provider/cmd/pulumi-resource-kong/bridge-metadata.json diff --git a/.ci-mgmt.yaml b/.ci-mgmt.yaml index 09a0f4db..ad7f39d8 100644 --- a/.ci-mgmt.yaml +++ b/.ci-mgmt.yaml @@ -2,4 +2,3 @@ provider: kong major-version: 4 docker: true makeTemplate: bridged -team: ecosystem diff --git a/provider/cmd/pulumi-resource-kong/bridge-metadata.json b/provider/cmd/pulumi-resource-kong/bridge-metadata.json new file mode 100644 index 00000000..a64d3569 --- /dev/null +++ b/provider/cmd/pulumi-resource-kong/bridge-metadata.json @@ -0,0 +1,343 @@ +{ + "auto-aliasing": { + "resources": { + "kong_certificate": { + "current": "kong:index/certificate:Certificate", + "majorVersion": 4, + "fields": { + "snis": { + "maxItemsOne": false + }, + "tags": { + "maxItemsOne": false + } + } + }, + "kong_consumer": { + "current": "kong:index/consumer:Consumer", + "majorVersion": 4, + "fields": { + "tags": { + "maxItemsOne": false + } + } + }, + "kong_consumer_acl": { + "current": "kong:index/consumerAcl:ConsumerAcl", + "majorVersion": 4, + "fields": { + "tags": { + "maxItemsOne": false + } + } + }, + "kong_consumer_basic_auth": { + "current": "kong:index/consumerBasicAuth:ConsumerBasicAuth", + "majorVersion": 4, + "fields": { + "tags": { + "maxItemsOne": false + } + } + }, + "kong_consumer_jwt_auth": { + "current": "kong:index/consumerJwtAuth:ConsumerJwtAuth", + "majorVersion": 4, + "fields": { + "tags": { + "maxItemsOne": false + } + } + }, + "kong_consumer_key_auth": { + "current": "kong:index/consumerKeyAuth:ConsumerKeyAuth", + "majorVersion": 4, + "fields": { + "tags": { + "maxItemsOne": false + } + } + }, + "kong_consumer_oauth2": { + "current": "kong:index/consumerOauth2:ConsumerOauth2", + "majorVersion": 4, + "fields": { + "redirect_uris": { + "maxItemsOne": false + }, + "tags": { + "maxItemsOne": false + } + } + }, + "kong_plugin": { + "current": "kong:index/plugin:Plugin", + "majorVersion": 4, + "fields": { + "tags": { + "maxItemsOne": false + } + } + }, + "kong_route": { + "current": "kong:index/route:Route", + "majorVersion": 4, + "fields": { + "destination": { + "maxItemsOne": false + }, + "header": { + "maxItemsOne": false, + "elem": { + "fields": { + "values": { + "maxItemsOne": false + } + } + } + }, + "hosts": { + "maxItemsOne": false + }, + "methods": { + "maxItemsOne": false + }, + "paths": { + "maxItemsOne": false + }, + "protocols": { + "maxItemsOne": false + }, + "snis": { + "maxItemsOne": false + }, + "source": { + "maxItemsOne": false + }, + "tags": { + "maxItemsOne": false + } + } + }, + "kong_service": { + "current": "kong:index/service:Service", + "majorVersion": 4, + "fields": { + "ca_certificate_ids": { + "maxItemsOne": false + }, + "tags": { + "maxItemsOne": false + } + } + }, + "kong_target": { + "current": "kong:index/target:Target", + "majorVersion": 4, + "fields": { + "tags": { + "maxItemsOne": false + } + } + }, + "kong_upstream": { + "current": "kong:index/upstream:Upstream", + "majorVersion": 4, + "fields": { + "healthchecks": { + "maxItemsOne": true, + "elem": { + "fields": { + "active": { + "maxItemsOne": true, + "elem": { + "fields": { + "healthy": { + "maxItemsOne": true, + "elem": { + "fields": { + "http_statuses": { + "maxItemsOne": false + } + } + } + }, + "unhealthy": { + "maxItemsOne": true, + "elem": { + "fields": { + "http_statuses": { + "maxItemsOne": false + } + } + } + } + } + } + }, + "passive": { + "maxItemsOne": true, + "elem": { + "fields": { + "healthy": { + "maxItemsOne": true, + "elem": { + "fields": { + "http_statuses": { + "maxItemsOne": false + } + } + } + }, + "unhealthy": { + "maxItemsOne": true, + "elem": { + "fields": { + "http_statuses": { + "maxItemsOne": false + } + } + } + } + } + } + } + } + } + }, + "tags": { + "maxItemsOne": false + } + } + } + } + }, + "renames": { + "resources": { + "kong:index/certificate:Certificate": "kong_certificate", + "kong:index/consumer:Consumer": "kong_consumer", + "kong:index/consumerAcl:ConsumerAcl": "kong_consumer_acl", + "kong:index/consumerBasicAuth:ConsumerBasicAuth": "kong_consumer_basic_auth", + "kong:index/consumerJwtAuth:ConsumerJwtAuth": "kong_consumer_jwt_auth", + "kong:index/consumerKeyAuth:ConsumerKeyAuth": "kong_consumer_key_auth", + "kong:index/consumerOauth2:ConsumerOauth2": "kong_consumer_oauth2", + "kong:index/plugin:Plugin": "kong_plugin", + "kong:index/route:Route": "kong_route", + "kong:index/service:Service": "kong_service", + "kong:index/target:Target": "kong_target", + "kong:index/upstream:Upstream": "kong_upstream" + }, + "renamedProperties": { + "kong:index/UpstreamHealthchecksActive:UpstreamHealthchecksActive": { + "httpPath": "http_path", + "httpsSni": "https_sni", + "httpsVerifyCertificate": "https_verify_certificate" + }, + "kong:index/UpstreamHealthchecksActiveHealthy:UpstreamHealthchecksActiveHealthy": { + "httpStatuses": "http_statuses" + }, + "kong:index/UpstreamHealthchecksActiveUnhealthy:UpstreamHealthchecksActiveUnhealthy": { + "httpFailures": "http_failures", + "httpStatuses": "http_statuses", + "tcpFailures": "tcp_failures" + }, + "kong:index/UpstreamHealthchecksPassiveHealthy:UpstreamHealthchecksPassiveHealthy": { + "httpStatuses": "http_statuses" + }, + "kong:index/UpstreamHealthchecksPassiveUnhealthy:UpstreamHealthchecksPassiveUnhealthy": { + "httpFailures": "http_failures", + "httpStatuses": "http_statuses", + "tcpFailures": "tcp_failures" + }, + "kong:index/certificate:Certificate": { + "privateKey": "private_key" + }, + "kong:index/consumer:Consumer": { + "customId": "custom_id" + }, + "kong:index/consumerAcl:ConsumerAcl": { + "consumerId": "consumer_id" + }, + "kong:index/consumerBasicAuth:ConsumerBasicAuth": { + "consumerId": "consumer_id" + }, + "kong:index/consumerJwtAuth:ConsumerJwtAuth": { + "consumerId": "consumer_id", + "rsaPublicKey": "rsa_public_key" + }, + "kong:index/consumerKeyAuth:ConsumerKeyAuth": { + "consumerId": "consumer_id" + }, + "kong:index/consumerOauth2:ConsumerOauth2": { + "clientId": "client_id", + "clientSecret": "client_secret", + "consumerId": "consumer_id", + "hashSecret": "hash_secret", + "redirectUris": "redirect_uris" + }, + "kong:index/plugin:Plugin": { + "computedConfig": "computed_config", + "configJson": "config_json", + "consumerId": "consumer_id", + "routeId": "route_id", + "serviceId": "service_id", + "strictMatch": "strict_match" + }, + "kong:index/route:Route": { + "destinations": "destination", + "headers": "header", + "httpsRedirectStatusCode": "https_redirect_status_code", + "pathHandling": "path_handling", + "preserveHost": "preserve_host", + "regexPriority": "regex_priority", + "requestBuffering": "request_buffering", + "responseBuffering": "response_buffering", + "serviceId": "service_id", + "sources": "source", + "stripPath": "strip_path" + }, + "kong:index/service:Service": { + "caCertificateIds": "ca_certificate_ids", + "clientCertificateId": "client_certificate_id", + "connectTimeout": "connect_timeout", + "readTimeout": "read_timeout", + "tlsVerify": "tls_verify", + "tlsVerifyDepth": "tls_verify_depth", + "writeTimeout": "write_timeout" + }, + "kong:index/target:Target": { + "upstreamId": "upstream_id" + }, + "kong:index/upstream:Upstream": { + "clientCertificateId": "client_certificate_id", + "hashFallback": "hash_fallback", + "hashFallbackHeader": "hash_fallback_header", + "hashOn": "hash_on", + "hashOnCookie": "hash_on_cookie", + "hashOnCookiePath": "hash_on_cookie_path", + "hashOnHeader": "hash_on_header", + "hostHeader": "host_header" + }, + "kong:index:Provider": { + "kongAdminPassword": "kong_admin_password", + "kongAdminToken": "kong_admin_token", + "kongAdminUri": "kong_admin_uri", + "kongAdminUsername": "kong_admin_username", + "kongApiKey": "kong_api_key", + "kongWorkspace": "kong_workspace", + "strictPluginsMatch": "strict_plugins_match", + "tlsSkipVerify": "tls_skip_verify" + } + }, + "renamedConfigProperties": { + "kongAdminPassword": "kong_admin_password", + "kongAdminToken": "kong_admin_token", + "kongAdminUri": "kong_admin_uri", + "kongAdminUsername": "kong_admin_username", + "kongApiKey": "kong_api_key", + "kongWorkspace": "kong_workspace", + "strictPluginsMatch": "strict_plugins_match", + "tlsSkipVerify": "tls_skip_verify" + } + } +} \ No newline at end of file diff --git a/provider/resources.go b/provider/resources.go index 8019023f..75ea6185 100644 --- a/provider/resources.go +++ b/provider/resources.go @@ -15,15 +15,15 @@ package kong import ( + _ "embed" // allow embedding metadata "fmt" - "path/filepath" - "unicode" + "path" "github.com/kevholditch/terraform-provider-kong/kong" "github.com/pulumi/pulumi-kong/provider/v4/pkg/version" "github.com/pulumi/pulumi-terraform-bridge/v3/pkg/tfbridge" + "github.com/pulumi/pulumi-terraform-bridge/v3/pkg/tfbridge/tokens" shimv2 "github.com/pulumi/pulumi-terraform-bridge/v3/pkg/tfshim/sdk-v2" - "github.com/pulumi/pulumi/sdk/v3/go/common/tokens" ) // all of the token components used below. @@ -34,32 +34,14 @@ const ( mainMod = "index" // the y module ) -// makeMember manufactures a type token for the package and the given module and type. -func makeMember(mod string, mem string) tokens.ModuleMember { - return tokens.ModuleMember(mainPkg + ":" + mod + ":" + mem) -} - -// makeType manufactures a type token for the package and the given module and type. -func makeType(mod string, typ string) tokens.Type { - return tokens.Type(makeMember(mod, typ)) -} - -// makeResource manufactures a standard resource token given a module and resource name. It -// automatically uses the main package and names the file by simply lower casing the resource's -// first character. -func makeResource(mod string, res string) tokens.Type { - fn := string(unicode.ToLower(rune(res[0]))) + res[1:] - return makeType(mod+"/"+fn, res) -} +func ref[T any](t T) *T { return &t } -func refProviderLicense(license tfbridge.TFProviderLicense) *tfbridge.TFProviderLicense { - return &license -} +//go:embed cmd/pulumi-resource-kong/bridge-metadata.json +var metadata []byte func Provider() tfbridge.ProviderInfo { - p := shimv2.NewProvider(kong.Provider()) prov := tfbridge.ProviderInfo{ - P: p, + P: shimv2.NewProvider(kong.Provider()), Name: "kong", Description: "A Pulumi package for creating and managing Kong resources.", Keywords: []string{"pulumi", "kong"}, @@ -67,7 +49,9 @@ func Provider() tfbridge.ProviderInfo { License: "Apache-2.0", Homepage: "https://pulumi.io", Repository: "https://github.com/pulumi/pulumi-kong", - TFProviderLicense: refProviderLicense(tfbridge.MITLicenseType), + TFProviderLicense: ref(tfbridge.MITLicenseType), + Version: version.Version, + MetadataInfo: tfbridge.NewProviderMetadata(metadata), Config: map[string]*tfbridge.SchemaInfo{ "tls_skip_verify": { Default: &tfbridge.DefaultInfo{ @@ -83,31 +67,19 @@ func Provider() tfbridge.ProviderInfo { }, Resources: map[string]*tfbridge.ResourceInfo{ "kong_certificate": { - Tok: makeResource(mainMod, "Certificate"), Fields: map[string]*tfbridge.SchemaInfo{ "certificate": { CSharpName: "Cert", }, }, }, - "kong_consumer": {Tok: makeResource(mainMod, "Consumer")}, - "kong_plugin": {Tok: makeResource(mainMod, "Plugin")}, - "kong_upstream": {Tok: makeResource(mainMod, "Upstream")}, "kong_target": { - Tok: makeResource(mainMod, "Target"), Fields: map[string]*tfbridge.SchemaInfo{ "target": { CSharpName: "TargetAddress", }, }, }, - "kong_service": {Tok: makeResource(mainMod, "Service")}, - "kong_route": {Tok: makeResource(mainMod, "Route")}, - "kong_consumer_acl": {Tok: makeResource(mainMod, "ConsumerAcl")}, - "kong_consumer_basic_auth": {Tok: makeResource(mainMod, "ConsumerBasicAuth")}, - "kong_consumer_jwt_auth": {Tok: makeResource(mainMod, "ConsumerJwtAuth")}, - "kong_consumer_key_auth": {Tok: makeResource(mainMod, "ConsumerKeyAuth")}, - "kong_consumer_oauth2": {Tok: makeResource(mainMod, "ConsumerOauth2")}, }, JavaScript: &tfbridge.JavaScriptInfo{ Dependencies: map[string]string{ @@ -118,17 +90,15 @@ func Provider() tfbridge.ProviderInfo { "@types/mime": "^2.0.0", }, }, - Python: (func() *tfbridge.PythonInfo { - i := &tfbridge.PythonInfo{ - Requires: map[string]string{ - "pulumi": ">=3.0.0,<4.0.0", - }} - i.PyProject.Enabled = true - return i - })(), + Python: &tfbridge.PythonInfo{ + Requires: map[string]string{ + "pulumi": ">=3.0.0,<4.0.0", + }, + PyProject: struct{ Enabled bool }{true}, + }, Golang: &tfbridge.GolangInfo{ - ImportBasePath: filepath.Join( + ImportBasePath: path.Join( fmt.Sprintf("github.com/pulumi/pulumi-%[1]s/sdk/", mainPkg), tfbridge.GetModuleMajorVersion(version.Version), "go", @@ -146,7 +116,11 @@ func Provider() tfbridge.ProviderInfo { }, } + prov.MustComputeTokens(tokens.SingleModule("kong_", mainMod, tokens.MakeStandard(mainPkg))) + prov.SetAutonaming(255, "-") + prov.MustApplyAutoAliases() + return prov }