From ea12be616e8148960debaea12461c9fa5977ac2a Mon Sep 17 00:00:00 2001 From: guineveresaenger Date: Wed, 20 Nov 2024 12:28:41 -0800 Subject: [PATCH 01/16] MVP using a shallow clone at version tag and rudimentary parsing of input parameters. Needs refinement. --- dynamic/info.go | 20 ++++++--- dynamic/main.go | 12 +++++- dynamic/parameterize/args.go | 11 ++++- pkg/tfgen/generate.go | 79 +++++++++++++++++++++++------------- pkg/tfgen/source.go | 7 +++- testing/go.mod | 1 - testing/go.sum | 4 +- 7 files changed, 94 insertions(+), 40 deletions(-) diff --git a/dynamic/info.go b/dynamic/info.go index 16720139b..fc81efe9c 100644 --- a/dynamic/info.go +++ b/dynamic/info.go @@ -33,12 +33,22 @@ import ( func providerInfo(ctx context.Context, p run.Provider, value parameterize.Value) (tfbridge.ProviderInfo, error) { provider := proto.New(ctx, p) + // TODO: what if this is local? + remoteURL := value.Remote.URL + //remoteVersion := value.Remote.Version //TODO: use the package ? + urlFields := strings.Split(remoteURL, "/") + //TODO: the final two fields here are the github repo where the docs are, maybe? + // -> find out if this assertion is true; if yes then we're good, if no, we need more options + ghOrg := urlFields[len(urlFields)-2] + ghRepo := urlFields[len(urlFields)-1] + ghAddr := "https://github.com/" + ghOrg + "/terraform-provider-" + ghRepo prov := tfbridge.ProviderInfo{ - P: provider, - Name: p.Name(), - Version: p.Version(), - Description: "A Pulumi provider dynamically bridged from " + p.Name() + ".", - Publisher: "Pulumi", + P: provider, + Name: p.Name(), + Version: p.Version(), + Description: "A Pulumi provider dynamically bridged from " + p.Name() + ".", + Publisher: "Pulumi", + UpstreamRepoPath: ghAddr, ResourcePrefix: inferResourcePrefix(provider), diff --git a/dynamic/main.go b/dynamic/main.go index f9a148f02..003c06407 100644 --- a/dynamic/main.go +++ b/dynamic/main.go @@ -63,14 +63,23 @@ func initialSetup() (info.Provider, pfbridge.ProviderMetadata, func() error) { } var metadata pfbridge.ProviderMetadata + var fullDocs bool metadata = pfbridge.ProviderMetadata{ XGetSchema: func(ctx context.Context, req plugin.GetSchemaRequest) ([]byte, error) { + // By default, only read in docs from TF schema + var schemaDocsOnly = true + // If full docs is expected set schemaDocsOnly to false + if fullDocs { + schemaDocsOnly = false + } + packageSchema, err := tfgen.GenerateSchemaWithOptions(tfgen.GenerateSchemaOptions{ ProviderInfo: info, DiagnosticsSink: diag.DefaultSink(os.Stdout, os.Stderr, diag.FormatOptions{ Color: colors.Always, }), - XInMemoryDocs: true, + XInMemoryDocs: schemaDocsOnly, + XLoadUpstreamRepo: fullDocs, }) if err != nil { return nil, err @@ -147,6 +156,7 @@ func initialSetup() (info.Provider, pfbridge.ProviderMetadata, func() error) { if err != nil { return plugin.ParameterizeResponse{}, err } + fullDocs = args.Remote.Docs return plugin.ParameterizeResponse{ Name: p.Name(), diff --git a/dynamic/parameterize/args.go b/dynamic/parameterize/args.go index 65873b13e..05fd36ea9 100644 --- a/dynamic/parameterize/args.go +++ b/dynamic/parameterize/args.go @@ -31,6 +31,8 @@ type RemoteArgs struct { Name string // Version is the (possibly empty) version constraint on the provider. Version string + // Docs is the (possibly empty) argument to download and write docs into the schema + Docs bool } // LocalArgs represents a local TF provider referenced by path. @@ -52,6 +54,13 @@ func ParseArgs(args []string) (Args, error) { // This is a registry based provider var remote RemoteArgs switch len(args) { + // The third argument, if any, is the full docs option for when we need to generate docs + case 3: + docsArg := args[2] + if docsArg == "fullDocs" { + remote.Docs = true + } + fallthrough // The second argument, if any is the version case 2: remote.Version = args[1] @@ -61,6 +70,6 @@ func ParseArgs(args []string) (Args, error) { remote.Name = args[0] return Args{Remote: &remote}, nil default: - return Args{}, fmt.Errorf("expected to be parameterized by 1-2 arguments: [version]") + return Args{}, fmt.Errorf("expected to be parameterized by 1-3 arguments: [version] [fullDocs]") } } diff --git a/pkg/tfgen/generate.go b/pkg/tfgen/generate.go index 2027b009a..bbc38ba3e 100644 --- a/pkg/tfgen/generate.go +++ b/pkg/tfgen/generate.go @@ -19,6 +19,7 @@ import ( "encoding/json" "fmt" "os" + "os/exec" "path" "path/filepath" "sort" @@ -79,6 +80,9 @@ type Generator struct { // message. noDocsRepo bool + // Set if we want to download the upstream repo for docs purposes + loadDocsRepo bool + cliConverterState *cliConverter examplesCache *examplesCache @@ -775,9 +779,10 @@ func GenerateSchema(info tfbridge.ProviderInfo, sink diag.Sink) (pschema.Package } type GenerateSchemaOptions struct { - ProviderInfo tfbridge.ProviderInfo - DiagnosticsSink diag.Sink - XInMemoryDocs bool + ProviderInfo tfbridge.ProviderInfo + DiagnosticsSink diag.Sink + XInMemoryDocs bool + XLoadUpstreamRepo bool } type GenerateSchemaResult struct { @@ -786,21 +791,22 @@ type GenerateSchemaResult struct { func GenerateSchemaWithOptions(opts GenerateSchemaOptions) (*GenerateSchemaResult, error) { ctx := context.Background() + info := opts.ProviderInfo sink := opts.DiagnosticsSink g, err := NewGenerator(GeneratorOptions{ - Package: info.Name, - Version: info.Version, - Language: Schema, - ProviderInfo: info, - Root: afero.NewMemMapFs(), - Sink: sink, - XInMemoryDocs: opts.XInMemoryDocs, + Package: info.Name, + Version: info.Version, + Language: Schema, + ProviderInfo: info, + Root: afero.NewMemMapFs(), + Sink: sink, + XInMemoryDocs: opts.XInMemoryDocs, + XLoadUpstreamRepo: opts.XLoadUpstreamRepo, }) if err != nil { return nil, errors.Wrapf(err, "failed to create generator") } - return g.generateSchemaResult(ctx) } @@ -823,6 +829,11 @@ type GeneratorOptions struct { // XInMemoryDocs is an experimental feature, and does not have any backwards // compatibility guarantees. XInMemoryDocs bool + // XLoadUpstreamRepo instructs the generator to fetch the upstream repo for docsgen purposes. + // + // XLoadUpstreamRepo is an experimental feature, and does not have any backwards + //compatibility guarantees. + XLoadUpstreamRepo bool } // NewGenerator returns a code-generator for the given language runtime and package info. @@ -887,21 +898,23 @@ func NewGenerator(opts GeneratorOptions) (*Generator, error) { } return &Generator{ - pkg: pkg, - version: version, - language: lang, - info: info, - root: root, - providerShim: providerShim, - pluginHost: newCachingProviderHost(host), - packageCache: pcl.NewPackageCache(), - infoSource: host, - sink: sink, - skipDocs: opts.SkipDocs, - skipExamples: opts.SkipExamples, - coverageTracker: opts.CoverageTracker, - editRules: getEditRules(info.DocRules), - noDocsRepo: opts.XInMemoryDocs, + pkg: pkg, + version: version, + language: lang, + info: info, + root: root, + providerShim: providerShim, + pluginHost: newCachingProviderHost(host), + packageCache: pcl.NewPackageCache(), + infoSource: host, + terraformVersion: opts.TerraformVersion, + sink: sink, + skipDocs: opts.SkipDocs, + skipExamples: opts.SkipExamples, + coverageTracker: opts.CoverageTracker, + editRules: getEditRules(info.DocRules), + noDocsRepo: opts.XInMemoryDocs, + loadDocsRepo: opts.XLoadUpstreamRepo, }, nil } @@ -941,6 +954,14 @@ func (g *Generator) generateSchemaResult(ctx context.Context) (*GenerateSchemaRe if err != nil { return nil, err } + + // if docs don't exist, i.e. because the provider is dynamic, download docs at version and repo address + if g.loadDocsRepo { + versionWithPrefix := "v" + g.info.Version + cmd := exec.Command("git", "clone", "--depth", "1", "-b", versionWithPrefix, g.info.UpstreamRepoPath, "dynamicDocsDir") + err = cmd.Run() + } + // First gather up the entire package contents. This structure is complete and sufficient to hand off to the // language-specific generators to create the full output. pack, err := g.gatherPackage() @@ -1206,6 +1227,7 @@ func (g *Generator) gatherProvider() (*resourceType, error) { Tok: tokens.Type(g.pkg.String()), Fields: g.info.Config, } + res, err := g.gatherResource("", (&schema.Resource{Schema: cfg}).Shim(), info, true) return res, err } @@ -1303,7 +1325,7 @@ func (g *Generator) gatherResource(rawname string, var entityDocs entityDocs if !isProvider { // If g.noDocsRepo is set, we have established that it's pointless to get - // docs from the repo, so we don't try. + // docs from the repo, so we don't try. // TODO: is this redundant? unclear! if !g.noDocsRepo { source := NewGitRepoDocsSource(g) pulumiDocs, err := getDocsForResource(g, source, ResourceDocs, rawname, info) @@ -1676,8 +1698,9 @@ func (g *Generator) checkNoDocsError(err error) bool { return false } - // If we have already warned, we can just discard the message + // If we have already warned, we can just discard the message - TODO: this comment is about code we DIDN'T write I think! if !g.noDocsRepo { + //panic(g.noDocsRepo) g.logMissingRepoPath(e) } g.noDocsRepo = true diff --git a/pkg/tfgen/source.go b/pkg/tfgen/source.go index 37fb941cf..ffa5de26f 100644 --- a/pkg/tfgen/source.go +++ b/pkg/tfgen/source.go @@ -86,7 +86,6 @@ func (gh *gitRepoSource) getFile( if info != nil && len(info.Markdown) != 0 { return &DocFile{Content: info.Markdown}, nil } - repoPath := gh.upstreamRepoPath if repoPath == "" { var err error @@ -95,6 +94,12 @@ func (gh *gitRepoSource) getFile( return nil, fmt.Errorf("repo for token %q: %w", rawname, err) } } + // reset repoPath for dynamic providers + _, err := os.Stat("./dynamicDocsDir") + if err == nil { + repoPath = "./dynamicDocsDir" + } + var possibleMarkdownNames []string switch kind { case InstallationDocs: diff --git a/testing/go.mod b/testing/go.mod index 4345426aa..d9490efc2 100644 --- a/testing/go.mod +++ b/testing/go.mod @@ -11,7 +11,6 @@ replace github.com/pulumi/pulumi-terraform-bridge/v3 => ../ require github.com/pulumi/pulumi-terraform-bridge/v3 v3.0.0-00010101000000-000000000000 require ( - github.com/kr/text v0.2.0 // indirect github.com/stretchr/testify v1.9.0 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 // indirect google.golang.org/protobuf v1.35.1 // indirect diff --git a/testing/go.sum b/testing/go.sum index a7c2cc6ea..4ab866ff5 100644 --- a/testing/go.sum +++ b/testing/go.sum @@ -1,4 +1,3 @@ -github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= @@ -6,9 +5,8 @@ github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeN github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pulumi/pulumi/sdk/v3 v3.142.0 h1:SmcVddGuvwAh3g3XUVQQ5gVRQUKH1yZ6iETpDNHIHlw= From 9d84b2ea8df642ac33f937de6c40f2d769baf2b7 Mon Sep 17 00:00:00 2001 From: guineveresaenger Date: Fri, 22 Nov 2024 13:22:59 -0800 Subject: [PATCH 02/16] Fixup tests for args --- dynamic/main.go | 5 ++-- dynamic/parameterize/args.go | 4 ++- dynamic/parameterize/args_test.go | 18 +++++++++++-- pkg/tfgen/generate.go | 43 ++++++++++++++++--------------- pkg/tfgen/source.go | 8 +++--- 5 files changed, 47 insertions(+), 31 deletions(-) diff --git a/dynamic/main.go b/dynamic/main.go index 003c06407..b5381b353 100644 --- a/dynamic/main.go +++ b/dynamic/main.go @@ -78,8 +78,8 @@ func initialSetup() (info.Provider, pfbridge.ProviderMetadata, func() error) { DiagnosticsSink: diag.DefaultSink(os.Stdout, os.Stderr, diag.FormatOptions{ Color: colors.Always, }), - XInMemoryDocs: schemaDocsOnly, - XLoadUpstreamRepo: fullDocs, + XInMemoryDocs: schemaDocsOnly, + XLoadUpstreamRepoForDocs: fullDocs, }) if err != nil { return nil, err @@ -157,7 +157,6 @@ func initialSetup() (info.Provider, pfbridge.ProviderMetadata, func() error) { return plugin.ParameterizeResponse{}, err } fullDocs = args.Remote.Docs - return plugin.ParameterizeResponse{ Name: p.Name(), Version: v, diff --git a/dynamic/parameterize/args.go b/dynamic/parameterize/args.go index 05fd36ea9..af5ac9b6e 100644 --- a/dynamic/parameterize/args.go +++ b/dynamic/parameterize/args.go @@ -59,6 +59,8 @@ func ParseArgs(args []string) (Args, error) { docsArg := args[2] if docsArg == "fullDocs" { remote.Docs = true + } else { + return Args{}, fmt.Errorf("expected third parameterized argument to be 'fullDocs' or empty") } fallthrough // The second argument, if any is the version @@ -70,6 +72,6 @@ func ParseArgs(args []string) (Args, error) { remote.Name = args[0] return Args{Remote: &remote}, nil default: - return Args{}, fmt.Errorf("expected to be parameterized by 1-3 arguments: [version] [fullDocs]") + return Args{}, fmt.Errorf("expected to be parameterized by 1-3 arguments: [version] fullDocs") } } diff --git a/dynamic/parameterize/args_test.go b/dynamic/parameterize/args_test.go index c18bf108e..fa014baf8 100644 --- a/dynamic/parameterize/args_test.go +++ b/dynamic/parameterize/args_test.go @@ -51,12 +51,26 @@ func TestParseArgs(t *testing.T) { { name: "no args", args: []string{}, - errMsg: autogold.Expect("expected to be parameterized by 1-2 arguments: [version]"), + errMsg: autogold.Expect("expected to be parameterized by 1-3 arguments: [version] fullDocs"), }, { name: "too many args", + args: []string{"arg1", "arg2", "arg3", "arg4"}, + errMsg: autogold.Expect("expected to be parameterized by 1-3 arguments: [version] fullDocs"), + }, + { + name: "invalid third arg", args: []string{"arg1", "arg2", "arg3"}, - errMsg: autogold.Expect("expected to be parameterized by 1-2 arguments: [version]"), + errMsg: autogold.Expect("expected third parameterized argument to be 'fullDocs' or empty"), + }, + { + name: "valid third arg", + args: []string{"my-registry.io/typ", "1.2.3", "fullDocs"}, + expect: Args{Remote: &RemoteArgs{ + Name: "my-registry.io/typ", + Version: "1.2.3", + Docs: true, + }}, }, } diff --git a/pkg/tfgen/generate.go b/pkg/tfgen/generate.go index bbc38ba3e..1adebebb5 100644 --- a/pkg/tfgen/generate.go +++ b/pkg/tfgen/generate.go @@ -53,9 +53,10 @@ import ( ) const ( - tfgen = "the Pulumi Terraform Bridge (tfgen) Tool" - defaultOutDir = "sdk/" - maxWidth = 120 // the ideal maximum width of the generated file. + tfgen = "the Pulumi Terraform Bridge (tfgen) Tool" + defaultOutDir = "sdk/" + maxWidth = 120 // the ideal maximum width of the generated file. + dynamicDocsDir = "dynamicDocsDir" ) type Generator struct { @@ -80,7 +81,7 @@ type Generator struct { // message. noDocsRepo bool - // Set if we want to download the upstream repo for docs purposes + // Set if we want to download the upstream repo for docs purposes. loadDocsRepo bool cliConverterState *cliConverter @@ -779,10 +780,10 @@ func GenerateSchema(info tfbridge.ProviderInfo, sink diag.Sink) (pschema.Package } type GenerateSchemaOptions struct { - ProviderInfo tfbridge.ProviderInfo - DiagnosticsSink diag.Sink - XInMemoryDocs bool - XLoadUpstreamRepo bool + ProviderInfo tfbridge.ProviderInfo + DiagnosticsSink diag.Sink + XInMemoryDocs bool + XLoadUpstreamRepoForDocs bool } type GenerateSchemaResult struct { @@ -795,14 +796,14 @@ func GenerateSchemaWithOptions(opts GenerateSchemaOptions) (*GenerateSchemaResul info := opts.ProviderInfo sink := opts.DiagnosticsSink g, err := NewGenerator(GeneratorOptions{ - Package: info.Name, - Version: info.Version, - Language: Schema, - ProviderInfo: info, - Root: afero.NewMemMapFs(), - Sink: sink, - XInMemoryDocs: opts.XInMemoryDocs, - XLoadUpstreamRepo: opts.XLoadUpstreamRepo, + Package: info.Name, + Version: info.Version, + Language: Schema, + ProviderInfo: info, + Root: afero.NewMemMapFs(), + Sink: sink, + XInMemoryDocs: opts.XInMemoryDocs, + XLoadUpstreamRepoForDocs: opts.XLoadUpstreamRepoForDocs, }) if err != nil { return nil, errors.Wrapf(err, "failed to create generator") @@ -829,11 +830,11 @@ type GeneratorOptions struct { // XInMemoryDocs is an experimental feature, and does not have any backwards // compatibility guarantees. XInMemoryDocs bool - // XLoadUpstreamRepo instructs the generator to fetch the upstream repo for docsgen purposes. + // XLoadUpstreamRepoForDocs instructs the generator to fetch the upstream repo for docsgen purposes. // - // XLoadUpstreamRepo is an experimental feature, and does not have any backwards + // XLoadUpstreamRepoForDocs is an experimental feature, and does not have any backwards //compatibility guarantees. - XLoadUpstreamRepo bool + XLoadUpstreamRepoForDocs bool } // NewGenerator returns a code-generator for the given language runtime and package info. @@ -914,7 +915,7 @@ func NewGenerator(opts GeneratorOptions) (*Generator, error) { coverageTracker: opts.CoverageTracker, editRules: getEditRules(info.DocRules), noDocsRepo: opts.XInMemoryDocs, - loadDocsRepo: opts.XLoadUpstreamRepo, + loadDocsRepo: opts.XLoadUpstreamRepoForDocs, }, nil } @@ -958,7 +959,7 @@ func (g *Generator) generateSchemaResult(ctx context.Context) (*GenerateSchemaRe // if docs don't exist, i.e. because the provider is dynamic, download docs at version and repo address if g.loadDocsRepo { versionWithPrefix := "v" + g.info.Version - cmd := exec.Command("git", "clone", "--depth", "1", "-b", versionWithPrefix, g.info.UpstreamRepoPath, "dynamicDocsDir") + cmd := exec.Command("git", "clone", "--depth", "1", "-b", versionWithPrefix, g.info.UpstreamRepoPath, dynamicDocsDir) err = cmd.Run() } diff --git a/pkg/tfgen/source.go b/pkg/tfgen/source.go index ffa5de26f..d221cb053 100644 --- a/pkg/tfgen/source.go +++ b/pkg/tfgen/source.go @@ -94,10 +94,10 @@ func (gh *gitRepoSource) getFile( return nil, fmt.Errorf("repo for token %q: %w", rawname, err) } } - // reset repoPath for dynamic providers - _, err := os.Stat("./dynamicDocsDir") - if err == nil { - repoPath = "./dynamicDocsDir" + + // When we build full docs for dynamic providers, we expect a local download of the git repo in dynamicDocsDir. + if _, err := os.Stat(dynamicDocsDir); err == nil { + repoPath = dynamicDocsDir } var possibleMarkdownNames []string From 85cf598c9d016e68e63413fc23267b6da3e75daa Mon Sep 17 00:00:00 2001 From: guineveresaenger Date: Fri, 22 Nov 2024 14:25:13 -0800 Subject: [PATCH 03/16] Do not use upstreamRepoPath --- dynamic/info.go | 20 +++++++------------- pkg/tfgen/generate.go | 9 ++++----- pkg/tfgen/source.go | 19 +++++++++---------- 3 files changed, 20 insertions(+), 28 deletions(-) diff --git a/dynamic/info.go b/dynamic/info.go index fc81efe9c..321b117ab 100644 --- a/dynamic/info.go +++ b/dynamic/info.go @@ -33,23 +33,17 @@ import ( func providerInfo(ctx context.Context, p run.Provider, value parameterize.Value) (tfbridge.ProviderInfo, error) { provider := proto.New(ctx, p) - // TODO: what if this is local? + // TODO: handle docsgen for a local dynamic provider remoteURL := value.Remote.URL - //remoteVersion := value.Remote.Version //TODO: use the package ? urlFields := strings.Split(remoteURL, "/") - //TODO: the final two fields here are the github repo where the docs are, maybe? - // -> find out if this assertion is true; if yes then we're good, if no, we need more options ghOrg := urlFields[len(urlFields)-2] - ghRepo := urlFields[len(urlFields)-1] - ghAddr := "https://github.com/" + ghOrg + "/terraform-provider-" + ghRepo prov := tfbridge.ProviderInfo{ - P: provider, - Name: p.Name(), - Version: p.Version(), - Description: "A Pulumi provider dynamically bridged from " + p.Name() + ".", - Publisher: "Pulumi", - UpstreamRepoPath: ghAddr, - + P: provider, + Name: p.Name(), + Version: p.Version(), + Description: "A Pulumi provider dynamically bridged from " + p.Name() + ".", + Publisher: "Pulumi", + GitHubOrg: ghOrg, ResourcePrefix: inferResourcePrefix(provider), // To avoid bogging down schema generation speed, we skip all examples. diff --git a/pkg/tfgen/generate.go b/pkg/tfgen/generate.go index 1adebebb5..f5dada249 100644 --- a/pkg/tfgen/generate.go +++ b/pkg/tfgen/generate.go @@ -959,7 +959,8 @@ func (g *Generator) generateSchemaResult(ctx context.Context) (*GenerateSchemaRe // if docs don't exist, i.e. because the provider is dynamic, download docs at version and repo address if g.loadDocsRepo { versionWithPrefix := "v" + g.info.Version - cmd := exec.Command("git", "clone", "--depth", "1", "-b", versionWithPrefix, g.info.UpstreamRepoPath, dynamicDocsDir) + ghRepo := "https://github.com/" + g.info.GitHubOrg + "/terraform-provider-" + g.info.Name + cmd := exec.Command("git", "clone", "--depth", "1", "-b", versionWithPrefix, ghRepo, dynamicDocsDir) err = cmd.Run() } @@ -1228,7 +1229,6 @@ func (g *Generator) gatherProvider() (*resourceType, error) { Tok: tokens.Type(g.pkg.String()), Fields: g.info.Config, } - res, err := g.gatherResource("", (&schema.Resource{Schema: cfg}).Shim(), info, true) return res, err } @@ -1326,7 +1326,7 @@ func (g *Generator) gatherResource(rawname string, var entityDocs entityDocs if !isProvider { // If g.noDocsRepo is set, we have established that it's pointless to get - // docs from the repo, so we don't try. // TODO: is this redundant? unclear! + // docs from the repo, so we don't try. if !g.noDocsRepo { source := NewGitRepoDocsSource(g) pulumiDocs, err := getDocsForResource(g, source, ResourceDocs, rawname, info) @@ -1699,9 +1699,8 @@ func (g *Generator) checkNoDocsError(err error) bool { return false } - // If we have already warned, we can just discard the message - TODO: this comment is about code we DIDN'T write I think! + // If we have already warned, we can just discard the message if !g.noDocsRepo { - //panic(g.noDocsRepo) g.logMissingRepoPath(e) } g.noDocsRepo = true diff --git a/pkg/tfgen/source.go b/pkg/tfgen/source.go index d221cb053..fee8b3f80 100644 --- a/pkg/tfgen/source.go +++ b/pkg/tfgen/source.go @@ -88,18 +88,17 @@ func (gh *gitRepoSource) getFile( } repoPath := gh.upstreamRepoPath if repoPath == "" { - var err error - repoPath, err = getRepoPath(gh.githost, gh.org, gh.provider, gh.providerModuleVersion) - if err != nil { - return nil, fmt.Errorf("repo for token %q: %w", rawname, err) + // When we build full docs for dynamic providers, we expect a local download of the git repo in dynamicDocsDir. + if _, err := os.Stat(dynamicDocsDir); err == nil { + repoPath = dynamicDocsDir + } else { + var err error + repoPath, err = getRepoPath(gh.githost, gh.org, gh.provider, gh.providerModuleVersion) + if err != nil { + return nil, fmt.Errorf("repo for token %q: %w", rawname, err) + } } } - - // When we build full docs for dynamic providers, we expect a local download of the git repo in dynamicDocsDir. - if _, err := os.Stat(dynamicDocsDir); err == nil { - repoPath = dynamicDocsDir - } - var possibleMarkdownNames []string switch kind { case InstallationDocs: From efe1214a24bcfdbc070e8dec13dd28c2e2ea4202 Mon Sep 17 00:00:00 2001 From: guineveresaenger Date: Fri, 22 Nov 2024 15:48:30 -0800 Subject: [PATCH 04/16] lint --- pkg/tfgen/generate.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pkg/tfgen/generate.go b/pkg/tfgen/generate.go index f5dada249..ed9fd88fa 100644 --- a/pkg/tfgen/generate.go +++ b/pkg/tfgen/generate.go @@ -962,6 +962,9 @@ func (g *Generator) generateSchemaResult(ctx context.Context) (*GenerateSchemaRe ghRepo := "https://github.com/" + g.info.GitHubOrg + "/terraform-provider-" + g.info.Name cmd := exec.Command("git", "clone", "--depth", "1", "-b", versionWithPrefix, ghRepo, dynamicDocsDir) err = cmd.Run() + if err != nil { + return nil, errors.Wrapf(err, "failed to clone upstream provider for docs") + } } // First gather up the entire package contents. This structure is complete and sufficient to hand off to the From 9489b2d0da4e0970173965bf0bce1aba18279886 Mon Sep 17 00:00:00 2001 From: guineveresaenger Date: Wed, 27 Nov 2024 11:08:44 -0800 Subject: [PATCH 05/16] Load upstream repo in parameterize call and set upstreamRepoPath --- dynamic/info.go | 11 +++++++-- dynamic/main.go | 20 ++++++++++++++-- pkg/tfbridge/info/info.go | 5 +++- pkg/tfgen/generate.go | 50 ++++++++++----------------------------- pkg/tfgen/source.go | 13 ++++------ 5 files changed, 48 insertions(+), 51 deletions(-) diff --git a/dynamic/info.go b/dynamic/info.go index 321b117ab..dae85754d 100644 --- a/dynamic/info.go +++ b/dynamic/info.go @@ -34,8 +34,15 @@ import ( func providerInfo(ctx context.Context, p run.Provider, value parameterize.Value) (tfbridge.ProviderInfo, error) { provider := proto.New(ctx, p) // TODO: handle docsgen for a local dynamic provider - remoteURL := value.Remote.URL - urlFields := strings.Split(remoteURL, "/") + // https://github.com/opentofu/registry/issues/1337: Due to discrepancies in the registry protocol/implementation, + // we infer the Terraform provider's source code repository via the following assumptions: + // - The provider's source code is hosted at github.com + // - The provider's github org, for providers, is the namespace field of the registry name + // Example: + // + // opentofu.org/provider/hashicorp/random -> "hashicorp" is deduced to be the github org. + // Note that this will only work for the provider (not the module) protocol. + urlFields := strings.Split(value.Remote.URL, "/") ghOrg := urlFields[len(urlFields)-2] prov := tfbridge.ProviderInfo{ P: provider, diff --git a/dynamic/main.go b/dynamic/main.go index b5381b353..009a3c934 100644 --- a/dynamic/main.go +++ b/dynamic/main.go @@ -17,8 +17,10 @@ package main import ( "context" "encoding/json" + "errors" "fmt" "os" + "os/exec" "github.com/blang/semver" "github.com/opentofu/opentofu/shim/run" @@ -78,8 +80,7 @@ func initialSetup() (info.Provider, pfbridge.ProviderMetadata, func() error) { DiagnosticsSink: diag.DefaultSink(os.Stdout, os.Stderr, diag.FormatOptions{ Color: colors.Always, }), - XInMemoryDocs: schemaDocsOnly, - XLoadUpstreamRepoForDocs: fullDocs, + XInMemoryDocs: schemaDocsOnly, }) if err != nil { return nil, err @@ -157,6 +158,21 @@ func initialSetup() (info.Provider, pfbridge.ProviderMetadata, func() error) { return plugin.ParameterizeResponse{}, err } fullDocs = args.Remote.Docs + if fullDocs { + upstreamRepoDir := "terraform-provider-" + info.Name + "-v" + info.Version + // Only clone if the directory doesn't exist in the expected location + if _, err := os.Stat(upstreamRepoDir); errors.Is(err, os.ErrNotExist) { + versionWithPrefix := "v" + info.Version + ghRepo := "https://github.com/" + info.GitHubOrg + "/terraform-provider-" + info.Name + + cmd := exec.Command("git", "clone", "--depth", "1", "-b", versionWithPrefix, ghRepo, upstreamRepoDir) + err = cmd.Run() + if err != nil { + return plugin.ParameterizeResponse{}, err + } + } + info.UpstreamRepoPath = upstreamRepoDir + } return plugin.ParameterizeResponse{ Name: p.Name(), Version: v, diff --git a/pkg/tfbridge/info/info.go b/pkg/tfbridge/info/info.go index bcc461bc0..e11cd10fa 100644 --- a/pkg/tfbridge/info/info.go +++ b/pkg/tfbridge/info/info.go @@ -119,7 +119,7 @@ type Provider struct { // Rules that control file discovery and edits for any subset of docs in a provider. DocRules *DocRule - // An optional file path to the root of the upstream provider's git repo, for use in docs generation. + // An optional local file path to the root of the upstream provider's git repo, for use in docs generation. // // If UpstreamRepoPath is left blank, it is inferred to the location where Go downloaded the build // dependency of the provider. The following fields influence the inference decision: @@ -129,6 +129,9 @@ type Provider struct { // - Name // - TFProviderModuleVersion // + // For dynamically bridged providers, when the fullDocs option is set on the parameterized inputs, + // this field will be automatically set to "terraform-provider--v". + // This list may change over time. UpstreamRepoPath string diff --git a/pkg/tfgen/generate.go b/pkg/tfgen/generate.go index ed9fd88fa..e64f3d347 100644 --- a/pkg/tfgen/generate.go +++ b/pkg/tfgen/generate.go @@ -19,7 +19,6 @@ import ( "encoding/json" "fmt" "os" - "os/exec" "path" "path/filepath" "sort" @@ -53,10 +52,9 @@ import ( ) const ( - tfgen = "the Pulumi Terraform Bridge (tfgen) Tool" - defaultOutDir = "sdk/" - maxWidth = 120 // the ideal maximum width of the generated file. - dynamicDocsDir = "dynamicDocsDir" + tfgen = "the Pulumi Terraform Bridge (tfgen) Tool" + defaultOutDir = "sdk/" + maxWidth = 120 // the ideal maximum width of the generated file. ) type Generator struct { @@ -81,9 +79,6 @@ type Generator struct { // message. noDocsRepo bool - // Set if we want to download the upstream repo for docs purposes. - loadDocsRepo bool - cliConverterState *cliConverter examplesCache *examplesCache @@ -780,10 +775,9 @@ func GenerateSchema(info tfbridge.ProviderInfo, sink diag.Sink) (pschema.Package } type GenerateSchemaOptions struct { - ProviderInfo tfbridge.ProviderInfo - DiagnosticsSink diag.Sink - XInMemoryDocs bool - XLoadUpstreamRepoForDocs bool + ProviderInfo tfbridge.ProviderInfo + DiagnosticsSink diag.Sink + XInMemoryDocs bool } type GenerateSchemaResult struct { @@ -796,14 +790,13 @@ func GenerateSchemaWithOptions(opts GenerateSchemaOptions) (*GenerateSchemaResul info := opts.ProviderInfo sink := opts.DiagnosticsSink g, err := NewGenerator(GeneratorOptions{ - Package: info.Name, - Version: info.Version, - Language: Schema, - ProviderInfo: info, - Root: afero.NewMemMapFs(), - Sink: sink, - XInMemoryDocs: opts.XInMemoryDocs, - XLoadUpstreamRepoForDocs: opts.XLoadUpstreamRepoForDocs, + Package: info.Name, + Version: info.Version, + Language: Schema, + ProviderInfo: info, + Root: afero.NewMemMapFs(), + Sink: sink, + XInMemoryDocs: opts.XInMemoryDocs, }) if err != nil { return nil, errors.Wrapf(err, "failed to create generator") @@ -830,11 +823,6 @@ type GeneratorOptions struct { // XInMemoryDocs is an experimental feature, and does not have any backwards // compatibility guarantees. XInMemoryDocs bool - // XLoadUpstreamRepoForDocs instructs the generator to fetch the upstream repo for docsgen purposes. - // - // XLoadUpstreamRepoForDocs is an experimental feature, and does not have any backwards - //compatibility guarantees. - XLoadUpstreamRepoForDocs bool } // NewGenerator returns a code-generator for the given language runtime and package info. @@ -915,7 +903,6 @@ func NewGenerator(opts GeneratorOptions) (*Generator, error) { coverageTracker: opts.CoverageTracker, editRules: getEditRules(info.DocRules), noDocsRepo: opts.XInMemoryDocs, - loadDocsRepo: opts.XLoadUpstreamRepoForDocs, }, nil } @@ -956,17 +943,6 @@ func (g *Generator) generateSchemaResult(ctx context.Context) (*GenerateSchemaRe return nil, err } - // if docs don't exist, i.e. because the provider is dynamic, download docs at version and repo address - if g.loadDocsRepo { - versionWithPrefix := "v" + g.info.Version - ghRepo := "https://github.com/" + g.info.GitHubOrg + "/terraform-provider-" + g.info.Name - cmd := exec.Command("git", "clone", "--depth", "1", "-b", versionWithPrefix, ghRepo, dynamicDocsDir) - err = cmd.Run() - if err != nil { - return nil, errors.Wrapf(err, "failed to clone upstream provider for docs") - } - } - // First gather up the entire package contents. This structure is complete and sufficient to hand off to the // language-specific generators to create the full output. pack, err := g.gatherPackage() diff --git a/pkg/tfgen/source.go b/pkg/tfgen/source.go index fee8b3f80..07fc845df 100644 --- a/pkg/tfgen/source.go +++ b/pkg/tfgen/source.go @@ -88,15 +88,10 @@ func (gh *gitRepoSource) getFile( } repoPath := gh.upstreamRepoPath if repoPath == "" { - // When we build full docs for dynamic providers, we expect a local download of the git repo in dynamicDocsDir. - if _, err := os.Stat(dynamicDocsDir); err == nil { - repoPath = dynamicDocsDir - } else { - var err error - repoPath, err = getRepoPath(gh.githost, gh.org, gh.provider, gh.providerModuleVersion) - if err != nil { - return nil, fmt.Errorf("repo for token %q: %w", rawname, err) - } + var err error + repoPath, err = getRepoPath(gh.githost, gh.org, gh.provider, gh.providerModuleVersion) + if err != nil { + return nil, fmt.Errorf("repo for token %q: %w", rawname, err) } } var possibleMarkdownNames []string From 9df285b6cdc8a97504fe713d5ff92e8716a6f06f Mon Sep 17 00:00:00 2001 From: guineveresaenger Date: Wed, 27 Nov 2024 13:34:37 -0800 Subject: [PATCH 06/16] Update tests to reflect the provider name they were loaded with and add test for full docsgen --- dynamic/provider_test.go | 42 + .../Backblaze/b2-0.8.9.golden | 6 +- .../databricks/databricks-1.50.0.golden | 6 +- .../hashicorp/random-3.3.0.golden | 6 +- .../hashicorp/random-3.6.3.golden | 938 ++++++++++++++++++ 5 files changed, 989 insertions(+), 9 deletions(-) create mode 100644 dynamic/testdata/TestSchemaGenerationFullDocs/hashicorp/random-3.6.3.golden diff --git a/dynamic/provider_test.go b/dynamic/provider_test.go index 101cb59b4..e276f0b48 100644 --- a/dynamic/provider_test.go +++ b/dynamic/provider_test.go @@ -457,6 +457,48 @@ func TestSchemaGeneration(t *testing.T) { //nolint:paralleltest testSchema("databricks/databricks", "1.50.0") } +func TestSchemaGenerationFullDocs(t *testing.T) { //nolint:paralleltest + skipWindows(t) + type testCase struct { + name string + version string + fullDocs bool + } + + tc := testCase{ + name: "hashicorp/random", + version: "3.6.3", + fullDocs: true, + } + t.Run(strings.Join([]string{tc.name, tc.version}, "-"), func(t *testing.T) { + helper.Integration(t) + ctx := context.Background() + + server := grpcTestServer(ctx, t) + + result, err := server.Parameterize(ctx, &pulumirpc.ParameterizeRequest{ + Parameters: &pulumirpc.ParameterizeRequest_Args{ + Args: &pulumirpc.ParameterizeRequest_ParametersArgs{ + Args: []string{tc.name, tc.version, "fullDocs"}, + }, + }, + }) + require.NoError(t, err) + + assert.Equal(t, tc.version, result.Version) + + schema, err := server.GetSchema(ctx, &pulumirpc.GetSchemaRequest{ + SubpackageName: result.Name, + SubpackageVersion: result.Version, + }) + + require.NoError(t, err) + var fmtSchema bytes.Buffer + require.NoError(t, json.Indent(&fmtSchema, []byte(schema.Schema), "", " ")) + autogold.ExpectFile(t, autogold.Raw(fmtSchema.String())) + }) +} + func TestRandomCreate(t *testing.T) { t.Parallel() ctx := context.Background() diff --git a/dynamic/testdata/TestSchemaGeneration/Backblaze/b2-0.8.9.golden b/dynamic/testdata/TestSchemaGeneration/Backblaze/b2-0.8.9.golden index f1d362027..cb4cd1ecb 100644 --- a/dynamic/testdata/TestSchemaGeneration/Backblaze/b2-0.8.9.golden +++ b/dynamic/testdata/TestSchemaGeneration/Backblaze/b2-0.8.9.golden @@ -2,7 +2,7 @@ "name": "b2", "version": "0.8.9", "description": "A Pulumi provider dynamically bridged from b2.", - "attribution": "This Pulumi package is based on the [`b2` Terraform Provider](https://github.com/terraform-providers/terraform-provider-b2).", + "attribution": "This Pulumi package is based on the [`b2` Terraform Provider](https://github.com/backblaze/terraform-provider-b2).", "publisher": "Pulumi", "meta": { "moduleFormat": "(.*)(?:/[^/]*)" @@ -28,14 +28,14 @@ }, "nodejs": { "packageDescription": "A Pulumi provider dynamically bridged from b2.", - "readme": "\u003e This provider is a derived work of the [Terraform Provider](https://github.com/terraform-providers/terraform-provider-b2)\n\u003e distributed under [MPL 2.0](https://www.mozilla.org/en-US/MPL/2.0/). If you encounter a bug or missing feature,\n\u003e first check the [`pulumi-b2` repo](/issues); however, if that doesn't turn up anything,\n\u003e please consult the source [`terraform-provider-b2` repo](https://github.com/terraform-providers/terraform-provider-b2/issues).", + "readme": "\u003e This provider is a derived work of the [Terraform Provider](https://github.com/backblaze/terraform-provider-b2)\n\u003e distributed under [MPL 2.0](https://www.mozilla.org/en-US/MPL/2.0/). If you encounter a bug or missing feature,\n\u003e first check the [`pulumi-b2` repo](/issues); however, if that doesn't turn up anything,\n\u003e please consult the source [`terraform-provider-b2` repo](https://github.com/backblaze/terraform-provider-b2/issues).", "compatibility": "tfbridge20", "disableUnionOutputTypes": true, "liftSingleValueMethodReturns": true, "respectSchemaVersion": true }, "python": { - "readme": "\u003e This provider is a derived work of the [Terraform Provider](https://github.com/terraform-providers/terraform-provider-b2)\n\u003e distributed under [MPL 2.0](https://www.mozilla.org/en-US/MPL/2.0/). If you encounter a bug or missing feature,\n\u003e first check the [`pulumi-b2` repo](/issues); however, if that doesn't turn up anything,\n\u003e please consult the source [`terraform-provider-b2` repo](https://github.com/terraform-providers/terraform-provider-b2/issues).", + "readme": "\u003e This provider is a derived work of the [Terraform Provider](https://github.com/backblaze/terraform-provider-b2)\n\u003e distributed under [MPL 2.0](https://www.mozilla.org/en-US/MPL/2.0/). If you encounter a bug or missing feature,\n\u003e first check the [`pulumi-b2` repo](/issues); however, if that doesn't turn up anything,\n\u003e please consult the source [`terraform-provider-b2` repo](https://github.com/backblaze/terraform-provider-b2/issues).", "compatibility": "tfbridge20", "respectSchemaVersion": true, "pyproject": { diff --git a/dynamic/testdata/TestSchemaGeneration/databricks/databricks-1.50.0.golden b/dynamic/testdata/TestSchemaGeneration/databricks/databricks-1.50.0.golden index 288af648a..cd0c7a50d 100644 --- a/dynamic/testdata/TestSchemaGeneration/databricks/databricks-1.50.0.golden +++ b/dynamic/testdata/TestSchemaGeneration/databricks/databricks-1.50.0.golden @@ -2,7 +2,7 @@ "name": "databricks", "version": "1.50.0", "description": "A Pulumi provider dynamically bridged from databricks.", - "attribution": "This Pulumi package is based on the [`databricks` Terraform Provider](https://github.com/terraform-providers/terraform-provider-databricks).", + "attribution": "This Pulumi package is based on the [`databricks` Terraform Provider](https://github.com/databricks/terraform-provider-databricks).", "publisher": "Pulumi", "meta": { "moduleFormat": "(.*)(?:/[^/]*)" @@ -28,14 +28,14 @@ }, "nodejs": { "packageDescription": "A Pulumi provider dynamically bridged from databricks.", - "readme": "\u003e This provider is a derived work of the [Terraform Provider](https://github.com/terraform-providers/terraform-provider-databricks)\n\u003e distributed under [MPL 2.0](https://www.mozilla.org/en-US/MPL/2.0/). If you encounter a bug or missing feature,\n\u003e first check the [`pulumi-databricks` repo](/issues); however, if that doesn't turn up anything,\n\u003e please consult the source [`terraform-provider-databricks` repo](https://github.com/terraform-providers/terraform-provider-databricks/issues).", + "readme": "\u003e This provider is a derived work of the [Terraform Provider](https://github.com/databricks/terraform-provider-databricks)\n\u003e distributed under [MPL 2.0](https://www.mozilla.org/en-US/MPL/2.0/). If you encounter a bug or missing feature,\n\u003e first check the [`pulumi-databricks` repo](/issues); however, if that doesn't turn up anything,\n\u003e please consult the source [`terraform-provider-databricks` repo](https://github.com/databricks/terraform-provider-databricks/issues).", "compatibility": "tfbridge20", "disableUnionOutputTypes": true, "liftSingleValueMethodReturns": true, "respectSchemaVersion": true }, "python": { - "readme": "\u003e This provider is a derived work of the [Terraform Provider](https://github.com/terraform-providers/terraform-provider-databricks)\n\u003e distributed under [MPL 2.0](https://www.mozilla.org/en-US/MPL/2.0/). If you encounter a bug or missing feature,\n\u003e first check the [`pulumi-databricks` repo](/issues); however, if that doesn't turn up anything,\n\u003e please consult the source [`terraform-provider-databricks` repo](https://github.com/terraform-providers/terraform-provider-databricks/issues).", + "readme": "\u003e This provider is a derived work of the [Terraform Provider](https://github.com/databricks/terraform-provider-databricks)\n\u003e distributed under [MPL 2.0](https://www.mozilla.org/en-US/MPL/2.0/). If you encounter a bug or missing feature,\n\u003e first check the [`pulumi-databricks` repo](/issues); however, if that doesn't turn up anything,\n\u003e please consult the source [`terraform-provider-databricks` repo](https://github.com/databricks/terraform-provider-databricks/issues).", "compatibility": "tfbridge20", "respectSchemaVersion": true, "pyproject": { diff --git a/dynamic/testdata/TestSchemaGeneration/hashicorp/random-3.3.0.golden b/dynamic/testdata/TestSchemaGeneration/hashicorp/random-3.3.0.golden index 35edcadaa..3896e56d6 100644 --- a/dynamic/testdata/TestSchemaGeneration/hashicorp/random-3.3.0.golden +++ b/dynamic/testdata/TestSchemaGeneration/hashicorp/random-3.3.0.golden @@ -2,7 +2,7 @@ "name": "random", "version": "3.3.0", "description": "A Pulumi provider dynamically bridged from random.", - "attribution": "This Pulumi package is based on the [`random` Terraform Provider](https://github.com/terraform-providers/terraform-provider-random).", + "attribution": "This Pulumi package is based on the [`random` Terraform Provider](https://github.com/hashicorp/terraform-provider-random).", "publisher": "Pulumi", "meta": { "moduleFormat": "(.*)(?:/[^/]*)" @@ -28,14 +28,14 @@ }, "nodejs": { "packageDescription": "A Pulumi provider dynamically bridged from random.", - "readme": "\u003e This provider is a derived work of the [Terraform Provider](https://github.com/terraform-providers/terraform-provider-random)\n\u003e distributed under [MPL 2.0](https://www.mozilla.org/en-US/MPL/2.0/). If you encounter a bug or missing feature,\n\u003e first check the [`pulumi-random` repo](/issues); however, if that doesn't turn up anything,\n\u003e please consult the source [`terraform-provider-random` repo](https://github.com/terraform-providers/terraform-provider-random/issues).", + "readme": "\u003e This provider is a derived work of the [Terraform Provider](https://github.com/hashicorp/terraform-provider-random)\n\u003e distributed under [MPL 2.0](https://www.mozilla.org/en-US/MPL/2.0/). If you encounter a bug or missing feature,\n\u003e first check the [`pulumi-random` repo](/issues); however, if that doesn't turn up anything,\n\u003e please consult the source [`terraform-provider-random` repo](https://github.com/hashicorp/terraform-provider-random/issues).", "compatibility": "tfbridge20", "disableUnionOutputTypes": true, "liftSingleValueMethodReturns": true, "respectSchemaVersion": true }, "python": { - "readme": "\u003e This provider is a derived work of the [Terraform Provider](https://github.com/terraform-providers/terraform-provider-random)\n\u003e distributed under [MPL 2.0](https://www.mozilla.org/en-US/MPL/2.0/). If you encounter a bug or missing feature,\n\u003e first check the [`pulumi-random` repo](/issues); however, if that doesn't turn up anything,\n\u003e please consult the source [`terraform-provider-random` repo](https://github.com/terraform-providers/terraform-provider-random/issues).", + "readme": "\u003e This provider is a derived work of the [Terraform Provider](https://github.com/hashicorp/terraform-provider-random)\n\u003e distributed under [MPL 2.0](https://www.mozilla.org/en-US/MPL/2.0/). If you encounter a bug or missing feature,\n\u003e first check the [`pulumi-random` repo](/issues); however, if that doesn't turn up anything,\n\u003e please consult the source [`terraform-provider-random` repo](https://github.com/hashicorp/terraform-provider-random/issues).", "compatibility": "tfbridge20", "respectSchemaVersion": true, "pyproject": { diff --git a/dynamic/testdata/TestSchemaGenerationFullDocs/hashicorp/random-3.6.3.golden b/dynamic/testdata/TestSchemaGenerationFullDocs/hashicorp/random-3.6.3.golden new file mode 100644 index 000000000..ba4a15957 --- /dev/null +++ b/dynamic/testdata/TestSchemaGenerationFullDocs/hashicorp/random-3.6.3.golden @@ -0,0 +1,938 @@ +{ + "name": "random", + "version": "3.6.3", + "description": "A Pulumi provider dynamically bridged from random.", + "attribution": "This Pulumi package is based on the [`random` Terraform Provider](https://github.com/hashicorp/terraform-provider-random).", + "publisher": "Pulumi", + "meta": { + "moduleFormat": "(.*)(?:/[^/]*)" + }, + "language": { + "csharp": { + "compatibility": "tfbridge20", + "liftSingleValueMethodReturns": true, + "respectSchemaVersion": true + }, + "go": { + "importBasePath": "github.com/pulumi/pulumi-terraform-provider/sdks/go/random/v3", + "rootPackageName": "random", + "liftSingleValueMethodReturns": true, + "generateExtraInputTypes": true, + "respectSchemaVersion": true + }, + "java": { + "basePackage": "", + "buildFiles": "", + "gradleNexusPublishPluginVersion": "", + "gradleTest": "" + }, + "nodejs": { + "packageDescription": "A Pulumi provider dynamically bridged from random.", + "readme": "\u003e This provider is a derived work of the [Terraform Provider](https://github.com/hashicorp/terraform-provider-random)\n\u003e distributed under [MPL 2.0](https://www.mozilla.org/en-US/MPL/2.0/). If you encounter a bug or missing feature,\n\u003e first check the [`pulumi-random` repo](/issues); however, if that doesn't turn up anything,\n\u003e please consult the source [`terraform-provider-random` repo](https://github.com/hashicorp/terraform-provider-random/issues).", + "compatibility": "tfbridge20", + "disableUnionOutputTypes": true, + "liftSingleValueMethodReturns": true, + "respectSchemaVersion": true + }, + "python": { + "readme": "\u003e This provider is a derived work of the [Terraform Provider](https://github.com/hashicorp/terraform-provider-random)\n\u003e distributed under [MPL 2.0](https://www.mozilla.org/en-US/MPL/2.0/). If you encounter a bug or missing feature,\n\u003e first check the [`pulumi-random` repo](/issues); however, if that doesn't turn up anything,\n\u003e please consult the source [`terraform-provider-random` repo](https://github.com/hashicorp/terraform-provider-random/issues).", + "compatibility": "tfbridge20", + "respectSchemaVersion": true, + "pyproject": { + "enabled": true + } + } + }, + "config": {}, + "provider": { + "description": "The provider type for the random package. By default, resources use package-wide configuration\nsettings, however an explicit `Provider` instance may be created and passed during resource\nconstruction to achieve fine-grained programmatic control over provider settings. See the\n[documentation](https://www.pulumi.com/docs/reference/programming-model/#providers) for more information.\n" + }, + "resources": { + "random:index/bytes:Bytes": { + "description": "The resource `random.Bytes` generates random bytes that are intended to be used as a secret, or key. Use this in preference to `random.Id` when the output is considered sensitive, and should not be displayed in the CLI.\n\nThis resource *does* use a cryptographic random number generator.\n\n## Example Usage\n\n```terraform\nresource \"random_bytes\" \"jwt_secret\" {\n length = 64\n}\n\nresource \"azurerm_key_vault_secret\" \"jwt_secret\" {\n key_vault_id = \"some-azure-key-vault-id\"\n name = \"JwtSecret\"\n value = random_bytes.jwt_secret.base64\n}\n```\n\n## Import\n\nRandom bytes can be imported by specifying the value as base64 string.\n\n```sh\n$ pulumi import random:index/bytes:Bytes basic \"8/fu3q+2DcgSJ19i0jZ5Cw==\"\n```\n\n", + "properties": { + "base64": { + "type": "string", + "description": "The generated bytes presented in base64 string format.\n", + "secret": true + }, + "hex": { + "type": "string", + "description": "The generated bytes presented in lowercase hexadecimal string format. The length of the encoded string is exactly twice the `length` parameter.\n", + "secret": true + }, + "keepers": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "Arbitrary map of values that, when changed, will trigger recreation of resource. See the main provider documentation for more information.\n" + }, + "length": { + "type": "number", + "description": "The number of bytes requested. The minimum value for length is 1.\n" + } + }, + "required": [ + "base64", + "hex", + "length" + ], + "inputProperties": { + "keepers": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "Arbitrary map of values that, when changed, will trigger recreation of resource. See the main provider documentation for more information.\n" + }, + "length": { + "type": "number", + "description": "The number of bytes requested. The minimum value for length is 1.\n" + } + }, + "requiredInputs": [ + "length" + ], + "stateInputs": { + "description": "Input properties used for looking up and filtering Bytes resources.\n", + "properties": { + "base64": { + "type": "string", + "description": "The generated bytes presented in base64 string format.\n", + "secret": true + }, + "hex": { + "type": "string", + "description": "The generated bytes presented in lowercase hexadecimal string format. The length of the encoded string is exactly twice the `length` parameter.\n", + "secret": true + }, + "keepers": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "Arbitrary map of values that, when changed, will trigger recreation of resource. See the main provider documentation for more information.\n" + }, + "length": { + "type": "number", + "description": "The number of bytes requested. The minimum value for length is 1.\n" + } + }, + "type": "object" + } + }, + "random:index/id:Id": { + "description": "The resource `random.Id` generates random numbers that are intended to be\nused as unique identifiers for other resources. If the output is considered \nsensitive, and should not be displayed in the CLI, use `random.Bytes`\ninstead.\n\nThis resource *does* use a cryptographic random number generator in order\nto minimize the chance of collisions, making the results of this resource\nwhen a 16-byte identifier is requested of equivalent uniqueness to a\ntype-4 UUID.\n\nThis resource can be used in conjunction with resources that have\nthe `create_before_destroy` lifecycle flag set to avoid conflicts with\nunique names during the brief period where both the old and new resources\nexist concurrently.\n\n## Example Usage\n\n```terraform\n# The following example shows how to generate a unique name for an AWS EC2\n# instance that changes each time a new AMI id is selected.\n\nresource \"random_id\" \"server\" {\n keepers = {\n # Generate a new id each time we switch to a new AMI id\n ami_id = var.ami_id\n }\n\n byte_length = 8\n}\n\nresource \"aws_instance\" \"server\" {\n tags = {\n Name = \"web-server ${random_id.server.hex}\"\n }\n\n # Read the AMI id \"through\" the random_id resource to ensure that\n # both will change together.\n ami = random_id.server.keepers.ami_id\n\n # ... (other aws_instance arguments) ...\n}\n```\n\n## Import\n\nRandom IDs can be imported using the b64_url with an optional prefix. This\n\ncan be used to replace a config value with a value interpolated from the\n\nrandom provider without experiencing diffs.\n\nExample with no prefix:\n\n```sh\n$ pulumi import random:index/id:Id server p-9hUg\n```\n\nExample with prefix (prefix is separated by a ,):\n\n```sh\n$ pulumi import random:index/id:Id server my-prefix-,p-9hUg\n```\n\n", + "properties": { + "b64Std": { + "type": "string", + "description": "The generated id presented in base64 without additional transformations.\n" + }, + "b64Url": { + "type": "string", + "description": "The generated id presented in base64, using the URL-friendly character set: case-sensitive letters, digits and the characters `_` and `-`.\n" + }, + "byteLength": { + "type": "number", + "description": "The number of random bytes to produce. The minimum value is 1, which produces eight bits of randomness.\n" + }, + "dec": { + "type": "string", + "description": "The generated id presented in non-padded decimal digits.\n" + }, + "hex": { + "type": "string", + "description": "The generated id presented in padded hexadecimal digits. This result will always be twice as long as the requested byte length.\n" + }, + "keepers": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "Arbitrary map of values that, when changed, will trigger recreation of resource. See the main provider documentation for more information.\n" + }, + "prefix": { + "type": "string", + "description": "Arbitrary string to prefix the output value with. This string is supplied as-is, meaning it is not guaranteed to be URL-safe or base64 encoded.\n" + } + }, + "required": [ + "b64Std", + "b64Url", + "byteLength", + "dec", + "hex" + ], + "inputProperties": { + "byteLength": { + "type": "number", + "description": "The number of random bytes to produce. The minimum value is 1, which produces eight bits of randomness.\n" + }, + "keepers": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "Arbitrary map of values that, when changed, will trigger recreation of resource. See the main provider documentation for more information.\n" + }, + "prefix": { + "type": "string", + "description": "Arbitrary string to prefix the output value with. This string is supplied as-is, meaning it is not guaranteed to be URL-safe or base64 encoded.\n" + } + }, + "requiredInputs": [ + "byteLength" + ], + "stateInputs": { + "description": "Input properties used for looking up and filtering Id resources.\n", + "properties": { + "b64Std": { + "type": "string", + "description": "The generated id presented in base64 without additional transformations.\n" + }, + "b64Url": { + "type": "string", + "description": "The generated id presented in base64, using the URL-friendly character set: case-sensitive letters, digits and the characters `_` and `-`.\n" + }, + "byteLength": { + "type": "number", + "description": "The number of random bytes to produce. The minimum value is 1, which produces eight bits of randomness.\n" + }, + "dec": { + "type": "string", + "description": "The generated id presented in non-padded decimal digits.\n" + }, + "hex": { + "type": "string", + "description": "The generated id presented in padded hexadecimal digits. This result will always be twice as long as the requested byte length.\n" + }, + "keepers": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "Arbitrary map of values that, when changed, will trigger recreation of resource. See the main provider documentation for more information.\n" + }, + "prefix": { + "type": "string", + "description": "Arbitrary string to prefix the output value with. This string is supplied as-is, meaning it is not guaranteed to be URL-safe or base64 encoded.\n" + } + }, + "type": "object" + } + }, + "random:index/integer:Integer": { + "description": "The resource `random.Integer` generates random values from a given range, described by the `min` and `max` attributes of a given resource.\n\nThis resource can be used in conjunction with resources that have the `create_before_destroy` lifecycle flag set, to avoid conflicts with unique names during the brief period where both the old and new resources exist concurrently.\n\n## Example Usage\n\n```terraform\n# The following example shows how to generate a random priority\n# between 1 and 50000 for a aws_alb_listener_rule resource:\n\nresource \"random_integer\" \"priority\" {\n min = 1\n max = 50000\n keepers = {\n # Generate a new integer each time we switch to a new listener ARN\n listener_arn = var.listener_arn\n }\n}\n\nresource \"aws_alb_listener_rule\" \"main\" {\n listener_arn = random_integer.priority.keepers.listener_arn\n priority = random_integer.priority.result\n\n action {\n type = \"forward\"\n target_group_arn = var.target_group_arn\n }\n # ... (other aws_alb_listener_rule arguments) ...\n}\n```\n\n## Import\n\nRandom integers can be imported using the result, min, and max, with an\n\noptional seed. This can be used to replace a config value with a value\n\ninterpolated from the random provider without experiencing diffs.\n\nExample (values are separated by a ,):\n\n```sh\n$ pulumi import random:index/integer:Integer priority 15390,1,50000\n```\n\n", + "properties": { + "keepers": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "Arbitrary map of values that, when changed, will trigger recreation of resource. See the main provider documentation for more information.\n" + }, + "max": { + "type": "number", + "description": "The maximum inclusive value of the range.\n" + }, + "min": { + "type": "number", + "description": "The minimum inclusive value of the range.\n" + }, + "result": { + "type": "number", + "description": "The random integer result.\n" + }, + "seed": { + "type": "string", + "description": "A custom seed to always produce the same value.\n" + } + }, + "required": [ + "max", + "min", + "result" + ], + "inputProperties": { + "keepers": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "Arbitrary map of values that, when changed, will trigger recreation of resource. See the main provider documentation for more information.\n" + }, + "max": { + "type": "number", + "description": "The maximum inclusive value of the range.\n" + }, + "min": { + "type": "number", + "description": "The minimum inclusive value of the range.\n" + }, + "seed": { + "type": "string", + "description": "A custom seed to always produce the same value.\n" + } + }, + "requiredInputs": [ + "max", + "min" + ], + "stateInputs": { + "description": "Input properties used for looking up and filtering Integer resources.\n", + "properties": { + "keepers": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "Arbitrary map of values that, when changed, will trigger recreation of resource. See the main provider documentation for more information.\n" + }, + "max": { + "type": "number", + "description": "The maximum inclusive value of the range.\n" + }, + "min": { + "type": "number", + "description": "The minimum inclusive value of the range.\n" + }, + "result": { + "type": "number", + "description": "The random integer result.\n" + }, + "seed": { + "type": "string", + "description": "A custom seed to always produce the same value.\n" + } + }, + "type": "object" + } + }, + "random:index/password:Password": { + "description": "## Example Usage\n\n```terraform\nresource \"random_password\" \"password\" {\n length = 16\n special = true\n override_special = \"!#$%\u0026*()-_=+[]{}\u003c\u003e:?\"\n}\n\nresource \"aws_db_instance\" \"example\" {\n instance_class = \"db.t3.micro\"\n allocated_storage = 64\n engine = \"mysql\"\n username = \"someone\"\n password = random_password.password.result\n}\n```\n\n## Import\n\n### Avoiding Replacement\n\n```sh\n$ pulumi import random:index/password:Password If the resource were imported using `random_password.password securepassword`,\n```\n\nreplacement could be avoided by using:\n\n1. Attribute values that match the imported ID and defaults:\n\n terraform\n\n resource \"random_password\" \"password\" {\n\n length = 14\n\n lower = true\n\n }\n\n2. Attribute values that match the imported ID and omit the attributes with defaults:\n\n terraform\n\n resource \"random_password\" \"password\" {\n\n length = 14\n\n }\n\n3. `ignore_changes` specifying the attributes to ignore:\n\n terraform\n\n resource \"random_password\" \"password\" {\n\n length = 16\n\n lower = false\n\n lifecycle {\n\n ignore_changes = [\n\n length,\n\n lower,\n\n ]\n\n }\n\n }\n\n **NOTE** `ignore_changes` is only required until the resource is recreated after import,\n\n after which it will use the configuration values specified.\n\n", + "properties": { + "bcryptHash": { + "type": "string", + "description": "A bcrypt hash of the generated random string. **NOTE**: If the generated random string is greater than 72 bytes in length, `bcrypt_hash` will contain a hash of the first 72 bytes.\n", + "secret": true + }, + "keepers": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "Arbitrary map of values that, when changed, will trigger recreation of resource. See the main provider documentation for more information.\n" + }, + "length": { + "type": "number", + "description": "The length of the string desired. The minimum value for length is 1 and, length must also be \u003e= (`min_upper` + `min_lower` + `min_numeric` + `min_special`).\n" + }, + "lower": { + "type": "boolean", + "description": "Include lowercase alphabet characters in the result. Default value is `true`.\n" + }, + "minLower": { + "type": "number", + "description": "Minimum number of lowercase alphabet characters in the result. Default value is `0`.\n" + }, + "minNumeric": { + "type": "number", + "description": "Minimum number of numeric characters in the result. Default value is `0`.\n" + }, + "minSpecial": { + "type": "number", + "description": "Minimum number of special characters in the result. Default value is `0`.\n" + }, + "minUpper": { + "type": "number", + "description": "Minimum number of uppercase alphabet characters in the result. Default value is `0`.\n" + }, + "number": { + "type": "boolean", + "description": "Include numeric characters in the result. Default value is `true`. If `number`, `upper`, `lower`, and `special` are all configured, at least one of them must be set to `true`. **NOTE**: This is deprecated, use `numeric` instead.\n", + "deprecationMessage": "Deprecated" + }, + "numeric": { + "type": "boolean", + "description": "Include numeric characters in the result. Default value is `true`. If `numeric`, `upper`, `lower`, and `special` are all configured, at least one of them must be set to `true`.\n" + }, + "overrideSpecial": { + "type": "string", + "description": "Supply your own list of special characters to use for string generation. This overrides the default character list in the special argument. The `special` argument must still be set to true for any overwritten characters to be used in generation.\n" + }, + "result": { + "type": "string", + "description": "The generated random string.\n", + "secret": true + }, + "special": { + "type": "boolean", + "description": "Include special characters in the result. These are `!@#$%\u0026*()-_=+[]{}\u003c\u003e:?`. Default value is `true`.\n" + }, + "upper": { + "type": "boolean", + "description": "Include uppercase alphabet characters in the result. Default value is `true`.\n" + } + }, + "required": [ + "bcryptHash", + "length", + "lower", + "minLower", + "minNumeric", + "minSpecial", + "minUpper", + "number", + "numeric", + "result", + "special", + "upper" + ], + "inputProperties": { + "keepers": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "Arbitrary map of values that, when changed, will trigger recreation of resource. See the main provider documentation for more information.\n" + }, + "length": { + "type": "number", + "description": "The length of the string desired. The minimum value for length is 1 and, length must also be \u003e= (`min_upper` + `min_lower` + `min_numeric` + `min_special`).\n" + }, + "lower": { + "type": "boolean", + "description": "Include lowercase alphabet characters in the result. Default value is `true`.\n" + }, + "minLower": { + "type": "number", + "description": "Minimum number of lowercase alphabet characters in the result. Default value is `0`.\n" + }, + "minNumeric": { + "type": "number", + "description": "Minimum number of numeric characters in the result. Default value is `0`.\n" + }, + "minSpecial": { + "type": "number", + "description": "Minimum number of special characters in the result. Default value is `0`.\n" + }, + "minUpper": { + "type": "number", + "description": "Minimum number of uppercase alphabet characters in the result. Default value is `0`.\n" + }, + "number": { + "type": "boolean", + "description": "Include numeric characters in the result. Default value is `true`. If `number`, `upper`, `lower`, and `special` are all configured, at least one of them must be set to `true`. **NOTE**: This is deprecated, use `numeric` instead.\n", + "deprecationMessage": "Deprecated" + }, + "numeric": { + "type": "boolean", + "description": "Include numeric characters in the result. Default value is `true`. If `numeric`, `upper`, `lower`, and `special` are all configured, at least one of them must be set to `true`.\n" + }, + "overrideSpecial": { + "type": "string", + "description": "Supply your own list of special characters to use for string generation. This overrides the default character list in the special argument. The `special` argument must still be set to true for any overwritten characters to be used in generation.\n" + }, + "special": { + "type": "boolean", + "description": "Include special characters in the result. These are `!@#$%\u0026*()-_=+[]{}\u003c\u003e:?`. Default value is `true`.\n" + }, + "upper": { + "type": "boolean", + "description": "Include uppercase alphabet characters in the result. Default value is `true`.\n" + } + }, + "requiredInputs": [ + "length" + ], + "stateInputs": { + "description": "Input properties used for looking up and filtering Password resources.\n", + "properties": { + "bcryptHash": { + "type": "string", + "description": "A bcrypt hash of the generated random string. **NOTE**: If the generated random string is greater than 72 bytes in length, `bcrypt_hash` will contain a hash of the first 72 bytes.\n", + "secret": true + }, + "keepers": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "Arbitrary map of values that, when changed, will trigger recreation of resource. See the main provider documentation for more information.\n" + }, + "length": { + "type": "number", + "description": "The length of the string desired. The minimum value for length is 1 and, length must also be \u003e= (`min_upper` + `min_lower` + `min_numeric` + `min_special`).\n" + }, + "lower": { + "type": "boolean", + "description": "Include lowercase alphabet characters in the result. Default value is `true`.\n" + }, + "minLower": { + "type": "number", + "description": "Minimum number of lowercase alphabet characters in the result. Default value is `0`.\n" + }, + "minNumeric": { + "type": "number", + "description": "Minimum number of numeric characters in the result. Default value is `0`.\n" + }, + "minSpecial": { + "type": "number", + "description": "Minimum number of special characters in the result. Default value is `0`.\n" + }, + "minUpper": { + "type": "number", + "description": "Minimum number of uppercase alphabet characters in the result. Default value is `0`.\n" + }, + "number": { + "type": "boolean", + "description": "Include numeric characters in the result. Default value is `true`. If `number`, `upper`, `lower`, and `special` are all configured, at least one of them must be set to `true`. **NOTE**: This is deprecated, use `numeric` instead.\n", + "deprecationMessage": "Deprecated" + }, + "numeric": { + "type": "boolean", + "description": "Include numeric characters in the result. Default value is `true`. If `numeric`, `upper`, `lower`, and `special` are all configured, at least one of them must be set to `true`.\n" + }, + "overrideSpecial": { + "type": "string", + "description": "Supply your own list of special characters to use for string generation. This overrides the default character list in the special argument. The `special` argument must still be set to true for any overwritten characters to be used in generation.\n" + }, + "result": { + "type": "string", + "description": "The generated random string.\n", + "secret": true + }, + "special": { + "type": "boolean", + "description": "Include special characters in the result. These are `!@#$%\u0026*()-_=+[]{}\u003c\u003e:?`. Default value is `true`.\n" + }, + "upper": { + "type": "boolean", + "description": "Include uppercase alphabet characters in the result. Default value is `true`.\n" + } + }, + "type": "object" + } + }, + "random:index/pet:Pet": { + "description": "The resource `random.Pet` generates random pet names that are intended to be used as unique identifiers for other resources.\n\nThis resource can be used in conjunction with resources that have the `create_before_destroy` lifecycle flag set, to avoid conflicts with unique names during the brief period where both the old and new resources exist concurrently.\n\n## Example Usage\n\n```terraform\n# The following example shows how to generate a unique pet name\n# for an AWS EC2 instance that changes each time a new AMI id is\n# selected.\n\nresource \"random_pet\" \"server\" {\n keepers = {\n # Generate a new pet name each time we switch to a new AMI id\n ami_id = var.ami_id\n }\n}\n\nresource \"aws_instance\" \"server\" {\n tags = {\n Name = \"web-server-${random_pet.server.id}\"\n }\n\n # Read the AMI id \"through\" the random_pet resource to ensure that\n # both will change together.\n ami = random_pet.server.keepers.ami_id\n\n # ... (other aws_instance arguments) ...\n}\n```\n", + "properties": { + "keepers": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "Arbitrary map of values that, when changed, will trigger recreation of resource. See the main provider documentation for more information.\n" + }, + "length": { + "type": "number", + "description": "The length (in words) of the pet name. Defaults to 2\n" + }, + "prefix": { + "type": "string", + "description": "A string to prefix the name with.\n" + }, + "separator": { + "type": "string", + "description": "The character to separate words in the pet name. Defaults to \"-\"\n" + } + }, + "required": [ + "length", + "separator" + ], + "inputProperties": { + "keepers": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "Arbitrary map of values that, when changed, will trigger recreation of resource. See the main provider documentation for more information.\n" + }, + "length": { + "type": "number", + "description": "The length (in words) of the pet name. Defaults to 2\n" + }, + "prefix": { + "type": "string", + "description": "A string to prefix the name with.\n" + }, + "separator": { + "type": "string", + "description": "The character to separate words in the pet name. Defaults to \"-\"\n" + } + }, + "stateInputs": { + "description": "Input properties used for looking up and filtering Pet resources.\n", + "properties": { + "keepers": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "Arbitrary map of values that, when changed, will trigger recreation of resource. See the main provider documentation for more information.\n" + }, + "length": { + "type": "number", + "description": "The length (in words) of the pet name. Defaults to 2\n" + }, + "prefix": { + "type": "string", + "description": "A string to prefix the name with.\n" + }, + "separator": { + "type": "string", + "description": "The character to separate words in the pet name. Defaults to \"-\"\n" + } + }, + "type": "object" + } + }, + "random:index/shuffle:Shuffle": { + "description": "The resource `random.Shuffle` generates a random permutation of a list of strings given as an argument.\n\n## Example Usage\n\n```terraform\nresource \"random_shuffle\" \"az\" {\n input = [\"us-west-1a\", \"us-west-1c\", \"us-west-1d\", \"us-west-1e\"]\n result_count = 2\n}\n\nresource \"aws_elb\" \"example\" {\n # Place the ELB in any two of the given availability zones, selected\n # at random.\n availability_zones = random_shuffle.az.result\n\n # ... and other aws_elb arguments ...\n}\n```\n", + "properties": { + "inputs": { + "type": "array", + "items": { + "type": "string" + }, + "description": "The list of strings to shuffle.\n" + }, + "keepers": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "Arbitrary map of values that, when changed, will trigger recreation of resource. See the main provider documentation for more information.\n" + }, + "resultCount": { + "type": "number", + "description": "The number of results to return. Defaults to the number of items in the `input` list. If fewer items are requested, some elements will be excluded from the result. If more items are requested, items will be repeated in the result but not more frequently than the number of items in the input list.\n" + }, + "results": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Random permutation of the list of strings given in `input`. The number of elements is determined by `result_count` if\nset, or the number of elements in `input`.\n" + }, + "seed": { + "type": "string", + "description": "Arbitrary string with which to seed the random number generator, in order to produce less-volatile permutations of the list.\n" + } + }, + "required": [ + "inputs", + "results" + ], + "inputProperties": { + "inputs": { + "type": "array", + "items": { + "type": "string" + }, + "description": "The list of strings to shuffle.\n" + }, + "keepers": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "Arbitrary map of values that, when changed, will trigger recreation of resource. See the main provider documentation for more information.\n" + }, + "resultCount": { + "type": "number", + "description": "The number of results to return. Defaults to the number of items in the `input` list. If fewer items are requested, some elements will be excluded from the result. If more items are requested, items will be repeated in the result but not more frequently than the number of items in the input list.\n" + }, + "seed": { + "type": "string", + "description": "Arbitrary string with which to seed the random number generator, in order to produce less-volatile permutations of the list.\n" + } + }, + "requiredInputs": [ + "inputs" + ], + "stateInputs": { + "description": "Input properties used for looking up and filtering Shuffle resources.\n", + "properties": { + "inputs": { + "type": "array", + "items": { + "type": "string" + }, + "description": "The list of strings to shuffle.\n" + }, + "keepers": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "Arbitrary map of values that, when changed, will trigger recreation of resource. See the main provider documentation for more information.\n" + }, + "resultCount": { + "type": "number", + "description": "The number of results to return. Defaults to the number of items in the `input` list. If fewer items are requested, some elements will be excluded from the result. If more items are requested, items will be repeated in the result but not more frequently than the number of items in the input list.\n" + }, + "results": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Random permutation of the list of strings given in `input`. The number of elements is determined by `result_count` if\nset, or the number of elements in `input`.\n" + }, + "seed": { + "type": "string", + "description": "Arbitrary string with which to seed the random number generator, in order to produce less-volatile permutations of the list.\n" + } + }, + "type": "object" + } + }, + "random:index/string:String": { + "description": "The resource `random.String` generates a random permutation of alphanumeric characters and optionally special characters.\n\nThis resource *does* use a cryptographic random number generator.\n\nHistorically this resource's intended usage has been ambiguous as the original example used it in a password. For backwards compatibility it will continue to exist. For unique ids please use random_id, for sensitive random values please use random_password.\n\n## Example Usage\n\n```terraform\nresource \"random_string\" \"random\" {\n length = 16\n special = true\n override_special = \"/@£$\"\n}\n```\n\n## Import\n\n### Avoiding Replacement\n\n```sh\n$ pulumi import random:index/string:String If the resource were imported using `random_string.test test`,\n```\n\nreplacement can be avoided by using:\n\n1. Attribute values that match the imported ID and defaults:\n\n terraform\n\n resource \"random_string\" \"test\" {\n\n length = 4\n\n lower = true\n\n }\n\n2. Attribute values that match the imported ID and omit the attributes with defaults:\n\n terraform\n\n resource \"random_string\" \"test\" {\n\n length = 4\n\n }\n\n3. `ignore_changes` specifying the attributes to ignore:\n\n terraform\n\n resource \"random_string\" \"test\" {\n\n length = 16\n\n lower = false\n\n lifecycle {\n\n ignore_changes = [\n\n length,\n\n lower,\n\n ]\n\n }\n\n }\n\n **NOTE** `ignore_changes` is only required until the resource is recreated after import,\n\n after which it will use the configuration values specified.\n\n", + "properties": { + "keepers": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "Arbitrary map of values that, when changed, will trigger recreation of resource. See the main provider documentation for more information.\n" + }, + "length": { + "type": "number", + "description": "The length of the string desired. The minimum value for length is 1 and, length must also be \u003e= (`min_upper` + `min_lower` + `min_numeric` + `min_special`).\n" + }, + "lower": { + "type": "boolean", + "description": "Include lowercase alphabet characters in the result. Default value is `true`.\n" + }, + "minLower": { + "type": "number", + "description": "Minimum number of lowercase alphabet characters in the result. Default value is `0`.\n" + }, + "minNumeric": { + "type": "number", + "description": "Minimum number of numeric characters in the result. Default value is `0`.\n" + }, + "minSpecial": { + "type": "number", + "description": "Minimum number of special characters in the result. Default value is `0`.\n" + }, + "minUpper": { + "type": "number", + "description": "Minimum number of uppercase alphabet characters in the result. Default value is `0`.\n" + }, + "number": { + "type": "boolean", + "description": "Include numeric characters in the result. Default value is `true`. If `number`, `upper`, `lower`, and `special` are all configured, at least one of them must be set to `true`. **NOTE**: This is deprecated, use `numeric` instead.\n", + "deprecationMessage": "Deprecated" + }, + "numeric": { + "type": "boolean", + "description": "Include numeric characters in the result. Default value is `true`. If `numeric`, `upper`, `lower`, and `special` are all configured, at least one of them must be set to `true`.\n" + }, + "overrideSpecial": { + "type": "string", + "description": "Supply your own list of special characters to use for string generation. This overrides the default character list in the special argument. The `special` argument must still be set to true for any overwritten characters to be used in generation.\n" + }, + "result": { + "type": "string", + "description": "The generated random string.\n" + }, + "special": { + "type": "boolean", + "description": "Include special characters in the result. These are `!@#$%\u0026*()-_=+[]{}\u003c\u003e:?`. Default value is `true`.\n" + }, + "upper": { + "type": "boolean", + "description": "Include uppercase alphabet characters in the result. Default value is `true`.\n" + } + }, + "required": [ + "length", + "lower", + "minLower", + "minNumeric", + "minSpecial", + "minUpper", + "number", + "numeric", + "result", + "special", + "upper" + ], + "inputProperties": { + "keepers": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "Arbitrary map of values that, when changed, will trigger recreation of resource. See the main provider documentation for more information.\n" + }, + "length": { + "type": "number", + "description": "The length of the string desired. The minimum value for length is 1 and, length must also be \u003e= (`min_upper` + `min_lower` + `min_numeric` + `min_special`).\n" + }, + "lower": { + "type": "boolean", + "description": "Include lowercase alphabet characters in the result. Default value is `true`.\n" + }, + "minLower": { + "type": "number", + "description": "Minimum number of lowercase alphabet characters in the result. Default value is `0`.\n" + }, + "minNumeric": { + "type": "number", + "description": "Minimum number of numeric characters in the result. Default value is `0`.\n" + }, + "minSpecial": { + "type": "number", + "description": "Minimum number of special characters in the result. Default value is `0`.\n" + }, + "minUpper": { + "type": "number", + "description": "Minimum number of uppercase alphabet characters in the result. Default value is `0`.\n" + }, + "number": { + "type": "boolean", + "description": "Include numeric characters in the result. Default value is `true`. If `number`, `upper`, `lower`, and `special` are all configured, at least one of them must be set to `true`. **NOTE**: This is deprecated, use `numeric` instead.\n", + "deprecationMessage": "Deprecated" + }, + "numeric": { + "type": "boolean", + "description": "Include numeric characters in the result. Default value is `true`. If `numeric`, `upper`, `lower`, and `special` are all configured, at least one of them must be set to `true`.\n" + }, + "overrideSpecial": { + "type": "string", + "description": "Supply your own list of special characters to use for string generation. This overrides the default character list in the special argument. The `special` argument must still be set to true for any overwritten characters to be used in generation.\n" + }, + "special": { + "type": "boolean", + "description": "Include special characters in the result. These are `!@#$%\u0026*()-_=+[]{}\u003c\u003e:?`. Default value is `true`.\n" + }, + "upper": { + "type": "boolean", + "description": "Include uppercase alphabet characters in the result. Default value is `true`.\n" + } + }, + "requiredInputs": [ + "length" + ], + "stateInputs": { + "description": "Input properties used for looking up and filtering String resources.\n", + "properties": { + "keepers": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "Arbitrary map of values that, when changed, will trigger recreation of resource. See the main provider documentation for more information.\n" + }, + "length": { + "type": "number", + "description": "The length of the string desired. The minimum value for length is 1 and, length must also be \u003e= (`min_upper` + `min_lower` + `min_numeric` + `min_special`).\n" + }, + "lower": { + "type": "boolean", + "description": "Include lowercase alphabet characters in the result. Default value is `true`.\n" + }, + "minLower": { + "type": "number", + "description": "Minimum number of lowercase alphabet characters in the result. Default value is `0`.\n" + }, + "minNumeric": { + "type": "number", + "description": "Minimum number of numeric characters in the result. Default value is `0`.\n" + }, + "minSpecial": { + "type": "number", + "description": "Minimum number of special characters in the result. Default value is `0`.\n" + }, + "minUpper": { + "type": "number", + "description": "Minimum number of uppercase alphabet characters in the result. Default value is `0`.\n" + }, + "number": { + "type": "boolean", + "description": "Include numeric characters in the result. Default value is `true`. If `number`, `upper`, `lower`, and `special` are all configured, at least one of them must be set to `true`. **NOTE**: This is deprecated, use `numeric` instead.\n", + "deprecationMessage": "Deprecated" + }, + "numeric": { + "type": "boolean", + "description": "Include numeric characters in the result. Default value is `true`. If `numeric`, `upper`, `lower`, and `special` are all configured, at least one of them must be set to `true`.\n" + }, + "overrideSpecial": { + "type": "string", + "description": "Supply your own list of special characters to use for string generation. This overrides the default character list in the special argument. The `special` argument must still be set to true for any overwritten characters to be used in generation.\n" + }, + "result": { + "type": "string", + "description": "The generated random string.\n" + }, + "special": { + "type": "boolean", + "description": "Include special characters in the result. These are `!@#$%\u0026*()-_=+[]{}\u003c\u003e:?`. Default value is `true`.\n" + }, + "upper": { + "type": "boolean", + "description": "Include uppercase alphabet characters in the result. Default value is `true`.\n" + } + }, + "type": "object" + } + }, + "random:index/uuid:Uuid": { + "description": "## Example Usage\n\n```terraform\n# The following example shows how to generate a unique name for an Azure Resource Group.\n\nresource \"random_uuid\" \"test\" {\n}\n\nresource \"azurerm_resource_group\" \"test\" {\n name = \"${random_uuid.test.result}-rg\"\n location = \"Central US\"\n}\n```\n\n## Import\n\nRandom UUID's can be imported. This can be used to replace a config\n\nvalue with a value interpolated from the random provider without\n\nexperiencing diffs.\n\n```sh\n$ pulumi import random:index/uuid:Uuid main aabbccdd-eeff-0011-2233-445566778899\n```\n\n", + "properties": { + "keepers": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "Arbitrary map of values that, when changed, will trigger recreation of resource. See the main provider documentation for more information.\n" + }, + "result": { + "type": "string", + "description": "The generated uuid presented in string format.\n" + } + }, + "required": [ + "result" + ], + "inputProperties": { + "keepers": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "Arbitrary map of values that, when changed, will trigger recreation of resource. See the main provider documentation for more information.\n" + } + }, + "stateInputs": { + "description": "Input properties used for looking up and filtering Uuid resources.\n", + "properties": { + "keepers": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "Arbitrary map of values that, when changed, will trigger recreation of resource. See the main provider documentation for more information.\n" + }, + "result": { + "type": "string", + "description": "The generated uuid presented in string format.\n" + } + }, + "type": "object" + } + } + }, + "parameterization": { + "baseProvider": { + "name": "terraform-provider", + "version": "0.0.0-dev" + }, + "parameter": "eyJyZW1vdGUiOnsidXJsIjoicmVnaXN0cnkub3BlbnRvZnUub3JnL2hhc2hpY29ycC9yYW5kb20iLCJ2ZXJzaW9uIjoiMy42LjMifX0=" + } +} \ No newline at end of file From 463f39324287761b9d51ef6bd6eb963bfaacaab1 Mon Sep 17 00:00:00 2001 From: guineveresaenger Date: Wed, 27 Nov 2024 14:23:29 -0800 Subject: [PATCH 07/16] Use temporary directory --- dynamic/main.go | 31 +++++++++++++++---------------- dynamic/parameterize/args.go | 2 +- dynamic/parameterize/args_test.go | 4 ++-- pkg/tfbridge/info/info.go | 2 +- pkg/tfgen/generate.go | 2 +- 5 files changed, 20 insertions(+), 21 deletions(-) diff --git a/dynamic/main.go b/dynamic/main.go index 009a3c934..8b424265e 100644 --- a/dynamic/main.go +++ b/dynamic/main.go @@ -17,11 +17,7 @@ package main import ( "context" "encoding/json" - "errors" "fmt" - "os" - "os/exec" - "github.com/blang/semver" "github.com/opentofu/opentofu/shim/run" "github.com/pulumi/pulumi/pkg/v3/codegen/schema" @@ -29,6 +25,8 @@ import ( "github.com/pulumi/pulumi/sdk/v3/go/common/diag/colors" "github.com/pulumi/pulumi/sdk/v3/go/common/resource/plugin" "github.com/pulumi/pulumi/sdk/v3/go/common/util/contract" + "os" + "os/exec" "github.com/pulumi/pulumi-terraform-bridge/dynamic/parameterize" "github.com/pulumi/pulumi-terraform-bridge/dynamic/version" @@ -159,19 +157,20 @@ func initialSetup() (info.Provider, pfbridge.ProviderMetadata, func() error) { } fullDocs = args.Remote.Docs if fullDocs { - upstreamRepoDir := "terraform-provider-" + info.Name + "-v" + info.Version - // Only clone if the directory doesn't exist in the expected location - if _, err := os.Stat(upstreamRepoDir); errors.Is(err, os.ErrNotExist) { - versionWithPrefix := "v" + info.Version - ghRepo := "https://github.com/" + info.GitHubOrg + "/terraform-provider-" + info.Name - - cmd := exec.Command("git", "clone", "--depth", "1", "-b", versionWithPrefix, ghRepo, upstreamRepoDir) - err = cmd.Run() - if err != nil { - return plugin.ParameterizeResponse{}, err - } + // Write the upstream files at this version to a temporary directory + tmpDir, err := os.MkdirTemp("", "upstreamRepoDir") + if err != nil { + return plugin.ParameterizeResponse{}, err + } + versionWithPrefix := "v" + info.Version + ghRepo := "https://github.com/" + info.GitHubOrg + "/terraform-provider-" + info.Name + + cmd := exec.Command("git", "clone", "--depth", "1", "-b", versionWithPrefix, ghRepo, tmpDir) + err = cmd.Run() + if err != nil { + return plugin.ParameterizeResponse{}, err } - info.UpstreamRepoPath = upstreamRepoDir + info.UpstreamRepoPath = tmpDir } return plugin.ParameterizeResponse{ Name: p.Name(), diff --git a/dynamic/parameterize/args.go b/dynamic/parameterize/args.go index af5ac9b6e..ffe5dafa6 100644 --- a/dynamic/parameterize/args.go +++ b/dynamic/parameterize/args.go @@ -72,6 +72,6 @@ func ParseArgs(args []string) (Args, error) { remote.Name = args[0] return Args{Remote: &remote}, nil default: - return Args{}, fmt.Errorf("expected to be parameterized by 1-3 arguments: [version] fullDocs") + return Args{}, fmt.Errorf("expected to be parameterized by 1-3 arguments: [version] [fullDocs]") } } diff --git a/dynamic/parameterize/args_test.go b/dynamic/parameterize/args_test.go index fa014baf8..78f1c1c1b 100644 --- a/dynamic/parameterize/args_test.go +++ b/dynamic/parameterize/args_test.go @@ -51,12 +51,12 @@ func TestParseArgs(t *testing.T) { { name: "no args", args: []string{}, - errMsg: autogold.Expect("expected to be parameterized by 1-3 arguments: [version] fullDocs"), + errMsg: autogold.Expect("expected to be parameterized by 1-3 arguments: [version] [fullDocs]"), }, { name: "too many args", args: []string{"arg1", "arg2", "arg3", "arg4"}, - errMsg: autogold.Expect("expected to be parameterized by 1-3 arguments: [version] fullDocs"), + errMsg: autogold.Expect("expected to be parameterized by 1-3 arguments: [version] [fullDocs]"), }, { name: "invalid third arg", diff --git a/pkg/tfbridge/info/info.go b/pkg/tfbridge/info/info.go index e11cd10fa..2b071403a 100644 --- a/pkg/tfbridge/info/info.go +++ b/pkg/tfbridge/info/info.go @@ -130,7 +130,7 @@ type Provider struct { // - TFProviderModuleVersion // // For dynamically bridged providers, when the fullDocs option is set on the parameterized inputs, - // this field will be automatically set to "terraform-provider--v". + // this field will be automatically set to a temporary directory containing a shallow clone of the upstream repo. // This list may change over time. UpstreamRepoPath string diff --git a/pkg/tfgen/generate.go b/pkg/tfgen/generate.go index e64f3d347..132385789 100644 --- a/pkg/tfgen/generate.go +++ b/pkg/tfgen/generate.go @@ -786,7 +786,6 @@ type GenerateSchemaResult struct { func GenerateSchemaWithOptions(opts GenerateSchemaOptions) (*GenerateSchemaResult, error) { ctx := context.Background() - info := opts.ProviderInfo sink := opts.DiagnosticsSink g, err := NewGenerator(GeneratorOptions{ @@ -801,6 +800,7 @@ func GenerateSchemaWithOptions(opts GenerateSchemaOptions) (*GenerateSchemaResul if err != nil { return nil, errors.Wrapf(err, "failed to create generator") } + return g.generateSchemaResult(ctx) } From 75c16d4f3411d4fe9fbd1429a34340dc4bb955d2 Mon Sep 17 00:00:00 2001 From: guineveresaenger Date: Wed, 27 Nov 2024 14:56:57 -0800 Subject: [PATCH 08/16] Add check to ensure we're taking remote path when setting GitHubOrg --- dynamic/info.go | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/dynamic/info.go b/dynamic/info.go index dae85754d..a87bffcae 100644 --- a/dynamic/info.go +++ b/dynamic/info.go @@ -33,24 +33,13 @@ import ( func providerInfo(ctx context.Context, p run.Provider, value parameterize.Value) (tfbridge.ProviderInfo, error) { provider := proto.New(ctx, p) - // TODO: handle docsgen for a local dynamic provider - // https://github.com/opentofu/registry/issues/1337: Due to discrepancies in the registry protocol/implementation, - // we infer the Terraform provider's source code repository via the following assumptions: - // - The provider's source code is hosted at github.com - // - The provider's github org, for providers, is the namespace field of the registry name - // Example: - // - // opentofu.org/provider/hashicorp/random -> "hashicorp" is deduced to be the github org. - // Note that this will only work for the provider (not the module) protocol. - urlFields := strings.Split(value.Remote.URL, "/") - ghOrg := urlFields[len(urlFields)-2] + prov := tfbridge.ProviderInfo{ P: provider, Name: p.Name(), Version: p.Version(), Description: "A Pulumi provider dynamically bridged from " + p.Name() + ".", Publisher: "Pulumi", - GitHubOrg: ghOrg, ResourcePrefix: inferResourcePrefix(provider), // To avoid bogging down schema generation speed, we skip all examples. @@ -95,6 +84,22 @@ func providerInfo(ctx context.Context, p run.Provider, value parameterize.Value) } }, } + // Add presumed best-effort GitHub org to the provider info. + // We do not yet handle full docsgen for a local dynamic provider so we do not set the GitHubOrg field in that case. + if value.Remote != nil { + // https://github.com/opentofu/registry/issues/1337: + // Due to discrepancies in the registry protocol/implementation, + // we infer the Terraform provider's source code repository via the following assumptions: + // - The provider's source code is hosted at github.com + // - The provider's github org, for providers, is the namespace field of the registry name + // Example: + // + // opentofu.org/provider/hashicorp/random -> "hashicorp" is deduced to be the github org. + // Note that this will only work for the provider (not the module) protocol. + urlFields := strings.Split(value.Remote.URL, "/") + ghOrg := urlFields[len(urlFields)-2] + prov.GitHubOrg = ghOrg + } if err := fixup.Default(&prov); err != nil { return prov, err From 0fa490c59f951eade00e6b6daf91f0cef8e4edff Mon Sep 17 00:00:00 2001 From: guineveresaenger Date: Wed, 27 Nov 2024 17:28:04 -0800 Subject: [PATCH 09/16] Pass a local docs path to the local provider gen --- dynamic/info.go | 2 +- dynamic/main.go | 53 +++++++++++++++++-------------- dynamic/parameterize/args.go | 10 +++++- dynamic/parameterize/args_test.go | 17 ++++++++++ 4 files changed, 57 insertions(+), 25 deletions(-) diff --git a/dynamic/info.go b/dynamic/info.go index a87bffcae..403c9eea9 100644 --- a/dynamic/info.go +++ b/dynamic/info.go @@ -85,7 +85,7 @@ func providerInfo(ctx context.Context, p run.Provider, value parameterize.Value) }, } // Add presumed best-effort GitHub org to the provider info. - // We do not yet handle full docsgen for a local dynamic provider so we do not set the GitHubOrg field in that case. + // We do not set the GitHubOrg field for a local dynamic provider. if value.Remote != nil { // https://github.com/opentofu/registry/issues/1337: // Due to discrepancies in the registry protocol/implementation, diff --git a/dynamic/main.go b/dynamic/main.go index 8b424265e..bcc39c80c 100644 --- a/dynamic/main.go +++ b/dynamic/main.go @@ -18,6 +18,9 @@ import ( "context" "encoding/json" "fmt" + "os" + "os/exec" + "github.com/blang/semver" "github.com/opentofu/opentofu/shim/run" "github.com/pulumi/pulumi/pkg/v3/codegen/schema" @@ -25,8 +28,6 @@ import ( "github.com/pulumi/pulumi/sdk/v3/go/common/diag/colors" "github.com/pulumi/pulumi/sdk/v3/go/common/resource/plugin" "github.com/pulumi/pulumi/sdk/v3/go/common/util/contract" - "os" - "os/exec" "github.com/pulumi/pulumi-terraform-bridge/dynamic/parameterize" "github.com/pulumi/pulumi-terraform-bridge/dynamic/version" @@ -66,19 +67,12 @@ func initialSetup() (info.Provider, pfbridge.ProviderMetadata, func() error) { var fullDocs bool metadata = pfbridge.ProviderMetadata{ XGetSchema: func(ctx context.Context, req plugin.GetSchemaRequest) ([]byte, error) { - // By default, only read in docs from TF schema - var schemaDocsOnly = true - // If full docs is expected set schemaDocsOnly to false - if fullDocs { - schemaDocsOnly = false - } - packageSchema, err := tfgen.GenerateSchemaWithOptions(tfgen.GenerateSchemaOptions{ ProviderInfo: info, DiagnosticsSink: diag.DefaultSink(os.Stdout, os.Stderr, diag.FormatOptions{ Color: colors.Always, }), - XInMemoryDocs: schemaDocsOnly, + XInMemoryDocs: !fullDocs, }) if err != nil { return nil, err @@ -155,23 +149,36 @@ func initialSetup() (info.Provider, pfbridge.ProviderMetadata, func() error) { if err != nil { return plugin.ParameterizeResponse{}, err } - fullDocs = args.Remote.Docs - if fullDocs { - // Write the upstream files at this version to a temporary directory - tmpDir, err := os.MkdirTemp("", "upstreamRepoDir") - if err != nil { - return plugin.ParameterizeResponse{}, err + + if args.Remote != nil { + fullDocs = args.Remote.Docs + if fullDocs { + // Write the upstream files at this version to a temporary directory + tmpDir, err := os.MkdirTemp("", "upstreamRepoDir") + if err != nil { + return plugin.ParameterizeResponse{}, err + } + versionWithPrefix := "v" + info.Version + ghRepo := "https://github.com/" + info.GitHubOrg + "/terraform-provider-" + info.Name + + cmd := exec.Command( + "git", "clone", "--depth", "1", "-b", versionWithPrefix, ghRepo, tmpDir, + ) + err = cmd.Run() + if err != nil { + return plugin.ParameterizeResponse{}, err + } + info.UpstreamRepoPath = tmpDir } - versionWithPrefix := "v" + info.Version - ghRepo := "https://github.com/" + info.GitHubOrg + "/terraform-provider-" + info.Name + } - cmd := exec.Command("git", "clone", "--depth", "1", "-b", versionWithPrefix, ghRepo, tmpDir) - err = cmd.Run() - if err != nil { - return plugin.ParameterizeResponse{}, err + if args.Local != nil { + if args.Local.DocsLocation != "" { + info.UpstreamRepoPath = args.Local.DocsLocation + fullDocs = true } - info.UpstreamRepoPath = tmpDir } + return plugin.ParameterizeResponse{ Name: p.Name(), Version: v, diff --git a/dynamic/parameterize/args.go b/dynamic/parameterize/args.go index ffe5dafa6..db99b98cc 100644 --- a/dynamic/parameterize/args.go +++ b/dynamic/parameterize/args.go @@ -39,14 +39,22 @@ type RemoteArgs struct { type LocalArgs struct { // Path is the path to the provider binary. It can be relative or absolute. Path string + // DocsLocation is the path to the provider documentation. + DocsLocation string } func ParseArgs(args []string) (Args, error) { // Check for a leading '.' or '/' to indicate a path + if len(args) >= 1 && (strings.HasPrefix(args[0], "./") || strings.HasPrefix(args[0], "/")) { if len(args) > 1 { - return Args{}, fmt.Errorf("path based providers are only parameterized by 1 argument: ") + docsArg := args[1] + docsLocation, found := strings.CutPrefix(docsArg, "docsLocation=") + if !found { + return Args{}, fmt.Errorf("path based providers are only parameterized by 2 arguments: [docsLocation]") + } + return Args{Local: &LocalArgs{Path: args[0], DocsLocation: docsLocation}}, nil } return Args{Local: &LocalArgs{Path: args[0]}}, nil } diff --git a/dynamic/parameterize/args_test.go b/dynamic/parameterize/args_test.go index 78f1c1c1b..e45e8ffb0 100644 --- a/dynamic/parameterize/args_test.go +++ b/dynamic/parameterize/args_test.go @@ -35,6 +35,23 @@ func TestParseArgs(t *testing.T) { args: []string{"./my-provider"}, expect: Args{Local: &LocalArgs{Path: "./my-provider"}}, }, + { + name: "local too many args", + args: []string{"./my-provider", "nonsense"}, + errMsg: autogold.Expect( + "path based providers are only parameterized by 2 arguments: [docsLocation]", + ), + }, + { + name: "local with docs location", + args: []string{"./my-provider", "docsLocation=./my-provider"}, + expect: Args{ + Local: &LocalArgs{ + Path: "./my-provider", + DocsLocation: "./my-provider", + }, + }, + }, { name: "remote", args: []string{"my-registry.io/typ"}, From 088bad9be7730fa4f58533caed5213155979ffb6 Mon Sep 17 00:00:00 2001 From: guineveresaenger Date: Tue, 3 Dec 2024 13:05:45 -0800 Subject: [PATCH 10/16] Refactor Generate call to return the package spec for outside consumption. Skip example conversion when fullDocs is not set. --- dynamic/go.mod | 4 ++-- dynamic/info.go | 3 ++- dynamic/main.go | 17 ++++++++++++++--- go.mod | 2 +- pkg/pf/tfgen/main.go | 6 ++++-- pkg/tfgen/convert_cli_test.go | 8 ++++---- pkg/tfgen/docs.go | 3 +-- pkg/tfgen/docs_test.go | 2 +- pkg/tfgen/generate.go | 36 ++++++++++++++++------------------- pkg/tfgen/main.go | 3 +-- 10 files changed, 46 insertions(+), 38 deletions(-) diff --git a/dynamic/go.mod b/dynamic/go.mod index 237bcd069..35b01dca2 100644 --- a/dynamic/go.mod +++ b/dynamic/go.mod @@ -189,7 +189,7 @@ require ( github.com/pgavlin/fx v0.1.6 // indirect github.com/pgavlin/goldmark v1.1.33-0.20200616210433-b5eb04559386 // indirect github.com/pjbgf/sha1cd v0.3.0 // indirect - github.com/pkg/errors v0.9.1 // indirect + github.com/pkg/errors v0.9.1 github.com/pkg/term v1.1.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/posener/complete v1.2.3 // indirect @@ -212,7 +212,7 @@ require ( github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect github.com/shopspring/decimal v1.3.1 // indirect github.com/skeema/knownhosts v1.2.2 // indirect - github.com/spf13/afero v1.9.5 // indirect + github.com/spf13/afero v1.9.5 github.com/spf13/cast v1.5.0 // indirect github.com/spf13/cobra v1.8.0 // indirect github.com/spf13/pflag v1.0.5 // indirect diff --git a/dynamic/info.go b/dynamic/info.go index 403c9eea9..6cb80479b 100644 --- a/dynamic/info.go +++ b/dynamic/info.go @@ -43,7 +43,7 @@ func providerInfo(ctx context.Context, p run.Provider, value parameterize.Value) ResourcePrefix: inferResourcePrefix(provider), // To avoid bogging down schema generation speed, we skip all examples. - SkipExamples: func(tfbridge.SkipExamplesArgs) bool { return true }, + SkipExamples: func(tfbridge.SkipExamplesArgs) bool { return false }, MetadataInfo: &tfbridge.MetadataInfo{ Path: "", Data: tfbridge.ProviderMetadata(nil), @@ -99,6 +99,7 @@ func providerInfo(ctx context.Context, p run.Provider, value parameterize.Value) urlFields := strings.Split(value.Remote.URL, "/") ghOrg := urlFields[len(urlFields)-2] prov.GitHubOrg = ghOrg + } if err := fixup.Default(&prov); err != nil { diff --git a/dynamic/main.go b/dynamic/main.go index bcc39c80c..501775b0d 100644 --- a/dynamic/main.go +++ b/dynamic/main.go @@ -18,6 +18,8 @@ import ( "context" "encoding/json" "fmt" + "github.com/pkg/errors" + "github.com/spf13/afero" "os" "os/exec" @@ -67,13 +69,23 @@ func initialSetup() (info.Provider, pfbridge.ProviderMetadata, func() error) { var fullDocs bool metadata = pfbridge.ProviderMetadata{ XGetSchema: func(ctx context.Context, req plugin.GetSchemaRequest) ([]byte, error) { - packageSchema, err := tfgen.GenerateSchemaWithOptions(tfgen.GenerateSchemaOptions{ + // Create a custom generator for schema and, of fullDocs is set, examples + g, err := tfgen.NewGenerator(tfgen.GeneratorOptions{ + Package: info.Name, + Version: info.Version, + Language: tfgen.Schema, ProviderInfo: info, - DiagnosticsSink: diag.DefaultSink(os.Stdout, os.Stderr, diag.FormatOptions{ + Root: afero.NewMemMapFs(), + Sink: diag.DefaultSink(os.Stdout, os.Stderr, diag.FormatOptions{ Color: colors.Always, }), XInMemoryDocs: !fullDocs, + SkipExamples: !fullDocs, }) + if err != nil { + return nil, errors.Wrapf(err, "failed to create generator") + } + packageSchema, err := g.Generate() if err != nil { return nil, err } @@ -81,7 +93,6 @@ func initialSetup() (info.Provider, pfbridge.ProviderMetadata, func() error) { if info.SchemaPostProcessor != nil { info.SchemaPostProcessor(&packageSchema.PackageSpec) } - return json.Marshal(packageSchema.PackageSpec) }, XParamaterize: func(ctx context.Context, req plugin.ParameterizeRequest) (plugin.ParameterizeResponse, error) { diff --git a/go.mod b/go.mod index e9f28aeeb..e8d1b223f 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/pulumi/pulumi-terraform-bridge/v3 -go 1.22.0 +go 1.22.3 toolchain go1.23.2 diff --git a/pkg/pf/tfgen/main.go b/pkg/pf/tfgen/main.go index 057b44aac..0f82f51aa 100644 --- a/pkg/pf/tfgen/main.go +++ b/pkg/pf/tfgen/main.go @@ -53,8 +53,9 @@ func Main(provider string, info sdkBridge.ProviderInfo) { if err := check.Provider(g.Sink(), info); err != nil { return err } + _, err = g.Generate() - return g.Generate() + return err }) } @@ -109,6 +110,7 @@ func MainWithMuxer(provider string, info sdkBridge.ProviderInfo) { return err } - return g.Generate() + _, err = g.Generate() + return err }) } diff --git a/pkg/tfgen/convert_cli_test.go b/pkg/tfgen/convert_cli_test.go index d8a7bac60..21c134d52 100644 --- a/pkg/tfgen/convert_cli_test.go +++ b/pkg/tfgen/convert_cli_test.go @@ -183,7 +183,7 @@ output "someOutput" { }) assert.NoError(t, err) - err = g.Generate() + _, err = g.Generate() assert.NoError(t, err) d, err := os.ReadFile(filepath.Join(tempdir, "schema.json")) @@ -283,7 +283,7 @@ resource "azurerm_web_pubsub_custom_certificate" "test" { }) require.NoError(t, err) - err = g.Generate() + _, err = g.Generate() require.NoError(t, err) }) @@ -337,7 +337,7 @@ This is some intentionally broken HCL that should not convert. }) require.NoError(t, err) - err = g.Generate() + _, err = g.Generate() require.NoError(t, err) autogold.Expect("").Equal(t, stdout.String()) @@ -413,7 +413,7 @@ This is some intentionally broken HCL that should not convert. }) require.NoError(t, err) - err = g.Generate() + _, err = g.Generate() require.NoError(t, err) require.NotContains(t, stdout.String(), cliConverterErrUnexpectedHCLSnippet) diff --git a/pkg/tfgen/docs.go b/pkg/tfgen/docs.go index 2977e06f4..b2166a1a7 100644 --- a/pkg/tfgen/docs.go +++ b/pkg/tfgen/docs.go @@ -186,6 +186,7 @@ func getDocsForResource(g *Generator, source DocsSource, kind DocKind, if g.skipDocs { return entityDocs{}, nil } + var docInfo *tfbridge.DocInfo if info != nil { docInfo = info.GetDocs() @@ -208,7 +209,6 @@ func getDocsForResource(g *Generator, source DocsSource, kind DocKind, docFile = nil } } - if err != nil { return entityDocs{}, fmt.Errorf("get docs for token %s: %w", rawname, err) } @@ -1457,7 +1457,6 @@ func (g *Generator) convertExamples(docs string, path examplePath) string { if docs == "" { return "" } - if g.info.SkipExamples != nil { if g.info.SkipExamples(tfbridge.SkipExamplesArgs{ Token: path.Token(), diff --git a/pkg/tfgen/docs_test.go b/pkg/tfgen/docs_test.go index 604866657..2995ea9c3 100644 --- a/pkg/tfgen/docs_test.go +++ b/pkg/tfgen/docs_test.go @@ -2165,7 +2165,7 @@ throw new Exception("!"); }) assert.NoError(t, err) - err = g.Generate() + _, err = g.Generate() assert.NoError(t, err) f, err := inmem.Open("schema.json") diff --git a/pkg/tfgen/generate.go b/pkg/tfgen/generate.go index 132385789..845849593 100644 --- a/pkg/tfgen/generate.go +++ b/pkg/tfgen/generate.go @@ -828,7 +828,6 @@ type GeneratorOptions struct { // NewGenerator returns a code-generator for the given language runtime and package info. func NewGenerator(opts GeneratorOptions) (*Generator, error) { pkgName, version, lang, info, root := opts.Package, opts.Version, opts.Language, opts.ProviderInfo, opts.Root - pkg := tokens.NewPackageToken(tokens.PackageName(tokens.IntoQName(pkgName))) // Ensure the language is valid. @@ -927,10 +926,10 @@ type GenerateOptions struct { } // Generate creates Pulumi packages from the information it was initialized with. -func (g *Generator) Generate() error { +func (g *Generator) Generate() (*GenerateSchemaResult, error) { genSchemaResult, err := g.generateSchemaResult(context.Background()) if err != nil { - return err + return nil, err } // Now push the schema through the rest of the generator. @@ -955,7 +954,6 @@ func (g *Generator) generateSchemaResult(ctx context.Context) (*GenerateSchemaRe if err != nil { return nil, errors.Wrapf(err, "failed to create Pulumi schema") } - // Apply schema post-processing if defined in the provider. if g.info.SchemaPostProcessor != nil { g.info.SchemaPostProcessor(&pulumiPackageSpec) @@ -970,7 +968,7 @@ func (g *Generator) generateSchemaResult(ctx context.Context) (*GenerateSchemaRe // This is an unstable API. We have exposed it so other packages within // pulumi-terraform-bridge can consume it. We do not recommend other packages consume this // API. -func (g *Generator) UnstableGenerateFromSchema(genSchemaResult *GenerateSchemaResult) error { +func (g *Generator) UnstableGenerateFromSchema(genSchemaResult *GenerateSchemaResult) (*GenerateSchemaResult, error) { pulumiPackageSpec := genSchemaResult.PackageSpec schemaStats = schemaTools.CountStats(pulumiPackageSpec) @@ -978,20 +976,19 @@ func (g *Generator) UnstableGenerateFromSchema(genSchemaResult *GenerateSchemaRe var err error g.providerShim.schema, err = json.Marshal(pulumiPackageSpec) if err != nil { - return errors.Wrapf(err, "failed to marshal intermediate schema") + return nil, errors.Wrapf(err, "failed to marshal intermediate schema") } // Add any supplemental examples: err = addExtraHclExamplesToResources(g.info.ExtraResourceHclExamples, &pulumiPackageSpec) if err != nil { - return err + return nil, err } err = addExtraHclExamplesToFunctions(g.info.ExtraFunctionHclExamples, &pulumiPackageSpec) if err != nil { - return err + return nil, err } - // Convert examples. if !g.skipExamples { pulumiPackageSpec = g.convertExamplesInSchema(pulumiPackageSpec) @@ -1006,11 +1003,11 @@ func (g *Generator) UnstableGenerateFromSchema(genSchemaResult *GenerateSchemaRe source := NewGitRepoDocsSource(g) installationFile, err := source.getInstallation(nil) if err != nil { - return errors.Wrapf(err, "failed to obtain an index.md file for this provider") + return nil, errors.Wrapf(err, "failed to obtain an index.md file for this provider") } content, err := plainDocsParser(installationFile, g) if err != nil { - return errors.Wrapf(err, "failed to parse installation docs") + return nil, errors.Wrapf(err, "failed to parse installation docs") } files["_index.md"] = content case Schema: @@ -1019,7 +1016,7 @@ func (g *Generator) UnstableGenerateFromSchema(genSchemaResult *GenerateSchemaRe bytes, err := json.MarshalIndent(pulumiPackageSpec, "", " ") if err != nil { - return errors.Wrapf(err, "failed to marshal schema") + return nil, errors.Wrapf(err, "failed to marshal schema") } files = map[string][]byte{"schema.json": bytes} @@ -1032,7 +1029,7 @@ func (g *Generator) UnstableGenerateFromSchema(genSchemaResult *GenerateSchemaRe } case PCL: if g.skipExamples { - return fmt.Errorf("Cannot set skipExamples and get PCL") + return nil, fmt.Errorf("Cannot set skipExamples and get PCL") } files = map[string][]byte{} for path, code := range g.convertedCode { @@ -1042,13 +1039,13 @@ func (g *Generator) UnstableGenerateFromSchema(genSchemaResult *GenerateSchemaRe default: pulumiPackage, diags, err := pschema.BindSpec(pulumiPackageSpec, nil) if err != nil { - return errors.Wrapf(err, "failed to import Pulumi schema") + return nil, errors.Wrapf(err, "failed to import Pulumi schema") } if diags.HasErrors() { - return err + return nil, err } if files, err = g.language.emitSDK(pulumiPackage, g.info, g.root); err != nil { - return errors.Wrapf(err, "failed to generate package") + return nil, errors.Wrapf(err, "failed to generate package") } } @@ -1060,21 +1057,21 @@ func (g *Generator) UnstableGenerateFromSchema(genSchemaResult *GenerateSchemaRe } } if err := emitFile(g.root, f, contents); err != nil { - return errors.Wrapf(err, "emitting file %v", f) + return nil, errors.Wrapf(err, "emitting file %v", f) } } // Emit the Pulumi project information. if g.language != RegistryDocs { if err = g.emitProjectMetadata(g.pkg, g.language); err != nil { - return errors.Wrapf(err, "failed to create project file") + return nil, errors.Wrapf(err, "failed to create project file") } } // Close the plugin host. g.pluginHost.Close() - return nil + return &GenerateSchemaResult{PackageSpec: pulumiPackageSpec}, nil } // gatherPackage creates a package plus module structure for the entire set of members of this package. @@ -1425,7 +1422,6 @@ func (g *Generator) gatherResource(rawname string, g.warn(msg) } } - return res, nil } diff --git a/pkg/tfgen/main.go b/pkg/tfgen/main.go index 1bd34a42a..deafe15a1 100644 --- a/pkg/tfgen/main.go +++ b/pkg/tfgen/main.go @@ -49,11 +49,10 @@ func Main(pkg string, version string, prov tfbridge.ProviderInfo) { } // Let's generate some code! - err = g.Generate() + _, err = g.Generate() if err != nil { return err } - return err }) } From 94d855846397ead422afec83b96d4291d7c4b0d3 Mon Sep 17 00:00:00 2001 From: guineveresaenger Date: Tue, 3 Dec 2024 14:58:08 -0800 Subject: [PATCH 11/16] Review comments --- dynamic/info.go | 3 ++- dynamic/main.go | 15 +++++++-------- dynamic/parameterize/args.go | 25 ++++++++++++++++++------- dynamic/parameterize/args_test.go | 15 +++++++++++---- pkg/tfbridge/info/info.go | 3 --- pkg/tfgen/generate.go | 2 +- pkg/tfgen/main.go | 3 --- pkg/tfgen/source.go | 1 + 8 files changed, 40 insertions(+), 27 deletions(-) diff --git a/dynamic/info.go b/dynamic/info.go index 6cb80479b..8fe40d96e 100644 --- a/dynamic/info.go +++ b/dynamic/info.go @@ -98,8 +98,9 @@ func providerInfo(ctx context.Context, p run.Provider, value parameterize.Value) // Note that this will only work for the provider (not the module) protocol. urlFields := strings.Split(value.Remote.URL, "/") ghOrg := urlFields[len(urlFields)-2] + name := urlFields[len(urlFields)-1] prov.GitHubOrg = ghOrg - + prov.Repository = "https://github.com/" + ghOrg + "/terraform-provider-" + name } if err := fixup.Default(&prov); err != nil { diff --git a/dynamic/main.go b/dynamic/main.go index 501775b0d..23af820e2 100644 --- a/dynamic/main.go +++ b/dynamic/main.go @@ -18,11 +18,12 @@ import ( "context" "encoding/json" "fmt" - "github.com/pkg/errors" - "github.com/spf13/afero" "os" "os/exec" + "github.com/pkg/errors" + "github.com/spf13/afero" + "github.com/blang/semver" "github.com/opentofu/opentofu/shim/run" "github.com/pulumi/pulumi/pkg/v3/codegen/schema" @@ -169,11 +170,9 @@ func initialSetup() (info.Provider, pfbridge.ProviderMetadata, func() error) { if err != nil { return plugin.ParameterizeResponse{}, err } - versionWithPrefix := "v" + info.Version - ghRepo := "https://github.com/" + info.GitHubOrg + "/terraform-provider-" + info.Name - + versionTag := "v" + info.Version cmd := exec.Command( - "git", "clone", "--depth", "1", "-b", versionWithPrefix, ghRepo, tmpDir, + "git", "clone", "--depth", "1", "-b", versionTag, info.Repository, tmpDir, ) err = cmd.Run() if err != nil { @@ -184,8 +183,8 @@ func initialSetup() (info.Provider, pfbridge.ProviderMetadata, func() error) { } if args.Local != nil { - if args.Local.DocsLocation != "" { - info.UpstreamRepoPath = args.Local.DocsLocation + if args.Local.UpstreamRepoPath != "" { + info.UpstreamRepoPath = args.Local.UpstreamRepoPath fullDocs = true } } diff --git a/dynamic/parameterize/args.go b/dynamic/parameterize/args.go index db99b98cc..b1444f91a 100644 --- a/dynamic/parameterize/args.go +++ b/dynamic/parameterize/args.go @@ -31,7 +31,7 @@ type RemoteArgs struct { Name string // Version is the (possibly empty) version constraint on the provider. Version string - // Docs is the (possibly empty) argument to download and write docs into the schema + // Docs indicates if full schema documentation should be generated. Docs bool } @@ -39,22 +39,33 @@ type RemoteArgs struct { type LocalArgs struct { // Path is the path to the provider binary. It can be relative or absolute. Path string - // DocsLocation is the path to the provider documentation. - DocsLocation string + // UpstreamRepoPath (if provided) is the local path to the dynamically bridged Terraform provider's repo. + // + // If set, full documentation will be generated for the provider. + // If not set, only documentation from the TF provider's schema will be used. + UpstreamRepoPath string } func ParseArgs(args []string) (Args, error) { // Check for a leading '.' or '/' to indicate a path - if len(args) >= 1 && (strings.HasPrefix(args[0], "./") || strings.HasPrefix(args[0], "/")) { if len(args) > 1 { docsArg := args[1] - docsLocation, found := strings.CutPrefix(docsArg, "docsLocation=") + upstreamRepoPath, found := strings.CutPrefix(docsArg, "upstreamRepoPath=") if !found { - return Args{}, fmt.Errorf("path based providers are only parameterized by 2 arguments: [docsLocation]") + return Args{}, fmt.Errorf( + "path based providers are only parameterized by 2 arguments: " + + "[upstreamRepoPath=]", + ) + } + if upstreamRepoPath == "" { + return Args{}, fmt.Errorf( + "upstreamRepoPath must be set to a non-empty value: " + + "upstreamRepoPath=path/to/files", + ) } - return Args{Local: &LocalArgs{Path: args[0], DocsLocation: docsLocation}}, nil + return Args{Local: &LocalArgs{Path: args[0], UpstreamRepoPath: upstreamRepoPath}}, nil } return Args{Local: &LocalArgs{Path: args[0]}}, nil } diff --git a/dynamic/parameterize/args_test.go b/dynamic/parameterize/args_test.go index e45e8ffb0..409855a8c 100644 --- a/dynamic/parameterize/args_test.go +++ b/dynamic/parameterize/args_test.go @@ -39,19 +39,26 @@ func TestParseArgs(t *testing.T) { name: "local too many args", args: []string{"./my-provider", "nonsense"}, errMsg: autogold.Expect( - "path based providers are only parameterized by 2 arguments: [docsLocation]", + "path based providers are only parameterized by 2 arguments: [upstreamRepoPath=]", ), }, { name: "local with docs location", - args: []string{"./my-provider", "docsLocation=./my-provider"}, + args: []string{"./my-provider", "upstreamRepoPath=./my-provider"}, expect: Args{ Local: &LocalArgs{ - Path: "./my-provider", - DocsLocation: "./my-provider", + Path: "./my-provider", + UpstreamRepoPath: "./my-provider", }, }, }, + { + name: "local empty upstreamRepoPath", + args: []string{"./my-provider", "upstreamRepoPath="}, + errMsg: autogold.Expect( + "upstreamRepoPath must be set to a non-empty value: upstreamRepoPath=path/to/files", + ), + }, { name: "remote", args: []string{"my-registry.io/typ"}, diff --git a/pkg/tfbridge/info/info.go b/pkg/tfbridge/info/info.go index 2b071403a..26037c941 100644 --- a/pkg/tfbridge/info/info.go +++ b/pkg/tfbridge/info/info.go @@ -129,9 +129,6 @@ type Provider struct { // - Name // - TFProviderModuleVersion // - // For dynamically bridged providers, when the fullDocs option is set on the parameterized inputs, - // this field will be automatically set to a temporary directory containing a shallow clone of the upstream repo. - // This list may change over time. UpstreamRepoPath string diff --git a/pkg/tfgen/generate.go b/pkg/tfgen/generate.go index 845849593..24af79dbb 100644 --- a/pkg/tfgen/generate.go +++ b/pkg/tfgen/generate.go @@ -941,7 +941,6 @@ func (g *Generator) generateSchemaResult(ctx context.Context) (*GenerateSchemaRe if err != nil { return nil, err } - // First gather up the entire package contents. This structure is complete and sufficient to hand off to the // language-specific generators to create the full output. pack, err := g.gatherPackage() @@ -1422,6 +1421,7 @@ func (g *Generator) gatherResource(rawname string, g.warn(msg) } } + return res, nil } diff --git a/pkg/tfgen/main.go b/pkg/tfgen/main.go index deafe15a1..4aa68e713 100644 --- a/pkg/tfgen/main.go +++ b/pkg/tfgen/main.go @@ -50,9 +50,6 @@ func Main(pkg string, version string, prov tfbridge.ProviderInfo) { // Let's generate some code! _, err = g.Generate() - if err != nil { - return err - } return err }) } diff --git a/pkg/tfgen/source.go b/pkg/tfgen/source.go index 07fc845df..37fb941cf 100644 --- a/pkg/tfgen/source.go +++ b/pkg/tfgen/source.go @@ -86,6 +86,7 @@ func (gh *gitRepoSource) getFile( if info != nil && len(info.Markdown) != 0 { return &DocFile{Content: info.Markdown}, nil } + repoPath := gh.upstreamRepoPath if repoPath == "" { var err error From b287bf358f9cb71b95cf6c8f9bbe73118bb228e4 Mon Sep 17 00:00:00 2001 From: guineveresaenger Date: Tue, 3 Dec 2024 15:38:09 -0800 Subject: [PATCH 12/16] Upgrade Terraform converter to v1.0.20 and adjust tests --- Makefile | 2 +- dynamic/main.go | 5 ++- .../Backblaze/b2-0.8.9.golden | 6 ++-- .../databricks/databricks-1.50.0.golden | 6 ++-- .../hashicorp/random-3.3.0.golden | 6 ++-- .../unparameterized.golden | 1 - .../hashicorp/random-3.6.3.golden | 22 ++++++------- .../cmd/pulumi-resource-tpsdkv2/schema.json | 4 +-- .../convert/testdata/schemas/blocks.json | 5 +-- .../convert/testdata/schemas/complex.json | 5 +-- .../convert/testdata/schemas/renames.json | 5 +-- .../convert/testdata/schemas/simple.json | 5 +-- pkg/tfgen/generate.go | 31 +++++++++---------- pkg/tfgen/generate_schema.go | 17 ++++++++-- pkg/tfgen/generate_schema_test.go | 1 + pkg/tfgen/generate_test.go | 1 + .../TestConvertViaPulumiCLI/schema.json | 4 +-- pkg/tfgen/testdata/TestTypeSharing.golden | 5 +-- 18 files changed, 73 insertions(+), 58 deletions(-) diff --git a/Makefile b/Makefile index 1eabcb694..d54e5c5ec 100644 --- a/Makefile +++ b/Makefile @@ -6,7 +6,7 @@ export PULUMI_DISABLE_AUTOMATIC_PLUGIN_ACQUISITION := true PROJECT_DIR := $(patsubst %/,%,$(dir $(abspath $(lastword $(MAKEFILE_LIST))))) install_plugins:: - pulumi plugin install converter terraform 1.0.19 + pulumi plugin install converter terraform 1.0.20 pulumi plugin install resource random 4.16.3 pulumi plugin install resource aws 6.22.2 pulumi plugin install resource archive 0.0.4 diff --git a/dynamic/main.go b/dynamic/main.go index 23af820e2..61e1750de 100644 --- a/dynamic/main.go +++ b/dynamic/main.go @@ -21,16 +21,15 @@ import ( "os" "os/exec" - "github.com/pkg/errors" - "github.com/spf13/afero" - "github.com/blang/semver" "github.com/opentofu/opentofu/shim/run" + "github.com/pkg/errors" "github.com/pulumi/pulumi/pkg/v3/codegen/schema" "github.com/pulumi/pulumi/sdk/v3/go/common/diag" "github.com/pulumi/pulumi/sdk/v3/go/common/diag/colors" "github.com/pulumi/pulumi/sdk/v3/go/common/resource/plugin" "github.com/pulumi/pulumi/sdk/v3/go/common/util/contract" + "github.com/spf13/afero" "github.com/pulumi/pulumi-terraform-bridge/dynamic/parameterize" "github.com/pulumi/pulumi-terraform-bridge/dynamic/version" diff --git a/dynamic/testdata/TestSchemaGeneration/Backblaze/b2-0.8.9.golden b/dynamic/testdata/TestSchemaGeneration/Backblaze/b2-0.8.9.golden index cb4cd1ecb..59a37ed4e 100644 --- a/dynamic/testdata/TestSchemaGeneration/Backblaze/b2-0.8.9.golden +++ b/dynamic/testdata/TestSchemaGeneration/Backblaze/b2-0.8.9.golden @@ -1,8 +1,8 @@ { "name": "b2", - "version": "0.8.9", "description": "A Pulumi provider dynamically bridged from b2.", "attribution": "This Pulumi package is based on the [`b2` Terraform Provider](https://github.com/backblaze/terraform-provider-b2).", + "repository": "https://github.com/backblaze/terraform-provider-b2", "publisher": "Pulumi", "meta": { "moduleFormat": "(.*)(?:/[^/]*)" @@ -28,14 +28,14 @@ }, "nodejs": { "packageDescription": "A Pulumi provider dynamically bridged from b2.", - "readme": "\u003e This provider is a derived work of the [Terraform Provider](https://github.com/backblaze/terraform-provider-b2)\n\u003e distributed under [MPL 2.0](https://www.mozilla.org/en-US/MPL/2.0/). If you encounter a bug or missing feature,\n\u003e first check the [`pulumi-b2` repo](/issues); however, if that doesn't turn up anything,\n\u003e please consult the source [`terraform-provider-b2` repo](https://github.com/backblaze/terraform-provider-b2/issues).", + "readme": "\u003e This provider is a derived work of the [Terraform Provider](https://github.com/backblaze/terraform-provider-b2)\n\u003e distributed under [MPL 2.0](https://www.mozilla.org/en-US/MPL/2.0/). If you encounter a bug or missing feature,\n\u003e please consult the source [`terraform-provider-b2` repo](https://github.com/backblaze/terraform-provider-b2/issues).", "compatibility": "tfbridge20", "disableUnionOutputTypes": true, "liftSingleValueMethodReturns": true, "respectSchemaVersion": true }, "python": { - "readme": "\u003e This provider is a derived work of the [Terraform Provider](https://github.com/backblaze/terraform-provider-b2)\n\u003e distributed under [MPL 2.0](https://www.mozilla.org/en-US/MPL/2.0/). If you encounter a bug or missing feature,\n\u003e first check the [`pulumi-b2` repo](/issues); however, if that doesn't turn up anything,\n\u003e please consult the source [`terraform-provider-b2` repo](https://github.com/backblaze/terraform-provider-b2/issues).", + "readme": "\u003e This provider is a derived work of the [Terraform Provider](https://github.com/backblaze/terraform-provider-b2)\n\u003e distributed under [MPL 2.0](https://www.mozilla.org/en-US/MPL/2.0/). If you encounter a bug or missing feature,\n\u003e please consult the source [`terraform-provider-b2` repo](https://github.com/backblaze/terraform-provider-b2/issues).", "compatibility": "tfbridge20", "respectSchemaVersion": true, "pyproject": { diff --git a/dynamic/testdata/TestSchemaGeneration/databricks/databricks-1.50.0.golden b/dynamic/testdata/TestSchemaGeneration/databricks/databricks-1.50.0.golden index cd0c7a50d..ff3847eeb 100644 --- a/dynamic/testdata/TestSchemaGeneration/databricks/databricks-1.50.0.golden +++ b/dynamic/testdata/TestSchemaGeneration/databricks/databricks-1.50.0.golden @@ -1,8 +1,8 @@ { "name": "databricks", - "version": "1.50.0", "description": "A Pulumi provider dynamically bridged from databricks.", "attribution": "This Pulumi package is based on the [`databricks` Terraform Provider](https://github.com/databricks/terraform-provider-databricks).", + "repository": "https://github.com/databricks/terraform-provider-databricks", "publisher": "Pulumi", "meta": { "moduleFormat": "(.*)(?:/[^/]*)" @@ -28,14 +28,14 @@ }, "nodejs": { "packageDescription": "A Pulumi provider dynamically bridged from databricks.", - "readme": "\u003e This provider is a derived work of the [Terraform Provider](https://github.com/databricks/terraform-provider-databricks)\n\u003e distributed under [MPL 2.0](https://www.mozilla.org/en-US/MPL/2.0/). If you encounter a bug or missing feature,\n\u003e first check the [`pulumi-databricks` repo](/issues); however, if that doesn't turn up anything,\n\u003e please consult the source [`terraform-provider-databricks` repo](https://github.com/databricks/terraform-provider-databricks/issues).", + "readme": "\u003e This provider is a derived work of the [Terraform Provider](https://github.com/databricks/terraform-provider-databricks)\n\u003e distributed under [MPL 2.0](https://www.mozilla.org/en-US/MPL/2.0/). If you encounter a bug or missing feature,\n\u003e please consult the source [`terraform-provider-databricks` repo](https://github.com/databricks/terraform-provider-databricks/issues).", "compatibility": "tfbridge20", "disableUnionOutputTypes": true, "liftSingleValueMethodReturns": true, "respectSchemaVersion": true }, "python": { - "readme": "\u003e This provider is a derived work of the [Terraform Provider](https://github.com/databricks/terraform-provider-databricks)\n\u003e distributed under [MPL 2.0](https://www.mozilla.org/en-US/MPL/2.0/). If you encounter a bug or missing feature,\n\u003e first check the [`pulumi-databricks` repo](/issues); however, if that doesn't turn up anything,\n\u003e please consult the source [`terraform-provider-databricks` repo](https://github.com/databricks/terraform-provider-databricks/issues).", + "readme": "\u003e This provider is a derived work of the [Terraform Provider](https://github.com/databricks/terraform-provider-databricks)\n\u003e distributed under [MPL 2.0](https://www.mozilla.org/en-US/MPL/2.0/). If you encounter a bug or missing feature,\n\u003e please consult the source [`terraform-provider-databricks` repo](https://github.com/databricks/terraform-provider-databricks/issues).", "compatibility": "tfbridge20", "respectSchemaVersion": true, "pyproject": { diff --git a/dynamic/testdata/TestSchemaGeneration/hashicorp/random-3.3.0.golden b/dynamic/testdata/TestSchemaGeneration/hashicorp/random-3.3.0.golden index 3896e56d6..584322726 100644 --- a/dynamic/testdata/TestSchemaGeneration/hashicorp/random-3.3.0.golden +++ b/dynamic/testdata/TestSchemaGeneration/hashicorp/random-3.3.0.golden @@ -1,8 +1,8 @@ { "name": "random", - "version": "3.3.0", "description": "A Pulumi provider dynamically bridged from random.", "attribution": "This Pulumi package is based on the [`random` Terraform Provider](https://github.com/hashicorp/terraform-provider-random).", + "repository": "https://github.com/hashicorp/terraform-provider-random", "publisher": "Pulumi", "meta": { "moduleFormat": "(.*)(?:/[^/]*)" @@ -28,14 +28,14 @@ }, "nodejs": { "packageDescription": "A Pulumi provider dynamically bridged from random.", - "readme": "\u003e This provider is a derived work of the [Terraform Provider](https://github.com/hashicorp/terraform-provider-random)\n\u003e distributed under [MPL 2.0](https://www.mozilla.org/en-US/MPL/2.0/). If you encounter a bug or missing feature,\n\u003e first check the [`pulumi-random` repo](/issues); however, if that doesn't turn up anything,\n\u003e please consult the source [`terraform-provider-random` repo](https://github.com/hashicorp/terraform-provider-random/issues).", + "readme": "\u003e This provider is a derived work of the [Terraform Provider](https://github.com/hashicorp/terraform-provider-random)\n\u003e distributed under [MPL 2.0](https://www.mozilla.org/en-US/MPL/2.0/). If you encounter a bug or missing feature,\n\u003e please consult the source [`terraform-provider-random` repo](https://github.com/hashicorp/terraform-provider-random/issues).", "compatibility": "tfbridge20", "disableUnionOutputTypes": true, "liftSingleValueMethodReturns": true, "respectSchemaVersion": true }, "python": { - "readme": "\u003e This provider is a derived work of the [Terraform Provider](https://github.com/hashicorp/terraform-provider-random)\n\u003e distributed under [MPL 2.0](https://www.mozilla.org/en-US/MPL/2.0/). If you encounter a bug or missing feature,\n\u003e first check the [`pulumi-random` repo](/issues); however, if that doesn't turn up anything,\n\u003e please consult the source [`terraform-provider-random` repo](https://github.com/hashicorp/terraform-provider-random/issues).", + "readme": "\u003e This provider is a derived work of the [Terraform Provider](https://github.com/hashicorp/terraform-provider-random)\n\u003e distributed under [MPL 2.0](https://www.mozilla.org/en-US/MPL/2.0/). If you encounter a bug or missing feature,\n\u003e please consult the source [`terraform-provider-random` repo](https://github.com/hashicorp/terraform-provider-random/issues).", "compatibility": "tfbridge20", "respectSchemaVersion": true, "pyproject": { diff --git a/dynamic/testdata/TestSchemaGeneration/unparameterized.golden b/dynamic/testdata/TestSchemaGeneration/unparameterized.golden index 8809cef0f..45c104ce0 100644 --- a/dynamic/testdata/TestSchemaGeneration/unparameterized.golden +++ b/dynamic/testdata/TestSchemaGeneration/unparameterized.golden @@ -1,7 +1,6 @@ { "name": "terraform-provider", "displayName": "Any Terraform Provider", - "version": "v0.0.0-dev", "description": "Use any Terraform provider with Pulumi", "keywords": [ "category/utility" diff --git a/dynamic/testdata/TestSchemaGenerationFullDocs/hashicorp/random-3.6.3.golden b/dynamic/testdata/TestSchemaGenerationFullDocs/hashicorp/random-3.6.3.golden index ba4a15957..cac441f13 100644 --- a/dynamic/testdata/TestSchemaGenerationFullDocs/hashicorp/random-3.6.3.golden +++ b/dynamic/testdata/TestSchemaGenerationFullDocs/hashicorp/random-3.6.3.golden @@ -1,8 +1,8 @@ { "name": "random", - "version": "3.6.3", "description": "A Pulumi provider dynamically bridged from random.", "attribution": "This Pulumi package is based on the [`random` Terraform Provider](https://github.com/hashicorp/terraform-provider-random).", + "repository": "https://github.com/hashicorp/terraform-provider-random", "publisher": "Pulumi", "meta": { "moduleFormat": "(.*)(?:/[^/]*)" @@ -28,14 +28,14 @@ }, "nodejs": { "packageDescription": "A Pulumi provider dynamically bridged from random.", - "readme": "\u003e This provider is a derived work of the [Terraform Provider](https://github.com/hashicorp/terraform-provider-random)\n\u003e distributed under [MPL 2.0](https://www.mozilla.org/en-US/MPL/2.0/). If you encounter a bug or missing feature,\n\u003e first check the [`pulumi-random` repo](/issues); however, if that doesn't turn up anything,\n\u003e please consult the source [`terraform-provider-random` repo](https://github.com/hashicorp/terraform-provider-random/issues).", + "readme": "\u003e This provider is a derived work of the [Terraform Provider](https://github.com/hashicorp/terraform-provider-random)\n\u003e distributed under [MPL 2.0](https://www.mozilla.org/en-US/MPL/2.0/). If you encounter a bug or missing feature,\n\u003e please consult the source [`terraform-provider-random` repo](https://github.com/hashicorp/terraform-provider-random/issues).", "compatibility": "tfbridge20", "disableUnionOutputTypes": true, "liftSingleValueMethodReturns": true, "respectSchemaVersion": true }, "python": { - "readme": "\u003e This provider is a derived work of the [Terraform Provider](https://github.com/hashicorp/terraform-provider-random)\n\u003e distributed under [MPL 2.0](https://www.mozilla.org/en-US/MPL/2.0/). If you encounter a bug or missing feature,\n\u003e first check the [`pulumi-random` repo](/issues); however, if that doesn't turn up anything,\n\u003e please consult the source [`terraform-provider-random` repo](https://github.com/hashicorp/terraform-provider-random/issues).", + "readme": "\u003e This provider is a derived work of the [Terraform Provider](https://github.com/hashicorp/terraform-provider-random)\n\u003e distributed under [MPL 2.0](https://www.mozilla.org/en-US/MPL/2.0/). If you encounter a bug or missing feature,\n\u003e please consult the source [`terraform-provider-random` repo](https://github.com/hashicorp/terraform-provider-random/issues).", "compatibility": "tfbridge20", "respectSchemaVersion": true, "pyproject": { @@ -49,7 +49,7 @@ }, "resources": { "random:index/bytes:Bytes": { - "description": "The resource `random.Bytes` generates random bytes that are intended to be used as a secret, or key. Use this in preference to `random.Id` when the output is considered sensitive, and should not be displayed in the CLI.\n\nThis resource *does* use a cryptographic random number generator.\n\n## Example Usage\n\n```terraform\nresource \"random_bytes\" \"jwt_secret\" {\n length = 64\n}\n\nresource \"azurerm_key_vault_secret\" \"jwt_secret\" {\n key_vault_id = \"some-azure-key-vault-id\"\n name = \"JwtSecret\"\n value = random_bytes.jwt_secret.base64\n}\n```\n\n## Import\n\nRandom bytes can be imported by specifying the value as base64 string.\n\n```sh\n$ pulumi import random:index/bytes:Bytes basic \"8/fu3q+2DcgSJ19i0jZ5Cw==\"\n```\n\n", + "description": "The resource `random.Bytes` generates random bytes that are intended to be used as a secret, or key. Use this in preference to `random.Id` when the output is considered sensitive, and should not be displayed in the CLI.\n\nThis resource *does* use a cryptographic random number generator.\n\n## Example Usage\n\n\u003c!--Start PulumiCodeChooser --\u003e\n```typescript\nimport * as pulumi from \"@pulumi/pulumi\";\nimport * as azurerm from \"@pulumi/azurerm\";\nimport * as random from \"@pulumi/random\";\n\nconst jwtSecretBytes = new random.Bytes(\"jwtSecretBytes\", {length: 64});\nconst jwtSecretazurerm_key_vault_secret = new azurerm.index.Azurerm_key_vault_secret(\"jwtSecretazurerm_key_vault_secret\", {\n keyVaultId: \"some-azure-key-vault-id\",\n name: \"JwtSecret\",\n value: jwtSecretBytes.base64,\n});\n```\n```python\nimport pulumi\nimport pulumi_azurerm as azurerm\nimport pulumi_random as random\n\njwt_secret_bytes = random.Bytes(\"jwtSecretBytes\", length=64)\njwt_secretazurerm_key_vault_secret = azurerm.index.Azurerm_key_vault_secret(\"jwtSecretazurerm_key_vault_secret\",\n key_vault_id=some-azure-key-vault-id,\n name=JwtSecret,\n value=jwt_secret_bytes.base64)\n```\n```csharp\nusing System.Collections.Generic;\nusing System.Linq;\nusing Pulumi;\nusing Azurerm = Pulumi.Azurerm;\nusing Random = Pulumi.Random;\n\nreturn await Deployment.RunAsync(() =\u003e \n{\n var jwtSecretBytes = new Random.Bytes(\"jwtSecretBytes\", new()\n {\n Length = 64,\n });\n\n var jwtSecretazurerm_key_vault_secret = new Azurerm.Index.Azurerm_key_vault_secret(\"jwtSecretazurerm_key_vault_secret\", new()\n {\n KeyVaultId = \"some-azure-key-vault-id\",\n Name = \"JwtSecret\",\n Value = jwtSecretBytes.Base64,\n });\n\n});\n```\n```go\npackage main\n\nimport (\n\t\"github.com/pulumi/pulumi-azurerm/sdk/go/azurerm\"\n\trandom \"github.com/pulumi/pulumi-terraform-provider/sdks/go/random/v3\"\n\t\"github.com/pulumi/pulumi/sdk/v3/go/pulumi\"\n)\n\nfunc main() {\n\tpulumi.Run(func(ctx *pulumi.Context) error {\n\t\tjwtSecretBytes, err := random.NewBytes(ctx, \"jwtSecretBytes\", \u0026random.BytesArgs{\n\t\t\tLength: pulumi.Float64(64),\n\t\t})\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\t_, err = azurerm.NewAzurerm_key_vault_secret(ctx, \"jwtSecretazurerm_key_vault_secret\", \u0026azurerm.Azurerm_key_vault_secretArgs{\n\t\t\tKeyVaultId: \"some-azure-key-vault-id\",\n\t\t\tName: \"JwtSecret\",\n\t\t\tValue: jwtSecretBytes.Base64,\n\t\t})\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn nil\n\t})\n}\n```\n```java\npackage generated_program;\n\nimport com.pulumi.Context;\nimport com.pulumi.Pulumi;\nimport com.pulumi.core.Output;\nimport com.pulumi.random.Bytes;\nimport com.pulumi.random.BytesArgs;\nimport com.pulumi.azurerm.azurerm_key_vault_secret;\nimport com.pulumi.azurerm.Azurerm_key_vault_secretArgs;\nimport java.util.List;\nimport java.util.ArrayList;\nimport java.util.Map;\nimport java.io.File;\nimport java.nio.file.Files;\nimport java.nio.file.Paths;\n\npublic class App {\n public static void main(String[] args) {\n Pulumi.run(App::stack);\n }\n\n public static void stack(Context ctx) {\n var jwtSecretBytes = new Bytes(\"jwtSecretBytes\", BytesArgs.builder()\n .length(64)\n .build());\n\n var jwtSecretazurerm_key_vault_secret = new Azurerm_key_vault_secret(\"jwtSecretazurerm_key_vault_secret\", Azurerm_key_vault_secretArgs.builder()\n .keyVaultId(\"some-azure-key-vault-id\")\n .name(\"JwtSecret\")\n .value(jwtSecretBytes.base64())\n .build());\n\n }\n}\n```\n```yaml\nresources:\n jwtSecretBytes:\n type: random:Bytes\n properties:\n length: 64\n jwtSecretazurerm_key_vault_secret:\n type: azurerm:azurerm_key_vault_secret\n properties:\n keyVaultId: some-azure-key-vault-id\n name: JwtSecret\n value: ${jwtSecretBytes.base64}\n```\n\u003c!--End PulumiCodeChooser --\u003e\n\n## Import\n\nRandom bytes can be imported by specifying the value as base64 string.\n\n```sh\n$ pulumi import random:index/bytes:Bytes basic \"8/fu3q+2DcgSJ19i0jZ5Cw==\"\n```\n\n", "properties": { "base64": { "type": "string", @@ -123,7 +123,7 @@ } }, "random:index/id:Id": { - "description": "The resource `random.Id` generates random numbers that are intended to be\nused as unique identifiers for other resources. If the output is considered \nsensitive, and should not be displayed in the CLI, use `random.Bytes`\ninstead.\n\nThis resource *does* use a cryptographic random number generator in order\nto minimize the chance of collisions, making the results of this resource\nwhen a 16-byte identifier is requested of equivalent uniqueness to a\ntype-4 UUID.\n\nThis resource can be used in conjunction with resources that have\nthe `create_before_destroy` lifecycle flag set to avoid conflicts with\nunique names during the brief period where both the old and new resources\nexist concurrently.\n\n## Example Usage\n\n```terraform\n# The following example shows how to generate a unique name for an AWS EC2\n# instance that changes each time a new AMI id is selected.\n\nresource \"random_id\" \"server\" {\n keepers = {\n # Generate a new id each time we switch to a new AMI id\n ami_id = var.ami_id\n }\n\n byte_length = 8\n}\n\nresource \"aws_instance\" \"server\" {\n tags = {\n Name = \"web-server ${random_id.server.hex}\"\n }\n\n # Read the AMI id \"through\" the random_id resource to ensure that\n # both will change together.\n ami = random_id.server.keepers.ami_id\n\n # ... (other aws_instance arguments) ...\n}\n```\n\n## Import\n\nRandom IDs can be imported using the b64_url with an optional prefix. This\n\ncan be used to replace a config value with a value interpolated from the\n\nrandom provider without experiencing diffs.\n\nExample with no prefix:\n\n```sh\n$ pulumi import random:index/id:Id server p-9hUg\n```\n\nExample with prefix (prefix is separated by a ,):\n\n```sh\n$ pulumi import random:index/id:Id server my-prefix-,p-9hUg\n```\n\n", + "description": "The resource `random.Id` generates random numbers that are intended to be\nused as unique identifiers for other resources. If the output is considered \nsensitive, and should not be displayed in the CLI, use `random.Bytes`\ninstead.\n\nThis resource *does* use a cryptographic random number generator in order\nto minimize the chance of collisions, making the results of this resource\nwhen a 16-byte identifier is requested of equivalent uniqueness to a\ntype-4 UUID.\n\nThis resource can be used in conjunction with resources that have\nthe `create_before_destroy` lifecycle flag set to avoid conflicts with\nunique names during the brief period where both the old and new resources\nexist concurrently.\n\n## Example Usage\n\n\u003c!--Start PulumiCodeChooser --\u003e\n```typescript\nimport * as pulumi from \"@pulumi/pulumi\";\nimport * as aws from \"@pulumi/aws\";\nimport * as random from \"@pulumi/random\";\n\n// The following example shows how to generate a unique name for an AWS EC2\n// instance that changes each time a new AMI id is selected.\nconst serverId = new random.Id(\"serverId\", {\n keepers: {\n ami_id: _var.ami_id,\n },\n byteLength: 8,\n});\nconst serverInstance = new aws.ec2.Instance(\"serverInstance\", {\n tags: {\n Name: pulumi.interpolate`web-server ${serverId.hex}`,\n },\n ami: serverId.keepers.apply(keepers =\u003e keepers?.amiId),\n});\n// ... (other aws_instance arguments) ...\n```\n```python\nimport pulumi\nimport pulumi_aws as aws\nimport pulumi_random as random\n\n# The following example shows how to generate a unique name for an AWS EC2\n# instance that changes each time a new AMI id is selected.\nserver_id = random.Id(\"serverId\",\n keepers={\n \"ami_id\": var[\"ami_id\"],\n },\n byte_length=8)\nserver_instance = aws.ec2.Instance(\"serverInstance\",\n tags={\n \"Name\": server_id.hex.apply(lambda hex: f\"web-server {hex}\"),\n },\n ami=server_id.keepers[\"amiId\"])\n# ... (other aws_instance arguments) ...\n```\n```csharp\nusing System.Collections.Generic;\nusing System.Linq;\nusing Pulumi;\nusing Aws = Pulumi.Aws;\nusing Random = Pulumi.Random;\n\nreturn await Deployment.RunAsync(() =\u003e \n{\n // The following example shows how to generate a unique name for an AWS EC2\n // instance that changes each time a new AMI id is selected.\n var serverId = new Random.Id(\"serverId\", new()\n {\n Keepers = \n {\n { \"ami_id\", @var.Ami_id },\n },\n ByteLength = 8,\n });\n\n var serverInstance = new Aws.Ec2.Instance(\"serverInstance\", new()\n {\n Tags = \n {\n { \"Name\", serverId.Hex.Apply(hex =\u003e $\"web-server {hex}\") },\n },\n Ami = serverId.Keepers.Apply(keepers =\u003e keepers?.AmiId),\n });\n\n // ... (other aws_instance arguments) ...\n});\n```\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/pulumi/pulumi-aws/sdk/v6/go/aws/ec2\"\n\trandom \"github.com/pulumi/pulumi-terraform-provider/sdks/go/random/v3\"\n\t\"github.com/pulumi/pulumi/sdk/v3/go/pulumi\"\n)\n\nfunc main() {\n\tpulumi.Run(func(ctx *pulumi.Context) error {\n\t\t// The following example shows how to generate a unique name for an AWS EC2\n\t\t// instance that changes each time a new AMI id is selected.\n\t\tserverId, err := random.NewId(ctx, \"serverId\", \u0026random.IdArgs{\n\t\t\tKeepers: pulumi.StringMap{\n\t\t\t\t\"ami_id\": pulumi.Any(_var.Ami_id),\n\t\t\t},\n\t\t\tByteLength: pulumi.Float64(8),\n\t\t})\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\t_, err = ec2.NewInstance(ctx, \"serverInstance\", \u0026ec2.InstanceArgs{\n\t\t\tTags: pulumi.StringMap{\n\t\t\t\t\"Name\": serverId.Hex.ApplyT(func(hex string) (string, error) {\n\t\t\t\t\treturn fmt.Sprintf(\"web-server %v\", hex), nil\n\t\t\t\t}).(pulumi.StringOutput),\n\t\t\t},\n\t\t\tAmi: pulumi.String(serverId.Keepers.ApplyT(func(keepers map[string]string) (*string, error) {\n\t\t\t\treturn \u0026keepers.AmiId, nil\n\t\t\t}).(pulumi.StringPtrOutput)),\n\t\t})\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn nil\n\t})\n}\n```\n```java\npackage generated_program;\n\nimport com.pulumi.Context;\nimport com.pulumi.Pulumi;\nimport com.pulumi.core.Output;\nimport com.pulumi.random.Id;\nimport com.pulumi.random.IdArgs;\nimport com.pulumi.aws.ec2.Instance;\nimport com.pulumi.aws.ec2.InstanceArgs;\nimport java.util.List;\nimport java.util.ArrayList;\nimport java.util.Map;\nimport java.io.File;\nimport java.nio.file.Files;\nimport java.nio.file.Paths;\n\npublic class App {\n public static void main(String[] args) {\n Pulumi.run(App::stack);\n }\n\n public static void stack(Context ctx) {\n // The following example shows how to generate a unique name for an AWS EC2\n // instance that changes each time a new AMI id is selected.\n var serverId = new Id(\"serverId\", IdArgs.builder()\n .keepers(Map.of(\"ami_id\", var_.ami_id()))\n .byteLength(8)\n .build());\n\n var serverInstance = new Instance(\"serverInstance\", InstanceArgs.builder()\n .tags(Map.of(\"Name\", serverId.hex().applyValue(hex -\u003e String.format(\"web-server %s\", hex))))\n .ami(serverId.keepers().applyValue(keepers -\u003e keepers.amiId()))\n .build());\n\n // ... (other aws_instance arguments) ...\n }\n}\n```\n```yaml\nresources:\n # The following example shows how to generate a unique name for an AWS EC2\n # instance that changes each time a new AMI id is selected.\n serverId:\n type: random:Id\n properties:\n keepers:\n ami_id: ${var.ami_id}\n byteLength: 8\n serverInstance:\n type: aws:ec2:Instance\n properties:\n tags:\n Name: web-server ${serverId.hex}\n # Read the AMI id \"through\" the random_id resource to ensure that\n # # both will change together.\n ami: ${serverId.keepers.amiId}\n```\n\u003c!--End PulumiCodeChooser --\u003e\n\n## Import\n\nRandom IDs can be imported using the b64_url with an optional prefix. This\n\ncan be used to replace a config value with a value interpolated from the\n\nrandom provider without experiencing diffs.\n\nExample with no prefix:\n\n```sh\n$ pulumi import random:index/id:Id server p-9hUg\n```\n\nExample with prefix (prefix is separated by a ,):\n\n```sh\n$ pulumi import random:index/id:Id server my-prefix-,p-9hUg\n```\n\n", "properties": { "b64Std": { "type": "string", @@ -223,7 +223,7 @@ } }, "random:index/integer:Integer": { - "description": "The resource `random.Integer` generates random values from a given range, described by the `min` and `max` attributes of a given resource.\n\nThis resource can be used in conjunction with resources that have the `create_before_destroy` lifecycle flag set, to avoid conflicts with unique names during the brief period where both the old and new resources exist concurrently.\n\n## Example Usage\n\n```terraform\n# The following example shows how to generate a random priority\n# between 1 and 50000 for a aws_alb_listener_rule resource:\n\nresource \"random_integer\" \"priority\" {\n min = 1\n max = 50000\n keepers = {\n # Generate a new integer each time we switch to a new listener ARN\n listener_arn = var.listener_arn\n }\n}\n\nresource \"aws_alb_listener_rule\" \"main\" {\n listener_arn = random_integer.priority.keepers.listener_arn\n priority = random_integer.priority.result\n\n action {\n type = \"forward\"\n target_group_arn = var.target_group_arn\n }\n # ... (other aws_alb_listener_rule arguments) ...\n}\n```\n\n## Import\n\nRandom integers can be imported using the result, min, and max, with an\n\noptional seed. This can be used to replace a config value with a value\n\ninterpolated from the random provider without experiencing diffs.\n\nExample (values are separated by a ,):\n\n```sh\n$ pulumi import random:index/integer:Integer priority 15390,1,50000\n```\n\n", + "description": "The resource `random.Integer` generates random values from a given range, described by the `min` and `max` attributes of a given resource.\n\nThis resource can be used in conjunction with resources that have the `create_before_destroy` lifecycle flag set, to avoid conflicts with unique names during the brief period where both the old and new resources exist concurrently.\n\n## Example Usage\n\n\u003c!--Start PulumiCodeChooser --\u003e\n```typescript\nimport * as pulumi from \"@pulumi/pulumi\";\nimport * as aws from \"@pulumi/aws\";\nimport * as random from \"@pulumi/random\";\n\n// The following example shows how to generate a random priority\n// between 1 and 50000 for a aws_alb_listener_rule resource:\nconst priority = new random.Integer(\"priority\", {\n min: 1,\n max: 50000,\n keepers: {\n listener_arn: _var.listener_arn,\n },\n});\nconst main = new aws.alb.ListenerRule(\"main\", {\n listenerArn: priority.keepers.apply(keepers =\u003e keepers?.listenerArn),\n priority: priority.result,\n actions: [{\n type: \"forward\",\n targetGroupArn: _var.target_group_arn,\n }],\n});\n// ... (other aws_alb_listener_rule arguments) ...\n```\n```python\nimport pulumi\nimport pulumi_aws as aws\nimport pulumi_random as random\n\n# The following example shows how to generate a random priority\n# between 1 and 50000 for a aws_alb_listener_rule resource:\npriority = random.Integer(\"priority\",\n min=1,\n max=50000,\n keepers={\n \"listener_arn\": var[\"listener_arn\"],\n })\nmain = aws.alb.ListenerRule(\"main\",\n listener_arn=priority.keepers[\"listenerArn\"],\n priority=priority.result,\n actions=[{\n \"type\": \"forward\",\n \"target_group_arn\": var[\"target_group_arn\"],\n }])\n# ... (other aws_alb_listener_rule arguments) ...\n```\n```csharp\nusing System.Collections.Generic;\nusing System.Linq;\nusing Pulumi;\nusing Aws = Pulumi.Aws;\nusing Random = Pulumi.Random;\n\nreturn await Deployment.RunAsync(() =\u003e \n{\n // The following example shows how to generate a random priority\n // between 1 and 50000 for a aws_alb_listener_rule resource:\n var priority = new Random.Integer(\"priority\", new()\n {\n Min = 1,\n Max = 50000,\n Keepers = \n {\n { \"listener_arn\", @var.Listener_arn },\n },\n });\n\n var main = new Aws.Alb.ListenerRule(\"main\", new()\n {\n ListenerArn = priority.Keepers.Apply(keepers =\u003e keepers?.ListenerArn),\n Priority = priority.Result,\n Actions = new[]\n {\n new Aws.Alb.Inputs.ListenerRuleActionArgs\n {\n Type = \"forward\",\n TargetGroupArn = @var.Target_group_arn,\n },\n },\n });\n\n // ... (other aws_alb_listener_rule arguments) ...\n});\n```\n```go\npackage main\n\nimport (\n\t\"github.com/pulumi/pulumi-aws/sdk/v6/go/aws/alb\"\n\trandom \"github.com/pulumi/pulumi-terraform-provider/sdks/go/random/v3\"\n\t\"github.com/pulumi/pulumi/sdk/v3/go/pulumi\"\n)\n\nfunc main() {\n\tpulumi.Run(func(ctx *pulumi.Context) error {\n\t\t// The following example shows how to generate a random priority\n\t\t// between 1 and 50000 for a aws_alb_listener_rule resource:\n\t\tpriority, err := random.NewInteger(ctx, \"priority\", \u0026random.IntegerArgs{\n\t\t\tMin: pulumi.Float64(1),\n\t\t\tMax: pulumi.Float64(50000),\n\t\t\tKeepers: pulumi.StringMap{\n\t\t\t\t\"listener_arn\": pulumi.Any(_var.Listener_arn),\n\t\t\t},\n\t\t})\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\t_, err = alb.NewListenerRule(ctx, \"main\", \u0026alb.ListenerRuleArgs{\n\t\t\tListenerArn: pulumi.String(priority.Keepers.ApplyT(func(keepers map[string]string) (*string, error) {\n\t\t\t\treturn \u0026keepers.ListenerArn, nil\n\t\t\t}).(pulumi.StringPtrOutput)),\n\t\t\tPriority: priority.Result,\n\t\t\tActions: alb.ListenerRuleActionArray{\n\t\t\t\t\u0026alb.ListenerRuleActionArgs{\n\t\t\t\t\tType: pulumi.String(\"forward\"),\n\t\t\t\t\tTargetGroupArn: pulumi.Any(_var.Target_group_arn),\n\t\t\t\t},\n\t\t\t},\n\t\t})\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn nil\n\t})\n}\n```\n```java\npackage generated_program;\n\nimport com.pulumi.Context;\nimport com.pulumi.Pulumi;\nimport com.pulumi.core.Output;\nimport com.pulumi.random.Integer;\nimport com.pulumi.random.IntegerArgs;\nimport com.pulumi.aws.alb.ListenerRule;\nimport com.pulumi.aws.alb.ListenerRuleArgs;\nimport com.pulumi.aws.alb.inputs.ListenerRuleActionArgs;\nimport java.util.List;\nimport java.util.ArrayList;\nimport java.util.Map;\nimport java.io.File;\nimport java.nio.file.Files;\nimport java.nio.file.Paths;\n\npublic class App {\n public static void main(String[] args) {\n Pulumi.run(App::stack);\n }\n\n public static void stack(Context ctx) {\n // The following example shows how to generate a random priority\n // between 1 and 50000 for a aws_alb_listener_rule resource:\n var priority = new Integer(\"priority\", IntegerArgs.builder()\n .min(1)\n .max(50000)\n .keepers(Map.of(\"listener_arn\", var_.listener_arn()))\n .build());\n\n var main = new ListenerRule(\"main\", ListenerRuleArgs.builder()\n .listenerArn(priority.keepers().applyValue(keepers -\u003e keepers.listenerArn()))\n .priority(priority.result())\n .actions(ListenerRuleActionArgs.builder()\n .type(\"forward\")\n .targetGroupArn(var_.target_group_arn())\n .build())\n .build());\n\n // ... (other aws_alb_listener_rule arguments) ...\n }\n}\n```\n```yaml\nresources:\n # The following example shows how to generate a random priority\n # between 1 and 50000 for a aws_alb_listener_rule resource:\n priority:\n type: random:Integer\n properties:\n min: 1\n max: 50000\n keepers:\n listener_arn: ${var.listener_arn}\n main:\n type: aws:alb:ListenerRule\n properties:\n listenerArn: ${priority.keepers.listenerArn}\n priority: ${priority.result}\n actions:\n - type: forward\n targetGroupArn: ${var.target_group_arn}\n```\n\u003c!--End PulumiCodeChooser --\u003e\n\n## Import\n\nRandom integers can be imported using the result, min, and max, with an\n\noptional seed. This can be used to replace a config value with a value\n\ninterpolated from the random provider without experiencing diffs.\n\nExample (values are separated by a ,):\n\n```sh\n$ pulumi import random:index/integer:Integer priority 15390,1,50000\n```\n\n", "properties": { "keepers": { "type": "object", @@ -310,7 +310,7 @@ } }, "random:index/password:Password": { - "description": "## Example Usage\n\n```terraform\nresource \"random_password\" \"password\" {\n length = 16\n special = true\n override_special = \"!#$%\u0026*()-_=+[]{}\u003c\u003e:?\"\n}\n\nresource \"aws_db_instance\" \"example\" {\n instance_class = \"db.t3.micro\"\n allocated_storage = 64\n engine = \"mysql\"\n username = \"someone\"\n password = random_password.password.result\n}\n```\n\n## Import\n\n### Avoiding Replacement\n\n```sh\n$ pulumi import random:index/password:Password If the resource were imported using `random_password.password securepassword`,\n```\n\nreplacement could be avoided by using:\n\n1. Attribute values that match the imported ID and defaults:\n\n terraform\n\n resource \"random_password\" \"password\" {\n\n length = 14\n\n lower = true\n\n }\n\n2. Attribute values that match the imported ID and omit the attributes with defaults:\n\n terraform\n\n resource \"random_password\" \"password\" {\n\n length = 14\n\n }\n\n3. `ignore_changes` specifying the attributes to ignore:\n\n terraform\n\n resource \"random_password\" \"password\" {\n\n length = 16\n\n lower = false\n\n lifecycle {\n\n ignore_changes = [\n\n length,\n\n lower,\n\n ]\n\n }\n\n }\n\n **NOTE** `ignore_changes` is only required until the resource is recreated after import,\n\n after which it will use the configuration values specified.\n\n", + "description": "## Example Usage\n\n\u003c!--Start PulumiCodeChooser --\u003e\n```typescript\nimport * as pulumi from \"@pulumi/pulumi\";\nimport * as aws from \"@pulumi/aws\";\nimport * as random from \"@pulumi/random\";\n\nconst password = new random.Password(\"password\", {\n length: 16,\n special: true,\n overrideSpecial: \"!#$%\u0026*()-_=+[]{}\u003c\u003e:?\",\n});\nconst example = new aws.rds.Instance(\"example\", {\n instanceClass: aws.rds.InstanceType.T3_Micro,\n allocatedStorage: 64,\n engine: \"mysql\",\n username: \"someone\",\n password: password.result,\n});\n```\n```python\nimport pulumi\nimport pulumi_aws as aws\nimport pulumi_random as random\n\npassword = random.Password(\"password\",\n length=16,\n special=True,\n override_special=\"!#$%\u0026*()-_=+[]{}\u003c\u003e:?\")\nexample = aws.rds.Instance(\"example\",\n instance_class=aws.rds.InstanceType.T3_MICRO,\n allocated_storage=64,\n engine=\"mysql\",\n username=\"someone\",\n password=password.result)\n```\n```csharp\nusing System.Collections.Generic;\nusing System.Linq;\nusing Pulumi;\nusing Aws = Pulumi.Aws;\nusing Random = Pulumi.Random;\n\nreturn await Deployment.RunAsync(() =\u003e \n{\n var password = new Random.Password(\"password\", new()\n {\n Length = 16,\n Special = true,\n OverrideSpecial = \"!#$%\u0026*()-_=+[]{}\u003c\u003e:?\",\n });\n\n var example = new Aws.Rds.Instance(\"example\", new()\n {\n InstanceClass = Aws.Rds.InstanceType.T3_Micro,\n AllocatedStorage = 64,\n Engine = \"mysql\",\n Username = \"someone\",\n Password = password.Result,\n });\n\n});\n```\n```go\npackage main\n\nimport (\n\t\"github.com/pulumi/pulumi-aws/sdk/v6/go/aws/rds\"\n\trandom \"github.com/pulumi/pulumi-terraform-provider/sdks/go/random/v3\"\n\t\"github.com/pulumi/pulumi/sdk/v3/go/pulumi\"\n)\n\nfunc main() {\n\tpulumi.Run(func(ctx *pulumi.Context) error {\n\t\tpassword, err := random.NewPassword(ctx, \"password\", \u0026random.PasswordArgs{\n\t\t\tLength: pulumi.Float64(16),\n\t\t\tSpecial: pulumi.Bool(true),\n\t\t\tOverrideSpecial: pulumi.String(\"!#$%\u0026*()-_=+[]{}\u003c\u003e:?\"),\n\t\t})\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\t_, err = rds.NewInstance(ctx, \"example\", \u0026rds.InstanceArgs{\n\t\t\tInstanceClass: pulumi.String(rds.InstanceType_T3_Micro),\n\t\t\tAllocatedStorage: pulumi.Int(64),\n\t\t\tEngine: pulumi.String(\"mysql\"),\n\t\t\tUsername: pulumi.String(\"someone\"),\n\t\t\tPassword: password.Result,\n\t\t})\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn nil\n\t})\n}\n```\n```java\npackage generated_program;\n\nimport com.pulumi.Context;\nimport com.pulumi.Pulumi;\nimport com.pulumi.core.Output;\nimport com.pulumi.random.Password;\nimport com.pulumi.random.PasswordArgs;\nimport com.pulumi.aws.rds.Instance;\nimport com.pulumi.aws.rds.InstanceArgs;\nimport java.util.List;\nimport java.util.ArrayList;\nimport java.util.Map;\nimport java.io.File;\nimport java.nio.file.Files;\nimport java.nio.file.Paths;\n\npublic class App {\n public static void main(String[] args) {\n Pulumi.run(App::stack);\n }\n\n public static void stack(Context ctx) {\n var password = new Password(\"password\", PasswordArgs.builder()\n .length(16)\n .special(true)\n .overrideSpecial(\"!#$%\u0026*()-_=+[]{}\u003c\u003e:?\")\n .build());\n\n var example = new Instance(\"example\", InstanceArgs.builder()\n .instanceClass(\"db.t3.micro\")\n .allocatedStorage(64)\n .engine(\"mysql\")\n .username(\"someone\")\n .password(password.result())\n .build());\n\n }\n}\n```\n```yaml\nresources:\n password:\n type: random:Password\n properties:\n length: 16\n special: true\n overrideSpecial: '!#$%\u0026*()-_=+[]{}\u003c\u003e:?'\n example:\n type: aws:rds:Instance\n properties:\n instanceClass: db.t3.micro\n allocatedStorage: 64\n engine: mysql\n username: someone\n password: ${password.result}\n```\n\u003c!--End PulumiCodeChooser --\u003e\n\n## Import\n\n### Avoiding Replacement\n\n```sh\n$ pulumi import random:index/password:Password If the resource were imported using `random_password.password securepassword`,\n```\n\nreplacement could be avoided by using:\n\n1. Attribute values that match the imported ID and defaults:\n\n terraform\n\n resource \"random_password\" \"password\" {\n\n length = 14\n\n lower = true\n\n }\n\n2. Attribute values that match the imported ID and omit the attributes with defaults:\n\n terraform\n\n resource \"random_password\" \"password\" {\n\n length = 14\n\n }\n\n3. `ignore_changes` specifying the attributes to ignore:\n\n terraform\n\n resource \"random_password\" \"password\" {\n\n length = 16\n\n lower = false\n\n lifecycle {\n\n ignore_changes = [\n\n length,\n\n lower,\n\n ]\n\n }\n\n }\n\n **NOTE** `ignore_changes` is only required until the resource is recreated after import,\n\n after which it will use the configuration values specified.\n\n", "properties": { "bcryptHash": { "type": "string", @@ -516,7 +516,7 @@ } }, "random:index/pet:Pet": { - "description": "The resource `random.Pet` generates random pet names that are intended to be used as unique identifiers for other resources.\n\nThis resource can be used in conjunction with resources that have the `create_before_destroy` lifecycle flag set, to avoid conflicts with unique names during the brief period where both the old and new resources exist concurrently.\n\n## Example Usage\n\n```terraform\n# The following example shows how to generate a unique pet name\n# for an AWS EC2 instance that changes each time a new AMI id is\n# selected.\n\nresource \"random_pet\" \"server\" {\n keepers = {\n # Generate a new pet name each time we switch to a new AMI id\n ami_id = var.ami_id\n }\n}\n\nresource \"aws_instance\" \"server\" {\n tags = {\n Name = \"web-server-${random_pet.server.id}\"\n }\n\n # Read the AMI id \"through\" the random_pet resource to ensure that\n # both will change together.\n ami = random_pet.server.keepers.ami_id\n\n # ... (other aws_instance arguments) ...\n}\n```\n", + "description": "The resource `random.Pet` generates random pet names that are intended to be used as unique identifiers for other resources.\n\nThis resource can be used in conjunction with resources that have the `create_before_destroy` lifecycle flag set, to avoid conflicts with unique names during the brief period where both the old and new resources exist concurrently.\n\n## Example Usage\n\n\u003c!--Start PulumiCodeChooser --\u003e\n```typescript\nimport * as pulumi from \"@pulumi/pulumi\";\nimport * as aws from \"@pulumi/aws\";\nimport * as random from \"@pulumi/random\";\n\n// The following example shows how to generate a unique pet name\n// for an AWS EC2 instance that changes each time a new AMI id is\n// selected.\nconst serverPet = new random.Pet(\"serverPet\", {keepers: {\n ami_id: _var.ami_id,\n}});\nconst serverInstance = new aws.ec2.Instance(\"serverInstance\", {\n tags: {\n Name: pulumi.interpolate`web-server-${serverPet.id}`,\n },\n ami: serverPet.keepers.apply(keepers =\u003e keepers?.amiId),\n});\n// ... (other aws_instance arguments) ...\n```\n```python\nimport pulumi\nimport pulumi_aws as aws\nimport pulumi_random as random\n\n# The following example shows how to generate a unique pet name\n# for an AWS EC2 instance that changes each time a new AMI id is\n# selected.\nserver_pet = random.Pet(\"serverPet\", keepers={\n \"ami_id\": var[\"ami_id\"],\n})\nserver_instance = aws.ec2.Instance(\"serverInstance\",\n tags={\n \"Name\": server_pet.id.apply(lambda id: f\"web-server-{id}\"),\n },\n ami=server_pet.keepers[\"amiId\"])\n# ... (other aws_instance arguments) ...\n```\n```csharp\nusing System.Collections.Generic;\nusing System.Linq;\nusing Pulumi;\nusing Aws = Pulumi.Aws;\nusing Random = Pulumi.Random;\n\nreturn await Deployment.RunAsync(() =\u003e \n{\n // The following example shows how to generate a unique pet name\n // for an AWS EC2 instance that changes each time a new AMI id is\n // selected.\n var serverPet = new Random.Pet(\"serverPet\", new()\n {\n Keepers = \n {\n { \"ami_id\", @var.Ami_id },\n },\n });\n\n var serverInstance = new Aws.Ec2.Instance(\"serverInstance\", new()\n {\n Tags = \n {\n { \"Name\", serverPet.Id.Apply(id =\u003e $\"web-server-{id}\") },\n },\n Ami = serverPet.Keepers.Apply(keepers =\u003e keepers?.AmiId),\n });\n\n // ... (other aws_instance arguments) ...\n});\n```\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/pulumi/pulumi-aws/sdk/v6/go/aws/ec2\"\n\trandom \"github.com/pulumi/pulumi-terraform-provider/sdks/go/random/v3\"\n\t\"github.com/pulumi/pulumi/sdk/v3/go/pulumi\"\n)\n\nfunc main() {\n\tpulumi.Run(func(ctx *pulumi.Context) error {\n\t\t// The following example shows how to generate a unique pet name\n\t\t// for an AWS EC2 instance that changes each time a new AMI id is\n\t\t// selected.\n\t\tserverPet, err := random.NewPet(ctx, \"serverPet\", \u0026random.PetArgs{\n\t\t\tKeepers: pulumi.StringMap{\n\t\t\t\t\"ami_id\": pulumi.Any(_var.Ami_id),\n\t\t\t},\n\t\t})\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\t_, err = ec2.NewInstance(ctx, \"serverInstance\", \u0026ec2.InstanceArgs{\n\t\t\tTags: pulumi.StringMap{\n\t\t\t\t\"Name\": serverPet.ID().ApplyT(func(id string) (string, error) {\n\t\t\t\t\treturn fmt.Sprintf(\"web-server-%v\", id), nil\n\t\t\t\t}).(pulumi.StringOutput),\n\t\t\t},\n\t\t\tAmi: pulumi.String(serverPet.Keepers.ApplyT(func(keepers map[string]string) (*string, error) {\n\t\t\t\treturn \u0026keepers.AmiId, nil\n\t\t\t}).(pulumi.StringPtrOutput)),\n\t\t})\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn nil\n\t})\n}\n```\n```java\npackage generated_program;\n\nimport com.pulumi.Context;\nimport com.pulumi.Pulumi;\nimport com.pulumi.core.Output;\nimport com.pulumi.random.Pet;\nimport com.pulumi.random.PetArgs;\nimport com.pulumi.aws.ec2.Instance;\nimport com.pulumi.aws.ec2.InstanceArgs;\nimport java.util.List;\nimport java.util.ArrayList;\nimport java.util.Map;\nimport java.io.File;\nimport java.nio.file.Files;\nimport java.nio.file.Paths;\n\npublic class App {\n public static void main(String[] args) {\n Pulumi.run(App::stack);\n }\n\n public static void stack(Context ctx) {\n // The following example shows how to generate a unique pet name\n // for an AWS EC2 instance that changes each time a new AMI id is\n // selected.\n var serverPet = new Pet(\"serverPet\", PetArgs.builder()\n .keepers(Map.of(\"ami_id\", var_.ami_id()))\n .build());\n\n var serverInstance = new Instance(\"serverInstance\", InstanceArgs.builder()\n .tags(Map.of(\"Name\", serverPet.id().applyValue(id -\u003e String.format(\"web-server-%s\", id))))\n .ami(serverPet.keepers().applyValue(keepers -\u003e keepers.amiId()))\n .build());\n\n // ... (other aws_instance arguments) ...\n }\n}\n```\n```yaml\nresources:\n # The following example shows how to generate a unique pet name\n # for an AWS EC2 instance that changes each time a new AMI id is\n # selected.\n serverPet:\n type: random:Pet\n properties:\n keepers:\n ami_id: ${var.ami_id}\n serverInstance:\n type: aws:ec2:Instance\n properties:\n tags:\n Name: web-server-${serverPet.id}\n # Read the AMI id \"through\" the random_pet resource to ensure that\n # # both will change together.\n ami: ${serverPet.keepers.amiId}\n```\n\u003c!--End PulumiCodeChooser --\u003e\n", "properties": { "keepers": { "type": "object", @@ -590,7 +590,7 @@ } }, "random:index/shuffle:Shuffle": { - "description": "The resource `random.Shuffle` generates a random permutation of a list of strings given as an argument.\n\n## Example Usage\n\n```terraform\nresource \"random_shuffle\" \"az\" {\n input = [\"us-west-1a\", \"us-west-1c\", \"us-west-1d\", \"us-west-1e\"]\n result_count = 2\n}\n\nresource \"aws_elb\" \"example\" {\n # Place the ELB in any two of the given availability zones, selected\n # at random.\n availability_zones = random_shuffle.az.result\n\n # ... and other aws_elb arguments ...\n}\n```\n", + "description": "The resource `random.Shuffle` generates a random permutation of a list of strings given as an argument.\n\n## Example Usage\n\n\u003c!--Start PulumiCodeChooser --\u003e\n```typescript\nimport * as pulumi from \"@pulumi/pulumi\";\nimport * as aws from \"@pulumi/aws\";\nimport * as random from \"@pulumi/random\";\n\nconst az = new random.Shuffle(\"az\", {\n inputs: [\n \"us-west-1a\",\n \"us-west-1c\",\n \"us-west-1d\",\n \"us-west-1e\",\n ],\n resultCount: 2,\n});\nconst example = new aws.elb.LoadBalancer(\"example\", {availabilityZones: az.results});\n// ... and other aws_elb arguments ...\n```\n```python\nimport pulumi\nimport pulumi_aws as aws\nimport pulumi_random as random\n\naz = random.Shuffle(\"az\",\n inputs=[\n \"us-west-1a\",\n \"us-west-1c\",\n \"us-west-1d\",\n \"us-west-1e\",\n ],\n result_count=2)\nexample = aws.elb.LoadBalancer(\"example\", availability_zones=az.results)\n# ... and other aws_elb arguments ...\n```\n```csharp\nusing System.Collections.Generic;\nusing System.Linq;\nusing Pulumi;\nusing Aws = Pulumi.Aws;\nusing Random = Pulumi.Random;\n\nreturn await Deployment.RunAsync(() =\u003e \n{\n var az = new Random.Shuffle(\"az\", new()\n {\n Inputs = new[]\n {\n \"us-west-1a\",\n \"us-west-1c\",\n \"us-west-1d\",\n \"us-west-1e\",\n },\n ResultCount = 2,\n });\n\n var example = new Aws.Elb.LoadBalancer(\"example\", new()\n {\n AvailabilityZones = az.Results,\n });\n\n // ... and other aws_elb arguments ...\n});\n```\n```go\npackage main\n\nimport (\n\t\"github.com/pulumi/pulumi-aws/sdk/v6/go/aws/elb\"\n\trandom \"github.com/pulumi/pulumi-terraform-provider/sdks/go/random/v3\"\n\t\"github.com/pulumi/pulumi/sdk/v3/go/pulumi\"\n)\n\nfunc main() {\n\tpulumi.Run(func(ctx *pulumi.Context) error {\n\t\taz, err := random.NewShuffle(ctx, \"az\", \u0026random.ShuffleArgs{\n\t\t\tInputs: pulumi.StringArray{\n\t\t\t\tpulumi.String(\"us-west-1a\"),\n\t\t\t\tpulumi.String(\"us-west-1c\"),\n\t\t\t\tpulumi.String(\"us-west-1d\"),\n\t\t\t\tpulumi.String(\"us-west-1e\"),\n\t\t\t},\n\t\t\tResultCount: pulumi.Float64(2),\n\t\t})\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\t_, err = elb.NewLoadBalancer(ctx, \"example\", \u0026elb.LoadBalancerArgs{\n\t\t\tAvailabilityZones: az.Results,\n\t\t})\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn nil\n\t})\n}\n```\n```java\npackage generated_program;\n\nimport com.pulumi.Context;\nimport com.pulumi.Pulumi;\nimport com.pulumi.core.Output;\nimport com.pulumi.random.Shuffle;\nimport com.pulumi.random.ShuffleArgs;\nimport com.pulumi.aws.elb.LoadBalancer;\nimport com.pulumi.aws.elb.LoadBalancerArgs;\nimport java.util.List;\nimport java.util.ArrayList;\nimport java.util.Map;\nimport java.io.File;\nimport java.nio.file.Files;\nimport java.nio.file.Paths;\n\npublic class App {\n public static void main(String[] args) {\n Pulumi.run(App::stack);\n }\n\n public static void stack(Context ctx) {\n var az = new Shuffle(\"az\", ShuffleArgs.builder()\n .inputs( \n \"us-west-1a\",\n \"us-west-1c\",\n \"us-west-1d\",\n \"us-west-1e\")\n .resultCount(2)\n .build());\n\n var example = new LoadBalancer(\"example\", LoadBalancerArgs.builder()\n .availabilityZones(az.results())\n .build());\n\n // ... and other aws_elb arguments ...\n }\n}\n```\n```yaml\nresources:\n az:\n type: random:Shuffle\n properties:\n inputs:\n - us-west-1a\n - us-west-1c\n - us-west-1d\n - us-west-1e\n resultCount: 2\n example:\n type: aws:elb:LoadBalancer\n properties:\n # Place the ELB in any two of the given availability zones, selected\n # # at random.\n availabilityZones: ${az.results}\n```\n\u003c!--End PulumiCodeChooser --\u003e\n", "properties": { "inputs": { "type": "array", @@ -690,7 +690,7 @@ } }, "random:index/string:String": { - "description": "The resource `random.String` generates a random permutation of alphanumeric characters and optionally special characters.\n\nThis resource *does* use a cryptographic random number generator.\n\nHistorically this resource's intended usage has been ambiguous as the original example used it in a password. For backwards compatibility it will continue to exist. For unique ids please use random_id, for sensitive random values please use random_password.\n\n## Example Usage\n\n```terraform\nresource \"random_string\" \"random\" {\n length = 16\n special = true\n override_special = \"/@£$\"\n}\n```\n\n## Import\n\n### Avoiding Replacement\n\n```sh\n$ pulumi import random:index/string:String If the resource were imported using `random_string.test test`,\n```\n\nreplacement can be avoided by using:\n\n1. Attribute values that match the imported ID and defaults:\n\n terraform\n\n resource \"random_string\" \"test\" {\n\n length = 4\n\n lower = true\n\n }\n\n2. Attribute values that match the imported ID and omit the attributes with defaults:\n\n terraform\n\n resource \"random_string\" \"test\" {\n\n length = 4\n\n }\n\n3. `ignore_changes` specifying the attributes to ignore:\n\n terraform\n\n resource \"random_string\" \"test\" {\n\n length = 16\n\n lower = false\n\n lifecycle {\n\n ignore_changes = [\n\n length,\n\n lower,\n\n ]\n\n }\n\n }\n\n **NOTE** `ignore_changes` is only required until the resource is recreated after import,\n\n after which it will use the configuration values specified.\n\n", + "description": "The resource `random.String` generates a random permutation of alphanumeric characters and optionally special characters.\n\nThis resource *does* use a cryptographic random number generator.\n\nHistorically this resource's intended usage has been ambiguous as the original example used it in a password. For backwards compatibility it will continue to exist. For unique ids please use random_id, for sensitive random values please use random_password.\n\n## Example Usage\n\n\u003c!--Start PulumiCodeChooser --\u003e\n```typescript\nimport * as pulumi from \"@pulumi/pulumi\";\nimport * as random from \"@pulumi/random\";\n\nconst random = new random.String(\"random\", {\n length: 16,\n overrideSpecial: \"/@£$\",\n special: true,\n});\n```\n```python\nimport pulumi\nimport pulumi_random as random\n\nrandom = random.String(\"random\",\n length=16,\n override_special=\"/@£$\",\n special=True)\n```\n```csharp\nusing System.Collections.Generic;\nusing System.Linq;\nusing Pulumi;\nusing Random = Pulumi.Random;\n\nreturn await Deployment.RunAsync(() =\u003e \n{\n var random = new Random.String(\"random\", new()\n {\n Length = 16,\n OverrideSpecial = \"/@£$\",\n Special = true,\n });\n\n});\n```\n```go\npackage main\n\nimport (\n\trandom \"github.com/pulumi/pulumi-terraform-provider/sdks/go/random/v3\"\n\t\"github.com/pulumi/pulumi/sdk/v3/go/pulumi\"\n)\n\nfunc main() {\n\tpulumi.Run(func(ctx *pulumi.Context) error {\n\t\t_, err := random.NewString(ctx, \"random\", \u0026random.StringArgs{\n\t\t\tLength: pulumi.Float64(16),\n\t\t\tOverrideSpecial: pulumi.String(\"/@£$\"),\n\t\t\tSpecial: pulumi.Bool(true),\n\t\t})\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn nil\n\t})\n}\n```\n```java\npackage generated_program;\n\nimport com.pulumi.Context;\nimport com.pulumi.Pulumi;\nimport com.pulumi.core.Output;\nimport com.pulumi.random.String;\nimport com.pulumi.random.StringArgs;\nimport java.util.List;\nimport java.util.ArrayList;\nimport java.util.Map;\nimport java.io.File;\nimport java.nio.file.Files;\nimport java.nio.file.Paths;\n\npublic class App {\n public static void main(String[] args) {\n Pulumi.run(App::stack);\n }\n\n public static void stack(Context ctx) {\n var random = new String(\"random\", StringArgs.builder()\n .length(16)\n .overrideSpecial(\"/@£$\")\n .special(true)\n .build());\n\n }\n}\n```\n```yaml\nresources:\n random:\n type: random:String\n properties:\n length: 16\n overrideSpecial: /@£$\n special: true\n```\n\u003c!--End PulumiCodeChooser --\u003e\n\n## Import\n\n### Avoiding Replacement\n\n```sh\n$ pulumi import random:index/string:String If the resource were imported using `random_string.test test`,\n```\n\nreplacement can be avoided by using:\n\n1. Attribute values that match the imported ID and defaults:\n\n terraform\n\n resource \"random_string\" \"test\" {\n\n length = 4\n\n lower = true\n\n }\n\n2. Attribute values that match the imported ID and omit the attributes with defaults:\n\n terraform\n\n resource \"random_string\" \"test\" {\n\n length = 4\n\n }\n\n3. `ignore_changes` specifying the attributes to ignore:\n\n terraform\n\n resource \"random_string\" \"test\" {\n\n length = 16\n\n lower = false\n\n lifecycle {\n\n ignore_changes = [\n\n length,\n\n lower,\n\n ]\n\n }\n\n }\n\n **NOTE** `ignore_changes` is only required until the resource is recreated after import,\n\n after which it will use the configuration values specified.\n\n", "properties": { "keepers": { "type": "object", @@ -883,7 +883,7 @@ } }, "random:index/uuid:Uuid": { - "description": "## Example Usage\n\n```terraform\n# The following example shows how to generate a unique name for an Azure Resource Group.\n\nresource \"random_uuid\" \"test\" {\n}\n\nresource \"azurerm_resource_group\" \"test\" {\n name = \"${random_uuid.test.result}-rg\"\n location = \"Central US\"\n}\n```\n\n## Import\n\nRandom UUID's can be imported. This can be used to replace a config\n\nvalue with a value interpolated from the random provider without\n\nexperiencing diffs.\n\n```sh\n$ pulumi import random:index/uuid:Uuid main aabbccdd-eeff-0011-2233-445566778899\n```\n\n", + "description": "## Example Usage\n\n\u003c!--Start PulumiCodeChooser --\u003e\n```typescript\nimport * as pulumi from \"@pulumi/pulumi\";\nimport * as azurerm from \"@pulumi/azurerm\";\nimport * as random from \"@pulumi/random\";\n\n// The following example shows how to generate a unique name for an Azure Resource Group.\nconst testUuid = new random.Uuid(\"testUuid\", {});\nconst testazurerm_resource_group = new azurerm.index.Azurerm_resource_group(\"testazurerm_resource_group\", {\n name: `${testUuid.result}-rg`,\n location: \"Central US\",\n});\n```\n```python\nimport pulumi\nimport pulumi_azurerm as azurerm\nimport pulumi_random as random\n\n# The following example shows how to generate a unique name for an Azure Resource Group.\ntest_uuid = random.Uuid(\"testUuid\")\ntestazurerm_resource_group = azurerm.index.Azurerm_resource_group(\"testazurerm_resource_group\",\n name=f{test_uuid.result}-rg,\n location=Central US)\n```\n```csharp\nusing System.Collections.Generic;\nusing System.Linq;\nusing Pulumi;\nusing Azurerm = Pulumi.Azurerm;\nusing Random = Pulumi.Random;\n\nreturn await Deployment.RunAsync(() =\u003e \n{\n // The following example shows how to generate a unique name for an Azure Resource Group.\n var testUuid = new Random.Uuid(\"testUuid\");\n\n var testazurerm_resource_group = new Azurerm.Index.Azurerm_resource_group(\"testazurerm_resource_group\", new()\n {\n Name = $\"{testUuid.Result}-rg\",\n Location = \"Central US\",\n });\n\n});\n```\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/pulumi/pulumi-azurerm/sdk/go/azurerm\"\n\trandom \"github.com/pulumi/pulumi-terraform-provider/sdks/go/random/v3\"\n\t\"github.com/pulumi/pulumi/sdk/v3/go/pulumi\"\n)\n\nfunc main() {\n\tpulumi.Run(func(ctx *pulumi.Context) error {\n\t\t// The following example shows how to generate a unique name for an Azure Resource Group.\n\t\ttestUuid, err := random.NewUuid(ctx, \"testUuid\", nil)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\t_, err = azurerm.NewAzurerm_resource_group(ctx, \"testazurerm_resource_group\", \u0026azurerm.Azurerm_resource_groupArgs{\n\t\t\tName: pulumi.Sprintf(\"%v-rg\", testUuid.Result),\n\t\t\tLocation: \"Central US\",\n\t\t})\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn nil\n\t})\n}\n```\n```java\npackage generated_program;\n\nimport com.pulumi.Context;\nimport com.pulumi.Pulumi;\nimport com.pulumi.core.Output;\nimport com.pulumi.random.Uuid;\nimport com.pulumi.azurerm.azurerm_resource_group;\nimport com.pulumi.azurerm.Azurerm_resource_groupArgs;\nimport java.util.List;\nimport java.util.ArrayList;\nimport java.util.Map;\nimport java.io.File;\nimport java.nio.file.Files;\nimport java.nio.file.Paths;\n\npublic class App {\n public static void main(String[] args) {\n Pulumi.run(App::stack);\n }\n\n public static void stack(Context ctx) {\n // The following example shows how to generate a unique name for an Azure Resource Group.\n var testUuid = new Uuid(\"testUuid\");\n\n var testazurerm_resource_group = new Azurerm_resource_group(\"testazurerm_resource_group\", Azurerm_resource_groupArgs.builder()\n .name(String.format(\"%s-rg\", testUuid.result()))\n .location(\"Central US\")\n .build());\n\n }\n}\n```\n```yaml\nresources:\n # The following example shows how to generate a unique name for an Azure Resource Group.\n testUuid:\n type: random:Uuid\n testazurerm_resource_group:\n type: azurerm:azurerm_resource_group\n properties:\n name: ${testUuid.result}-rg\n location: Central US\n```\n\u003c!--End PulumiCodeChooser --\u003e\n\n## Import\n\nRandom UUID's can be imported. This can be used to replace a config\n\nvalue with a value interpolated from the random provider without\n\nexperiencing diffs.\n\n```sh\n$ pulumi import random:index/uuid:Uuid main aabbccdd-eeff-0011-2233-445566778899\n```\n\n", "properties": { "keepers": { "type": "object", diff --git a/internal/testprovider_sdkv2/cmd/pulumi-resource-tpsdkv2/schema.json b/internal/testprovider_sdkv2/cmd/pulumi-resource-tpsdkv2/schema.json index 40a76cabf..a2325fbc0 100644 --- a/internal/testprovider_sdkv2/cmd/pulumi-resource-tpsdkv2/schema.json +++ b/internal/testprovider_sdkv2/cmd/pulumi-resource-tpsdkv2/schema.json @@ -6,12 +6,12 @@ }, "language": { "nodejs": { - "readme": "\u003e This provider is a derived work of the [Terraform Provider](https://github.com/terraform-providers/terraform-provider-tpsdkv2)\n\u003e distributed under [MPL 2.0](https://www.mozilla.org/en-US/MPL/2.0/). If you encounter a bug or missing feature,\n\u003e first check the [`pulumi-tpsdkv2` repo](/issues); however, if that doesn't turn up anything,\n\u003e please consult the source [`terraform-provider-tpsdkv2` repo](https://github.com/terraform-providers/terraform-provider-tpsdkv2/issues).", + "readme": "\u003e This provider is a derived work of the [Terraform Provider](https://github.com/terraform-providers/terraform-provider-tpsdkv2)\n\u003e distributed under [MPL 2.0](https://www.mozilla.org/en-US/MPL/2.0/). If you encounter a bug or missing feature,\n\u003e please consult the source [`terraform-provider-tpsdkv2` repo](https://github.com/terraform-providers/terraform-provider-tpsdkv2/issues).", "compatibility": "tfbridge20", "disableUnionOutputTypes": true }, "python": { - "readme": "\u003e This provider is a derived work of the [Terraform Provider](https://github.com/terraform-providers/terraform-provider-tpsdkv2)\n\u003e distributed under [MPL 2.0](https://www.mozilla.org/en-US/MPL/2.0/). If you encounter a bug or missing feature,\n\u003e first check the [`pulumi-tpsdkv2` repo](/issues); however, if that doesn't turn up anything,\n\u003e please consult the source [`terraform-provider-tpsdkv2` repo](https://github.com/terraform-providers/terraform-provider-tpsdkv2/issues).", + "readme": "\u003e This provider is a derived work of the [Terraform Provider](https://github.com/terraform-providers/terraform-provider-tpsdkv2)\n\u003e distributed under [MPL 2.0](https://www.mozilla.org/en-US/MPL/2.0/). If you encounter a bug or missing feature,\n\u003e please consult the source [`terraform-provider-tpsdkv2` repo](https://github.com/terraform-providers/terraform-provider-tpsdkv2/issues).", "compatibility": "tfbridge20", "pyproject": {} } diff --git a/pkg/tf2pulumi/convert/testdata/schemas/blocks.json b/pkg/tf2pulumi/convert/testdata/schemas/blocks.json index 12f40109f..7f7ebdb1b 100644 --- a/pkg/tf2pulumi/convert/testdata/schemas/blocks.json +++ b/pkg/tf2pulumi/convert/testdata/schemas/blocks.json @@ -1,17 +1,18 @@ { "name": "blocks", "attribution": "This Pulumi package is based on the [`blocks` Terraform Provider](https://github.com/terraform-providers/terraform-provider-blocks).", + "repository": "https://github.com/pulumi/pulumi-blocks", "meta": { "moduleFormat": "(.*)(?:/[^/]*)" }, "language": { "nodejs": { - "readme": "\u003e This provider is a derived work of the [Terraform Provider](https://github.com/terraform-providers/terraform-provider-blocks)\n\u003e distributed under [MPL 2.0](https://www.mozilla.org/en-US/MPL/2.0/). If you encounter a bug or missing feature,\n\u003e first check the [`pulumi-blocks` repo](/issues); however, if that doesn't turn up anything,\n\u003e please consult the source [`terraform-provider-blocks` repo](https://github.com/terraform-providers/terraform-provider-blocks/issues).", + "readme": "\u003e This provider is a derived work of the [Terraform Provider](https://github.com/terraform-providers/terraform-provider-blocks)\n\u003e distributed under [MPL 2.0](https://www.mozilla.org/en-US/MPL/2.0/). If you encounter a bug or missing feature,\n\u003e first check the [`pulumi-blocks` repo](https://github.com/pulumi/pulumi-blocks/issues); however, if that doesn't turn up anything,\n\u003e please consult the source [`terraform-provider-blocks` repo](https://github.com/terraform-providers/terraform-provider-blocks/issues).", "compatibility": "tfbridge20", "disableUnionOutputTypes": true }, "python": { - "readme": "\u003e This provider is a derived work of the [Terraform Provider](https://github.com/terraform-providers/terraform-provider-blocks)\n\u003e distributed under [MPL 2.0](https://www.mozilla.org/en-US/MPL/2.0/). If you encounter a bug or missing feature,\n\u003e first check the [`pulumi-blocks` repo](/issues); however, if that doesn't turn up anything,\n\u003e please consult the source [`terraform-provider-blocks` repo](https://github.com/terraform-providers/terraform-provider-blocks/issues).", + "readme": "\u003e This provider is a derived work of the [Terraform Provider](https://github.com/terraform-providers/terraform-provider-blocks)\n\u003e distributed under [MPL 2.0](https://www.mozilla.org/en-US/MPL/2.0/). If you encounter a bug or missing feature,\n\u003e first check the [`pulumi-blocks` repo](https://github.com/pulumi/pulumi-blocks/issues); however, if that doesn't turn up anything,\n\u003e please consult the source [`terraform-provider-blocks` repo](https://github.com/terraform-providers/terraform-provider-blocks/issues).", "compatibility": "tfbridge20", "pyproject": {} } diff --git a/pkg/tf2pulumi/convert/testdata/schemas/complex.json b/pkg/tf2pulumi/convert/testdata/schemas/complex.json index 7a1996854..5c5adaf33 100644 --- a/pkg/tf2pulumi/convert/testdata/schemas/complex.json +++ b/pkg/tf2pulumi/convert/testdata/schemas/complex.json @@ -1,17 +1,18 @@ { "name": "complex", "attribution": "This Pulumi package is based on the [`complex` Terraform Provider](https://github.com/terraform-providers/terraform-provider-complex).", + "repository": "https://github.com/pulumi/pulumi-complex", "meta": { "moduleFormat": "(.*)(?:/[^/]*)" }, "language": { "nodejs": { - "readme": "\u003e This provider is a derived work of the [Terraform Provider](https://github.com/terraform-providers/terraform-provider-complex)\n\u003e distributed under [MPL 2.0](https://www.mozilla.org/en-US/MPL/2.0/). If you encounter a bug or missing feature,\n\u003e first check the [`pulumi-complex` repo](/issues); however, if that doesn't turn up anything,\n\u003e please consult the source [`terraform-provider-complex` repo](https://github.com/terraform-providers/terraform-provider-complex/issues).", + "readme": "\u003e This provider is a derived work of the [Terraform Provider](https://github.com/terraform-providers/terraform-provider-complex)\n\u003e distributed under [MPL 2.0](https://www.mozilla.org/en-US/MPL/2.0/). If you encounter a bug or missing feature,\n\u003e first check the [`pulumi-complex` repo](https://github.com/pulumi/pulumi-complex/issues); however, if that doesn't turn up anything,\n\u003e please consult the source [`terraform-provider-complex` repo](https://github.com/terraform-providers/terraform-provider-complex/issues).", "compatibility": "tfbridge20", "disableUnionOutputTypes": true }, "python": { - "readme": "\u003e This provider is a derived work of the [Terraform Provider](https://github.com/terraform-providers/terraform-provider-complex)\n\u003e distributed under [MPL 2.0](https://www.mozilla.org/en-US/MPL/2.0/). If you encounter a bug or missing feature,\n\u003e first check the [`pulumi-complex` repo](/issues); however, if that doesn't turn up anything,\n\u003e please consult the source [`terraform-provider-complex` repo](https://github.com/terraform-providers/terraform-provider-complex/issues).", + "readme": "\u003e This provider is a derived work of the [Terraform Provider](https://github.com/terraform-providers/terraform-provider-complex)\n\u003e distributed under [MPL 2.0](https://www.mozilla.org/en-US/MPL/2.0/). If you encounter a bug or missing feature,\n\u003e first check the [`pulumi-complex` repo](https://github.com/pulumi/pulumi-complex/issues); however, if that doesn't turn up anything,\n\u003e please consult the source [`terraform-provider-complex` repo](https://github.com/terraform-providers/terraform-provider-complex/issues).", "compatibility": "tfbridge20", "pyproject": {} } diff --git a/pkg/tf2pulumi/convert/testdata/schemas/renames.json b/pkg/tf2pulumi/convert/testdata/schemas/renames.json index d600f0ae2..679fcd24b 100644 --- a/pkg/tf2pulumi/convert/testdata/schemas/renames.json +++ b/pkg/tf2pulumi/convert/testdata/schemas/renames.json @@ -1,17 +1,18 @@ { "name": "renames", "attribution": "This Pulumi package is based on the [`renames` Terraform Provider](https://github.com/terraform-providers/terraform-provider-renames).", + "repository": "https://github.com/pulumi/pulumi-renames", "meta": { "moduleFormat": "(.*)(?:/[^/]*)" }, "language": { "nodejs": { - "readme": "\u003e This provider is a derived work of the [Terraform Provider](https://github.com/terraform-providers/terraform-provider-renames)\n\u003e distributed under [MPL 2.0](https://www.mozilla.org/en-US/MPL/2.0/). If you encounter a bug or missing feature,\n\u003e first check the [`pulumi-renames` repo](/issues); however, if that doesn't turn up anything,\n\u003e please consult the source [`terraform-provider-renames` repo](https://github.com/terraform-providers/terraform-provider-renames/issues).", + "readme": "\u003e This provider is a derived work of the [Terraform Provider](https://github.com/terraform-providers/terraform-provider-renames)\n\u003e distributed under [MPL 2.0](https://www.mozilla.org/en-US/MPL/2.0/). If you encounter a bug or missing feature,\n\u003e first check the [`pulumi-renames` repo](https://github.com/pulumi/pulumi-renames/issues); however, if that doesn't turn up anything,\n\u003e please consult the source [`terraform-provider-renames` repo](https://github.com/terraform-providers/terraform-provider-renames/issues).", "compatibility": "tfbridge20", "disableUnionOutputTypes": true }, "python": { - "readme": "\u003e This provider is a derived work of the [Terraform Provider](https://github.com/terraform-providers/terraform-provider-renames)\n\u003e distributed under [MPL 2.0](https://www.mozilla.org/en-US/MPL/2.0/). If you encounter a bug or missing feature,\n\u003e first check the [`pulumi-renames` repo](/issues); however, if that doesn't turn up anything,\n\u003e please consult the source [`terraform-provider-renames` repo](https://github.com/terraform-providers/terraform-provider-renames/issues).", + "readme": "\u003e This provider is a derived work of the [Terraform Provider](https://github.com/terraform-providers/terraform-provider-renames)\n\u003e distributed under [MPL 2.0](https://www.mozilla.org/en-US/MPL/2.0/). If you encounter a bug or missing feature,\n\u003e first check the [`pulumi-renames` repo](https://github.com/pulumi/pulumi-renames/issues); however, if that doesn't turn up anything,\n\u003e please consult the source [`terraform-provider-renames` repo](https://github.com/terraform-providers/terraform-provider-renames/issues).", "compatibility": "tfbridge20", "pyproject": {} } diff --git a/pkg/tf2pulumi/convert/testdata/schemas/simple.json b/pkg/tf2pulumi/convert/testdata/schemas/simple.json index 1b3a13fde..bda221e9c 100644 --- a/pkg/tf2pulumi/convert/testdata/schemas/simple.json +++ b/pkg/tf2pulumi/convert/testdata/schemas/simple.json @@ -1,17 +1,18 @@ { "name": "simple", "attribution": "This Pulumi package is based on the [`simple` Terraform Provider](https://github.com/terraform-providers/terraform-provider-simple).", + "repository": "https://github.com/pulumi/pulumi-simple", "meta": { "moduleFormat": "(.*)(?:/[^/]*)" }, "language": { "nodejs": { - "readme": "\u003e This provider is a derived work of the [Terraform Provider](https://github.com/terraform-providers/terraform-provider-simple)\n\u003e distributed under [MPL 2.0](https://www.mozilla.org/en-US/MPL/2.0/). If you encounter a bug or missing feature,\n\u003e first check the [`pulumi-simple` repo](/issues); however, if that doesn't turn up anything,\n\u003e please consult the source [`terraform-provider-simple` repo](https://github.com/terraform-providers/terraform-provider-simple/issues).", + "readme": "\u003e This provider is a derived work of the [Terraform Provider](https://github.com/terraform-providers/terraform-provider-simple)\n\u003e distributed under [MPL 2.0](https://www.mozilla.org/en-US/MPL/2.0/). If you encounter a bug or missing feature,\n\u003e first check the [`pulumi-simple` repo](https://github.com/pulumi/pulumi-simple/issues); however, if that doesn't turn up anything,\n\u003e please consult the source [`terraform-provider-simple` repo](https://github.com/terraform-providers/terraform-provider-simple/issues).", "compatibility": "tfbridge20", "disableUnionOutputTypes": true }, "python": { - "readme": "\u003e This provider is a derived work of the [Terraform Provider](https://github.com/terraform-providers/terraform-provider-simple)\n\u003e distributed under [MPL 2.0](https://www.mozilla.org/en-US/MPL/2.0/). If you encounter a bug or missing feature,\n\u003e first check the [`pulumi-simple` repo](/issues); however, if that doesn't turn up anything,\n\u003e please consult the source [`terraform-provider-simple` repo](https://github.com/terraform-providers/terraform-provider-simple/issues).", + "readme": "\u003e This provider is a derived work of the [Terraform Provider](https://github.com/terraform-providers/terraform-provider-simple)\n\u003e distributed under [MPL 2.0](https://www.mozilla.org/en-US/MPL/2.0/). If you encounter a bug or missing feature,\n\u003e first check the [`pulumi-simple` repo](https://github.com/pulumi/pulumi-simple/issues); however, if that doesn't turn up anything,\n\u003e please consult the source [`terraform-provider-simple` repo](https://github.com/terraform-providers/terraform-provider-simple/issues).", "compatibility": "tfbridge20", "pyproject": {} } diff --git a/pkg/tfgen/generate.go b/pkg/tfgen/generate.go index 24af79dbb..09cf83bd2 100644 --- a/pkg/tfgen/generate.go +++ b/pkg/tfgen/generate.go @@ -886,22 +886,21 @@ func NewGenerator(opts GeneratorOptions) (*Generator, error) { } return &Generator{ - pkg: pkg, - version: version, - language: lang, - info: info, - root: root, - providerShim: providerShim, - pluginHost: newCachingProviderHost(host), - packageCache: pcl.NewPackageCache(), - infoSource: host, - terraformVersion: opts.TerraformVersion, - sink: sink, - skipDocs: opts.SkipDocs, - skipExamples: opts.SkipExamples, - coverageTracker: opts.CoverageTracker, - editRules: getEditRules(info.DocRules), - noDocsRepo: opts.XInMemoryDocs, + pkg: pkg, + version: version, + language: lang, + info: info, + root: root, + providerShim: providerShim, + pluginHost: newCachingProviderHost(host), + packageCache: pcl.NewPackageCache(), + infoSource: host, + sink: sink, + skipDocs: opts.SkipDocs, + skipExamples: opts.SkipExamples, + coverageTracker: opts.CoverageTracker, + editRules: getEditRules(info.DocRules), + noDocsRepo: opts.XInMemoryDocs, }, nil } diff --git a/pkg/tfgen/generate_schema.go b/pkg/tfgen/generate_schema.go index cfcf52c1d..13f2a94fe 100644 --- a/pkg/tfgen/generate_schema.go +++ b/pkg/tfgen/generate_schema.go @@ -587,16 +587,27 @@ func nodeLanguageExtensions(providerInfo *tfbridge.ProviderInfo, readme string) func getDefaultReadme(pulumiPackageName tokens.Package, tfProviderShortName string, tfGitHubOrg string, pulumiProvLicense tfbridge.TFProviderLicense, pulumiProvLicenseURI string, githubHost string, - pulumiProvRepo string, + sourceRepo string, ) string { //nolint:lll standardDocReadme := `> This provider is a derived work of the [Terraform Provider](https://%[6]s/%[3]s/terraform-provider-%[2]s) > distributed under [%[4]s](%[5]s). If you encounter a bug or missing feature, > first check the [` + "`pulumi-%[1]s`" + ` repo](%[7]s/issues); however, if that doesn't turn up anything, > please consult the source [` + "`terraform-provider-%[2]s`" + ` repo](https://%[6]s/%[3]s/terraform-provider-%[2]s/issues).` + //nolint:lll + dynamicDocReadme := `> This provider is a derived work of the [Terraform Provider](https://%[6]s/%[3]s/terraform-provider-%[2]s) +> distributed under [%[4]s](%[5]s). If you encounter a bug or missing feature, +> please consult the source [` + "`terraform-provider-%[2]s`" + ` repo](https://%[6]s/%[3]s/terraform-provider-%[2]s/issues).` + + var returnReadme string + if strings.Contains(sourceRepo, "pulumi") { + returnReadme = standardDocReadme + } else { + returnReadme = dynamicDocReadme + } - return fmt.Sprintf(standardDocReadme, pulumiPackageName, tfProviderShortName, tfGitHubOrg, pulumiProvLicense, - pulumiProvLicenseURI, githubHost, pulumiProvRepo) + return fmt.Sprintf(returnReadme, pulumiPackageName, tfProviderShortName, tfGitHubOrg, pulumiProvLicense, + pulumiProvLicenseURI, githubHost, sourceRepo) } func (g *schemaGenerator) genDocComment(comment string) string { diff --git a/pkg/tfgen/generate_schema_test.go b/pkg/tfgen/generate_schema_test.go index 9ce5670fa..18b06938e 100644 --- a/pkg/tfgen/generate_schema_test.go +++ b/pkg/tfgen/generate_schema_test.go @@ -222,6 +222,7 @@ func TestTypeSharing(t *testing.T) { }, }), UpstreamRepoPath: tmpdir, + Repository: "https://github.com/pulumi/pulumi-testprov", Resources: map[string]*info.Resource{ "testprov_r1": { Tok: "testprov:index:R1", diff --git a/pkg/tfgen/generate_test.go b/pkg/tfgen/generate_test.go index 0595dd6e8..84c1bf278 100644 --- a/pkg/tfgen/generate_test.go +++ b/pkg/tfgen/generate_test.go @@ -136,6 +136,7 @@ func Test_GenerateTestDataSchemas(t *testing.T) { pkg := strings.Replace(info.Name(), filepath.Ext(info.Name()), "", -1) provInfo, err := providerInfoSource.GetProviderInfo("", "", pkg, "") require.NoError(t, err) + provInfo.Repository = "https://github.com/pulumi/pulumi-" + pkg schema, err := GenerateSchema(*provInfo, nilSink) require.NoError(t, err) diff --git a/pkg/tfgen/test_data/TestConvertViaPulumiCLI/schema.json b/pkg/tfgen/test_data/TestConvertViaPulumiCLI/schema.json index 90244c719..b224b949b 100644 --- a/pkg/tfgen/test_data/TestConvertViaPulumiCLI/schema.json +++ b/pkg/tfgen/test_data/TestConvertViaPulumiCLI/schema.json @@ -6,12 +6,12 @@ }, "language": { "nodejs": { - "readme": "\u003e This provider is a derived work of the [Terraform Provider](https://github.com/terraform-providers/terraform-provider-simple)\n\u003e distributed under [MPL 2.0](https://www.mozilla.org/en-US/MPL/2.0/). If you encounter a bug or missing feature,\n\u003e first check the [`pulumi-simple` repo](/issues); however, if that doesn't turn up anything,\n\u003e please consult the source [`terraform-provider-simple` repo](https://github.com/terraform-providers/terraform-provider-simple/issues).", + "readme": "\u003e This provider is a derived work of the [Terraform Provider](https://github.com/terraform-providers/terraform-provider-simple)\n\u003e distributed under [MPL 2.0](https://www.mozilla.org/en-US/MPL/2.0/). If you encounter a bug or missing feature,\n\u003e please consult the source [`terraform-provider-simple` repo](https://github.com/terraform-providers/terraform-provider-simple/issues).", "compatibility": "tfbridge20", "disableUnionOutputTypes": true }, "python": { - "readme": "\u003e This provider is a derived work of the [Terraform Provider](https://github.com/terraform-providers/terraform-provider-simple)\n\u003e distributed under [MPL 2.0](https://www.mozilla.org/en-US/MPL/2.0/). If you encounter a bug or missing feature,\n\u003e first check the [`pulumi-simple` repo](/issues); however, if that doesn't turn up anything,\n\u003e please consult the source [`terraform-provider-simple` repo](https://github.com/terraform-providers/terraform-provider-simple/issues).", + "readme": "\u003e This provider is a derived work of the [Terraform Provider](https://github.com/terraform-providers/terraform-provider-simple)\n\u003e distributed under [MPL 2.0](https://www.mozilla.org/en-US/MPL/2.0/). If you encounter a bug or missing feature,\n\u003e please consult the source [`terraform-provider-simple` repo](https://github.com/terraform-providers/terraform-provider-simple/issues).", "compatibility": "tfbridge20", "pyproject": {} } diff --git a/pkg/tfgen/testdata/TestTypeSharing.golden b/pkg/tfgen/testdata/TestTypeSharing.golden index a846f64e7..727ff09aa 100644 --- a/pkg/tfgen/testdata/TestTypeSharing.golden +++ b/pkg/tfgen/testdata/TestTypeSharing.golden @@ -1,17 +1,18 @@ { "name": "testprov", "attribution": "This Pulumi package is based on the [`testprov` Terraform Provider](https://github.com/terraform-providers/terraform-provider-testprov).", + "repository": "https://github.com/pulumi/pulumi-testprov", "meta": { "moduleFormat": "(.*)(?:/[^/]*)" }, "language": { "nodejs": { - "readme": "\u003e This provider is a derived work of the [Terraform Provider](https://github.com/terraform-providers/terraform-provider-testprov)\n\u003e distributed under [MPL 2.0](https://www.mozilla.org/en-US/MPL/2.0/). If you encounter a bug or missing feature,\n\u003e first check the [`pulumi-testprov` repo](/issues); however, if that doesn't turn up anything,\n\u003e please consult the source [`terraform-provider-testprov` repo](https://github.com/terraform-providers/terraform-provider-testprov/issues).", + "readme": "\u003e This provider is a derived work of the [Terraform Provider](https://github.com/terraform-providers/terraform-provider-testprov)\n\u003e distributed under [MPL 2.0](https://www.mozilla.org/en-US/MPL/2.0/). If you encounter a bug or missing feature,\n\u003e first check the [`pulumi-testprov` repo](https://github.com/pulumi/pulumi-testprov/issues); however, if that doesn't turn up anything,\n\u003e please consult the source [`terraform-provider-testprov` repo](https://github.com/terraform-providers/terraform-provider-testprov/issues).", "compatibility": "tfbridge20", "disableUnionOutputTypes": true }, "python": { - "readme": "\u003e This provider is a derived work of the [Terraform Provider](https://github.com/terraform-providers/terraform-provider-testprov)\n\u003e distributed under [MPL 2.0](https://www.mozilla.org/en-US/MPL/2.0/). If you encounter a bug or missing feature,\n\u003e first check the [`pulumi-testprov` repo](/issues); however, if that doesn't turn up anything,\n\u003e please consult the source [`terraform-provider-testprov` repo](https://github.com/terraform-providers/terraform-provider-testprov/issues).", + "readme": "\u003e This provider is a derived work of the [Terraform Provider](https://github.com/terraform-providers/terraform-provider-testprov)\n\u003e distributed under [MPL 2.0](https://www.mozilla.org/en-US/MPL/2.0/). If you encounter a bug or missing feature,\n\u003e first check the [`pulumi-testprov` repo](https://github.com/pulumi/pulumi-testprov/issues); however, if that doesn't turn up anything,\n\u003e please consult the source [`terraform-provider-testprov` repo](https://github.com/terraform-providers/terraform-provider-testprov/issues).", "compatibility": "tfbridge20", "pyproject": {} } From a51dc4e73fac342e1363d39f7a247e0ba933e44f Mon Sep 17 00:00:00 2001 From: guineveresaenger Date: Mon, 9 Dec 2024 11:37:06 -0800 Subject: [PATCH 13/16] Address review comments. Standardize docs flag to be a flag for both Local and Remote arguments. --- dynamic/info.go | 3 --- dynamic/main.go | 19 ++++++++-------- dynamic/parameterize/args.go | 17 +++++++++++--- dynamic/parameterize/args_test.go | 37 ++++++++++++++++++++++++++----- dynamic/provider_test.go | 7 +++--- pkg/tfgen/docs.go | 3 ++- 6 files changed, 62 insertions(+), 24 deletions(-) diff --git a/dynamic/info.go b/dynamic/info.go index 8fe40d96e..d5b05fbca 100644 --- a/dynamic/info.go +++ b/dynamic/info.go @@ -42,9 +42,6 @@ func providerInfo(ctx context.Context, p run.Provider, value parameterize.Value) Publisher: "Pulumi", ResourcePrefix: inferResourcePrefix(provider), - // To avoid bogging down schema generation speed, we skip all examples. - SkipExamples: func(tfbridge.SkipExamplesArgs) bool { return false }, - MetadataInfo: &tfbridge.MetadataInfo{ Path: "", Data: tfbridge.ProviderMetadata(nil), }, diff --git a/dynamic/main.go b/dynamic/main.go index 61e1750de..0a97b970f 100644 --- a/dynamic/main.go +++ b/dynamic/main.go @@ -69,7 +69,7 @@ func initialSetup() (info.Provider, pfbridge.ProviderMetadata, func() error) { var fullDocs bool metadata = pfbridge.ProviderMetadata{ XGetSchema: func(ctx context.Context, req plugin.GetSchemaRequest) ([]byte, error) { - // Create a custom generator for schema and, of fullDocs is set, examples + // Create a custom generator for schema. Examples will only be generated if `fullDocs` is set. g, err := tfgen.NewGenerator(tfgen.GeneratorOptions{ Package: info.Name, Version: info.Version, @@ -93,6 +93,7 @@ func initialSetup() (info.Provider, pfbridge.ProviderMetadata, func() error) { if info.SchemaPostProcessor != nil { info.SchemaPostProcessor(&packageSchema.PackageSpec) } + return json.Marshal(packageSchema.PackageSpec) }, XParamaterize: func(ctx context.Context, req plugin.ParameterizeRequest) (plugin.ParameterizeResponse, error) { @@ -161,7 +162,14 @@ func initialSetup() (info.Provider, pfbridge.ProviderMetadata, func() error) { return plugin.ParameterizeResponse{}, err } - if args.Remote != nil { + switch args.Remote { + case nil: + // We're using local args. + if args.Local.UpstreamRepoPath != "" { + info.UpstreamRepoPath = args.Local.UpstreamRepoPath + fullDocs = true + } + default: fullDocs = args.Remote.Docs if fullDocs { // Write the upstream files at this version to a temporary directory @@ -181,13 +189,6 @@ func initialSetup() (info.Provider, pfbridge.ProviderMetadata, func() error) { } } - if args.Local != nil { - if args.Local.UpstreamRepoPath != "" { - info.UpstreamRepoPath = args.Local.UpstreamRepoPath - fullDocs = true - } - } - return plugin.ParameterizeResponse{ Name: p.Name(), Version: v, diff --git a/dynamic/parameterize/args.go b/dynamic/parameterize/args.go index b1444f91a..a0f22a3af 100644 --- a/dynamic/parameterize/args.go +++ b/dynamic/parameterize/args.go @@ -76,11 +76,22 @@ func ParseArgs(args []string) (Args, error) { // The third argument, if any, is the full docs option for when we need to generate docs case 3: docsArg := args[2] - if docsArg == "fullDocs" { + errMsg := "expected third parameterized argument to be 'fullDocs=true/false' or be empty" + + fullDocs, found := strings.CutPrefix(docsArg, "fullDocs=") + if !found { + return Args{}, fmt.Errorf("%s", errMsg) + } + + switch fullDocs { + case "true": remote.Docs = true - } else { - return Args{}, fmt.Errorf("expected third parameterized argument to be 'fullDocs' or empty") + case "false": + // Do nothing + default: + return Args{}, fmt.Errorf("%s", errMsg) } + fallthrough // The second argument, if any is the version case 2: diff --git a/dynamic/parameterize/args_test.go b/dynamic/parameterize/args_test.go index 409855a8c..fcd679cf9 100644 --- a/dynamic/parameterize/args_test.go +++ b/dynamic/parameterize/args_test.go @@ -83,19 +83,46 @@ func TestParseArgs(t *testing.T) { errMsg: autogold.Expect("expected to be parameterized by 1-3 arguments: [version] [fullDocs]"), }, { - name: "invalid third arg", - args: []string{"arg1", "arg2", "arg3"}, - errMsg: autogold.Expect("expected third parameterized argument to be 'fullDocs' or empty"), + name: "invalid third arg", + args: []string{"arg1", "arg2", "arg3"}, + errMsg: autogold.Expect( + "expected third parameterized argument to be 'fullDocs=true/false' or be empty", + ), + }, + { + name: "empty third arg", + args: []string{"arg1", "arg2"}, + expect: Args{Remote: &RemoteArgs{ + Name: "arg1", + Version: "arg2", + Docs: false, + }}, }, { - name: "valid third arg", - args: []string{"my-registry.io/typ", "1.2.3", "fullDocs"}, + name: "valid third arg true", + args: []string{"my-registry.io/typ", "1.2.3", "fullDocs=true"}, expect: Args{Remote: &RemoteArgs{ Name: "my-registry.io/typ", Version: "1.2.3", Docs: true, }}, }, + { + name: "valid third arg false", + args: []string{"my-registry.io/typ", "1.2.3", "fullDocs=false"}, + expect: Args{Remote: &RemoteArgs{ + Name: "my-registry.io/typ", + Version: "1.2.3", + Docs: false, + }}, + }, + { + name: "third arg invalid input", + args: []string{"my-registry.io/typ", "1.2.3", "fullDocs=invalid-input"}, + errMsg: autogold.Expect( + "expected third parameterized argument to be 'fullDocs=true/false' or be empty", + ), + }, } for _, tt := range tests { diff --git a/dynamic/provider_test.go b/dynamic/provider_test.go index e276f0b48..41753566c 100644 --- a/dynamic/provider_test.go +++ b/dynamic/provider_test.go @@ -462,14 +462,15 @@ func TestSchemaGenerationFullDocs(t *testing.T) { //nolint:paralleltest type testCase struct { name string version string - fullDocs bool + fullDocs string } tc := testCase{ name: "hashicorp/random", version: "3.6.3", - fullDocs: true, + fullDocs: "fullDocs=true", } + t.Run(strings.Join([]string{tc.name, tc.version}, "-"), func(t *testing.T) { helper.Integration(t) ctx := context.Background() @@ -479,7 +480,7 @@ func TestSchemaGenerationFullDocs(t *testing.T) { //nolint:paralleltest result, err := server.Parameterize(ctx, &pulumirpc.ParameterizeRequest{ Parameters: &pulumirpc.ParameterizeRequest_Args{ Args: &pulumirpc.ParameterizeRequest_ParametersArgs{ - Args: []string{tc.name, tc.version, "fullDocs"}, + Args: []string{tc.name, tc.version, tc.fullDocs}, }, }, }) diff --git a/pkg/tfgen/docs.go b/pkg/tfgen/docs.go index b2166a1a7..2977e06f4 100644 --- a/pkg/tfgen/docs.go +++ b/pkg/tfgen/docs.go @@ -186,7 +186,6 @@ func getDocsForResource(g *Generator, source DocsSource, kind DocKind, if g.skipDocs { return entityDocs{}, nil } - var docInfo *tfbridge.DocInfo if info != nil { docInfo = info.GetDocs() @@ -209,6 +208,7 @@ func getDocsForResource(g *Generator, source DocsSource, kind DocKind, docFile = nil } } + if err != nil { return entityDocs{}, fmt.Errorf("get docs for token %s: %w", rawname, err) } @@ -1457,6 +1457,7 @@ func (g *Generator) convertExamples(docs string, path examplePath) string { if docs == "" { return "" } + if g.info.SkipExamples != nil { if g.info.SkipExamples(tfbridge.SkipExamplesArgs{ Token: path.Token(), From 8b48a82a8356f237ee109330b8e284f8707afce6 Mon Sep 17 00:00:00 2001 From: guineveresaenger Date: Tue, 10 Dec 2024 10:53:34 -0800 Subject: [PATCH 14/16] tweak arg output --- dynamic/parameterize/args.go | 4 ++-- dynamic/parameterize/args_test.go | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/dynamic/parameterize/args.go b/dynamic/parameterize/args.go index a0f22a3af..aa7352899 100644 --- a/dynamic/parameterize/args.go +++ b/dynamic/parameterize/args.go @@ -76,7 +76,7 @@ func ParseArgs(args []string) (Args, error) { // The third argument, if any, is the full docs option for when we need to generate docs case 3: docsArg := args[2] - errMsg := "expected third parameterized argument to be 'fullDocs=true/false' or be empty" + errMsg := "expected third parameterized argument to be 'fullDocs=' or be empty" fullDocs, found := strings.CutPrefix(docsArg, "fullDocs=") if !found { @@ -102,6 +102,6 @@ func ParseArgs(args []string) (Args, error) { remote.Name = args[0] return Args{Remote: &remote}, nil default: - return Args{}, fmt.Errorf("expected to be parameterized by 1-3 arguments: [version] [fullDocs]") + return Args{}, fmt.Errorf("expected to be parameterized by 1-3 arguments: [version] [fullDocs=]") } } diff --git a/dynamic/parameterize/args_test.go b/dynamic/parameterize/args_test.go index fcd679cf9..f3530e36b 100644 --- a/dynamic/parameterize/args_test.go +++ b/dynamic/parameterize/args_test.go @@ -75,18 +75,18 @@ func TestParseArgs(t *testing.T) { { name: "no args", args: []string{}, - errMsg: autogold.Expect("expected to be parameterized by 1-3 arguments: [version] [fullDocs]"), + errMsg: autogold.Expect("expected to be parameterized by 1-3 arguments: [version] [fullDocs=]"), }, { name: "too many args", args: []string{"arg1", "arg2", "arg3", "arg4"}, - errMsg: autogold.Expect("expected to be parameterized by 1-3 arguments: [version] [fullDocs]"), + errMsg: autogold.Expect("expected to be parameterized by 1-3 arguments: [version] [fullDocs=]"), }, { name: "invalid third arg", args: []string{"arg1", "arg2", "arg3"}, errMsg: autogold.Expect( - "expected third parameterized argument to be 'fullDocs=true/false' or be empty", + "expected third parameterized argument to be 'fullDocs=' or be empty", ), }, { @@ -120,7 +120,7 @@ func TestParseArgs(t *testing.T) { name: "third arg invalid input", args: []string{"my-registry.io/typ", "1.2.3", "fullDocs=invalid-input"}, errMsg: autogold.Expect( - "expected third parameterized argument to be 'fullDocs=true/false' or be empty", + "expected third parameterized argument to be 'fullDocs=' or be empty", ), }, } From cbbd64872b2ad3b2d786962f2e50c4309cd8200d Mon Sep 17 00:00:00 2001 From: guineveresaenger Date: Tue, 10 Dec 2024 11:22:34 -0800 Subject: [PATCH 15/16] rebase and update test --- .../hashicorp/random-3.6.3.golden | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/dynamic/testdata/TestSchemaGenerationFullDocs/hashicorp/random-3.6.3.golden b/dynamic/testdata/TestSchemaGenerationFullDocs/hashicorp/random-3.6.3.golden index cac441f13..7c273bfd4 100644 --- a/dynamic/testdata/TestSchemaGenerationFullDocs/hashicorp/random-3.6.3.golden +++ b/dynamic/testdata/TestSchemaGenerationFullDocs/hashicorp/random-3.6.3.golden @@ -14,7 +14,7 @@ "respectSchemaVersion": true }, "go": { - "importBasePath": "github.com/pulumi/pulumi-terraform-provider/sdks/go/random/v3", + "importBasePath": "github.com/pulumi/pulumi-terraform-provider/sdks/go/random/v3/random", "rootPackageName": "random", "liftSingleValueMethodReturns": true, "generateExtraInputTypes": true, @@ -49,7 +49,7 @@ }, "resources": { "random:index/bytes:Bytes": { - "description": "The resource `random.Bytes` generates random bytes that are intended to be used as a secret, or key. Use this in preference to `random.Id` when the output is considered sensitive, and should not be displayed in the CLI.\n\nThis resource *does* use a cryptographic random number generator.\n\n## Example Usage\n\n\u003c!--Start PulumiCodeChooser --\u003e\n```typescript\nimport * as pulumi from \"@pulumi/pulumi\";\nimport * as azurerm from \"@pulumi/azurerm\";\nimport * as random from \"@pulumi/random\";\n\nconst jwtSecretBytes = new random.Bytes(\"jwtSecretBytes\", {length: 64});\nconst jwtSecretazurerm_key_vault_secret = new azurerm.index.Azurerm_key_vault_secret(\"jwtSecretazurerm_key_vault_secret\", {\n keyVaultId: \"some-azure-key-vault-id\",\n name: \"JwtSecret\",\n value: jwtSecretBytes.base64,\n});\n```\n```python\nimport pulumi\nimport pulumi_azurerm as azurerm\nimport pulumi_random as random\n\njwt_secret_bytes = random.Bytes(\"jwtSecretBytes\", length=64)\njwt_secretazurerm_key_vault_secret = azurerm.index.Azurerm_key_vault_secret(\"jwtSecretazurerm_key_vault_secret\",\n key_vault_id=some-azure-key-vault-id,\n name=JwtSecret,\n value=jwt_secret_bytes.base64)\n```\n```csharp\nusing System.Collections.Generic;\nusing System.Linq;\nusing Pulumi;\nusing Azurerm = Pulumi.Azurerm;\nusing Random = Pulumi.Random;\n\nreturn await Deployment.RunAsync(() =\u003e \n{\n var jwtSecretBytes = new Random.Bytes(\"jwtSecretBytes\", new()\n {\n Length = 64,\n });\n\n var jwtSecretazurerm_key_vault_secret = new Azurerm.Index.Azurerm_key_vault_secret(\"jwtSecretazurerm_key_vault_secret\", new()\n {\n KeyVaultId = \"some-azure-key-vault-id\",\n Name = \"JwtSecret\",\n Value = jwtSecretBytes.Base64,\n });\n\n});\n```\n```go\npackage main\n\nimport (\n\t\"github.com/pulumi/pulumi-azurerm/sdk/go/azurerm\"\n\trandom \"github.com/pulumi/pulumi-terraform-provider/sdks/go/random/v3\"\n\t\"github.com/pulumi/pulumi/sdk/v3/go/pulumi\"\n)\n\nfunc main() {\n\tpulumi.Run(func(ctx *pulumi.Context) error {\n\t\tjwtSecretBytes, err := random.NewBytes(ctx, \"jwtSecretBytes\", \u0026random.BytesArgs{\n\t\t\tLength: pulumi.Float64(64),\n\t\t})\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\t_, err = azurerm.NewAzurerm_key_vault_secret(ctx, \"jwtSecretazurerm_key_vault_secret\", \u0026azurerm.Azurerm_key_vault_secretArgs{\n\t\t\tKeyVaultId: \"some-azure-key-vault-id\",\n\t\t\tName: \"JwtSecret\",\n\t\t\tValue: jwtSecretBytes.Base64,\n\t\t})\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn nil\n\t})\n}\n```\n```java\npackage generated_program;\n\nimport com.pulumi.Context;\nimport com.pulumi.Pulumi;\nimport com.pulumi.core.Output;\nimport com.pulumi.random.Bytes;\nimport com.pulumi.random.BytesArgs;\nimport com.pulumi.azurerm.azurerm_key_vault_secret;\nimport com.pulumi.azurerm.Azurerm_key_vault_secretArgs;\nimport java.util.List;\nimport java.util.ArrayList;\nimport java.util.Map;\nimport java.io.File;\nimport java.nio.file.Files;\nimport java.nio.file.Paths;\n\npublic class App {\n public static void main(String[] args) {\n Pulumi.run(App::stack);\n }\n\n public static void stack(Context ctx) {\n var jwtSecretBytes = new Bytes(\"jwtSecretBytes\", BytesArgs.builder()\n .length(64)\n .build());\n\n var jwtSecretazurerm_key_vault_secret = new Azurerm_key_vault_secret(\"jwtSecretazurerm_key_vault_secret\", Azurerm_key_vault_secretArgs.builder()\n .keyVaultId(\"some-azure-key-vault-id\")\n .name(\"JwtSecret\")\n .value(jwtSecretBytes.base64())\n .build());\n\n }\n}\n```\n```yaml\nresources:\n jwtSecretBytes:\n type: random:Bytes\n properties:\n length: 64\n jwtSecretazurerm_key_vault_secret:\n type: azurerm:azurerm_key_vault_secret\n properties:\n keyVaultId: some-azure-key-vault-id\n name: JwtSecret\n value: ${jwtSecretBytes.base64}\n```\n\u003c!--End PulumiCodeChooser --\u003e\n\n## Import\n\nRandom bytes can be imported by specifying the value as base64 string.\n\n```sh\n$ pulumi import random:index/bytes:Bytes basic \"8/fu3q+2DcgSJ19i0jZ5Cw==\"\n```\n\n", + "description": "The resource `random.Bytes` generates random bytes that are intended to be used as a secret, or key. Use this in preference to `random.Id` when the output is considered sensitive, and should not be displayed in the CLI.\n\nThis resource *does* use a cryptographic random number generator.\n\n## Example Usage\n\n\u003c!--Start PulumiCodeChooser --\u003e\n```typescript\nimport * as pulumi from \"@pulumi/pulumi\";\nimport * as azurerm from \"@pulumi/azurerm\";\nimport * as random from \"@pulumi/random\";\n\nconst jwtSecretBytes = new random.Bytes(\"jwtSecretBytes\", {length: 64});\nconst jwtSecretazurerm_key_vault_secret = new azurerm.index.Azurerm_key_vault_secret(\"jwtSecretazurerm_key_vault_secret\", {\n keyVaultId: \"some-azure-key-vault-id\",\n name: \"JwtSecret\",\n value: jwtSecretBytes.base64,\n});\n```\n```python\nimport pulumi\nimport pulumi_azurerm as azurerm\nimport pulumi_random as random\n\njwt_secret_bytes = random.Bytes(\"jwtSecretBytes\", length=64)\njwt_secretazurerm_key_vault_secret = azurerm.index.Azurerm_key_vault_secret(\"jwtSecretazurerm_key_vault_secret\",\n key_vault_id=some-azure-key-vault-id,\n name=JwtSecret,\n value=jwt_secret_bytes.base64)\n```\n```csharp\nusing System.Collections.Generic;\nusing System.Linq;\nusing Pulumi;\nusing Azurerm = Pulumi.Azurerm;\nusing Random = Pulumi.Random;\n\nreturn await Deployment.RunAsync(() =\u003e \n{\n var jwtSecretBytes = new Random.Bytes(\"jwtSecretBytes\", new()\n {\n Length = 64,\n });\n\n var jwtSecretazurerm_key_vault_secret = new Azurerm.Index.Azurerm_key_vault_secret(\"jwtSecretazurerm_key_vault_secret\", new()\n {\n KeyVaultId = \"some-azure-key-vault-id\",\n Name = \"JwtSecret\",\n Value = jwtSecretBytes.Base64,\n });\n\n});\n```\n```go\npackage main\n\nimport (\n\t\"github.com/pulumi/pulumi-azurerm/sdk/go/azurerm\"\n\t\"github.com/pulumi/pulumi-terraform-provider/sdks/go/random/v3/random\"\n\t\"github.com/pulumi/pulumi/sdk/v3/go/pulumi\"\n)\n\nfunc main() {\n\tpulumi.Run(func(ctx *pulumi.Context) error {\n\t\tjwtSecretBytes, err := random.NewBytes(ctx, \"jwtSecretBytes\", \u0026random.BytesArgs{\n\t\t\tLength: pulumi.Float64(64),\n\t\t})\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\t_, err = azurerm.NewAzurerm_key_vault_secret(ctx, \"jwtSecretazurerm_key_vault_secret\", \u0026azurerm.Azurerm_key_vault_secretArgs{\n\t\t\tKeyVaultId: \"some-azure-key-vault-id\",\n\t\t\tName: \"JwtSecret\",\n\t\t\tValue: jwtSecretBytes.Base64,\n\t\t})\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn nil\n\t})\n}\n```\n```java\npackage generated_program;\n\nimport com.pulumi.Context;\nimport com.pulumi.Pulumi;\nimport com.pulumi.core.Output;\nimport com.pulumi.random.Bytes;\nimport com.pulumi.random.BytesArgs;\nimport com.pulumi.azurerm.azurerm_key_vault_secret;\nimport com.pulumi.azurerm.Azurerm_key_vault_secretArgs;\nimport java.util.List;\nimport java.util.ArrayList;\nimport java.util.Map;\nimport java.io.File;\nimport java.nio.file.Files;\nimport java.nio.file.Paths;\n\npublic class App {\n public static void main(String[] args) {\n Pulumi.run(App::stack);\n }\n\n public static void stack(Context ctx) {\n var jwtSecretBytes = new Bytes(\"jwtSecretBytes\", BytesArgs.builder()\n .length(64)\n .build());\n\n var jwtSecretazurerm_key_vault_secret = new Azurerm_key_vault_secret(\"jwtSecretazurerm_key_vault_secret\", Azurerm_key_vault_secretArgs.builder()\n .keyVaultId(\"some-azure-key-vault-id\")\n .name(\"JwtSecret\")\n .value(jwtSecretBytes.base64())\n .build());\n\n }\n}\n```\n```yaml\nresources:\n jwtSecretBytes:\n type: random:Bytes\n properties:\n length: 64\n jwtSecretazurerm_key_vault_secret:\n type: azurerm:azurerm_key_vault_secret\n properties:\n keyVaultId: some-azure-key-vault-id\n name: JwtSecret\n value: ${jwtSecretBytes.base64}\n```\n\u003c!--End PulumiCodeChooser --\u003e\n\n## Import\n\nRandom bytes can be imported by specifying the value as base64 string.\n\n```sh\n$ pulumi import random:index/bytes:Bytes basic \"8/fu3q+2DcgSJ19i0jZ5Cw==\"\n```\n\n", "properties": { "base64": { "type": "string", @@ -123,7 +123,7 @@ } }, "random:index/id:Id": { - "description": "The resource `random.Id` generates random numbers that are intended to be\nused as unique identifiers for other resources. If the output is considered \nsensitive, and should not be displayed in the CLI, use `random.Bytes`\ninstead.\n\nThis resource *does* use a cryptographic random number generator in order\nto minimize the chance of collisions, making the results of this resource\nwhen a 16-byte identifier is requested of equivalent uniqueness to a\ntype-4 UUID.\n\nThis resource can be used in conjunction with resources that have\nthe `create_before_destroy` lifecycle flag set to avoid conflicts with\nunique names during the brief period where both the old and new resources\nexist concurrently.\n\n## Example Usage\n\n\u003c!--Start PulumiCodeChooser --\u003e\n```typescript\nimport * as pulumi from \"@pulumi/pulumi\";\nimport * as aws from \"@pulumi/aws\";\nimport * as random from \"@pulumi/random\";\n\n// The following example shows how to generate a unique name for an AWS EC2\n// instance that changes each time a new AMI id is selected.\nconst serverId = new random.Id(\"serverId\", {\n keepers: {\n ami_id: _var.ami_id,\n },\n byteLength: 8,\n});\nconst serverInstance = new aws.ec2.Instance(\"serverInstance\", {\n tags: {\n Name: pulumi.interpolate`web-server ${serverId.hex}`,\n },\n ami: serverId.keepers.apply(keepers =\u003e keepers?.amiId),\n});\n// ... (other aws_instance arguments) ...\n```\n```python\nimport pulumi\nimport pulumi_aws as aws\nimport pulumi_random as random\n\n# The following example shows how to generate a unique name for an AWS EC2\n# instance that changes each time a new AMI id is selected.\nserver_id = random.Id(\"serverId\",\n keepers={\n \"ami_id\": var[\"ami_id\"],\n },\n byte_length=8)\nserver_instance = aws.ec2.Instance(\"serverInstance\",\n tags={\n \"Name\": server_id.hex.apply(lambda hex: f\"web-server {hex}\"),\n },\n ami=server_id.keepers[\"amiId\"])\n# ... (other aws_instance arguments) ...\n```\n```csharp\nusing System.Collections.Generic;\nusing System.Linq;\nusing Pulumi;\nusing Aws = Pulumi.Aws;\nusing Random = Pulumi.Random;\n\nreturn await Deployment.RunAsync(() =\u003e \n{\n // The following example shows how to generate a unique name for an AWS EC2\n // instance that changes each time a new AMI id is selected.\n var serverId = new Random.Id(\"serverId\", new()\n {\n Keepers = \n {\n { \"ami_id\", @var.Ami_id },\n },\n ByteLength = 8,\n });\n\n var serverInstance = new Aws.Ec2.Instance(\"serverInstance\", new()\n {\n Tags = \n {\n { \"Name\", serverId.Hex.Apply(hex =\u003e $\"web-server {hex}\") },\n },\n Ami = serverId.Keepers.Apply(keepers =\u003e keepers?.AmiId),\n });\n\n // ... (other aws_instance arguments) ...\n});\n```\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/pulumi/pulumi-aws/sdk/v6/go/aws/ec2\"\n\trandom \"github.com/pulumi/pulumi-terraform-provider/sdks/go/random/v3\"\n\t\"github.com/pulumi/pulumi/sdk/v3/go/pulumi\"\n)\n\nfunc main() {\n\tpulumi.Run(func(ctx *pulumi.Context) error {\n\t\t// The following example shows how to generate a unique name for an AWS EC2\n\t\t// instance that changes each time a new AMI id is selected.\n\t\tserverId, err := random.NewId(ctx, \"serverId\", \u0026random.IdArgs{\n\t\t\tKeepers: pulumi.StringMap{\n\t\t\t\t\"ami_id\": pulumi.Any(_var.Ami_id),\n\t\t\t},\n\t\t\tByteLength: pulumi.Float64(8),\n\t\t})\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\t_, err = ec2.NewInstance(ctx, \"serverInstance\", \u0026ec2.InstanceArgs{\n\t\t\tTags: pulumi.StringMap{\n\t\t\t\t\"Name\": serverId.Hex.ApplyT(func(hex string) (string, error) {\n\t\t\t\t\treturn fmt.Sprintf(\"web-server %v\", hex), nil\n\t\t\t\t}).(pulumi.StringOutput),\n\t\t\t},\n\t\t\tAmi: pulumi.String(serverId.Keepers.ApplyT(func(keepers map[string]string) (*string, error) {\n\t\t\t\treturn \u0026keepers.AmiId, nil\n\t\t\t}).(pulumi.StringPtrOutput)),\n\t\t})\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn nil\n\t})\n}\n```\n```java\npackage generated_program;\n\nimport com.pulumi.Context;\nimport com.pulumi.Pulumi;\nimport com.pulumi.core.Output;\nimport com.pulumi.random.Id;\nimport com.pulumi.random.IdArgs;\nimport com.pulumi.aws.ec2.Instance;\nimport com.pulumi.aws.ec2.InstanceArgs;\nimport java.util.List;\nimport java.util.ArrayList;\nimport java.util.Map;\nimport java.io.File;\nimport java.nio.file.Files;\nimport java.nio.file.Paths;\n\npublic class App {\n public static void main(String[] args) {\n Pulumi.run(App::stack);\n }\n\n public static void stack(Context ctx) {\n // The following example shows how to generate a unique name for an AWS EC2\n // instance that changes each time a new AMI id is selected.\n var serverId = new Id(\"serverId\", IdArgs.builder()\n .keepers(Map.of(\"ami_id\", var_.ami_id()))\n .byteLength(8)\n .build());\n\n var serverInstance = new Instance(\"serverInstance\", InstanceArgs.builder()\n .tags(Map.of(\"Name\", serverId.hex().applyValue(hex -\u003e String.format(\"web-server %s\", hex))))\n .ami(serverId.keepers().applyValue(keepers -\u003e keepers.amiId()))\n .build());\n\n // ... (other aws_instance arguments) ...\n }\n}\n```\n```yaml\nresources:\n # The following example shows how to generate a unique name for an AWS EC2\n # instance that changes each time a new AMI id is selected.\n serverId:\n type: random:Id\n properties:\n keepers:\n ami_id: ${var.ami_id}\n byteLength: 8\n serverInstance:\n type: aws:ec2:Instance\n properties:\n tags:\n Name: web-server ${serverId.hex}\n # Read the AMI id \"through\" the random_id resource to ensure that\n # # both will change together.\n ami: ${serverId.keepers.amiId}\n```\n\u003c!--End PulumiCodeChooser --\u003e\n\n## Import\n\nRandom IDs can be imported using the b64_url with an optional prefix. This\n\ncan be used to replace a config value with a value interpolated from the\n\nrandom provider without experiencing diffs.\n\nExample with no prefix:\n\n```sh\n$ pulumi import random:index/id:Id server p-9hUg\n```\n\nExample with prefix (prefix is separated by a ,):\n\n```sh\n$ pulumi import random:index/id:Id server my-prefix-,p-9hUg\n```\n\n", + "description": "The resource `random.Id` generates random numbers that are intended to be\nused as unique identifiers for other resources. If the output is considered \nsensitive, and should not be displayed in the CLI, use `random.Bytes`\ninstead.\n\nThis resource *does* use a cryptographic random number generator in order\nto minimize the chance of collisions, making the results of this resource\nwhen a 16-byte identifier is requested of equivalent uniqueness to a\ntype-4 UUID.\n\nThis resource can be used in conjunction with resources that have\nthe `create_before_destroy` lifecycle flag set to avoid conflicts with\nunique names during the brief period where both the old and new resources\nexist concurrently.\n\n## Example Usage\n\n\u003c!--Start PulumiCodeChooser --\u003e\n```typescript\nimport * as pulumi from \"@pulumi/pulumi\";\nimport * as aws from \"@pulumi/aws\";\nimport * as random from \"@pulumi/random\";\n\n// The following example shows how to generate a unique name for an AWS EC2\n// instance that changes each time a new AMI id is selected.\nconst serverId = new random.Id(\"serverId\", {\n keepers: {\n ami_id: _var.ami_id,\n },\n byteLength: 8,\n});\nconst serveraws_instance = new aws.index.Aws_instance(\"serveraws_instance\", {\n tags: {\n Name: `web-server ${serverId.hex}`,\n },\n ami: serverId.keepers?.amiId,\n});\n// ... (other aws_instance arguments) ...\n```\n```python\nimport pulumi\nimport pulumi_aws as aws\nimport pulumi_random as random\n\n# The following example shows how to generate a unique name for an AWS EC2\n# instance that changes each time a new AMI id is selected.\nserver_id = random.Id(\"serverId\",\n keepers={\n \"ami_id\": var[\"ami_id\"],\n },\n byte_length=8)\nserveraws_instance = aws.index.Aws_instance(\"serveraws_instance\",\n tags={\n Name: fweb-server {server_id.hex},\n },\n ami=server_id.keepers.ami_id)\n# ... (other aws_instance arguments) ...\n```\n```csharp\nusing System.Collections.Generic;\nusing System.Linq;\nusing Pulumi;\nusing Aws = Pulumi.Aws;\nusing Random = Pulumi.Random;\n\nreturn await Deployment.RunAsync(() =\u003e \n{\n // The following example shows how to generate a unique name for an AWS EC2\n // instance that changes each time a new AMI id is selected.\n var serverId = new Random.Id(\"serverId\", new()\n {\n Keepers = \n {\n { \"ami_id\", @var.Ami_id },\n },\n ByteLength = 8,\n });\n\n var serveraws_instance = new Aws.Index.Aws_instance(\"serveraws_instance\", new()\n {\n Tags = \n {\n { \"Name\", $\"web-server {serverId.Hex}\" },\n },\n Ami = serverId.Keepers?.AmiId,\n });\n\n // ... (other aws_instance arguments) ...\n});\n```\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/pulumi/pulumi-aws/sdk/go/aws\"\n\t\"github.com/pulumi/pulumi-terraform-provider/sdks/go/random/v3/random\"\n\t\"github.com/pulumi/pulumi/sdk/v3/go/pulumi\"\n)\n\nfunc main() {\n\tpulumi.Run(func(ctx *pulumi.Context) error {\n\t\t// The following example shows how to generate a unique name for an AWS EC2\n\t\t// instance that changes each time a new AMI id is selected.\n\t\tserverId, err := random.NewId(ctx, \"serverId\", \u0026random.IdArgs{\n\t\t\tKeepers: pulumi.StringMap{\n\t\t\t\t\"ami_id\": pulumi.Any(_var.Ami_id),\n\t\t\t},\n\t\t\tByteLength: pulumi.Float64(8),\n\t\t})\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\t_, err = aws.NewAws_instance(ctx, \"serveraws_instance\", \u0026aws.Aws_instanceArgs{\n\t\t\tTags: map[string]interface{}{\n\t\t\t\t\"Name\": pulumi.Sprintf(\"web-server %v\", serverId.Hex),\n\t\t\t},\n\t\t\tAmi: serverId.Keepers.AmiId,\n\t\t})\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn nil\n\t})\n}\n```\n```java\npackage generated_program;\n\nimport com.pulumi.Context;\nimport com.pulumi.Pulumi;\nimport com.pulumi.core.Output;\nimport com.pulumi.random.Id;\nimport com.pulumi.random.IdArgs;\nimport com.pulumi.aws.aws_instance;\nimport com.pulumi.aws.Aws_instanceArgs;\nimport java.util.List;\nimport java.util.ArrayList;\nimport java.util.Map;\nimport java.io.File;\nimport java.nio.file.Files;\nimport java.nio.file.Paths;\n\npublic class App {\n public static void main(String[] args) {\n Pulumi.run(App::stack);\n }\n\n public static void stack(Context ctx) {\n // The following example shows how to generate a unique name for an AWS EC2\n // instance that changes each time a new AMI id is selected.\n var serverId = new Id(\"serverId\", IdArgs.builder()\n .keepers(Map.of(\"ami_id\", var_.ami_id()))\n .byteLength(8)\n .build());\n\n var serveraws_instance = new Aws_instance(\"serveraws_instance\", Aws_instanceArgs.builder()\n .tags(%!v(PANIC=Format method: runtime error: invalid memory address or nil pointer dereference))\n .ami(serverId.keepers().amiId())\n .build());\n\n // ... (other aws_instance arguments) ...\n }\n}\n```\n```yaml\nresources:\n # The following example shows how to generate a unique name for an AWS EC2\n # instance that changes each time a new AMI id is selected.\n serverId:\n type: random:Id\n properties:\n keepers:\n ami_id: ${var.ami_id}\n byteLength: 8\n serveraws_instance:\n type: aws:aws_instance\n properties:\n tags:\n Name: web-server ${serverId.hex}\n # Read the AMI id \"through\" the random_id resource to ensure that\n # # both will change together.\n ami: ${serverId.keepers.amiId}\n```\n\u003c!--End PulumiCodeChooser --\u003e\n\n## Import\n\nRandom IDs can be imported using the b64_url with an optional prefix. This\n\ncan be used to replace a config value with a value interpolated from the\n\nrandom provider without experiencing diffs.\n\nExample with no prefix:\n\n```sh\n$ pulumi import random:index/id:Id server p-9hUg\n```\n\nExample with prefix (prefix is separated by a ,):\n\n```sh\n$ pulumi import random:index/id:Id server my-prefix-,p-9hUg\n```\n\n", "properties": { "b64Std": { "type": "string", @@ -223,7 +223,7 @@ } }, "random:index/integer:Integer": { - "description": "The resource `random.Integer` generates random values from a given range, described by the `min` and `max` attributes of a given resource.\n\nThis resource can be used in conjunction with resources that have the `create_before_destroy` lifecycle flag set, to avoid conflicts with unique names during the brief period where both the old and new resources exist concurrently.\n\n## Example Usage\n\n\u003c!--Start PulumiCodeChooser --\u003e\n```typescript\nimport * as pulumi from \"@pulumi/pulumi\";\nimport * as aws from \"@pulumi/aws\";\nimport * as random from \"@pulumi/random\";\n\n// The following example shows how to generate a random priority\n// between 1 and 50000 for a aws_alb_listener_rule resource:\nconst priority = new random.Integer(\"priority\", {\n min: 1,\n max: 50000,\n keepers: {\n listener_arn: _var.listener_arn,\n },\n});\nconst main = new aws.alb.ListenerRule(\"main\", {\n listenerArn: priority.keepers.apply(keepers =\u003e keepers?.listenerArn),\n priority: priority.result,\n actions: [{\n type: \"forward\",\n targetGroupArn: _var.target_group_arn,\n }],\n});\n// ... (other aws_alb_listener_rule arguments) ...\n```\n```python\nimport pulumi\nimport pulumi_aws as aws\nimport pulumi_random as random\n\n# The following example shows how to generate a random priority\n# between 1 and 50000 for a aws_alb_listener_rule resource:\npriority = random.Integer(\"priority\",\n min=1,\n max=50000,\n keepers={\n \"listener_arn\": var[\"listener_arn\"],\n })\nmain = aws.alb.ListenerRule(\"main\",\n listener_arn=priority.keepers[\"listenerArn\"],\n priority=priority.result,\n actions=[{\n \"type\": \"forward\",\n \"target_group_arn\": var[\"target_group_arn\"],\n }])\n# ... (other aws_alb_listener_rule arguments) ...\n```\n```csharp\nusing System.Collections.Generic;\nusing System.Linq;\nusing Pulumi;\nusing Aws = Pulumi.Aws;\nusing Random = Pulumi.Random;\n\nreturn await Deployment.RunAsync(() =\u003e \n{\n // The following example shows how to generate a random priority\n // between 1 and 50000 for a aws_alb_listener_rule resource:\n var priority = new Random.Integer(\"priority\", new()\n {\n Min = 1,\n Max = 50000,\n Keepers = \n {\n { \"listener_arn\", @var.Listener_arn },\n },\n });\n\n var main = new Aws.Alb.ListenerRule(\"main\", new()\n {\n ListenerArn = priority.Keepers.Apply(keepers =\u003e keepers?.ListenerArn),\n Priority = priority.Result,\n Actions = new[]\n {\n new Aws.Alb.Inputs.ListenerRuleActionArgs\n {\n Type = \"forward\",\n TargetGroupArn = @var.Target_group_arn,\n },\n },\n });\n\n // ... (other aws_alb_listener_rule arguments) ...\n});\n```\n```go\npackage main\n\nimport (\n\t\"github.com/pulumi/pulumi-aws/sdk/v6/go/aws/alb\"\n\trandom \"github.com/pulumi/pulumi-terraform-provider/sdks/go/random/v3\"\n\t\"github.com/pulumi/pulumi/sdk/v3/go/pulumi\"\n)\n\nfunc main() {\n\tpulumi.Run(func(ctx *pulumi.Context) error {\n\t\t// The following example shows how to generate a random priority\n\t\t// between 1 and 50000 for a aws_alb_listener_rule resource:\n\t\tpriority, err := random.NewInteger(ctx, \"priority\", \u0026random.IntegerArgs{\n\t\t\tMin: pulumi.Float64(1),\n\t\t\tMax: pulumi.Float64(50000),\n\t\t\tKeepers: pulumi.StringMap{\n\t\t\t\t\"listener_arn\": pulumi.Any(_var.Listener_arn),\n\t\t\t},\n\t\t})\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\t_, err = alb.NewListenerRule(ctx, \"main\", \u0026alb.ListenerRuleArgs{\n\t\t\tListenerArn: pulumi.String(priority.Keepers.ApplyT(func(keepers map[string]string) (*string, error) {\n\t\t\t\treturn \u0026keepers.ListenerArn, nil\n\t\t\t}).(pulumi.StringPtrOutput)),\n\t\t\tPriority: priority.Result,\n\t\t\tActions: alb.ListenerRuleActionArray{\n\t\t\t\t\u0026alb.ListenerRuleActionArgs{\n\t\t\t\t\tType: pulumi.String(\"forward\"),\n\t\t\t\t\tTargetGroupArn: pulumi.Any(_var.Target_group_arn),\n\t\t\t\t},\n\t\t\t},\n\t\t})\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn nil\n\t})\n}\n```\n```java\npackage generated_program;\n\nimport com.pulumi.Context;\nimport com.pulumi.Pulumi;\nimport com.pulumi.core.Output;\nimport com.pulumi.random.Integer;\nimport com.pulumi.random.IntegerArgs;\nimport com.pulumi.aws.alb.ListenerRule;\nimport com.pulumi.aws.alb.ListenerRuleArgs;\nimport com.pulumi.aws.alb.inputs.ListenerRuleActionArgs;\nimport java.util.List;\nimport java.util.ArrayList;\nimport java.util.Map;\nimport java.io.File;\nimport java.nio.file.Files;\nimport java.nio.file.Paths;\n\npublic class App {\n public static void main(String[] args) {\n Pulumi.run(App::stack);\n }\n\n public static void stack(Context ctx) {\n // The following example shows how to generate a random priority\n // between 1 and 50000 for a aws_alb_listener_rule resource:\n var priority = new Integer(\"priority\", IntegerArgs.builder()\n .min(1)\n .max(50000)\n .keepers(Map.of(\"listener_arn\", var_.listener_arn()))\n .build());\n\n var main = new ListenerRule(\"main\", ListenerRuleArgs.builder()\n .listenerArn(priority.keepers().applyValue(keepers -\u003e keepers.listenerArn()))\n .priority(priority.result())\n .actions(ListenerRuleActionArgs.builder()\n .type(\"forward\")\n .targetGroupArn(var_.target_group_arn())\n .build())\n .build());\n\n // ... (other aws_alb_listener_rule arguments) ...\n }\n}\n```\n```yaml\nresources:\n # The following example shows how to generate a random priority\n # between 1 and 50000 for a aws_alb_listener_rule resource:\n priority:\n type: random:Integer\n properties:\n min: 1\n max: 50000\n keepers:\n listener_arn: ${var.listener_arn}\n main:\n type: aws:alb:ListenerRule\n properties:\n listenerArn: ${priority.keepers.listenerArn}\n priority: ${priority.result}\n actions:\n - type: forward\n targetGroupArn: ${var.target_group_arn}\n```\n\u003c!--End PulumiCodeChooser --\u003e\n\n## Import\n\nRandom integers can be imported using the result, min, and max, with an\n\noptional seed. This can be used to replace a config value with a value\n\ninterpolated from the random provider without experiencing diffs.\n\nExample (values are separated by a ,):\n\n```sh\n$ pulumi import random:index/integer:Integer priority 15390,1,50000\n```\n\n", + "description": "The resource `random.Integer` generates random values from a given range, described by the `min` and `max` attributes of a given resource.\n\nThis resource can be used in conjunction with resources that have the `create_before_destroy` lifecycle flag set, to avoid conflicts with unique names during the brief period where both the old and new resources exist concurrently.\n\n## Example Usage\n\n\u003c!--Start PulumiCodeChooser --\u003e\n```typescript\nimport * as pulumi from \"@pulumi/pulumi\";\nimport * as aws from \"@pulumi/aws\";\nimport * as random from \"@pulumi/random\";\n\n// The following example shows how to generate a random priority\n// between 1 and 50000 for a aws_alb_listener_rule resource:\nconst priority = new random.Integer(\"priority\", {\n min: 1,\n max: 50000,\n keepers: {\n listener_arn: _var.listener_arn,\n },\n});\nconst main = new aws.index.Aws_alb_listener_rule(\"main\", {\n listenerArn: priority.keepers?.listenerArn,\n priority: priority.result,\n action: [{\n type: \"forward\",\n targetGroupArn: _var.target_group_arn,\n }],\n});\n// ... (other aws_alb_listener_rule arguments) ...\n```\n```python\nimport pulumi\nimport pulumi_aws as aws\nimport pulumi_random as random\n\n# The following example shows how to generate a random priority\n# between 1 and 50000 for a aws_alb_listener_rule resource:\npriority = random.Integer(\"priority\",\n min=1,\n max=50000,\n keepers={\n \"listener_arn\": var[\"listener_arn\"],\n })\nmain = aws.index.Aws_alb_listener_rule(\"main\",\n listener_arn=priority.keepers.listener_arn,\n priority=priority.result,\n action=[{\n type: forward,\n targetGroupArn: var.target_group_arn,\n }])\n# ... (other aws_alb_listener_rule arguments) ...\n```\n```csharp\nusing System.Collections.Generic;\nusing System.Linq;\nusing Pulumi;\nusing Aws = Pulumi.Aws;\nusing Random = Pulumi.Random;\n\nreturn await Deployment.RunAsync(() =\u003e \n{\n // The following example shows how to generate a random priority\n // between 1 and 50000 for a aws_alb_listener_rule resource:\n var priority = new Random.Integer(\"priority\", new()\n {\n Min = 1,\n Max = 50000,\n Keepers = \n {\n { \"listener_arn\", @var.Listener_arn },\n },\n });\n\n var main = new Aws.Index.Aws_alb_listener_rule(\"main\", new()\n {\n ListenerArn = priority.Keepers?.ListenerArn,\n Priority = priority.Result,\n Action = new[]\n {\n \n {\n { \"type\", \"forward\" },\n { \"targetGroupArn\", @var.Target_group_arn },\n },\n },\n });\n\n // ... (other aws_alb_listener_rule arguments) ...\n});\n```\n```go\npackage main\n\nimport (\n\t\"github.com/pulumi/pulumi-aws/sdk/go/aws\"\n\t\"github.com/pulumi/pulumi-terraform-provider/sdks/go/random/v3/random\"\n\t\"github.com/pulumi/pulumi/sdk/v3/go/pulumi\"\n)\n\nfunc main() {\n\tpulumi.Run(func(ctx *pulumi.Context) error {\n\t\t// The following example shows how to generate a random priority\n\t\t// between 1 and 50000 for a aws_alb_listener_rule resource:\n\t\tpriority, err := random.NewInteger(ctx, \"priority\", \u0026random.IntegerArgs{\n\t\t\tMin: pulumi.Float64(1),\n\t\t\tMax: pulumi.Float64(50000),\n\t\t\tKeepers: pulumi.StringMap{\n\t\t\t\t\"listener_arn\": pulumi.Any(_var.Listener_arn),\n\t\t\t},\n\t\t})\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\t_, err = aws.NewAws_alb_listener_rule(ctx, \"main\", \u0026aws.Aws_alb_listener_ruleArgs{\n\t\t\tListenerArn: priority.Keepers.ListenerArn,\n\t\t\tPriority: priority.Result,\n\t\t\tAction: []map[string]interface{}{\n\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\"type\": \"forward\",\n\t\t\t\t\t\"targetGroupArn\": _var.Target_group_arn,\n\t\t\t\t},\n\t\t\t},\n\t\t})\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn nil\n\t})\n}\n```\n```java\npackage generated_program;\n\nimport com.pulumi.Context;\nimport com.pulumi.Pulumi;\nimport com.pulumi.core.Output;\nimport com.pulumi.random.Integer;\nimport com.pulumi.random.IntegerArgs;\nimport com.pulumi.aws.aws_alb_listener_rule;\nimport com.pulumi.aws.Aws_alb_listener_ruleArgs;\nimport java.util.List;\nimport java.util.ArrayList;\nimport java.util.Map;\nimport java.io.File;\nimport java.nio.file.Files;\nimport java.nio.file.Paths;\n\npublic class App {\n public static void main(String[] args) {\n Pulumi.run(App::stack);\n }\n\n public static void stack(Context ctx) {\n // The following example shows how to generate a random priority\n // between 1 and 50000 for a aws_alb_listener_rule resource:\n var priority = new Integer(\"priority\", IntegerArgs.builder()\n .min(1)\n .max(50000)\n .keepers(Map.of(\"listener_arn\", var_.listener_arn()))\n .build());\n\n var main = new Aws_alb_listener_rule(\"main\", Aws_alb_listener_ruleArgs.builder()\n .listenerArn(priority.keepers().listenerArn())\n .priority(priority.result())\n .action(%!v(PANIC=Format method: runtime error: invalid memory address or nil pointer dereference))\n .build());\n\n // ... (other aws_alb_listener_rule arguments) ...\n }\n}\n```\n```yaml\nresources:\n # The following example shows how to generate a random priority\n # between 1 and 50000 for a aws_alb_listener_rule resource:\n priority:\n type: random:Integer\n properties:\n min: 1\n max: 50000\n keepers:\n listener_arn: ${var.listener_arn}\n main:\n type: aws:aws_alb_listener_rule\n properties:\n listenerArn: ${priority.keepers.listenerArn}\n priority: ${priority.result}\n action:\n - type: forward\n targetGroupArn: ${var.target_group_arn}\n```\n\u003c!--End PulumiCodeChooser --\u003e\n\n## Import\n\nRandom integers can be imported using the result, min, and max, with an\n\noptional seed. This can be used to replace a config value with a value\n\ninterpolated from the random provider without experiencing diffs.\n\nExample (values are separated by a ,):\n\n```sh\n$ pulumi import random:index/integer:Integer priority 15390,1,50000\n```\n\n", "properties": { "keepers": { "type": "object", @@ -310,7 +310,7 @@ } }, "random:index/password:Password": { - "description": "## Example Usage\n\n\u003c!--Start PulumiCodeChooser --\u003e\n```typescript\nimport * as pulumi from \"@pulumi/pulumi\";\nimport * as aws from \"@pulumi/aws\";\nimport * as random from \"@pulumi/random\";\n\nconst password = new random.Password(\"password\", {\n length: 16,\n special: true,\n overrideSpecial: \"!#$%\u0026*()-_=+[]{}\u003c\u003e:?\",\n});\nconst example = new aws.rds.Instance(\"example\", {\n instanceClass: aws.rds.InstanceType.T3_Micro,\n allocatedStorage: 64,\n engine: \"mysql\",\n username: \"someone\",\n password: password.result,\n});\n```\n```python\nimport pulumi\nimport pulumi_aws as aws\nimport pulumi_random as random\n\npassword = random.Password(\"password\",\n length=16,\n special=True,\n override_special=\"!#$%\u0026*()-_=+[]{}\u003c\u003e:?\")\nexample = aws.rds.Instance(\"example\",\n instance_class=aws.rds.InstanceType.T3_MICRO,\n allocated_storage=64,\n engine=\"mysql\",\n username=\"someone\",\n password=password.result)\n```\n```csharp\nusing System.Collections.Generic;\nusing System.Linq;\nusing Pulumi;\nusing Aws = Pulumi.Aws;\nusing Random = Pulumi.Random;\n\nreturn await Deployment.RunAsync(() =\u003e \n{\n var password = new Random.Password(\"password\", new()\n {\n Length = 16,\n Special = true,\n OverrideSpecial = \"!#$%\u0026*()-_=+[]{}\u003c\u003e:?\",\n });\n\n var example = new Aws.Rds.Instance(\"example\", new()\n {\n InstanceClass = Aws.Rds.InstanceType.T3_Micro,\n AllocatedStorage = 64,\n Engine = \"mysql\",\n Username = \"someone\",\n Password = password.Result,\n });\n\n});\n```\n```go\npackage main\n\nimport (\n\t\"github.com/pulumi/pulumi-aws/sdk/v6/go/aws/rds\"\n\trandom \"github.com/pulumi/pulumi-terraform-provider/sdks/go/random/v3\"\n\t\"github.com/pulumi/pulumi/sdk/v3/go/pulumi\"\n)\n\nfunc main() {\n\tpulumi.Run(func(ctx *pulumi.Context) error {\n\t\tpassword, err := random.NewPassword(ctx, \"password\", \u0026random.PasswordArgs{\n\t\t\tLength: pulumi.Float64(16),\n\t\t\tSpecial: pulumi.Bool(true),\n\t\t\tOverrideSpecial: pulumi.String(\"!#$%\u0026*()-_=+[]{}\u003c\u003e:?\"),\n\t\t})\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\t_, err = rds.NewInstance(ctx, \"example\", \u0026rds.InstanceArgs{\n\t\t\tInstanceClass: pulumi.String(rds.InstanceType_T3_Micro),\n\t\t\tAllocatedStorage: pulumi.Int(64),\n\t\t\tEngine: pulumi.String(\"mysql\"),\n\t\t\tUsername: pulumi.String(\"someone\"),\n\t\t\tPassword: password.Result,\n\t\t})\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn nil\n\t})\n}\n```\n```java\npackage generated_program;\n\nimport com.pulumi.Context;\nimport com.pulumi.Pulumi;\nimport com.pulumi.core.Output;\nimport com.pulumi.random.Password;\nimport com.pulumi.random.PasswordArgs;\nimport com.pulumi.aws.rds.Instance;\nimport com.pulumi.aws.rds.InstanceArgs;\nimport java.util.List;\nimport java.util.ArrayList;\nimport java.util.Map;\nimport java.io.File;\nimport java.nio.file.Files;\nimport java.nio.file.Paths;\n\npublic class App {\n public static void main(String[] args) {\n Pulumi.run(App::stack);\n }\n\n public static void stack(Context ctx) {\n var password = new Password(\"password\", PasswordArgs.builder()\n .length(16)\n .special(true)\n .overrideSpecial(\"!#$%\u0026*()-_=+[]{}\u003c\u003e:?\")\n .build());\n\n var example = new Instance(\"example\", InstanceArgs.builder()\n .instanceClass(\"db.t3.micro\")\n .allocatedStorage(64)\n .engine(\"mysql\")\n .username(\"someone\")\n .password(password.result())\n .build());\n\n }\n}\n```\n```yaml\nresources:\n password:\n type: random:Password\n properties:\n length: 16\n special: true\n overrideSpecial: '!#$%\u0026*()-_=+[]{}\u003c\u003e:?'\n example:\n type: aws:rds:Instance\n properties:\n instanceClass: db.t3.micro\n allocatedStorage: 64\n engine: mysql\n username: someone\n password: ${password.result}\n```\n\u003c!--End PulumiCodeChooser --\u003e\n\n## Import\n\n### Avoiding Replacement\n\n```sh\n$ pulumi import random:index/password:Password If the resource were imported using `random_password.password securepassword`,\n```\n\nreplacement could be avoided by using:\n\n1. Attribute values that match the imported ID and defaults:\n\n terraform\n\n resource \"random_password\" \"password\" {\n\n length = 14\n\n lower = true\n\n }\n\n2. Attribute values that match the imported ID and omit the attributes with defaults:\n\n terraform\n\n resource \"random_password\" \"password\" {\n\n length = 14\n\n }\n\n3. `ignore_changes` specifying the attributes to ignore:\n\n terraform\n\n resource \"random_password\" \"password\" {\n\n length = 16\n\n lower = false\n\n lifecycle {\n\n ignore_changes = [\n\n length,\n\n lower,\n\n ]\n\n }\n\n }\n\n **NOTE** `ignore_changes` is only required until the resource is recreated after import,\n\n after which it will use the configuration values specified.\n\n", + "description": "## Example Usage\n\n\u003c!--Start PulumiCodeChooser --\u003e\n```typescript\nimport * as pulumi from \"@pulumi/pulumi\";\nimport * as aws from \"@pulumi/aws\";\nimport * as random from \"@pulumi/random\";\n\nconst password = new random.Password(\"password\", {\n length: 16,\n special: true,\n overrideSpecial: \"!#$%\u0026*()-_=+[]{}\u003c\u003e:?\",\n});\nconst example = new aws.index.Aws_db_instance(\"example\", {\n instanceClass: \"db.t3.micro\",\n allocatedStorage: 64,\n engine: \"mysql\",\n username: \"someone\",\n password: password.result,\n});\n```\n```python\nimport pulumi\nimport pulumi_aws as aws\nimport pulumi_random as random\n\npassword = random.Password(\"password\",\n length=16,\n special=True,\n override_special=\"!#$%\u0026*()-_=+[]{}\u003c\u003e:?\")\nexample = aws.index.Aws_db_instance(\"example\",\n instance_class=db.t3.micro,\n allocated_storage=64,\n engine=mysql,\n username=someone,\n password=password.result)\n```\n```csharp\nusing System.Collections.Generic;\nusing System.Linq;\nusing Pulumi;\nusing Aws = Pulumi.Aws;\nusing Random = Pulumi.Random;\n\nreturn await Deployment.RunAsync(() =\u003e \n{\n var password = new Random.Password(\"password\", new()\n {\n Length = 16,\n Special = true,\n OverrideSpecial = \"!#$%\u0026*()-_=+[]{}\u003c\u003e:?\",\n });\n\n var example = new Aws.Index.Aws_db_instance(\"example\", new()\n {\n InstanceClass = \"db.t3.micro\",\n AllocatedStorage = 64,\n Engine = \"mysql\",\n Username = \"someone\",\n Password = password.Result,\n });\n\n});\n```\n```go\npackage main\n\nimport (\n\t\"github.com/pulumi/pulumi-aws/sdk/go/aws\"\n\t\"github.com/pulumi/pulumi-terraform-provider/sdks/go/random/v3/random\"\n\t\"github.com/pulumi/pulumi/sdk/v3/go/pulumi\"\n)\n\nfunc main() {\n\tpulumi.Run(func(ctx *pulumi.Context) error {\n\t\tpassword, err := random.NewPassword(ctx, \"password\", \u0026random.PasswordArgs{\n\t\t\tLength: pulumi.Float64(16),\n\t\t\tSpecial: pulumi.Bool(true),\n\t\t\tOverrideSpecial: pulumi.String(\"!#$%\u0026*()-_=+[]{}\u003c\u003e:?\"),\n\t\t})\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\t_, err = aws.NewAws_db_instance(ctx, \"example\", \u0026aws.Aws_db_instanceArgs{\n\t\t\tInstanceClass: \"db.t3.micro\",\n\t\t\tAllocatedStorage: 64,\n\t\t\tEngine: \"mysql\",\n\t\t\tUsername: \"someone\",\n\t\t\tPassword: password.Result,\n\t\t})\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn nil\n\t})\n}\n```\n```java\npackage generated_program;\n\nimport com.pulumi.Context;\nimport com.pulumi.Pulumi;\nimport com.pulumi.core.Output;\nimport com.pulumi.random.Password;\nimport com.pulumi.random.PasswordArgs;\nimport com.pulumi.aws.aws_db_instance;\nimport com.pulumi.aws.Aws_db_instanceArgs;\nimport java.util.List;\nimport java.util.ArrayList;\nimport java.util.Map;\nimport java.io.File;\nimport java.nio.file.Files;\nimport java.nio.file.Paths;\n\npublic class App {\n public static void main(String[] args) {\n Pulumi.run(App::stack);\n }\n\n public static void stack(Context ctx) {\n var password = new Password(\"password\", PasswordArgs.builder()\n .length(16)\n .special(true)\n .overrideSpecial(\"!#$%\u0026*()-_=+[]{}\u003c\u003e:?\")\n .build());\n\n var example = new Aws_db_instance(\"example\", Aws_db_instanceArgs.builder()\n .instanceClass(\"db.t3.micro\")\n .allocatedStorage(64)\n .engine(\"mysql\")\n .username(\"someone\")\n .password(password.result())\n .build());\n\n }\n}\n```\n```yaml\nresources:\n password:\n type: random:Password\n properties:\n length: 16\n special: true\n overrideSpecial: '!#$%\u0026*()-_=+[]{}\u003c\u003e:?'\n example:\n type: aws:aws_db_instance\n properties:\n instanceClass: db.t3.micro\n allocatedStorage: 64\n engine: mysql\n username: someone\n password: ${password.result}\n```\n\u003c!--End PulumiCodeChooser --\u003e\n\n## Import\n\n### Avoiding Replacement\n\n```sh\n$ pulumi import random:index/password:Password If the resource were imported using `random_password.password securepassword`,\n```\n\nreplacement could be avoided by using:\n\n1. Attribute values that match the imported ID and defaults:\n\n terraform\n\n resource \"random_password\" \"password\" {\n\n length = 14\n\n lower = true\n\n }\n\n2. Attribute values that match the imported ID and omit the attributes with defaults:\n\n terraform\n\n resource \"random_password\" \"password\" {\n\n length = 14\n\n }\n\n3. `ignore_changes` specifying the attributes to ignore:\n\n terraform\n\n resource \"random_password\" \"password\" {\n\n length = 16\n\n lower = false\n\n lifecycle {\n\n ignore_changes = [\n\n length,\n\n lower,\n\n ]\n\n }\n\n }\n\n **NOTE** `ignore_changes` is only required until the resource is recreated after import,\n\n after which it will use the configuration values specified.\n\n", "properties": { "bcryptHash": { "type": "string", @@ -516,7 +516,7 @@ } }, "random:index/pet:Pet": { - "description": "The resource `random.Pet` generates random pet names that are intended to be used as unique identifiers for other resources.\n\nThis resource can be used in conjunction with resources that have the `create_before_destroy` lifecycle flag set, to avoid conflicts with unique names during the brief period where both the old and new resources exist concurrently.\n\n## Example Usage\n\n\u003c!--Start PulumiCodeChooser --\u003e\n```typescript\nimport * as pulumi from \"@pulumi/pulumi\";\nimport * as aws from \"@pulumi/aws\";\nimport * as random from \"@pulumi/random\";\n\n// The following example shows how to generate a unique pet name\n// for an AWS EC2 instance that changes each time a new AMI id is\n// selected.\nconst serverPet = new random.Pet(\"serverPet\", {keepers: {\n ami_id: _var.ami_id,\n}});\nconst serverInstance = new aws.ec2.Instance(\"serverInstance\", {\n tags: {\n Name: pulumi.interpolate`web-server-${serverPet.id}`,\n },\n ami: serverPet.keepers.apply(keepers =\u003e keepers?.amiId),\n});\n// ... (other aws_instance arguments) ...\n```\n```python\nimport pulumi\nimport pulumi_aws as aws\nimport pulumi_random as random\n\n# The following example shows how to generate a unique pet name\n# for an AWS EC2 instance that changes each time a new AMI id is\n# selected.\nserver_pet = random.Pet(\"serverPet\", keepers={\n \"ami_id\": var[\"ami_id\"],\n})\nserver_instance = aws.ec2.Instance(\"serverInstance\",\n tags={\n \"Name\": server_pet.id.apply(lambda id: f\"web-server-{id}\"),\n },\n ami=server_pet.keepers[\"amiId\"])\n# ... (other aws_instance arguments) ...\n```\n```csharp\nusing System.Collections.Generic;\nusing System.Linq;\nusing Pulumi;\nusing Aws = Pulumi.Aws;\nusing Random = Pulumi.Random;\n\nreturn await Deployment.RunAsync(() =\u003e \n{\n // The following example shows how to generate a unique pet name\n // for an AWS EC2 instance that changes each time a new AMI id is\n // selected.\n var serverPet = new Random.Pet(\"serverPet\", new()\n {\n Keepers = \n {\n { \"ami_id\", @var.Ami_id },\n },\n });\n\n var serverInstance = new Aws.Ec2.Instance(\"serverInstance\", new()\n {\n Tags = \n {\n { \"Name\", serverPet.Id.Apply(id =\u003e $\"web-server-{id}\") },\n },\n Ami = serverPet.Keepers.Apply(keepers =\u003e keepers?.AmiId),\n });\n\n // ... (other aws_instance arguments) ...\n});\n```\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/pulumi/pulumi-aws/sdk/v6/go/aws/ec2\"\n\trandom \"github.com/pulumi/pulumi-terraform-provider/sdks/go/random/v3\"\n\t\"github.com/pulumi/pulumi/sdk/v3/go/pulumi\"\n)\n\nfunc main() {\n\tpulumi.Run(func(ctx *pulumi.Context) error {\n\t\t// The following example shows how to generate a unique pet name\n\t\t// for an AWS EC2 instance that changes each time a new AMI id is\n\t\t// selected.\n\t\tserverPet, err := random.NewPet(ctx, \"serverPet\", \u0026random.PetArgs{\n\t\t\tKeepers: pulumi.StringMap{\n\t\t\t\t\"ami_id\": pulumi.Any(_var.Ami_id),\n\t\t\t},\n\t\t})\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\t_, err = ec2.NewInstance(ctx, \"serverInstance\", \u0026ec2.InstanceArgs{\n\t\t\tTags: pulumi.StringMap{\n\t\t\t\t\"Name\": serverPet.ID().ApplyT(func(id string) (string, error) {\n\t\t\t\t\treturn fmt.Sprintf(\"web-server-%v\", id), nil\n\t\t\t\t}).(pulumi.StringOutput),\n\t\t\t},\n\t\t\tAmi: pulumi.String(serverPet.Keepers.ApplyT(func(keepers map[string]string) (*string, error) {\n\t\t\t\treturn \u0026keepers.AmiId, nil\n\t\t\t}).(pulumi.StringPtrOutput)),\n\t\t})\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn nil\n\t})\n}\n```\n```java\npackage generated_program;\n\nimport com.pulumi.Context;\nimport com.pulumi.Pulumi;\nimport com.pulumi.core.Output;\nimport com.pulumi.random.Pet;\nimport com.pulumi.random.PetArgs;\nimport com.pulumi.aws.ec2.Instance;\nimport com.pulumi.aws.ec2.InstanceArgs;\nimport java.util.List;\nimport java.util.ArrayList;\nimport java.util.Map;\nimport java.io.File;\nimport java.nio.file.Files;\nimport java.nio.file.Paths;\n\npublic class App {\n public static void main(String[] args) {\n Pulumi.run(App::stack);\n }\n\n public static void stack(Context ctx) {\n // The following example shows how to generate a unique pet name\n // for an AWS EC2 instance that changes each time a new AMI id is\n // selected.\n var serverPet = new Pet(\"serverPet\", PetArgs.builder()\n .keepers(Map.of(\"ami_id\", var_.ami_id()))\n .build());\n\n var serverInstance = new Instance(\"serverInstance\", InstanceArgs.builder()\n .tags(Map.of(\"Name\", serverPet.id().applyValue(id -\u003e String.format(\"web-server-%s\", id))))\n .ami(serverPet.keepers().applyValue(keepers -\u003e keepers.amiId()))\n .build());\n\n // ... (other aws_instance arguments) ...\n }\n}\n```\n```yaml\nresources:\n # The following example shows how to generate a unique pet name\n # for an AWS EC2 instance that changes each time a new AMI id is\n # selected.\n serverPet:\n type: random:Pet\n properties:\n keepers:\n ami_id: ${var.ami_id}\n serverInstance:\n type: aws:ec2:Instance\n properties:\n tags:\n Name: web-server-${serverPet.id}\n # Read the AMI id \"through\" the random_pet resource to ensure that\n # # both will change together.\n ami: ${serverPet.keepers.amiId}\n```\n\u003c!--End PulumiCodeChooser --\u003e\n", + "description": "The resource `random.Pet` generates random pet names that are intended to be used as unique identifiers for other resources.\n\nThis resource can be used in conjunction with resources that have the `create_before_destroy` lifecycle flag set, to avoid conflicts with unique names during the brief period where both the old and new resources exist concurrently.\n\n## Example Usage\n\n\u003c!--Start PulumiCodeChooser --\u003e\n```typescript\nimport * as pulumi from \"@pulumi/pulumi\";\nimport * as aws from \"@pulumi/aws\";\nimport * as random from \"@pulumi/random\";\n\n// The following example shows how to generate a unique pet name\n// for an AWS EC2 instance that changes each time a new AMI id is\n// selected.\nconst serverPet = new random.Pet(\"serverPet\", {keepers: {\n ami_id: _var.ami_id,\n}});\nconst serveraws_instance = new aws.index.Aws_instance(\"serveraws_instance\", {\n tags: {\n Name: `web-server-${serverPet.id}`,\n },\n ami: serverPet.keepers?.amiId,\n});\n// ... (other aws_instance arguments) ...\n```\n```python\nimport pulumi\nimport pulumi_aws as aws\nimport pulumi_random as random\n\n# The following example shows how to generate a unique pet name\n# for an AWS EC2 instance that changes each time a new AMI id is\n# selected.\nserver_pet = random.Pet(\"serverPet\", keepers={\n \"ami_id\": var[\"ami_id\"],\n})\nserveraws_instance = aws.index.Aws_instance(\"serveraws_instance\",\n tags={\n Name: fweb-server-{server_pet.id},\n },\n ami=server_pet.keepers.ami_id)\n# ... (other aws_instance arguments) ...\n```\n```csharp\nusing System.Collections.Generic;\nusing System.Linq;\nusing Pulumi;\nusing Aws = Pulumi.Aws;\nusing Random = Pulumi.Random;\n\nreturn await Deployment.RunAsync(() =\u003e \n{\n // The following example shows how to generate a unique pet name\n // for an AWS EC2 instance that changes each time a new AMI id is\n // selected.\n var serverPet = new Random.Pet(\"serverPet\", new()\n {\n Keepers = \n {\n { \"ami_id\", @var.Ami_id },\n },\n });\n\n var serveraws_instance = new Aws.Index.Aws_instance(\"serveraws_instance\", new()\n {\n Tags = \n {\n { \"Name\", $\"web-server-{serverPet.Id}\" },\n },\n Ami = serverPet.Keepers?.AmiId,\n });\n\n // ... (other aws_instance arguments) ...\n});\n```\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/pulumi/pulumi-aws/sdk/go/aws\"\n\t\"github.com/pulumi/pulumi-terraform-provider/sdks/go/random/v3/random\"\n\t\"github.com/pulumi/pulumi/sdk/v3/go/pulumi\"\n)\n\nfunc main() {\n\tpulumi.Run(func(ctx *pulumi.Context) error {\n\t\t// The following example shows how to generate a unique pet name\n\t\t// for an AWS EC2 instance that changes each time a new AMI id is\n\t\t// selected.\n\t\tserverPet, err := random.NewPet(ctx, \"serverPet\", \u0026random.PetArgs{\n\t\t\tKeepers: pulumi.StringMap{\n\t\t\t\t\"ami_id\": pulumi.Any(_var.Ami_id),\n\t\t\t},\n\t\t})\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\t_, err = aws.NewAws_instance(ctx, \"serveraws_instance\", \u0026aws.Aws_instanceArgs{\n\t\t\tTags: map[string]interface{}{\n\t\t\t\t\"Name\": pulumi.Sprintf(\"web-server-%v\", serverPet.ID()),\n\t\t\t},\n\t\t\tAmi: serverPet.Keepers.AmiId,\n\t\t})\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn nil\n\t})\n}\n```\n```java\npackage generated_program;\n\nimport com.pulumi.Context;\nimport com.pulumi.Pulumi;\nimport com.pulumi.core.Output;\nimport com.pulumi.random.Pet;\nimport com.pulumi.random.PetArgs;\nimport com.pulumi.aws.aws_instance;\nimport com.pulumi.aws.Aws_instanceArgs;\nimport java.util.List;\nimport java.util.ArrayList;\nimport java.util.Map;\nimport java.io.File;\nimport java.nio.file.Files;\nimport java.nio.file.Paths;\n\npublic class App {\n public static void main(String[] args) {\n Pulumi.run(App::stack);\n }\n\n public static void stack(Context ctx) {\n // The following example shows how to generate a unique pet name\n // for an AWS EC2 instance that changes each time a new AMI id is\n // selected.\n var serverPet = new Pet(\"serverPet\", PetArgs.builder()\n .keepers(Map.of(\"ami_id\", var_.ami_id()))\n .build());\n\n var serveraws_instance = new Aws_instance(\"serveraws_instance\", Aws_instanceArgs.builder()\n .tags(%!v(PANIC=Format method: runtime error: invalid memory address or nil pointer dereference))\n .ami(serverPet.keepers().amiId())\n .build());\n\n // ... (other aws_instance arguments) ...\n }\n}\n```\n```yaml\nresources:\n # The following example shows how to generate a unique pet name\n # for an AWS EC2 instance that changes each time a new AMI id is\n # selected.\n serverPet:\n type: random:Pet\n properties:\n keepers:\n ami_id: ${var.ami_id}\n serveraws_instance:\n type: aws:aws_instance\n properties:\n tags:\n Name: web-server-${serverPet.id}\n # Read the AMI id \"through\" the random_pet resource to ensure that\n # # both will change together.\n ami: ${serverPet.keepers.amiId}\n```\n\u003c!--End PulumiCodeChooser --\u003e\n", "properties": { "keepers": { "type": "object", @@ -590,7 +590,7 @@ } }, "random:index/shuffle:Shuffle": { - "description": "The resource `random.Shuffle` generates a random permutation of a list of strings given as an argument.\n\n## Example Usage\n\n\u003c!--Start PulumiCodeChooser --\u003e\n```typescript\nimport * as pulumi from \"@pulumi/pulumi\";\nimport * as aws from \"@pulumi/aws\";\nimport * as random from \"@pulumi/random\";\n\nconst az = new random.Shuffle(\"az\", {\n inputs: [\n \"us-west-1a\",\n \"us-west-1c\",\n \"us-west-1d\",\n \"us-west-1e\",\n ],\n resultCount: 2,\n});\nconst example = new aws.elb.LoadBalancer(\"example\", {availabilityZones: az.results});\n// ... and other aws_elb arguments ...\n```\n```python\nimport pulumi\nimport pulumi_aws as aws\nimport pulumi_random as random\n\naz = random.Shuffle(\"az\",\n inputs=[\n \"us-west-1a\",\n \"us-west-1c\",\n \"us-west-1d\",\n \"us-west-1e\",\n ],\n result_count=2)\nexample = aws.elb.LoadBalancer(\"example\", availability_zones=az.results)\n# ... and other aws_elb arguments ...\n```\n```csharp\nusing System.Collections.Generic;\nusing System.Linq;\nusing Pulumi;\nusing Aws = Pulumi.Aws;\nusing Random = Pulumi.Random;\n\nreturn await Deployment.RunAsync(() =\u003e \n{\n var az = new Random.Shuffle(\"az\", new()\n {\n Inputs = new[]\n {\n \"us-west-1a\",\n \"us-west-1c\",\n \"us-west-1d\",\n \"us-west-1e\",\n },\n ResultCount = 2,\n });\n\n var example = new Aws.Elb.LoadBalancer(\"example\", new()\n {\n AvailabilityZones = az.Results,\n });\n\n // ... and other aws_elb arguments ...\n});\n```\n```go\npackage main\n\nimport (\n\t\"github.com/pulumi/pulumi-aws/sdk/v6/go/aws/elb\"\n\trandom \"github.com/pulumi/pulumi-terraform-provider/sdks/go/random/v3\"\n\t\"github.com/pulumi/pulumi/sdk/v3/go/pulumi\"\n)\n\nfunc main() {\n\tpulumi.Run(func(ctx *pulumi.Context) error {\n\t\taz, err := random.NewShuffle(ctx, \"az\", \u0026random.ShuffleArgs{\n\t\t\tInputs: pulumi.StringArray{\n\t\t\t\tpulumi.String(\"us-west-1a\"),\n\t\t\t\tpulumi.String(\"us-west-1c\"),\n\t\t\t\tpulumi.String(\"us-west-1d\"),\n\t\t\t\tpulumi.String(\"us-west-1e\"),\n\t\t\t},\n\t\t\tResultCount: pulumi.Float64(2),\n\t\t})\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\t_, err = elb.NewLoadBalancer(ctx, \"example\", \u0026elb.LoadBalancerArgs{\n\t\t\tAvailabilityZones: az.Results,\n\t\t})\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn nil\n\t})\n}\n```\n```java\npackage generated_program;\n\nimport com.pulumi.Context;\nimport com.pulumi.Pulumi;\nimport com.pulumi.core.Output;\nimport com.pulumi.random.Shuffle;\nimport com.pulumi.random.ShuffleArgs;\nimport com.pulumi.aws.elb.LoadBalancer;\nimport com.pulumi.aws.elb.LoadBalancerArgs;\nimport java.util.List;\nimport java.util.ArrayList;\nimport java.util.Map;\nimport java.io.File;\nimport java.nio.file.Files;\nimport java.nio.file.Paths;\n\npublic class App {\n public static void main(String[] args) {\n Pulumi.run(App::stack);\n }\n\n public static void stack(Context ctx) {\n var az = new Shuffle(\"az\", ShuffleArgs.builder()\n .inputs( \n \"us-west-1a\",\n \"us-west-1c\",\n \"us-west-1d\",\n \"us-west-1e\")\n .resultCount(2)\n .build());\n\n var example = new LoadBalancer(\"example\", LoadBalancerArgs.builder()\n .availabilityZones(az.results())\n .build());\n\n // ... and other aws_elb arguments ...\n }\n}\n```\n```yaml\nresources:\n az:\n type: random:Shuffle\n properties:\n inputs:\n - us-west-1a\n - us-west-1c\n - us-west-1d\n - us-west-1e\n resultCount: 2\n example:\n type: aws:elb:LoadBalancer\n properties:\n # Place the ELB in any two of the given availability zones, selected\n # # at random.\n availabilityZones: ${az.results}\n```\n\u003c!--End PulumiCodeChooser --\u003e\n", + "description": "The resource `random.Shuffle` generates a random permutation of a list of strings given as an argument.\n\n## Example Usage\n\n\u003c!--Start PulumiCodeChooser --\u003e\n```typescript\nimport * as pulumi from \"@pulumi/pulumi\";\nimport * as aws from \"@pulumi/aws\";\nimport * as random from \"@pulumi/random\";\n\nconst az = new random.Shuffle(\"az\", {\n inputs: [\n \"us-west-1a\",\n \"us-west-1c\",\n \"us-west-1d\",\n \"us-west-1e\",\n ],\n resultCount: 2,\n});\nconst example = new aws.index.Aws_elb(\"example\", {availabilityZones: az.results});\n// ... and other aws_elb arguments ...\n```\n```python\nimport pulumi\nimport pulumi_aws as aws\nimport pulumi_random as random\n\naz = random.Shuffle(\"az\",\n inputs=[\n \"us-west-1a\",\n \"us-west-1c\",\n \"us-west-1d\",\n \"us-west-1e\",\n ],\n result_count=2)\nexample = aws.index.Aws_elb(\"example\", availability_zones=az.results)\n# ... and other aws_elb arguments ...\n```\n```csharp\nusing System.Collections.Generic;\nusing System.Linq;\nusing Pulumi;\nusing Aws = Pulumi.Aws;\nusing Random = Pulumi.Random;\n\nreturn await Deployment.RunAsync(() =\u003e \n{\n var az = new Random.Shuffle(\"az\", new()\n {\n Inputs = new[]\n {\n \"us-west-1a\",\n \"us-west-1c\",\n \"us-west-1d\",\n \"us-west-1e\",\n },\n ResultCount = 2,\n });\n\n var example = new Aws.Index.Aws_elb(\"example\", new()\n {\n AvailabilityZones = az.Results,\n });\n\n // ... and other aws_elb arguments ...\n});\n```\n```go\npackage main\n\nimport (\n\t\"github.com/pulumi/pulumi-aws/sdk/go/aws\"\n\t\"github.com/pulumi/pulumi-terraform-provider/sdks/go/random/v3/random\"\n\t\"github.com/pulumi/pulumi/sdk/v3/go/pulumi\"\n)\n\nfunc main() {\n\tpulumi.Run(func(ctx *pulumi.Context) error {\n\t\taz, err := random.NewShuffle(ctx, \"az\", \u0026random.ShuffleArgs{\n\t\t\tInputs: pulumi.StringArray{\n\t\t\t\tpulumi.String(\"us-west-1a\"),\n\t\t\t\tpulumi.String(\"us-west-1c\"),\n\t\t\t\tpulumi.String(\"us-west-1d\"),\n\t\t\t\tpulumi.String(\"us-west-1e\"),\n\t\t\t},\n\t\t\tResultCount: pulumi.Float64(2),\n\t\t})\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\t_, err = aws.NewAws_elb(ctx, \"example\", \u0026aws.Aws_elbArgs{\n\t\t\tAvailabilityZones: az.Results,\n\t\t})\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn nil\n\t})\n}\n```\n```java\npackage generated_program;\n\nimport com.pulumi.Context;\nimport com.pulumi.Pulumi;\nimport com.pulumi.core.Output;\nimport com.pulumi.random.Shuffle;\nimport com.pulumi.random.ShuffleArgs;\nimport com.pulumi.aws.aws_elb;\nimport com.pulumi.aws.Aws_elbArgs;\nimport java.util.List;\nimport java.util.ArrayList;\nimport java.util.Map;\nimport java.io.File;\nimport java.nio.file.Files;\nimport java.nio.file.Paths;\n\npublic class App {\n public static void main(String[] args) {\n Pulumi.run(App::stack);\n }\n\n public static void stack(Context ctx) {\n var az = new Shuffle(\"az\", ShuffleArgs.builder()\n .inputs( \n \"us-west-1a\",\n \"us-west-1c\",\n \"us-west-1d\",\n \"us-west-1e\")\n .resultCount(2)\n .build());\n\n var example = new Aws_elb(\"example\", Aws_elbArgs.builder()\n .availabilityZones(az.results())\n .build());\n\n // ... and other aws_elb arguments ...\n }\n}\n```\n```yaml\nresources:\n az:\n type: random:Shuffle\n properties:\n inputs:\n - us-west-1a\n - us-west-1c\n - us-west-1d\n - us-west-1e\n resultCount: 2\n example:\n type: aws:aws_elb\n properties:\n # Place the ELB in any two of the given availability zones, selected\n # # at random.\n availabilityZones: ${az.results}\n```\n\u003c!--End PulumiCodeChooser --\u003e\n", "properties": { "inputs": { "type": "array", @@ -690,7 +690,7 @@ } }, "random:index/string:String": { - "description": "The resource `random.String` generates a random permutation of alphanumeric characters and optionally special characters.\n\nThis resource *does* use a cryptographic random number generator.\n\nHistorically this resource's intended usage has been ambiguous as the original example used it in a password. For backwards compatibility it will continue to exist. For unique ids please use random_id, for sensitive random values please use random_password.\n\n## Example Usage\n\n\u003c!--Start PulumiCodeChooser --\u003e\n```typescript\nimport * as pulumi from \"@pulumi/pulumi\";\nimport * as random from \"@pulumi/random\";\n\nconst random = new random.String(\"random\", {\n length: 16,\n overrideSpecial: \"/@£$\",\n special: true,\n});\n```\n```python\nimport pulumi\nimport pulumi_random as random\n\nrandom = random.String(\"random\",\n length=16,\n override_special=\"/@£$\",\n special=True)\n```\n```csharp\nusing System.Collections.Generic;\nusing System.Linq;\nusing Pulumi;\nusing Random = Pulumi.Random;\n\nreturn await Deployment.RunAsync(() =\u003e \n{\n var random = new Random.String(\"random\", new()\n {\n Length = 16,\n OverrideSpecial = \"/@£$\",\n Special = true,\n });\n\n});\n```\n```go\npackage main\n\nimport (\n\trandom \"github.com/pulumi/pulumi-terraform-provider/sdks/go/random/v3\"\n\t\"github.com/pulumi/pulumi/sdk/v3/go/pulumi\"\n)\n\nfunc main() {\n\tpulumi.Run(func(ctx *pulumi.Context) error {\n\t\t_, err := random.NewString(ctx, \"random\", \u0026random.StringArgs{\n\t\t\tLength: pulumi.Float64(16),\n\t\t\tOverrideSpecial: pulumi.String(\"/@£$\"),\n\t\t\tSpecial: pulumi.Bool(true),\n\t\t})\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn nil\n\t})\n}\n```\n```java\npackage generated_program;\n\nimport com.pulumi.Context;\nimport com.pulumi.Pulumi;\nimport com.pulumi.core.Output;\nimport com.pulumi.random.String;\nimport com.pulumi.random.StringArgs;\nimport java.util.List;\nimport java.util.ArrayList;\nimport java.util.Map;\nimport java.io.File;\nimport java.nio.file.Files;\nimport java.nio.file.Paths;\n\npublic class App {\n public static void main(String[] args) {\n Pulumi.run(App::stack);\n }\n\n public static void stack(Context ctx) {\n var random = new String(\"random\", StringArgs.builder()\n .length(16)\n .overrideSpecial(\"/@£$\")\n .special(true)\n .build());\n\n }\n}\n```\n```yaml\nresources:\n random:\n type: random:String\n properties:\n length: 16\n overrideSpecial: /@£$\n special: true\n```\n\u003c!--End PulumiCodeChooser --\u003e\n\n## Import\n\n### Avoiding Replacement\n\n```sh\n$ pulumi import random:index/string:String If the resource were imported using `random_string.test test`,\n```\n\nreplacement can be avoided by using:\n\n1. Attribute values that match the imported ID and defaults:\n\n terraform\n\n resource \"random_string\" \"test\" {\n\n length = 4\n\n lower = true\n\n }\n\n2. Attribute values that match the imported ID and omit the attributes with defaults:\n\n terraform\n\n resource \"random_string\" \"test\" {\n\n length = 4\n\n }\n\n3. `ignore_changes` specifying the attributes to ignore:\n\n terraform\n\n resource \"random_string\" \"test\" {\n\n length = 16\n\n lower = false\n\n lifecycle {\n\n ignore_changes = [\n\n length,\n\n lower,\n\n ]\n\n }\n\n }\n\n **NOTE** `ignore_changes` is only required until the resource is recreated after import,\n\n after which it will use the configuration values specified.\n\n", + "description": "The resource `random.String` generates a random permutation of alphanumeric characters and optionally special characters.\n\nThis resource *does* use a cryptographic random number generator.\n\nHistorically this resource's intended usage has been ambiguous as the original example used it in a password. For backwards compatibility it will continue to exist. For unique ids please use random_id, for sensitive random values please use random_password.\n\n## Example Usage\n\n\u003c!--Start PulumiCodeChooser --\u003e\n```typescript\nimport * as pulumi from \"@pulumi/pulumi\";\nimport * as random from \"@pulumi/random\";\n\nconst random = new random.String(\"random\", {\n length: 16,\n overrideSpecial: \"/@£$\",\n special: true,\n});\n```\n```python\nimport pulumi\nimport pulumi_random as random\n\nrandom = random.String(\"random\",\n length=16,\n override_special=\"/@£$\",\n special=True)\n```\n```csharp\nusing System.Collections.Generic;\nusing System.Linq;\nusing Pulumi;\nusing Random = Pulumi.Random;\n\nreturn await Deployment.RunAsync(() =\u003e \n{\n var random = new Random.String(\"random\", new()\n {\n Length = 16,\n OverrideSpecial = \"/@£$\",\n Special = true,\n });\n\n});\n```\n```go\npackage main\n\nimport (\n\t\"github.com/pulumi/pulumi-terraform-provider/sdks/go/random/v3/random\"\n\t\"github.com/pulumi/pulumi/sdk/v3/go/pulumi\"\n)\n\nfunc main() {\n\tpulumi.Run(func(ctx *pulumi.Context) error {\n\t\t_, err := random.NewString(ctx, \"random\", \u0026random.StringArgs{\n\t\t\tLength: pulumi.Float64(16),\n\t\t\tOverrideSpecial: pulumi.String(\"/@£$\"),\n\t\t\tSpecial: pulumi.Bool(true),\n\t\t})\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn nil\n\t})\n}\n```\n```java\npackage generated_program;\n\nimport com.pulumi.Context;\nimport com.pulumi.Pulumi;\nimport com.pulumi.core.Output;\nimport com.pulumi.random.String;\nimport com.pulumi.random.StringArgs;\nimport java.util.List;\nimport java.util.ArrayList;\nimport java.util.Map;\nimport java.io.File;\nimport java.nio.file.Files;\nimport java.nio.file.Paths;\n\npublic class App {\n public static void main(String[] args) {\n Pulumi.run(App::stack);\n }\n\n public static void stack(Context ctx) {\n var random = new String(\"random\", StringArgs.builder()\n .length(16)\n .overrideSpecial(\"/@£$\")\n .special(true)\n .build());\n\n }\n}\n```\n```yaml\nresources:\n random:\n type: random:String\n properties:\n length: 16\n overrideSpecial: /@£$\n special: true\n```\n\u003c!--End PulumiCodeChooser --\u003e\n\n## Import\n\n### Avoiding Replacement\n\n```sh\n$ pulumi import random:index/string:String If the resource were imported using `random_string.test test`,\n```\n\nreplacement can be avoided by using:\n\n1. Attribute values that match the imported ID and defaults:\n\n terraform\n\n resource \"random_string\" \"test\" {\n\n length = 4\n\n lower = true\n\n }\n\n2. Attribute values that match the imported ID and omit the attributes with defaults:\n\n terraform\n\n resource \"random_string\" \"test\" {\n\n length = 4\n\n }\n\n3. `ignore_changes` specifying the attributes to ignore:\n\n terraform\n\n resource \"random_string\" \"test\" {\n\n length = 16\n\n lower = false\n\n lifecycle {\n\n ignore_changes = [\n\n length,\n\n lower,\n\n ]\n\n }\n\n }\n\n **NOTE** `ignore_changes` is only required until the resource is recreated after import,\n\n after which it will use the configuration values specified.\n\n", "properties": { "keepers": { "type": "object", @@ -883,7 +883,7 @@ } }, "random:index/uuid:Uuid": { - "description": "## Example Usage\n\n\u003c!--Start PulumiCodeChooser --\u003e\n```typescript\nimport * as pulumi from \"@pulumi/pulumi\";\nimport * as azurerm from \"@pulumi/azurerm\";\nimport * as random from \"@pulumi/random\";\n\n// The following example shows how to generate a unique name for an Azure Resource Group.\nconst testUuid = new random.Uuid(\"testUuid\", {});\nconst testazurerm_resource_group = new azurerm.index.Azurerm_resource_group(\"testazurerm_resource_group\", {\n name: `${testUuid.result}-rg`,\n location: \"Central US\",\n});\n```\n```python\nimport pulumi\nimport pulumi_azurerm as azurerm\nimport pulumi_random as random\n\n# The following example shows how to generate a unique name for an Azure Resource Group.\ntest_uuid = random.Uuid(\"testUuid\")\ntestazurerm_resource_group = azurerm.index.Azurerm_resource_group(\"testazurerm_resource_group\",\n name=f{test_uuid.result}-rg,\n location=Central US)\n```\n```csharp\nusing System.Collections.Generic;\nusing System.Linq;\nusing Pulumi;\nusing Azurerm = Pulumi.Azurerm;\nusing Random = Pulumi.Random;\n\nreturn await Deployment.RunAsync(() =\u003e \n{\n // The following example shows how to generate a unique name for an Azure Resource Group.\n var testUuid = new Random.Uuid(\"testUuid\");\n\n var testazurerm_resource_group = new Azurerm.Index.Azurerm_resource_group(\"testazurerm_resource_group\", new()\n {\n Name = $\"{testUuid.Result}-rg\",\n Location = \"Central US\",\n });\n\n});\n```\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/pulumi/pulumi-azurerm/sdk/go/azurerm\"\n\trandom \"github.com/pulumi/pulumi-terraform-provider/sdks/go/random/v3\"\n\t\"github.com/pulumi/pulumi/sdk/v3/go/pulumi\"\n)\n\nfunc main() {\n\tpulumi.Run(func(ctx *pulumi.Context) error {\n\t\t// The following example shows how to generate a unique name for an Azure Resource Group.\n\t\ttestUuid, err := random.NewUuid(ctx, \"testUuid\", nil)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\t_, err = azurerm.NewAzurerm_resource_group(ctx, \"testazurerm_resource_group\", \u0026azurerm.Azurerm_resource_groupArgs{\n\t\t\tName: pulumi.Sprintf(\"%v-rg\", testUuid.Result),\n\t\t\tLocation: \"Central US\",\n\t\t})\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn nil\n\t})\n}\n```\n```java\npackage generated_program;\n\nimport com.pulumi.Context;\nimport com.pulumi.Pulumi;\nimport com.pulumi.core.Output;\nimport com.pulumi.random.Uuid;\nimport com.pulumi.azurerm.azurerm_resource_group;\nimport com.pulumi.azurerm.Azurerm_resource_groupArgs;\nimport java.util.List;\nimport java.util.ArrayList;\nimport java.util.Map;\nimport java.io.File;\nimport java.nio.file.Files;\nimport java.nio.file.Paths;\n\npublic class App {\n public static void main(String[] args) {\n Pulumi.run(App::stack);\n }\n\n public static void stack(Context ctx) {\n // The following example shows how to generate a unique name for an Azure Resource Group.\n var testUuid = new Uuid(\"testUuid\");\n\n var testazurerm_resource_group = new Azurerm_resource_group(\"testazurerm_resource_group\", Azurerm_resource_groupArgs.builder()\n .name(String.format(\"%s-rg\", testUuid.result()))\n .location(\"Central US\")\n .build());\n\n }\n}\n```\n```yaml\nresources:\n # The following example shows how to generate a unique name for an Azure Resource Group.\n testUuid:\n type: random:Uuid\n testazurerm_resource_group:\n type: azurerm:azurerm_resource_group\n properties:\n name: ${testUuid.result}-rg\n location: Central US\n```\n\u003c!--End PulumiCodeChooser --\u003e\n\n## Import\n\nRandom UUID's can be imported. This can be used to replace a config\n\nvalue with a value interpolated from the random provider without\n\nexperiencing diffs.\n\n```sh\n$ pulumi import random:index/uuid:Uuid main aabbccdd-eeff-0011-2233-445566778899\n```\n\n", + "description": "## Example Usage\n\n\u003c!--Start PulumiCodeChooser --\u003e\n```typescript\nimport * as pulumi from \"@pulumi/pulumi\";\nimport * as azurerm from \"@pulumi/azurerm\";\nimport * as random from \"@pulumi/random\";\n\n// The following example shows how to generate a unique name for an Azure Resource Group.\nconst testUuid = new random.Uuid(\"testUuid\", {});\nconst testazurerm_resource_group = new azurerm.index.Azurerm_resource_group(\"testazurerm_resource_group\", {\n name: `${testUuid.result}-rg`,\n location: \"Central US\",\n});\n```\n```python\nimport pulumi\nimport pulumi_azurerm as azurerm\nimport pulumi_random as random\n\n# The following example shows how to generate a unique name for an Azure Resource Group.\ntest_uuid = random.Uuid(\"testUuid\")\ntestazurerm_resource_group = azurerm.index.Azurerm_resource_group(\"testazurerm_resource_group\",\n name=f{test_uuid.result}-rg,\n location=Central US)\n```\n```csharp\nusing System.Collections.Generic;\nusing System.Linq;\nusing Pulumi;\nusing Azurerm = Pulumi.Azurerm;\nusing Random = Pulumi.Random;\n\nreturn await Deployment.RunAsync(() =\u003e \n{\n // The following example shows how to generate a unique name for an Azure Resource Group.\n var testUuid = new Random.Uuid(\"testUuid\");\n\n var testazurerm_resource_group = new Azurerm.Index.Azurerm_resource_group(\"testazurerm_resource_group\", new()\n {\n Name = $\"{testUuid.Result}-rg\",\n Location = \"Central US\",\n });\n\n});\n```\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/pulumi/pulumi-azurerm/sdk/go/azurerm\"\n\t\"github.com/pulumi/pulumi-terraform-provider/sdks/go/random/v3/random\"\n\t\"github.com/pulumi/pulumi/sdk/v3/go/pulumi\"\n)\n\nfunc main() {\n\tpulumi.Run(func(ctx *pulumi.Context) error {\n\t\t// The following example shows how to generate a unique name for an Azure Resource Group.\n\t\ttestUuid, err := random.NewUuid(ctx, \"testUuid\", nil)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\t_, err = azurerm.NewAzurerm_resource_group(ctx, \"testazurerm_resource_group\", \u0026azurerm.Azurerm_resource_groupArgs{\n\t\t\tName: pulumi.Sprintf(\"%v-rg\", testUuid.Result),\n\t\t\tLocation: \"Central US\",\n\t\t})\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn nil\n\t})\n}\n```\n```java\npackage generated_program;\n\nimport com.pulumi.Context;\nimport com.pulumi.Pulumi;\nimport com.pulumi.core.Output;\nimport com.pulumi.random.Uuid;\nimport com.pulumi.azurerm.azurerm_resource_group;\nimport com.pulumi.azurerm.Azurerm_resource_groupArgs;\nimport java.util.List;\nimport java.util.ArrayList;\nimport java.util.Map;\nimport java.io.File;\nimport java.nio.file.Files;\nimport java.nio.file.Paths;\n\npublic class App {\n public static void main(String[] args) {\n Pulumi.run(App::stack);\n }\n\n public static void stack(Context ctx) {\n // The following example shows how to generate a unique name for an Azure Resource Group.\n var testUuid = new Uuid(\"testUuid\");\n\n var testazurerm_resource_group = new Azurerm_resource_group(\"testazurerm_resource_group\", Azurerm_resource_groupArgs.builder()\n .name(String.format(\"%s-rg\", testUuid.result()))\n .location(\"Central US\")\n .build());\n\n }\n}\n```\n```yaml\nresources:\n # The following example shows how to generate a unique name for an Azure Resource Group.\n testUuid:\n type: random:Uuid\n testazurerm_resource_group:\n type: azurerm:azurerm_resource_group\n properties:\n name: ${testUuid.result}-rg\n location: Central US\n```\n\u003c!--End PulumiCodeChooser --\u003e\n\n## Import\n\nRandom UUID's can be imported. This can be used to replace a config\n\nvalue with a value interpolated from the random provider without\n\nexperiencing diffs.\n\n```sh\n$ pulumi import random:index/uuid:Uuid main aabbccdd-eeff-0011-2233-445566778899\n```\n\n", "properties": { "keepers": { "type": "object", From 5df05c703be6578f5f6dbd0d457561fee10d3893 Mon Sep 17 00:00:00 2001 From: guineveresaenger Date: Tue, 10 Dec 2024 12:32:07 -0800 Subject: [PATCH 16/16] update tests with up to date plugins --- .../hashicorp/random-3.6.3.golden | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/dynamic/testdata/TestSchemaGenerationFullDocs/hashicorp/random-3.6.3.golden b/dynamic/testdata/TestSchemaGenerationFullDocs/hashicorp/random-3.6.3.golden index 7c273bfd4..abaf942eb 100644 --- a/dynamic/testdata/TestSchemaGenerationFullDocs/hashicorp/random-3.6.3.golden +++ b/dynamic/testdata/TestSchemaGenerationFullDocs/hashicorp/random-3.6.3.golden @@ -123,7 +123,7 @@ } }, "random:index/id:Id": { - "description": "The resource `random.Id` generates random numbers that are intended to be\nused as unique identifiers for other resources. If the output is considered \nsensitive, and should not be displayed in the CLI, use `random.Bytes`\ninstead.\n\nThis resource *does* use a cryptographic random number generator in order\nto minimize the chance of collisions, making the results of this resource\nwhen a 16-byte identifier is requested of equivalent uniqueness to a\ntype-4 UUID.\n\nThis resource can be used in conjunction with resources that have\nthe `create_before_destroy` lifecycle flag set to avoid conflicts with\nunique names during the brief period where both the old and new resources\nexist concurrently.\n\n## Example Usage\n\n\u003c!--Start PulumiCodeChooser --\u003e\n```typescript\nimport * as pulumi from \"@pulumi/pulumi\";\nimport * as aws from \"@pulumi/aws\";\nimport * as random from \"@pulumi/random\";\n\n// The following example shows how to generate a unique name for an AWS EC2\n// instance that changes each time a new AMI id is selected.\nconst serverId = new random.Id(\"serverId\", {\n keepers: {\n ami_id: _var.ami_id,\n },\n byteLength: 8,\n});\nconst serveraws_instance = new aws.index.Aws_instance(\"serveraws_instance\", {\n tags: {\n Name: `web-server ${serverId.hex}`,\n },\n ami: serverId.keepers?.amiId,\n});\n// ... (other aws_instance arguments) ...\n```\n```python\nimport pulumi\nimport pulumi_aws as aws\nimport pulumi_random as random\n\n# The following example shows how to generate a unique name for an AWS EC2\n# instance that changes each time a new AMI id is selected.\nserver_id = random.Id(\"serverId\",\n keepers={\n \"ami_id\": var[\"ami_id\"],\n },\n byte_length=8)\nserveraws_instance = aws.index.Aws_instance(\"serveraws_instance\",\n tags={\n Name: fweb-server {server_id.hex},\n },\n ami=server_id.keepers.ami_id)\n# ... (other aws_instance arguments) ...\n```\n```csharp\nusing System.Collections.Generic;\nusing System.Linq;\nusing Pulumi;\nusing Aws = Pulumi.Aws;\nusing Random = Pulumi.Random;\n\nreturn await Deployment.RunAsync(() =\u003e \n{\n // The following example shows how to generate a unique name for an AWS EC2\n // instance that changes each time a new AMI id is selected.\n var serverId = new Random.Id(\"serverId\", new()\n {\n Keepers = \n {\n { \"ami_id\", @var.Ami_id },\n },\n ByteLength = 8,\n });\n\n var serveraws_instance = new Aws.Index.Aws_instance(\"serveraws_instance\", new()\n {\n Tags = \n {\n { \"Name\", $\"web-server {serverId.Hex}\" },\n },\n Ami = serverId.Keepers?.AmiId,\n });\n\n // ... (other aws_instance arguments) ...\n});\n```\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/pulumi/pulumi-aws/sdk/go/aws\"\n\t\"github.com/pulumi/pulumi-terraform-provider/sdks/go/random/v3/random\"\n\t\"github.com/pulumi/pulumi/sdk/v3/go/pulumi\"\n)\n\nfunc main() {\n\tpulumi.Run(func(ctx *pulumi.Context) error {\n\t\t// The following example shows how to generate a unique name for an AWS EC2\n\t\t// instance that changes each time a new AMI id is selected.\n\t\tserverId, err := random.NewId(ctx, \"serverId\", \u0026random.IdArgs{\n\t\t\tKeepers: pulumi.StringMap{\n\t\t\t\t\"ami_id\": pulumi.Any(_var.Ami_id),\n\t\t\t},\n\t\t\tByteLength: pulumi.Float64(8),\n\t\t})\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\t_, err = aws.NewAws_instance(ctx, \"serveraws_instance\", \u0026aws.Aws_instanceArgs{\n\t\t\tTags: map[string]interface{}{\n\t\t\t\t\"Name\": pulumi.Sprintf(\"web-server %v\", serverId.Hex),\n\t\t\t},\n\t\t\tAmi: serverId.Keepers.AmiId,\n\t\t})\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn nil\n\t})\n}\n```\n```java\npackage generated_program;\n\nimport com.pulumi.Context;\nimport com.pulumi.Pulumi;\nimport com.pulumi.core.Output;\nimport com.pulumi.random.Id;\nimport com.pulumi.random.IdArgs;\nimport com.pulumi.aws.aws_instance;\nimport com.pulumi.aws.Aws_instanceArgs;\nimport java.util.List;\nimport java.util.ArrayList;\nimport java.util.Map;\nimport java.io.File;\nimport java.nio.file.Files;\nimport java.nio.file.Paths;\n\npublic class App {\n public static void main(String[] args) {\n Pulumi.run(App::stack);\n }\n\n public static void stack(Context ctx) {\n // The following example shows how to generate a unique name for an AWS EC2\n // instance that changes each time a new AMI id is selected.\n var serverId = new Id(\"serverId\", IdArgs.builder()\n .keepers(Map.of(\"ami_id\", var_.ami_id()))\n .byteLength(8)\n .build());\n\n var serveraws_instance = new Aws_instance(\"serveraws_instance\", Aws_instanceArgs.builder()\n .tags(%!v(PANIC=Format method: runtime error: invalid memory address or nil pointer dereference))\n .ami(serverId.keepers().amiId())\n .build());\n\n // ... (other aws_instance arguments) ...\n }\n}\n```\n```yaml\nresources:\n # The following example shows how to generate a unique name for an AWS EC2\n # instance that changes each time a new AMI id is selected.\n serverId:\n type: random:Id\n properties:\n keepers:\n ami_id: ${var.ami_id}\n byteLength: 8\n serveraws_instance:\n type: aws:aws_instance\n properties:\n tags:\n Name: web-server ${serverId.hex}\n # Read the AMI id \"through\" the random_id resource to ensure that\n # # both will change together.\n ami: ${serverId.keepers.amiId}\n```\n\u003c!--End PulumiCodeChooser --\u003e\n\n## Import\n\nRandom IDs can be imported using the b64_url with an optional prefix. This\n\ncan be used to replace a config value with a value interpolated from the\n\nrandom provider without experiencing diffs.\n\nExample with no prefix:\n\n```sh\n$ pulumi import random:index/id:Id server p-9hUg\n```\n\nExample with prefix (prefix is separated by a ,):\n\n```sh\n$ pulumi import random:index/id:Id server my-prefix-,p-9hUg\n```\n\n", + "description": "The resource `random.Id` generates random numbers that are intended to be\nused as unique identifiers for other resources. If the output is considered \nsensitive, and should not be displayed in the CLI, use `random.Bytes`\ninstead.\n\nThis resource *does* use a cryptographic random number generator in order\nto minimize the chance of collisions, making the results of this resource\nwhen a 16-byte identifier is requested of equivalent uniqueness to a\ntype-4 UUID.\n\nThis resource can be used in conjunction with resources that have\nthe `create_before_destroy` lifecycle flag set to avoid conflicts with\nunique names during the brief period where both the old and new resources\nexist concurrently.\n\n## Example Usage\n\n\u003c!--Start PulumiCodeChooser --\u003e\n```typescript\nimport * as pulumi from \"@pulumi/pulumi\";\nimport * as aws from \"@pulumi/aws\";\nimport * as random from \"@pulumi/random\";\n\n// The following example shows how to generate a unique name for an AWS EC2\n// instance that changes each time a new AMI id is selected.\nconst serverId = new random.Id(\"serverId\", {\n keepers: {\n ami_id: _var.ami_id,\n },\n byteLength: 8,\n});\nconst serverInstance = new aws.ec2.Instance(\"serverInstance\", {\n tags: {\n Name: pulumi.interpolate`web-server ${serverId.hex}`,\n },\n ami: serverId.keepers.apply(keepers =\u003e keepers?.amiId),\n});\n// ... (other aws_instance arguments) ...\n```\n```python\nimport pulumi\nimport pulumi_aws as aws\nimport pulumi_random as random\n\n# The following example shows how to generate a unique name for an AWS EC2\n# instance that changes each time a new AMI id is selected.\nserver_id = random.Id(\"serverId\",\n keepers={\n \"ami_id\": var[\"ami_id\"],\n },\n byte_length=8)\nserver_instance = aws.ec2.Instance(\"serverInstance\",\n tags={\n \"Name\": server_id.hex.apply(lambda hex: f\"web-server {hex}\"),\n },\n ami=server_id.keepers[\"amiId\"])\n# ... (other aws_instance arguments) ...\n```\n```csharp\nusing System.Collections.Generic;\nusing System.Linq;\nusing Pulumi;\nusing Aws = Pulumi.Aws;\nusing Random = Pulumi.Random;\n\nreturn await Deployment.RunAsync(() =\u003e \n{\n // The following example shows how to generate a unique name for an AWS EC2\n // instance that changes each time a new AMI id is selected.\n var serverId = new Random.Id(\"serverId\", new()\n {\n Keepers = \n {\n { \"ami_id\", @var.Ami_id },\n },\n ByteLength = 8,\n });\n\n var serverInstance = new Aws.Ec2.Instance(\"serverInstance\", new()\n {\n Tags = \n {\n { \"Name\", serverId.Hex.Apply(hex =\u003e $\"web-server {hex}\") },\n },\n Ami = serverId.Keepers.Apply(keepers =\u003e keepers?.AmiId),\n });\n\n // ... (other aws_instance arguments) ...\n});\n```\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/pulumi/pulumi-aws/sdk/v6/go/aws/ec2\"\n\t\"github.com/pulumi/pulumi-terraform-provider/sdks/go/random/v3/random\"\n\t\"github.com/pulumi/pulumi/sdk/v3/go/pulumi\"\n)\n\nfunc main() {\n\tpulumi.Run(func(ctx *pulumi.Context) error {\n\t\t// The following example shows how to generate a unique name for an AWS EC2\n\t\t// instance that changes each time a new AMI id is selected.\n\t\tserverId, err := random.NewId(ctx, \"serverId\", \u0026random.IdArgs{\n\t\t\tKeepers: pulumi.StringMap{\n\t\t\t\t\"ami_id\": pulumi.Any(_var.Ami_id),\n\t\t\t},\n\t\t\tByteLength: pulumi.Float64(8),\n\t\t})\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\t_, err = ec2.NewInstance(ctx, \"serverInstance\", \u0026ec2.InstanceArgs{\n\t\t\tTags: pulumi.StringMap{\n\t\t\t\t\"Name\": serverId.Hex.ApplyT(func(hex string) (string, error) {\n\t\t\t\t\treturn fmt.Sprintf(\"web-server %v\", hex), nil\n\t\t\t\t}).(pulumi.StringOutput),\n\t\t\t},\n\t\t\tAmi: pulumi.String(serverId.Keepers.ApplyT(func(keepers map[string]string) (*string, error) {\n\t\t\t\treturn \u0026keepers.AmiId, nil\n\t\t\t}).(pulumi.StringPtrOutput)),\n\t\t})\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn nil\n\t})\n}\n```\n```java\npackage generated_program;\n\nimport com.pulumi.Context;\nimport com.pulumi.Pulumi;\nimport com.pulumi.core.Output;\nimport com.pulumi.random.Id;\nimport com.pulumi.random.IdArgs;\nimport com.pulumi.aws.ec2.Instance;\nimport com.pulumi.aws.ec2.InstanceArgs;\nimport java.util.List;\nimport java.util.ArrayList;\nimport java.util.Map;\nimport java.io.File;\nimport java.nio.file.Files;\nimport java.nio.file.Paths;\n\npublic class App {\n public static void main(String[] args) {\n Pulumi.run(App::stack);\n }\n\n public static void stack(Context ctx) {\n // The following example shows how to generate a unique name for an AWS EC2\n // instance that changes each time a new AMI id is selected.\n var serverId = new Id(\"serverId\", IdArgs.builder()\n .keepers(Map.of(\"ami_id\", var_.ami_id()))\n .byteLength(8)\n .build());\n\n var serverInstance = new Instance(\"serverInstance\", InstanceArgs.builder()\n .tags(Map.of(\"Name\", serverId.hex().applyValue(hex -\u003e String.format(\"web-server %s\", hex))))\n .ami(serverId.keepers().applyValue(keepers -\u003e keepers.amiId()))\n .build());\n\n // ... (other aws_instance arguments) ...\n }\n}\n```\n```yaml\nresources:\n # The following example shows how to generate a unique name for an AWS EC2\n # instance that changes each time a new AMI id is selected.\n serverId:\n type: random:Id\n properties:\n keepers:\n ami_id: ${var.ami_id}\n byteLength: 8\n serverInstance:\n type: aws:ec2:Instance\n properties:\n tags:\n Name: web-server ${serverId.hex}\n # Read the AMI id \"through\" the random_id resource to ensure that\n # # both will change together.\n ami: ${serverId.keepers.amiId}\n```\n\u003c!--End PulumiCodeChooser --\u003e\n\n## Import\n\nRandom IDs can be imported using the b64_url with an optional prefix. This\n\ncan be used to replace a config value with a value interpolated from the\n\nrandom provider without experiencing diffs.\n\nExample with no prefix:\n\n```sh\n$ pulumi import random:index/id:Id server p-9hUg\n```\n\nExample with prefix (prefix is separated by a ,):\n\n```sh\n$ pulumi import random:index/id:Id server my-prefix-,p-9hUg\n```\n\n", "properties": { "b64Std": { "type": "string", @@ -223,7 +223,7 @@ } }, "random:index/integer:Integer": { - "description": "The resource `random.Integer` generates random values from a given range, described by the `min` and `max` attributes of a given resource.\n\nThis resource can be used in conjunction with resources that have the `create_before_destroy` lifecycle flag set, to avoid conflicts with unique names during the brief period where both the old and new resources exist concurrently.\n\n## Example Usage\n\n\u003c!--Start PulumiCodeChooser --\u003e\n```typescript\nimport * as pulumi from \"@pulumi/pulumi\";\nimport * as aws from \"@pulumi/aws\";\nimport * as random from \"@pulumi/random\";\n\n// The following example shows how to generate a random priority\n// between 1 and 50000 for a aws_alb_listener_rule resource:\nconst priority = new random.Integer(\"priority\", {\n min: 1,\n max: 50000,\n keepers: {\n listener_arn: _var.listener_arn,\n },\n});\nconst main = new aws.index.Aws_alb_listener_rule(\"main\", {\n listenerArn: priority.keepers?.listenerArn,\n priority: priority.result,\n action: [{\n type: \"forward\",\n targetGroupArn: _var.target_group_arn,\n }],\n});\n// ... (other aws_alb_listener_rule arguments) ...\n```\n```python\nimport pulumi\nimport pulumi_aws as aws\nimport pulumi_random as random\n\n# The following example shows how to generate a random priority\n# between 1 and 50000 for a aws_alb_listener_rule resource:\npriority = random.Integer(\"priority\",\n min=1,\n max=50000,\n keepers={\n \"listener_arn\": var[\"listener_arn\"],\n })\nmain = aws.index.Aws_alb_listener_rule(\"main\",\n listener_arn=priority.keepers.listener_arn,\n priority=priority.result,\n action=[{\n type: forward,\n targetGroupArn: var.target_group_arn,\n }])\n# ... (other aws_alb_listener_rule arguments) ...\n```\n```csharp\nusing System.Collections.Generic;\nusing System.Linq;\nusing Pulumi;\nusing Aws = Pulumi.Aws;\nusing Random = Pulumi.Random;\n\nreturn await Deployment.RunAsync(() =\u003e \n{\n // The following example shows how to generate a random priority\n // between 1 and 50000 for a aws_alb_listener_rule resource:\n var priority = new Random.Integer(\"priority\", new()\n {\n Min = 1,\n Max = 50000,\n Keepers = \n {\n { \"listener_arn\", @var.Listener_arn },\n },\n });\n\n var main = new Aws.Index.Aws_alb_listener_rule(\"main\", new()\n {\n ListenerArn = priority.Keepers?.ListenerArn,\n Priority = priority.Result,\n Action = new[]\n {\n \n {\n { \"type\", \"forward\" },\n { \"targetGroupArn\", @var.Target_group_arn },\n },\n },\n });\n\n // ... (other aws_alb_listener_rule arguments) ...\n});\n```\n```go\npackage main\n\nimport (\n\t\"github.com/pulumi/pulumi-aws/sdk/go/aws\"\n\t\"github.com/pulumi/pulumi-terraform-provider/sdks/go/random/v3/random\"\n\t\"github.com/pulumi/pulumi/sdk/v3/go/pulumi\"\n)\n\nfunc main() {\n\tpulumi.Run(func(ctx *pulumi.Context) error {\n\t\t// The following example shows how to generate a random priority\n\t\t// between 1 and 50000 for a aws_alb_listener_rule resource:\n\t\tpriority, err := random.NewInteger(ctx, \"priority\", \u0026random.IntegerArgs{\n\t\t\tMin: pulumi.Float64(1),\n\t\t\tMax: pulumi.Float64(50000),\n\t\t\tKeepers: pulumi.StringMap{\n\t\t\t\t\"listener_arn\": pulumi.Any(_var.Listener_arn),\n\t\t\t},\n\t\t})\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\t_, err = aws.NewAws_alb_listener_rule(ctx, \"main\", \u0026aws.Aws_alb_listener_ruleArgs{\n\t\t\tListenerArn: priority.Keepers.ListenerArn,\n\t\t\tPriority: priority.Result,\n\t\t\tAction: []map[string]interface{}{\n\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\"type\": \"forward\",\n\t\t\t\t\t\"targetGroupArn\": _var.Target_group_arn,\n\t\t\t\t},\n\t\t\t},\n\t\t})\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn nil\n\t})\n}\n```\n```java\npackage generated_program;\n\nimport com.pulumi.Context;\nimport com.pulumi.Pulumi;\nimport com.pulumi.core.Output;\nimport com.pulumi.random.Integer;\nimport com.pulumi.random.IntegerArgs;\nimport com.pulumi.aws.aws_alb_listener_rule;\nimport com.pulumi.aws.Aws_alb_listener_ruleArgs;\nimport java.util.List;\nimport java.util.ArrayList;\nimport java.util.Map;\nimport java.io.File;\nimport java.nio.file.Files;\nimport java.nio.file.Paths;\n\npublic class App {\n public static void main(String[] args) {\n Pulumi.run(App::stack);\n }\n\n public static void stack(Context ctx) {\n // The following example shows how to generate a random priority\n // between 1 and 50000 for a aws_alb_listener_rule resource:\n var priority = new Integer(\"priority\", IntegerArgs.builder()\n .min(1)\n .max(50000)\n .keepers(Map.of(\"listener_arn\", var_.listener_arn()))\n .build());\n\n var main = new Aws_alb_listener_rule(\"main\", Aws_alb_listener_ruleArgs.builder()\n .listenerArn(priority.keepers().listenerArn())\n .priority(priority.result())\n .action(%!v(PANIC=Format method: runtime error: invalid memory address or nil pointer dereference))\n .build());\n\n // ... (other aws_alb_listener_rule arguments) ...\n }\n}\n```\n```yaml\nresources:\n # The following example shows how to generate a random priority\n # between 1 and 50000 for a aws_alb_listener_rule resource:\n priority:\n type: random:Integer\n properties:\n min: 1\n max: 50000\n keepers:\n listener_arn: ${var.listener_arn}\n main:\n type: aws:aws_alb_listener_rule\n properties:\n listenerArn: ${priority.keepers.listenerArn}\n priority: ${priority.result}\n action:\n - type: forward\n targetGroupArn: ${var.target_group_arn}\n```\n\u003c!--End PulumiCodeChooser --\u003e\n\n## Import\n\nRandom integers can be imported using the result, min, and max, with an\n\noptional seed. This can be used to replace a config value with a value\n\ninterpolated from the random provider without experiencing diffs.\n\nExample (values are separated by a ,):\n\n```sh\n$ pulumi import random:index/integer:Integer priority 15390,1,50000\n```\n\n", + "description": "The resource `random.Integer` generates random values from a given range, described by the `min` and `max` attributes of a given resource.\n\nThis resource can be used in conjunction with resources that have the `create_before_destroy` lifecycle flag set, to avoid conflicts with unique names during the brief period where both the old and new resources exist concurrently.\n\n## Example Usage\n\n\u003c!--Start PulumiCodeChooser --\u003e\n```typescript\nimport * as pulumi from \"@pulumi/pulumi\";\nimport * as aws from \"@pulumi/aws\";\nimport * as random from \"@pulumi/random\";\n\n// The following example shows how to generate a random priority\n// between 1 and 50000 for a aws_alb_listener_rule resource:\nconst priority = new random.Integer(\"priority\", {\n min: 1,\n max: 50000,\n keepers: {\n listener_arn: _var.listener_arn,\n },\n});\nconst main = new aws.alb.ListenerRule(\"main\", {\n listenerArn: priority.keepers.apply(keepers =\u003e keepers?.listenerArn),\n priority: priority.result,\n actions: [{\n type: \"forward\",\n targetGroupArn: _var.target_group_arn,\n }],\n});\n// ... (other aws_alb_listener_rule arguments) ...\n```\n```python\nimport pulumi\nimport pulumi_aws as aws\nimport pulumi_random as random\n\n# The following example shows how to generate a random priority\n# between 1 and 50000 for a aws_alb_listener_rule resource:\npriority = random.Integer(\"priority\",\n min=1,\n max=50000,\n keepers={\n \"listener_arn\": var[\"listener_arn\"],\n })\nmain = aws.alb.ListenerRule(\"main\",\n listener_arn=priority.keepers[\"listenerArn\"],\n priority=priority.result,\n actions=[{\n \"type\": \"forward\",\n \"target_group_arn\": var[\"target_group_arn\"],\n }])\n# ... (other aws_alb_listener_rule arguments) ...\n```\n```csharp\nusing System.Collections.Generic;\nusing System.Linq;\nusing Pulumi;\nusing Aws = Pulumi.Aws;\nusing Random = Pulumi.Random;\n\nreturn await Deployment.RunAsync(() =\u003e \n{\n // The following example shows how to generate a random priority\n // between 1 and 50000 for a aws_alb_listener_rule resource:\n var priority = new Random.Integer(\"priority\", new()\n {\n Min = 1,\n Max = 50000,\n Keepers = \n {\n { \"listener_arn\", @var.Listener_arn },\n },\n });\n\n var main = new Aws.Alb.ListenerRule(\"main\", new()\n {\n ListenerArn = priority.Keepers.Apply(keepers =\u003e keepers?.ListenerArn),\n Priority = priority.Result,\n Actions = new[]\n {\n new Aws.Alb.Inputs.ListenerRuleActionArgs\n {\n Type = \"forward\",\n TargetGroupArn = @var.Target_group_arn,\n },\n },\n });\n\n // ... (other aws_alb_listener_rule arguments) ...\n});\n```\n```go\npackage main\n\nimport (\n\t\"github.com/pulumi/pulumi-aws/sdk/v6/go/aws/alb\"\n\t\"github.com/pulumi/pulumi-terraform-provider/sdks/go/random/v3/random\"\n\t\"github.com/pulumi/pulumi/sdk/v3/go/pulumi\"\n)\n\nfunc main() {\n\tpulumi.Run(func(ctx *pulumi.Context) error {\n\t\t// The following example shows how to generate a random priority\n\t\t// between 1 and 50000 for a aws_alb_listener_rule resource:\n\t\tpriority, err := random.NewInteger(ctx, \"priority\", \u0026random.IntegerArgs{\n\t\t\tMin: pulumi.Float64(1),\n\t\t\tMax: pulumi.Float64(50000),\n\t\t\tKeepers: pulumi.StringMap{\n\t\t\t\t\"listener_arn\": pulumi.Any(_var.Listener_arn),\n\t\t\t},\n\t\t})\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\t_, err = alb.NewListenerRule(ctx, \"main\", \u0026alb.ListenerRuleArgs{\n\t\t\tListenerArn: pulumi.String(priority.Keepers.ApplyT(func(keepers map[string]string) (*string, error) {\n\t\t\t\treturn \u0026keepers.ListenerArn, nil\n\t\t\t}).(pulumi.StringPtrOutput)),\n\t\t\tPriority: priority.Result,\n\t\t\tActions: alb.ListenerRuleActionArray{\n\t\t\t\t\u0026alb.ListenerRuleActionArgs{\n\t\t\t\t\tType: pulumi.String(\"forward\"),\n\t\t\t\t\tTargetGroupArn: pulumi.Any(_var.Target_group_arn),\n\t\t\t\t},\n\t\t\t},\n\t\t})\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn nil\n\t})\n}\n```\n```java\npackage generated_program;\n\nimport com.pulumi.Context;\nimport com.pulumi.Pulumi;\nimport com.pulumi.core.Output;\nimport com.pulumi.random.Integer;\nimport com.pulumi.random.IntegerArgs;\nimport com.pulumi.aws.alb.ListenerRule;\nimport com.pulumi.aws.alb.ListenerRuleArgs;\nimport com.pulumi.aws.alb.inputs.ListenerRuleActionArgs;\nimport java.util.List;\nimport java.util.ArrayList;\nimport java.util.Map;\nimport java.io.File;\nimport java.nio.file.Files;\nimport java.nio.file.Paths;\n\npublic class App {\n public static void main(String[] args) {\n Pulumi.run(App::stack);\n }\n\n public static void stack(Context ctx) {\n // The following example shows how to generate a random priority\n // between 1 and 50000 for a aws_alb_listener_rule resource:\n var priority = new Integer(\"priority\", IntegerArgs.builder()\n .min(1)\n .max(50000)\n .keepers(Map.of(\"listener_arn\", var_.listener_arn()))\n .build());\n\n var main = new ListenerRule(\"main\", ListenerRuleArgs.builder()\n .listenerArn(priority.keepers().applyValue(keepers -\u003e keepers.listenerArn()))\n .priority(priority.result())\n .actions(ListenerRuleActionArgs.builder()\n .type(\"forward\")\n .targetGroupArn(var_.target_group_arn())\n .build())\n .build());\n\n // ... (other aws_alb_listener_rule arguments) ...\n }\n}\n```\n```yaml\nresources:\n # The following example shows how to generate a random priority\n # between 1 and 50000 for a aws_alb_listener_rule resource:\n priority:\n type: random:Integer\n properties:\n min: 1\n max: 50000\n keepers:\n listener_arn: ${var.listener_arn}\n main:\n type: aws:alb:ListenerRule\n properties:\n listenerArn: ${priority.keepers.listenerArn}\n priority: ${priority.result}\n actions:\n - type: forward\n targetGroupArn: ${var.target_group_arn}\n```\n\u003c!--End PulumiCodeChooser --\u003e\n\n## Import\n\nRandom integers can be imported using the result, min, and max, with an\n\noptional seed. This can be used to replace a config value with a value\n\ninterpolated from the random provider without experiencing diffs.\n\nExample (values are separated by a ,):\n\n```sh\n$ pulumi import random:index/integer:Integer priority 15390,1,50000\n```\n\n", "properties": { "keepers": { "type": "object", @@ -310,7 +310,7 @@ } }, "random:index/password:Password": { - "description": "## Example Usage\n\n\u003c!--Start PulumiCodeChooser --\u003e\n```typescript\nimport * as pulumi from \"@pulumi/pulumi\";\nimport * as aws from \"@pulumi/aws\";\nimport * as random from \"@pulumi/random\";\n\nconst password = new random.Password(\"password\", {\n length: 16,\n special: true,\n overrideSpecial: \"!#$%\u0026*()-_=+[]{}\u003c\u003e:?\",\n});\nconst example = new aws.index.Aws_db_instance(\"example\", {\n instanceClass: \"db.t3.micro\",\n allocatedStorage: 64,\n engine: \"mysql\",\n username: \"someone\",\n password: password.result,\n});\n```\n```python\nimport pulumi\nimport pulumi_aws as aws\nimport pulumi_random as random\n\npassword = random.Password(\"password\",\n length=16,\n special=True,\n override_special=\"!#$%\u0026*()-_=+[]{}\u003c\u003e:?\")\nexample = aws.index.Aws_db_instance(\"example\",\n instance_class=db.t3.micro,\n allocated_storage=64,\n engine=mysql,\n username=someone,\n password=password.result)\n```\n```csharp\nusing System.Collections.Generic;\nusing System.Linq;\nusing Pulumi;\nusing Aws = Pulumi.Aws;\nusing Random = Pulumi.Random;\n\nreturn await Deployment.RunAsync(() =\u003e \n{\n var password = new Random.Password(\"password\", new()\n {\n Length = 16,\n Special = true,\n OverrideSpecial = \"!#$%\u0026*()-_=+[]{}\u003c\u003e:?\",\n });\n\n var example = new Aws.Index.Aws_db_instance(\"example\", new()\n {\n InstanceClass = \"db.t3.micro\",\n AllocatedStorage = 64,\n Engine = \"mysql\",\n Username = \"someone\",\n Password = password.Result,\n });\n\n});\n```\n```go\npackage main\n\nimport (\n\t\"github.com/pulumi/pulumi-aws/sdk/go/aws\"\n\t\"github.com/pulumi/pulumi-terraform-provider/sdks/go/random/v3/random\"\n\t\"github.com/pulumi/pulumi/sdk/v3/go/pulumi\"\n)\n\nfunc main() {\n\tpulumi.Run(func(ctx *pulumi.Context) error {\n\t\tpassword, err := random.NewPassword(ctx, \"password\", \u0026random.PasswordArgs{\n\t\t\tLength: pulumi.Float64(16),\n\t\t\tSpecial: pulumi.Bool(true),\n\t\t\tOverrideSpecial: pulumi.String(\"!#$%\u0026*()-_=+[]{}\u003c\u003e:?\"),\n\t\t})\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\t_, err = aws.NewAws_db_instance(ctx, \"example\", \u0026aws.Aws_db_instanceArgs{\n\t\t\tInstanceClass: \"db.t3.micro\",\n\t\t\tAllocatedStorage: 64,\n\t\t\tEngine: \"mysql\",\n\t\t\tUsername: \"someone\",\n\t\t\tPassword: password.Result,\n\t\t})\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn nil\n\t})\n}\n```\n```java\npackage generated_program;\n\nimport com.pulumi.Context;\nimport com.pulumi.Pulumi;\nimport com.pulumi.core.Output;\nimport com.pulumi.random.Password;\nimport com.pulumi.random.PasswordArgs;\nimport com.pulumi.aws.aws_db_instance;\nimport com.pulumi.aws.Aws_db_instanceArgs;\nimport java.util.List;\nimport java.util.ArrayList;\nimport java.util.Map;\nimport java.io.File;\nimport java.nio.file.Files;\nimport java.nio.file.Paths;\n\npublic class App {\n public static void main(String[] args) {\n Pulumi.run(App::stack);\n }\n\n public static void stack(Context ctx) {\n var password = new Password(\"password\", PasswordArgs.builder()\n .length(16)\n .special(true)\n .overrideSpecial(\"!#$%\u0026*()-_=+[]{}\u003c\u003e:?\")\n .build());\n\n var example = new Aws_db_instance(\"example\", Aws_db_instanceArgs.builder()\n .instanceClass(\"db.t3.micro\")\n .allocatedStorage(64)\n .engine(\"mysql\")\n .username(\"someone\")\n .password(password.result())\n .build());\n\n }\n}\n```\n```yaml\nresources:\n password:\n type: random:Password\n properties:\n length: 16\n special: true\n overrideSpecial: '!#$%\u0026*()-_=+[]{}\u003c\u003e:?'\n example:\n type: aws:aws_db_instance\n properties:\n instanceClass: db.t3.micro\n allocatedStorage: 64\n engine: mysql\n username: someone\n password: ${password.result}\n```\n\u003c!--End PulumiCodeChooser --\u003e\n\n## Import\n\n### Avoiding Replacement\n\n```sh\n$ pulumi import random:index/password:Password If the resource were imported using `random_password.password securepassword`,\n```\n\nreplacement could be avoided by using:\n\n1. Attribute values that match the imported ID and defaults:\n\n terraform\n\n resource \"random_password\" \"password\" {\n\n length = 14\n\n lower = true\n\n }\n\n2. Attribute values that match the imported ID and omit the attributes with defaults:\n\n terraform\n\n resource \"random_password\" \"password\" {\n\n length = 14\n\n }\n\n3. `ignore_changes` specifying the attributes to ignore:\n\n terraform\n\n resource \"random_password\" \"password\" {\n\n length = 16\n\n lower = false\n\n lifecycle {\n\n ignore_changes = [\n\n length,\n\n lower,\n\n ]\n\n }\n\n }\n\n **NOTE** `ignore_changes` is only required until the resource is recreated after import,\n\n after which it will use the configuration values specified.\n\n", + "description": "## Example Usage\n\n\u003c!--Start PulumiCodeChooser --\u003e\n```typescript\nimport * as pulumi from \"@pulumi/pulumi\";\nimport * as aws from \"@pulumi/aws\";\nimport * as random from \"@pulumi/random\";\n\nconst password = new random.Password(\"password\", {\n length: 16,\n special: true,\n overrideSpecial: \"!#$%\u0026*()-_=+[]{}\u003c\u003e:?\",\n});\nconst example = new aws.rds.Instance(\"example\", {\n instanceClass: aws.rds.InstanceType.T3_Micro,\n allocatedStorage: 64,\n engine: \"mysql\",\n username: \"someone\",\n password: password.result,\n});\n```\n```python\nimport pulumi\nimport pulumi_aws as aws\nimport pulumi_random as random\n\npassword = random.Password(\"password\",\n length=16,\n special=True,\n override_special=\"!#$%\u0026*()-_=+[]{}\u003c\u003e:?\")\nexample = aws.rds.Instance(\"example\",\n instance_class=aws.rds.InstanceType.T3_MICRO,\n allocated_storage=64,\n engine=\"mysql\",\n username=\"someone\",\n password=password.result)\n```\n```csharp\nusing System.Collections.Generic;\nusing System.Linq;\nusing Pulumi;\nusing Aws = Pulumi.Aws;\nusing Random = Pulumi.Random;\n\nreturn await Deployment.RunAsync(() =\u003e \n{\n var password = new Random.Password(\"password\", new()\n {\n Length = 16,\n Special = true,\n OverrideSpecial = \"!#$%\u0026*()-_=+[]{}\u003c\u003e:?\",\n });\n\n var example = new Aws.Rds.Instance(\"example\", new()\n {\n InstanceClass = Aws.Rds.InstanceType.T3_Micro,\n AllocatedStorage = 64,\n Engine = \"mysql\",\n Username = \"someone\",\n Password = password.Result,\n });\n\n});\n```\n```go\npackage main\n\nimport (\n\t\"github.com/pulumi/pulumi-aws/sdk/v6/go/aws/rds\"\n\t\"github.com/pulumi/pulumi-terraform-provider/sdks/go/random/v3/random\"\n\t\"github.com/pulumi/pulumi/sdk/v3/go/pulumi\"\n)\n\nfunc main() {\n\tpulumi.Run(func(ctx *pulumi.Context) error {\n\t\tpassword, err := random.NewPassword(ctx, \"password\", \u0026random.PasswordArgs{\n\t\t\tLength: pulumi.Float64(16),\n\t\t\tSpecial: pulumi.Bool(true),\n\t\t\tOverrideSpecial: pulumi.String(\"!#$%\u0026*()-_=+[]{}\u003c\u003e:?\"),\n\t\t})\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\t_, err = rds.NewInstance(ctx, \"example\", \u0026rds.InstanceArgs{\n\t\t\tInstanceClass: pulumi.String(rds.InstanceType_T3_Micro),\n\t\t\tAllocatedStorage: pulumi.Int(64),\n\t\t\tEngine: pulumi.String(\"mysql\"),\n\t\t\tUsername: pulumi.String(\"someone\"),\n\t\t\tPassword: password.Result,\n\t\t})\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn nil\n\t})\n}\n```\n```java\npackage generated_program;\n\nimport com.pulumi.Context;\nimport com.pulumi.Pulumi;\nimport com.pulumi.core.Output;\nimport com.pulumi.random.Password;\nimport com.pulumi.random.PasswordArgs;\nimport com.pulumi.aws.rds.Instance;\nimport com.pulumi.aws.rds.InstanceArgs;\nimport java.util.List;\nimport java.util.ArrayList;\nimport java.util.Map;\nimport java.io.File;\nimport java.nio.file.Files;\nimport java.nio.file.Paths;\n\npublic class App {\n public static void main(String[] args) {\n Pulumi.run(App::stack);\n }\n\n public static void stack(Context ctx) {\n var password = new Password(\"password\", PasswordArgs.builder()\n .length(16)\n .special(true)\n .overrideSpecial(\"!#$%\u0026*()-_=+[]{}\u003c\u003e:?\")\n .build());\n\n var example = new Instance(\"example\", InstanceArgs.builder()\n .instanceClass(\"db.t3.micro\")\n .allocatedStorage(64)\n .engine(\"mysql\")\n .username(\"someone\")\n .password(password.result())\n .build());\n\n }\n}\n```\n```yaml\nresources:\n password:\n type: random:Password\n properties:\n length: 16\n special: true\n overrideSpecial: '!#$%\u0026*()-_=+[]{}\u003c\u003e:?'\n example:\n type: aws:rds:Instance\n properties:\n instanceClass: db.t3.micro\n allocatedStorage: 64\n engine: mysql\n username: someone\n password: ${password.result}\n```\n\u003c!--End PulumiCodeChooser --\u003e\n\n## Import\n\n### Avoiding Replacement\n\n```sh\n$ pulumi import random:index/password:Password If the resource were imported using `random_password.password securepassword`,\n```\n\nreplacement could be avoided by using:\n\n1. Attribute values that match the imported ID and defaults:\n\n terraform\n\n resource \"random_password\" \"password\" {\n\n length = 14\n\n lower = true\n\n }\n\n2. Attribute values that match the imported ID and omit the attributes with defaults:\n\n terraform\n\n resource \"random_password\" \"password\" {\n\n length = 14\n\n }\n\n3. `ignore_changes` specifying the attributes to ignore:\n\n terraform\n\n resource \"random_password\" \"password\" {\n\n length = 16\n\n lower = false\n\n lifecycle {\n\n ignore_changes = [\n\n length,\n\n lower,\n\n ]\n\n }\n\n }\n\n **NOTE** `ignore_changes` is only required until the resource is recreated after import,\n\n after which it will use the configuration values specified.\n\n", "properties": { "bcryptHash": { "type": "string", @@ -516,7 +516,7 @@ } }, "random:index/pet:Pet": { - "description": "The resource `random.Pet` generates random pet names that are intended to be used as unique identifiers for other resources.\n\nThis resource can be used in conjunction with resources that have the `create_before_destroy` lifecycle flag set, to avoid conflicts with unique names during the brief period where both the old and new resources exist concurrently.\n\n## Example Usage\n\n\u003c!--Start PulumiCodeChooser --\u003e\n```typescript\nimport * as pulumi from \"@pulumi/pulumi\";\nimport * as aws from \"@pulumi/aws\";\nimport * as random from \"@pulumi/random\";\n\n// The following example shows how to generate a unique pet name\n// for an AWS EC2 instance that changes each time a new AMI id is\n// selected.\nconst serverPet = new random.Pet(\"serverPet\", {keepers: {\n ami_id: _var.ami_id,\n}});\nconst serveraws_instance = new aws.index.Aws_instance(\"serveraws_instance\", {\n tags: {\n Name: `web-server-${serverPet.id}`,\n },\n ami: serverPet.keepers?.amiId,\n});\n// ... (other aws_instance arguments) ...\n```\n```python\nimport pulumi\nimport pulumi_aws as aws\nimport pulumi_random as random\n\n# The following example shows how to generate a unique pet name\n# for an AWS EC2 instance that changes each time a new AMI id is\n# selected.\nserver_pet = random.Pet(\"serverPet\", keepers={\n \"ami_id\": var[\"ami_id\"],\n})\nserveraws_instance = aws.index.Aws_instance(\"serveraws_instance\",\n tags={\n Name: fweb-server-{server_pet.id},\n },\n ami=server_pet.keepers.ami_id)\n# ... (other aws_instance arguments) ...\n```\n```csharp\nusing System.Collections.Generic;\nusing System.Linq;\nusing Pulumi;\nusing Aws = Pulumi.Aws;\nusing Random = Pulumi.Random;\n\nreturn await Deployment.RunAsync(() =\u003e \n{\n // The following example shows how to generate a unique pet name\n // for an AWS EC2 instance that changes each time a new AMI id is\n // selected.\n var serverPet = new Random.Pet(\"serverPet\", new()\n {\n Keepers = \n {\n { \"ami_id\", @var.Ami_id },\n },\n });\n\n var serveraws_instance = new Aws.Index.Aws_instance(\"serveraws_instance\", new()\n {\n Tags = \n {\n { \"Name\", $\"web-server-{serverPet.Id}\" },\n },\n Ami = serverPet.Keepers?.AmiId,\n });\n\n // ... (other aws_instance arguments) ...\n});\n```\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/pulumi/pulumi-aws/sdk/go/aws\"\n\t\"github.com/pulumi/pulumi-terraform-provider/sdks/go/random/v3/random\"\n\t\"github.com/pulumi/pulumi/sdk/v3/go/pulumi\"\n)\n\nfunc main() {\n\tpulumi.Run(func(ctx *pulumi.Context) error {\n\t\t// The following example shows how to generate a unique pet name\n\t\t// for an AWS EC2 instance that changes each time a new AMI id is\n\t\t// selected.\n\t\tserverPet, err := random.NewPet(ctx, \"serverPet\", \u0026random.PetArgs{\n\t\t\tKeepers: pulumi.StringMap{\n\t\t\t\t\"ami_id\": pulumi.Any(_var.Ami_id),\n\t\t\t},\n\t\t})\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\t_, err = aws.NewAws_instance(ctx, \"serveraws_instance\", \u0026aws.Aws_instanceArgs{\n\t\t\tTags: map[string]interface{}{\n\t\t\t\t\"Name\": pulumi.Sprintf(\"web-server-%v\", serverPet.ID()),\n\t\t\t},\n\t\t\tAmi: serverPet.Keepers.AmiId,\n\t\t})\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn nil\n\t})\n}\n```\n```java\npackage generated_program;\n\nimport com.pulumi.Context;\nimport com.pulumi.Pulumi;\nimport com.pulumi.core.Output;\nimport com.pulumi.random.Pet;\nimport com.pulumi.random.PetArgs;\nimport com.pulumi.aws.aws_instance;\nimport com.pulumi.aws.Aws_instanceArgs;\nimport java.util.List;\nimport java.util.ArrayList;\nimport java.util.Map;\nimport java.io.File;\nimport java.nio.file.Files;\nimport java.nio.file.Paths;\n\npublic class App {\n public static void main(String[] args) {\n Pulumi.run(App::stack);\n }\n\n public static void stack(Context ctx) {\n // The following example shows how to generate a unique pet name\n // for an AWS EC2 instance that changes each time a new AMI id is\n // selected.\n var serverPet = new Pet(\"serverPet\", PetArgs.builder()\n .keepers(Map.of(\"ami_id\", var_.ami_id()))\n .build());\n\n var serveraws_instance = new Aws_instance(\"serveraws_instance\", Aws_instanceArgs.builder()\n .tags(%!v(PANIC=Format method: runtime error: invalid memory address or nil pointer dereference))\n .ami(serverPet.keepers().amiId())\n .build());\n\n // ... (other aws_instance arguments) ...\n }\n}\n```\n```yaml\nresources:\n # The following example shows how to generate a unique pet name\n # for an AWS EC2 instance that changes each time a new AMI id is\n # selected.\n serverPet:\n type: random:Pet\n properties:\n keepers:\n ami_id: ${var.ami_id}\n serveraws_instance:\n type: aws:aws_instance\n properties:\n tags:\n Name: web-server-${serverPet.id}\n # Read the AMI id \"through\" the random_pet resource to ensure that\n # # both will change together.\n ami: ${serverPet.keepers.amiId}\n```\n\u003c!--End PulumiCodeChooser --\u003e\n", + "description": "The resource `random.Pet` generates random pet names that are intended to be used as unique identifiers for other resources.\n\nThis resource can be used in conjunction with resources that have the `create_before_destroy` lifecycle flag set, to avoid conflicts with unique names during the brief period where both the old and new resources exist concurrently.\n\n## Example Usage\n\n\u003c!--Start PulumiCodeChooser --\u003e\n```typescript\nimport * as pulumi from \"@pulumi/pulumi\";\nimport * as aws from \"@pulumi/aws\";\nimport * as random from \"@pulumi/random\";\n\n// The following example shows how to generate a unique pet name\n// for an AWS EC2 instance that changes each time a new AMI id is\n// selected.\nconst serverPet = new random.Pet(\"serverPet\", {keepers: {\n ami_id: _var.ami_id,\n}});\nconst serverInstance = new aws.ec2.Instance(\"serverInstance\", {\n tags: {\n Name: pulumi.interpolate`web-server-${serverPet.id}`,\n },\n ami: serverPet.keepers.apply(keepers =\u003e keepers?.amiId),\n});\n// ... (other aws_instance arguments) ...\n```\n```python\nimport pulumi\nimport pulumi_aws as aws\nimport pulumi_random as random\n\n# The following example shows how to generate a unique pet name\n# for an AWS EC2 instance that changes each time a new AMI id is\n# selected.\nserver_pet = random.Pet(\"serverPet\", keepers={\n \"ami_id\": var[\"ami_id\"],\n})\nserver_instance = aws.ec2.Instance(\"serverInstance\",\n tags={\n \"Name\": server_pet.id.apply(lambda id: f\"web-server-{id}\"),\n },\n ami=server_pet.keepers[\"amiId\"])\n# ... (other aws_instance arguments) ...\n```\n```csharp\nusing System.Collections.Generic;\nusing System.Linq;\nusing Pulumi;\nusing Aws = Pulumi.Aws;\nusing Random = Pulumi.Random;\n\nreturn await Deployment.RunAsync(() =\u003e \n{\n // The following example shows how to generate a unique pet name\n // for an AWS EC2 instance that changes each time a new AMI id is\n // selected.\n var serverPet = new Random.Pet(\"serverPet\", new()\n {\n Keepers = \n {\n { \"ami_id\", @var.Ami_id },\n },\n });\n\n var serverInstance = new Aws.Ec2.Instance(\"serverInstance\", new()\n {\n Tags = \n {\n { \"Name\", serverPet.Id.Apply(id =\u003e $\"web-server-{id}\") },\n },\n Ami = serverPet.Keepers.Apply(keepers =\u003e keepers?.AmiId),\n });\n\n // ... (other aws_instance arguments) ...\n});\n```\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/pulumi/pulumi-aws/sdk/v6/go/aws/ec2\"\n\t\"github.com/pulumi/pulumi-terraform-provider/sdks/go/random/v3/random\"\n\t\"github.com/pulumi/pulumi/sdk/v3/go/pulumi\"\n)\n\nfunc main() {\n\tpulumi.Run(func(ctx *pulumi.Context) error {\n\t\t// The following example shows how to generate a unique pet name\n\t\t// for an AWS EC2 instance that changes each time a new AMI id is\n\t\t// selected.\n\t\tserverPet, err := random.NewPet(ctx, \"serverPet\", \u0026random.PetArgs{\n\t\t\tKeepers: pulumi.StringMap{\n\t\t\t\t\"ami_id\": pulumi.Any(_var.Ami_id),\n\t\t\t},\n\t\t})\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\t_, err = ec2.NewInstance(ctx, \"serverInstance\", \u0026ec2.InstanceArgs{\n\t\t\tTags: pulumi.StringMap{\n\t\t\t\t\"Name\": serverPet.ID().ApplyT(func(id string) (string, error) {\n\t\t\t\t\treturn fmt.Sprintf(\"web-server-%v\", id), nil\n\t\t\t\t}).(pulumi.StringOutput),\n\t\t\t},\n\t\t\tAmi: pulumi.String(serverPet.Keepers.ApplyT(func(keepers map[string]string) (*string, error) {\n\t\t\t\treturn \u0026keepers.AmiId, nil\n\t\t\t}).(pulumi.StringPtrOutput)),\n\t\t})\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn nil\n\t})\n}\n```\n```java\npackage generated_program;\n\nimport com.pulumi.Context;\nimport com.pulumi.Pulumi;\nimport com.pulumi.core.Output;\nimport com.pulumi.random.Pet;\nimport com.pulumi.random.PetArgs;\nimport com.pulumi.aws.ec2.Instance;\nimport com.pulumi.aws.ec2.InstanceArgs;\nimport java.util.List;\nimport java.util.ArrayList;\nimport java.util.Map;\nimport java.io.File;\nimport java.nio.file.Files;\nimport java.nio.file.Paths;\n\npublic class App {\n public static void main(String[] args) {\n Pulumi.run(App::stack);\n }\n\n public static void stack(Context ctx) {\n // The following example shows how to generate a unique pet name\n // for an AWS EC2 instance that changes each time a new AMI id is\n // selected.\n var serverPet = new Pet(\"serverPet\", PetArgs.builder()\n .keepers(Map.of(\"ami_id\", var_.ami_id()))\n .build());\n\n var serverInstance = new Instance(\"serverInstance\", InstanceArgs.builder()\n .tags(Map.of(\"Name\", serverPet.id().applyValue(id -\u003e String.format(\"web-server-%s\", id))))\n .ami(serverPet.keepers().applyValue(keepers -\u003e keepers.amiId()))\n .build());\n\n // ... (other aws_instance arguments) ...\n }\n}\n```\n```yaml\nresources:\n # The following example shows how to generate a unique pet name\n # for an AWS EC2 instance that changes each time a new AMI id is\n # selected.\n serverPet:\n type: random:Pet\n properties:\n keepers:\n ami_id: ${var.ami_id}\n serverInstance:\n type: aws:ec2:Instance\n properties:\n tags:\n Name: web-server-${serverPet.id}\n # Read the AMI id \"through\" the random_pet resource to ensure that\n # # both will change together.\n ami: ${serverPet.keepers.amiId}\n```\n\u003c!--End PulumiCodeChooser --\u003e\n", "properties": { "keepers": { "type": "object", @@ -590,7 +590,7 @@ } }, "random:index/shuffle:Shuffle": { - "description": "The resource `random.Shuffle` generates a random permutation of a list of strings given as an argument.\n\n## Example Usage\n\n\u003c!--Start PulumiCodeChooser --\u003e\n```typescript\nimport * as pulumi from \"@pulumi/pulumi\";\nimport * as aws from \"@pulumi/aws\";\nimport * as random from \"@pulumi/random\";\n\nconst az = new random.Shuffle(\"az\", {\n inputs: [\n \"us-west-1a\",\n \"us-west-1c\",\n \"us-west-1d\",\n \"us-west-1e\",\n ],\n resultCount: 2,\n});\nconst example = new aws.index.Aws_elb(\"example\", {availabilityZones: az.results});\n// ... and other aws_elb arguments ...\n```\n```python\nimport pulumi\nimport pulumi_aws as aws\nimport pulumi_random as random\n\naz = random.Shuffle(\"az\",\n inputs=[\n \"us-west-1a\",\n \"us-west-1c\",\n \"us-west-1d\",\n \"us-west-1e\",\n ],\n result_count=2)\nexample = aws.index.Aws_elb(\"example\", availability_zones=az.results)\n# ... and other aws_elb arguments ...\n```\n```csharp\nusing System.Collections.Generic;\nusing System.Linq;\nusing Pulumi;\nusing Aws = Pulumi.Aws;\nusing Random = Pulumi.Random;\n\nreturn await Deployment.RunAsync(() =\u003e \n{\n var az = new Random.Shuffle(\"az\", new()\n {\n Inputs = new[]\n {\n \"us-west-1a\",\n \"us-west-1c\",\n \"us-west-1d\",\n \"us-west-1e\",\n },\n ResultCount = 2,\n });\n\n var example = new Aws.Index.Aws_elb(\"example\", new()\n {\n AvailabilityZones = az.Results,\n });\n\n // ... and other aws_elb arguments ...\n});\n```\n```go\npackage main\n\nimport (\n\t\"github.com/pulumi/pulumi-aws/sdk/go/aws\"\n\t\"github.com/pulumi/pulumi-terraform-provider/sdks/go/random/v3/random\"\n\t\"github.com/pulumi/pulumi/sdk/v3/go/pulumi\"\n)\n\nfunc main() {\n\tpulumi.Run(func(ctx *pulumi.Context) error {\n\t\taz, err := random.NewShuffle(ctx, \"az\", \u0026random.ShuffleArgs{\n\t\t\tInputs: pulumi.StringArray{\n\t\t\t\tpulumi.String(\"us-west-1a\"),\n\t\t\t\tpulumi.String(\"us-west-1c\"),\n\t\t\t\tpulumi.String(\"us-west-1d\"),\n\t\t\t\tpulumi.String(\"us-west-1e\"),\n\t\t\t},\n\t\t\tResultCount: pulumi.Float64(2),\n\t\t})\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\t_, err = aws.NewAws_elb(ctx, \"example\", \u0026aws.Aws_elbArgs{\n\t\t\tAvailabilityZones: az.Results,\n\t\t})\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn nil\n\t})\n}\n```\n```java\npackage generated_program;\n\nimport com.pulumi.Context;\nimport com.pulumi.Pulumi;\nimport com.pulumi.core.Output;\nimport com.pulumi.random.Shuffle;\nimport com.pulumi.random.ShuffleArgs;\nimport com.pulumi.aws.aws_elb;\nimport com.pulumi.aws.Aws_elbArgs;\nimport java.util.List;\nimport java.util.ArrayList;\nimport java.util.Map;\nimport java.io.File;\nimport java.nio.file.Files;\nimport java.nio.file.Paths;\n\npublic class App {\n public static void main(String[] args) {\n Pulumi.run(App::stack);\n }\n\n public static void stack(Context ctx) {\n var az = new Shuffle(\"az\", ShuffleArgs.builder()\n .inputs( \n \"us-west-1a\",\n \"us-west-1c\",\n \"us-west-1d\",\n \"us-west-1e\")\n .resultCount(2)\n .build());\n\n var example = new Aws_elb(\"example\", Aws_elbArgs.builder()\n .availabilityZones(az.results())\n .build());\n\n // ... and other aws_elb arguments ...\n }\n}\n```\n```yaml\nresources:\n az:\n type: random:Shuffle\n properties:\n inputs:\n - us-west-1a\n - us-west-1c\n - us-west-1d\n - us-west-1e\n resultCount: 2\n example:\n type: aws:aws_elb\n properties:\n # Place the ELB in any two of the given availability zones, selected\n # # at random.\n availabilityZones: ${az.results}\n```\n\u003c!--End PulumiCodeChooser --\u003e\n", + "description": "The resource `random.Shuffle` generates a random permutation of a list of strings given as an argument.\n\n## Example Usage\n\n\u003c!--Start PulumiCodeChooser --\u003e\n```typescript\nimport * as pulumi from \"@pulumi/pulumi\";\nimport * as aws from \"@pulumi/aws\";\nimport * as random from \"@pulumi/random\";\n\nconst az = new random.Shuffle(\"az\", {\n inputs: [\n \"us-west-1a\",\n \"us-west-1c\",\n \"us-west-1d\",\n \"us-west-1e\",\n ],\n resultCount: 2,\n});\nconst example = new aws.elb.LoadBalancer(\"example\", {availabilityZones: az.results});\n// ... and other aws_elb arguments ...\n```\n```python\nimport pulumi\nimport pulumi_aws as aws\nimport pulumi_random as random\n\naz = random.Shuffle(\"az\",\n inputs=[\n \"us-west-1a\",\n \"us-west-1c\",\n \"us-west-1d\",\n \"us-west-1e\",\n ],\n result_count=2)\nexample = aws.elb.LoadBalancer(\"example\", availability_zones=az.results)\n# ... and other aws_elb arguments ...\n```\n```csharp\nusing System.Collections.Generic;\nusing System.Linq;\nusing Pulumi;\nusing Aws = Pulumi.Aws;\nusing Random = Pulumi.Random;\n\nreturn await Deployment.RunAsync(() =\u003e \n{\n var az = new Random.Shuffle(\"az\", new()\n {\n Inputs = new[]\n {\n \"us-west-1a\",\n \"us-west-1c\",\n \"us-west-1d\",\n \"us-west-1e\",\n },\n ResultCount = 2,\n });\n\n var example = new Aws.Elb.LoadBalancer(\"example\", new()\n {\n AvailabilityZones = az.Results,\n });\n\n // ... and other aws_elb arguments ...\n});\n```\n```go\npackage main\n\nimport (\n\t\"github.com/pulumi/pulumi-aws/sdk/v6/go/aws/elb\"\n\t\"github.com/pulumi/pulumi-terraform-provider/sdks/go/random/v3/random\"\n\t\"github.com/pulumi/pulumi/sdk/v3/go/pulumi\"\n)\n\nfunc main() {\n\tpulumi.Run(func(ctx *pulumi.Context) error {\n\t\taz, err := random.NewShuffle(ctx, \"az\", \u0026random.ShuffleArgs{\n\t\t\tInputs: pulumi.StringArray{\n\t\t\t\tpulumi.String(\"us-west-1a\"),\n\t\t\t\tpulumi.String(\"us-west-1c\"),\n\t\t\t\tpulumi.String(\"us-west-1d\"),\n\t\t\t\tpulumi.String(\"us-west-1e\"),\n\t\t\t},\n\t\t\tResultCount: pulumi.Float64(2),\n\t\t})\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\t_, err = elb.NewLoadBalancer(ctx, \"example\", \u0026elb.LoadBalancerArgs{\n\t\t\tAvailabilityZones: az.Results,\n\t\t})\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn nil\n\t})\n}\n```\n```java\npackage generated_program;\n\nimport com.pulumi.Context;\nimport com.pulumi.Pulumi;\nimport com.pulumi.core.Output;\nimport com.pulumi.random.Shuffle;\nimport com.pulumi.random.ShuffleArgs;\nimport com.pulumi.aws.elb.LoadBalancer;\nimport com.pulumi.aws.elb.LoadBalancerArgs;\nimport java.util.List;\nimport java.util.ArrayList;\nimport java.util.Map;\nimport java.io.File;\nimport java.nio.file.Files;\nimport java.nio.file.Paths;\n\npublic class App {\n public static void main(String[] args) {\n Pulumi.run(App::stack);\n }\n\n public static void stack(Context ctx) {\n var az = new Shuffle(\"az\", ShuffleArgs.builder()\n .inputs( \n \"us-west-1a\",\n \"us-west-1c\",\n \"us-west-1d\",\n \"us-west-1e\")\n .resultCount(2)\n .build());\n\n var example = new LoadBalancer(\"example\", LoadBalancerArgs.builder()\n .availabilityZones(az.results())\n .build());\n\n // ... and other aws_elb arguments ...\n }\n}\n```\n```yaml\nresources:\n az:\n type: random:Shuffle\n properties:\n inputs:\n - us-west-1a\n - us-west-1c\n - us-west-1d\n - us-west-1e\n resultCount: 2\n example:\n type: aws:elb:LoadBalancer\n properties:\n # Place the ELB in any two of the given availability zones, selected\n # # at random.\n availabilityZones: ${az.results}\n```\n\u003c!--End PulumiCodeChooser --\u003e\n", "properties": { "inputs": { "type": "array",