Skip to content

Commit

Permalink
Add YAML support for Go SDK (#1093)
Browse files Browse the repository at this point in the history
  • Loading branch information
lblackstone authored May 7, 2020
1 parent d5dde74 commit 54b5f76
Show file tree
Hide file tree
Showing 27 changed files with 2,331 additions and 28 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
## HEAD (Unreleased)

### Improvements

- Add YAML support to Go SDK. (https://github.com/pulumi/pulumi-kubernetes/pull/1093).

### Bug Fixes

- fix(customresources): use a 3-way merge patch instead of strategic merge. (https://github.com/pulumi/pulumi-kubernetes/pull/1095)
Expand Down
66 changes: 62 additions & 4 deletions provider/cmd/pulumi-gen-kubernetes/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,21 +15,25 @@
package main

import (
"bytes"
"encoding/json"
"fmt"
"go/format"
"io/ioutil"
"log"
"os"
"path"
"path/filepath"
"sort"
"text/template"

"github.com/pkg/errors"
"github.com/pulumi/pulumi-kubernetes/provider/v2/pkg/gen"
"github.com/pulumi/pulumi/pkg/v2/codegen"
gogen "github.com/pulumi/pulumi/pkg/v2/codegen/go"
"github.com/pulumi/pulumi/pkg/v2/codegen/schema"
"github.com/pulumi/pulumi/sdk/v2/go/common/tools"
"github.com/pulumi/pulumi/sdk/v2/go/common/util/contract"

"github.com/pulumi/pulumi-kubernetes/provider/v2/pkg/gen"
)

// This is the URL for the v1.17.0 swagger spec. This is the last version of the spec containing the following
Expand Down Expand Up @@ -79,7 +83,7 @@ func main() {
case "dotnet":
writeDotnetClient(data, outdir, templateDir)
case "go":
writeGoClient(data, outdir)
writeGoClient(data, outdir, templateDir)
case "schema":
if err := writePulumiSchema(data, outdir); err != nil {
panic(err)
Expand Down Expand Up @@ -322,12 +326,41 @@ func writeDotnetClient(data map[string]interface{}, outdir, templateDir string)
}
}

func writeGoClient(data map[string]interface{}, outdir string) {
func writeGoClient(data map[string]interface{}, outdir string, templateDir string) {
pkg := genPulumiSchemaPackage(data)
files, err := gogen.GeneratePackage("pulumigen", pkg)
if err != nil {
panic(err)
}

resources, err := gogen.LanguageResources("pulumigen", pkg)
if err != nil {
panic(err)
}

templateResources := gen.TemplateResources{}
imports := codegen.StringSet{}
for _, resource := range resources {
r := gen.TemplateResource{
Alias: resource.Alias,
Name: resource.Name,
Package: resource.Package,
Token: resource.Token,
}
templateResources.Resources = append(templateResources.Resources, r)
importPath := fmt.Sprintf(`%s "%s"`, resource.Alias, resource.Package)
imports.Add(importPath)
}
templateResources.Imports = imports.SortedValues()
sort.Slice(templateResources.Resources, func(i, j int) bool {
return templateResources.Resources[i].Token < templateResources.Resources[j].Token
})

files["kubernetes/yaml/configFile.go"] = mustRenderTemplate(filepath.Join(templateDir, "yaml", "configFile.tmpl"), templateResources)
files["kubernetes/yaml/configGroup.go"] = mustRenderTemplate(filepath.Join(templateDir, "yaml", "configGroup.tmpl"), templateResources)
files["kubernetes/yaml/transformation.go"] = mustRenderTemplate(filepath.Join(templateDir, "yaml", "transformation.tmpl"), templateResources)
files["kubernetes/yaml/yaml.go"] = mustRenderTemplate(filepath.Join(templateDir, "yaml", "yaml.tmpl"), templateResources)

for filename, contents := range files {
path := filepath.Join(outdir, filename)

Expand All @@ -341,6 +374,31 @@ func writeGoClient(data map[string]interface{}, outdir string) {
}
}

func mustLoadFile(path string) []byte {
b, err := ioutil.ReadFile(path)
if err != nil {
panic(err)
}
return b
}

func mustRenderTemplate(path string, resources gen.TemplateResources) []byte {
b := mustLoadFile(path)
t := template.Must(template.New("resources").Parse(string(b)))

var buf bytes.Buffer
err := t.Execute(&buf, resources)
if err != nil {
panic(err)
}
formattedSource, err := format.Source(buf.Bytes())
if err != nil {
panic(err)
}

return formattedSource
}

func genPulumiSchemaPackage(data map[string]interface{}) *schema.Package {
pkgSpec := gen.PulumiSchema(data)
pkg, err := schema.ImportSpec(pkgSpec, nil)
Expand Down
4 changes: 2 additions & 2 deletions provider/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ require (
github.com/imdario/mergo v0.3.8
github.com/mitchellh/go-wordwrap v1.0.0
github.com/pkg/errors v0.9.1
github.com/pulumi/pulumi/pkg/v2 v2.1.0
github.com/pulumi/pulumi/sdk/v2 v2.1.0
github.com/pulumi/pulumi/pkg/v2 v2.1.1-0.20200506045153-0e512aa0ef84
github.com/pulumi/pulumi/sdk/v2 v2.1.1-0.20200506045153-0e512aa0ef84
github.com/stretchr/testify v1.5.1
google.golang.org/grpc v1.28.0
k8s.io/api v0.17.0
Expand Down
18 changes: 14 additions & 4 deletions provider/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,8 @@ github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7a
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d h1:3PaI8p3seN09VjbTYC/QWlUZdZ1qS1zGjy7LH2Wt07I=
github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls=
github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
Expand Down Expand Up @@ -437,12 +439,12 @@ github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
github.com/pulumi/pulumi/pkg/v2 v2.1.0 h1:L/gaZ4XQGLODxzXu1SVfIHUHWCR8ENO4mYQnpv6u+Go=
github.com/pulumi/pulumi/pkg/v2 v2.1.0/go.mod h1:NadTQy17wc69lQt/xTl5b6/fbl/tBiOPYMIZ+M/KtBI=
github.com/pulumi/pulumi/pkg/v2 v2.1.1-0.20200506045153-0e512aa0ef84 h1:IuN+CUhkLj7CwthEnWhifL25N4KRykiQEfKJXTI//mQ=
github.com/pulumi/pulumi/pkg/v2 v2.1.1-0.20200506045153-0e512aa0ef84/go.mod h1:hXaFYjGEnsQ7qGRJbCDhjuGh7sip3TsaOGNkU3ADt9s=
github.com/pulumi/pulumi/sdk/v2 v2.0.0 h1:3VMXbEo3bqeaU+YDt8ufVBLD0WhLYE3tG3t/nIZ3Iac=
github.com/pulumi/pulumi/sdk/v2 v2.0.0/go.mod h1:W7k1UDYerc5o97mHnlHHp5iQZKEby+oQrQefWt+2RF4=
github.com/pulumi/pulumi/sdk/v2 v2.1.0 h1:NZCLrvggMHlBzsaAcvChdDhQ5i9vJxARnLCY7NCFl18=
github.com/pulumi/pulumi/sdk/v2 v2.1.0/go.mod h1:W7k1UDYerc5o97mHnlHHp5iQZKEby+oQrQefWt+2RF4=
github.com/pulumi/pulumi/sdk/v2 v2.1.1-0.20200506045153-0e512aa0ef84 h1:6qDezDHciRcIKyhQQr/dA7numrfYmm3guPlQU6bYXp4=
github.com/pulumi/pulumi/sdk/v2 v2.1.1-0.20200506045153-0e512aa0ef84/go.mod h1:QNbWpL4gvf3X0lUFT7TXA2Jo1ff/Ti2l97AyFGYwvW4=
github.com/remyoudompheng/bigfft v0.0.0-20170806203942-52369c62f446/go.mod h1:uYEyJGbgTkfkS4+E/PavXkNJcbFIpEtjt2B0KDQ5+9M=
github.com/rjeczalik/notify v0.9.2/go.mod h1:aErll2f0sUX9PXZnVNyeiObbmTlk5jnMoCa4QEjJeqM=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
Expand Down Expand Up @@ -472,6 +474,8 @@ github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkU
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
github.com/spf13/cobra v0.0.6 h1:breEStsVwemnKh2/s6gMvSdMEkwW0sK8vGStnlVBMCs=
github.com/spf13/cobra v0.0.6/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
github.com/spf13/cobra v1.0.0 h1:6m/oheQuQ13N9ks4hubMG6BnvwOeaJrqSPLahSnczz8=
github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.2/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
Expand Down Expand Up @@ -521,6 +525,8 @@ go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU=
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/atomic v1.6.0 h1:Ezj3JGmsOnG1MoRWQkPBsKLe9DwWD9QeXzTRzzldNVk=
go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
gocloud.dev v0.19.0/go.mod h1:SmKwiR8YwIMMJvQBKLsC3fHNyMwXLw3PMDO+VVteJMI=
Expand Down Expand Up @@ -563,13 +569,15 @@ golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHl
golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
golang.org/x/lint v0.0.0-20200130185559-910be7a94367 h1:0IiAsCRByjO2QjX7ZPkw5oU9x+n1YqRL802rjC0c3Aw=
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.2.0 h1:KU7oHjnv3XNWfa5COkzUifxZmxp1TyI7ImMXqFxLwvQ=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
Expand Down Expand Up @@ -687,6 +695,7 @@ golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtn
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20190920225731-5eefd052ad72/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
Expand All @@ -700,6 +709,7 @@ golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapK
golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200224181240-023911ca70b2 h1:L/G4KZvrQn7FWLN/LlulBtBzrLUhqjiGfTWWDmrh+IQ=
golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
Expand Down
96 changes: 96 additions & 0 deletions provider/pkg/gen/go-templates/yaml/configFile.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
// Copyright 2016-2020, Pulumi Corporation.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// *** WARNING: this file was generated by pulumigen. ***
// *** Do not edit by hand unless you're certain you know what you are doing! ***

package yaml

import (
"fmt"

"github.com/pkg/errors"
"github.com/pulumi/pulumi/sdk/v2/go/pulumi"
)

// ConfigFile creates a set of Kubernetes resources from a Kubernetes YAML file.
type ConfigFile struct {
pulumi.ResourceState

Resources map[string]pulumi.Resource
}

// The set of arguments for constructing a ConfigFile resource.
type ConfigFileArgs struct {
// File is a path or URL that uniquely identifies a file.
File string
// Transformations is an optional list of transformations to apply to Kubernetes resource definitions
// before registering with the engine.
Transformations []Transformation
// ResourcePrefix is an optional prefix for the auto-generated resource names. For example, a resource named `bar`
// created with resource prefix of `"foo"` would produce a resource named `"foo-bar"`.
ResourcePrefix string
}

// NewConfigFile registers a new resource with the given unique name, arguments, and options.
func NewConfigFile(ctx *pulumi.Context,
name string, args *ConfigFileArgs, opts ...pulumi.ResourceOption) (*ConfigFile, error) {

// Register the resulting resource state.
configFile := &ConfigFile{
Resources: map[string]pulumi.Resource{},
}
err := ctx.RegisterComponentResource("kubernetes:yaml:ConfigFile", name, configFile, opts...)
if err != nil {
return nil, err
}

// Now provision all child resources by parsing the YAML file.
if args != nil {
// Honor the resource name prefix if specified.
if args.ResourcePrefix != "" {
name = args.ResourcePrefix + "-" + name
}

// Parse and decode the YAML files.
rs, err := parseDecodeYamlFiles(ctx, &ConfigGroupArgs{
Files: []string{args.File},
Transformations: args.Transformations,
ResourcePrefix: args.ResourcePrefix,
}, true, pulumi.Parent(configFile))
if err != nil {
return nil, err
}
configFile.Resources = rs
}

// Finally, register all of the resources found.
err = ctx.RegisterResourceOutputs(configFile, pulumi.Map{})
if err != nil {
return nil, errors.Wrapf(err, "registering child resources")
}

return configFile, nil
}

// GetResource returns a resource defined by a built-in Kubernetes group/version/kind, name and namespace.
// For example, GetResource("v1/Pod", "foo", "") would return a Pod called "foo" from the "default" namespace.
func (cf *ConfigFile) GetResource(gvk, name, namespace string) pulumi.Resource {
id := name
if len(namespace) > 0 && namespace != "default" {
id = fmt.Sprintf("%s/%s", namespace, name)
}
key := fmt.Sprintf("%s::%s", gvk, id)
return cf.Resources[key]
}
Loading

0 comments on commit 54b5f76

Please sign in to comment.