Merge remote-tracking branch 'origin/master' into ctpp

This commit is contained in:
Fraser Waters 2021-11-17 16:16:13 +00:00
commit 844e8f0c1e
140 changed files with 6236 additions and 111 deletions

View file

@ -1,16 +1,40 @@
### Improvements
- Adds CI detector for Buildkite
[#7933](https://github.com/pulumi/pulumi/pull/7933)
- [CLI] Adding the ability to use `pulumi org set [name]` to set a default org
to use when creating a stacks in the Pulumi Service backend or Self -hosted Service
- [cli] - Add `--exclude-protected` flag to `pulumi destroy`.
[#8359](https://github.com/pulumi/pulumi/pull/8359)
- [cli] Adding the ability to use `pulumi org set [name]` to set a default org
to use when creating a stacks in the Pulumi Service backend or self-hosted Service
[#8352](https://github.com/pulumi/pulumi/pull/8352)
- [schema] Add IsOverlay option to disable codegen for particular types
[#8338](https://github.com/pulumi/pulumi/pull/8338)
[#8425](https://github.com/pulumi/pulumi/pull/8425)
- [sdk/dotnet] - Marshal output values.
[#8316](https://github.com/pulumi/pulumi/pull/8316)
- [sdk/python] - Unmarshal output values in component provider.
[#8212](https://github.com/pulumi/pulumi/pull/8212)
- [sdk/nodejs] - Unmarshal output values in component provider.
[#8205](https://github.com/pulumi/pulumi/pull/8205)
- [sdk/nodejs] - Allow returning failures from Call in the provider without setting result outputs.
[#8424](https://github.com/pulumi/pulumi/pull/8424)
- [sdk/go] - Allow specifying Call failures from the provider.
[#8424](https://github.com/pulumi/pulumi/pull/8424)
### Bug Fixes
- [engine] - Compute dependents correctly during targeted deletes.
[#8360](https://github.com/pulumi/pulumi/pull/8360)
- [cli/engine] - Update command respects `--target-dependents`
[#8395](https://github.com/pulumi/pulumi/pull/8395)
- [docs] - Fix broken lists in dotnet docs
[docs#6558](https://github.com/pulumi/docs/issues/6558)

View file

@ -65,6 +65,8 @@ test_build:: $(TEST_ALL_DEPS)
cd tests/testprovider && go build -o pulumi-resource-testprovider
cd tests/integration/construct_component/testcomponent && yarn install && yarn link @pulumi/pulumi && yarn run tsc
cd tests/integration/construct_component/testcomponent-go && go build -o pulumi-resource-testcomponent
cd tests/integration/construct_component_output_values/testcomponent && yarn install && yarn link @pulumi/pulumi && yarn run tsc
cd tests/integration/construct_component_output_values/testcomponent-go && go build -o pulumi-resource-testcomponent
cd tests/integration/construct_component_slow/testcomponent && yarn install && yarn link @pulumi/pulumi && yarn run tsc
cd tests/integration/construct_component_plain/testcomponent && yarn install && yarn link @pulumi/pulumi && yarn run tsc
cd tests/integration/construct_component_plain/testcomponent-go && go build -o pulumi-resource-testcomponent
@ -79,6 +81,10 @@ test_build:: $(TEST_ALL_DEPS)
cd tests/integration/construct_component_provider/testcomponent-go && go build -o pulumi-resource-testcomponent
cd tests/integration/construct_component_methods_unknown/testcomponent && yarn install && yarn link @pulumi/pulumi && yarn run tsc
cd tests/integration/construct_component_methods_unknown/testcomponent-go && go build -o pulumi-resource-testcomponent
cd tests/integration/construct_component_methods_resources/testcomponent && yarn install && yarn link @pulumi/pulumi && yarn run tsc
cd tests/integration/construct_component_methods_resources/testcomponent-go && go build -o pulumi-resource-testcomponent
cd tests/integration/construct_component_methods_errors/testcomponent && yarn install && yarn link @pulumi/pulumi && yarn run tsc
cd tests/integration/construct_component_methods_errors/testcomponent-go && go build -o pulumi-resource-testcomponent
test_all:: test_build
cd pkg && $(GO_TEST) ${PROJECT_PKGS}

View file

@ -271,6 +271,10 @@
WorkingDirectory="$(TestsDirectory)\integration\construct_component\testcomponent" />
<Exec Command="yarn link @pulumi/pulumi"
WorkingDirectory="$(TestsDirectory)\integration\construct_component\testcomponent" />
<Exec Command="yarn install"
WorkingDirectory="$(TestsDirectory)\integration\construct_component_output_values\testcomponent" />
<Exec Command="yarn link @pulumi/pulumi"
WorkingDirectory="$(TestsDirectory)\integration\construct_component_output_values\testcomponent" />
<Exec Command="yarn install"
WorkingDirectory="$(TestsDirectory)\integration\construct_component_slow\testcomponent" />
<Exec Command="yarn link @pulumi/pulumi"
@ -299,6 +303,14 @@
WorkingDirectory="$(TestsDirectory)\integration\construct_component_methods_unknown\testcomponent" />
<Exec Command="yarn link @pulumi/pulumi"
WorkingDirectory="$(TestsDirectory)\integration\construct_component_methods_unknown\testcomponent" />
<Exec Command="yarn install"
WorkingDirectory="$(TestsDirectory)\integration\construct_component_methods_resources\testcomponent" />
<Exec Command="yarn link @pulumi/pulumi"
WorkingDirectory="$(TestsDirectory)\integration\construct_component_methods_resources\testcomponent" />
<Exec Command="yarn install"
WorkingDirectory="$(TestsDirectory)\integration\construct_component_methods_errors\testcomponent" />
<Exec Command="yarn link @pulumi/pulumi"
WorkingDirectory="$(TestsDirectory)\integration\construct_component_methods_errors\testcomponent" />
<Exec Command="yarn install"
WorkingDirectory="$(TestsDirectory)\integration\construct_component_provider\testcomponent" />
<Exec Command="yarn link @pulumi/pulumi"
@ -309,6 +321,8 @@
<Exec Command="go build -o pulumi-resource-testprovider.exe" WorkingDirectory="$(TestsDirectory)\testprovider" />
<Exec Command="yarn run tsc" WorkingDirectory="$(TestsDirectory)\integration\construct_component\testcomponent" />
<Exec Command="go build -o pulumi-resource-testcomponent.exe" WorkingDirectory="$(TestsDirectory)\integration\construct_component\testcomponent-go" />
<Exec Command="yarn run tsc" WorkingDirectory="$(TestsDirectory)\integration\construct_component_output_values\testcomponent" />
<Exec Command="go build -o pulumi-resource-testcomponent.exe" WorkingDirectory="$(TestsDirectory)\integration\construct_component_output_values\testcomponent-go" />
<Exec Command="yarn run tsc" WorkingDirectory="$(TestsDirectory)\integration\construct_component_slow\testcomponent" />
<Exec Command="yarn run tsc" WorkingDirectory="$(TestsDirectory)\integration\construct_component_plain\testcomponent" />
<Exec Command="go build -o pulumi-resource-testcomponent.exe" WorkingDirectory="$(TestsDirectory)\integration\construct_component_plain\testcomponent-go" />
@ -321,6 +335,10 @@
<Exec Command="go build -o pulumi-resource-testcomponent.exe" WorkingDirectory="$(TestsDirectory)\integration\construct_component_methods\testcomponent-go" />
<Exec Command="yarn run tsc" WorkingDirectory="$(TestsDirectory)\integration\construct_component_methods_unknown\testcomponent" />
<Exec Command="go build -o pulumi-resource-testcomponent.exe" WorkingDirectory="$(TestsDirectory)\integration\construct_component_methods_unknown\testcomponent-go" />
<Exec Command="yarn run tsc" WorkingDirectory="$(TestsDirectory)\integration\construct_component_methods_resources\testcomponent" />
<Exec Command="go build -o pulumi-resource-testcomponent.exe" WorkingDirectory="$(TestsDirectory)\integration\construct_component_methods_resources\testcomponent-go" />
<Exec Command="yarn run tsc" WorkingDirectory="$(TestsDirectory)\integration\construct_component_methods_errors\testcomponent" />
<Exec Command="go build -o pulumi-resource-testcomponent.exe" WorkingDirectory="$(TestsDirectory)\integration\construct_component_methods_errors\testcomponent-go" />
<Exec Command="yarn run tsc" WorkingDirectory="$(TestsDirectory)\integration\construct_component_provider\testcomponent" />
<Exec Command="go build -o pulumi-resource-testcomponent.exe" WorkingDirectory="$(TestsDirectory)\integration\construct_component_provider\testcomponent-go" />

View file

@ -57,6 +57,14 @@ The description of the package. Descriptions are interpreted as Markdown.
---
### `displayName`
The human-friendly name of the package.
`string`
---
### `functions`
A map from token to functionSpec that describes the set of functions defined by this package.
@ -159,6 +167,14 @@ The provider type for this package.
---
### `publisher`
The name of the person or organization that authored and published the package.
`string`
---
### `repository`
The URL at which the package's sources can be found.
@ -361,6 +377,14 @@ The bag of input values for the function, if any.
---
#### `isOverlay`
Indicates that the implementation of the function should not be generated from the schema, and is instead provided out-of-band by the package author
`boolean`
---
#### `language`
Additional language-specific data about the function.
@ -661,7 +685,7 @@ Indicates whether the resource is a component.
#### `isOverlay`
Indicates whether the resource is an overlay (code is generated by the package rather than by the core Pulumi codegen).
Indicates that the implementation of the resource should not be generated from the schema, and is instead provided out-of-band by the package author
`boolean`
@ -699,7 +723,7 @@ An optional objectTypeSpec that describes additional inputs that mau be necessar
`string`
Pattern: `^[a-zA-Z][-a-zA-Z0-9_]*:([^0-9][a-zA-Z0-9._/]*)?:[^0-9][a-zA-Z0-9._/]*$`
Pattern: `^[a-zA-Z][-a-zA-Z0-9_]*:([^0-9][a-zA-Z0-9._/-]*)?:[^0-9][a-zA-Z0-9._/]*$`
## Type Definition
@ -721,6 +745,14 @@ The description of the type, if any. Interpreted as Markdown.
---
#### `isOverlay`
Indicates that the implementation of the type should not be generated from the schema, and is instead provided out-of-band by the package author
`boolean`
---
#### `language`
Additional language-specific data about the type.

View file

@ -1,4 +1,4 @@
// Copyright 2016-2018, Pulumi Corporation.
// Copyright 2016-2021, Pulumi Corporation.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@ -24,8 +24,10 @@ import (
"github.com/pulumi/pulumi/pkg/v3/backend"
"github.com/pulumi/pulumi/pkg/v3/backend/display"
"github.com/pulumi/pulumi/pkg/v3/engine"
"github.com/pulumi/pulumi/pkg/v3/resource/graph"
"github.com/pulumi/pulumi/sdk/v3/go/common/resource"
"github.com/pulumi/pulumi/sdk/v3/go/common/util/cmdutil"
"github.com/pulumi/pulumi/sdk/v3/go/common/util/contract"
"github.com/pulumi/pulumi/sdk/v3/go/common/util/result"
)
@ -52,6 +54,7 @@ func newDestroyCmd() *cobra.Command {
var yes bool
var targets *[]string
var targetDependents bool
var excludeProtected bool
var cmd = &cobra.Command{
Use: "destroy",
@ -149,6 +152,29 @@ func newDestroyCmd() *cobra.Command {
if err != nil {
return result.FromError(err)
}
if targets != nil && len(*targets) > 0 && excludeProtected {
return result.FromError(errors.New("You cannot specify --target and --exclude-protected"))
}
var protectedCount int
if excludeProtected {
contract.Assert(len(targetUrns) == 0)
targetUrns, protectedCount, err = handleExcludeProtected(s)
if err != nil {
return result.FromError(err)
} else if protectedCount > 0 && len(targetUrns) == 0 {
if !jsonDisplay {
fmt.Printf("There were no unprotected resources to destroy. There are still %d"+
" protected resources associated with this stack.\n", protectedCount)
}
// We need to return now. Otherwise the update will conclude
// we tried to destroy everything and error for trying to
// destroy a protected resource.
return nil
}
}
opts.Engine = engine.UpdateOptions{
Parallel: parallel,
Debug: debug,
@ -170,8 +196,10 @@ func newDestroyCmd() *cobra.Command {
SecretsManager: sm,
Scopes: cancellationScopes,
})
if res == nil && len(*targets) == 0 && !jsonDisplay {
if res == nil && protectedCount > 0 && !jsonDisplay {
fmt.Printf("All unprotected resources were destroyed. There are still %d protected resources"+
" associated with this stack.\n", protectedCount)
} else if res == nil && len(*targets) == 0 && !jsonDisplay {
fmt.Printf("The resources in the stack have been deleted, but the history and configuration "+
"associated with the stack are still maintained. \nIf you want to remove the stack "+
"completely, run 'pulumi stack rm %s'.\n", s.Ref())
@ -202,6 +230,8 @@ func newDestroyCmd() *cobra.Command {
cmd.PersistentFlags().BoolVar(
&targetDependents, "target-dependents", false,
"Allows destroying of dependent targets discovered but not specified in --target list")
cmd.PersistentFlags().BoolVar(&excludeProtected, "exclude-protected", false, "Do not destroy protected resources."+
" Destroy all other resources.")
// Flags for engine.UpdateOptions.
cmd.PersistentFlags().BoolVar(
@ -257,3 +287,52 @@ func newDestroyCmd() *cobra.Command {
return cmd
}
// seperateProtected returns a list or unprotected and protected resources respectively. This allows
// us to safely destroy all resources in the unprotected list without invalidating any resource in
// the protected list. Protection is contravarient: A < B where A: Protected => B: Protected, A < B
// where B: Protected !=> A: Protected.
//
// A
// B: Parent = A
// C: Parent = A, Protect = True
// D: Parent = C
//
// -->
//
// Unprotected: B, D
// Protected: A, C
//
// We rely on the fact that `resources` is topologically sorted with respect to its dependencies.
// This function understands that providers live outside this topological sort.
func seperateProtected(resources []*resource.State) (
/*unprotected*/ []*resource.State /*protected*/, []*resource.State) {
dg := graph.NewDependencyGraph(resources)
transitiveProtected := graph.ResourceSet{}
for _, r := range resources {
if r.Protect {
rProtected := dg.TransitiveDependenciesOf(r)
rProtected[r] = true
transitiveProtected.UnionWith(rProtected)
}
}
allResources := graph.NewResourceSetFromArray(resources)
return allResources.SetMinus(transitiveProtected).ToArray(), transitiveProtected.ToArray()
}
// Returns the number of protected resources that remain. Appends all unprotected resources to `targetUrns`.
func handleExcludeProtected(s backend.Stack) ([]resource.URN, int, error) {
// Get snapshot
snapshot, err := s.Snapshot(commandContext())
if err != nil {
return nil, 0, err
} else if snapshot == nil {
return nil, 0, errors.New("Failed to find the stack snapshot. Are you in a stack?")
}
unprotected, protected := seperateProtected(snapshot.Resources)
targetUrns := []resource.URN{}
for _, r := range unprotected {
targetUrns = append(targetUrns, r.URN)
}
return targetUrns, len(protected), nil
}

View file

@ -2352,8 +2352,10 @@ func generateModuleContextMap(tool string, pkg *schema.Package) (map[string]*mod
mod := getModFromToken(typ.Token, pkg)
mod.types = append(mod.types, typ)
case *schema.EnumType:
mod := getModFromToken(typ.Token, pkg)
mod.enums = append(mod.enums, typ)
if !typ.IsOverlay {
mod := getModFromToken(typ.Token, pkg)
mod.enums = append(mod.enums, typ)
}
default:
continue
}

View file

@ -2769,8 +2769,10 @@ func generatePackageContextMap(tool string, pkg *schema.Package, goInfo GoPackag
}
populateDetailsForPropertyTypes(seenMap, typ.Properties, false)
case *schema.EnumType:
pkg := getPkgFromToken(typ.Token)
pkg.enums = append(pkg.enums, typ)
if !typ.IsOverlay {
pkg := getPkgFromToken(typ.Token)
pkg.enums = append(pkg.enums, typ)
}
}
}

View file

@ -54,9 +54,10 @@ var programTests = []programTest{
{
Name: "aws-s3-logging",
Description: "AWS S3 with logging",
SkipCompile: codegen.NewStringSet("dotnet", "nodejs"),
SkipCompile: codegen.NewStringSet("dotnet", "nodejs", "go"),
// Blocked on dotnet: TODO[pulumi/pulumi#8069]
// Blocked on nodejs: TODO[pulumi/pulumi#8068]
// Flaky in go: TODO[pulumi/pulumi#8123]
},
{
Name: "aws-webserver",

View file

@ -10,6 +10,16 @@
},
"type": "object"
},
"example::EnumOverlay": {
"type": "string",
"enum": [
{
"name": "SomeEnumValue",
"value": "SOME_ENUM_VALUE"
}
],
"isOverlay": true
},
"example::ConfigMapOverlay": {
"isOverlay": true,
"properties": {
@ -25,11 +35,17 @@
"properties": {
"foo": {
"$ref": "#/types/example::ConfigMapOverlay"
},
"bar": {
"$ref": "#/types/example::EnumOverlay"
}
},
"inputProperties": {
"foo": {
"$ref": "#/types/example::ConfigMapOverlay"
},
"bar": {
"$ref": "#/types/example::EnumOverlay"
}
},
"type": "object"
@ -39,11 +55,17 @@
"properties": {
"foo": {
"$ref": "#/types/example::ConfigMapOverlay"
},
"bar": {
"$ref": "#/types/example::EnumOverlay"
}
},
"inputProperties": {
"foo": {
"$ref": "#/types/example::ConfigMapOverlay"
},
"bar": {
"$ref": "#/types/example::EnumOverlay"
}
},
"type": "object"

View file

@ -27,6 +27,7 @@ no_edit_this_page: true
<div class="highlight"><pre class="chroma"><code class="language-python" data-lang="python"><span class=nd>@overload</span>
<span class="k">def </span><span class="nx">OverlayResource</span><span class="p">(</span><span class="nx">resource_name</span><span class="p">:</span> <span class="nx">str</span><span class="p">,</span>
<span class="nx">opts</span><span class="p">:</span> <span class="nx"><a href="/docs/reference/pkg/python/pulumi/#pulumi.ResourceOptions">Optional[ResourceOptions]</a></span> = None<span class="p">,</span>
<span class="nx">bar</span><span class="p">:</span> <span class="nx">Optional[EnumOverlay]</span> = None<span class="p">,</span>
<span class="nx">foo</span><span class="p">:</span> <span class="nx">Optional[ConfigMapOverlayArgs]</span> = None<span class="p">)</span>
<span class=nd>@overload</span>
<span class="k">def </span><span class="nx">OverlayResource</span><span class="p">(</span><span class="nx">resource_name</span><span class="p">:</span> <span class="nx">str</span><span class="p">,</span>
@ -157,6 +158,14 @@ The OverlayResource resource accepts the following [input]({{< relref "/docs/int
{{% choosable language csharp %}}
<dl class="resources-properties"><dt class="property-optional"
title="Optional">
<span id="bar_csharp">
<a href="#bar_csharp" style="color: inherit; text-decoration: inherit;">Bar</a>
</span>
<span class="property-indicator"></span>
<span class="property-type"><a href="#enumoverlay">Pulumi.<wbr>Example.<wbr>Enum<wbr>Overlay</a></span>
</dt>
<dd>{{% md %}}{{% /md %}}</dd><dt class="property-optional"
title="Optional">
<span id="foo_csharp">
<a href="#foo_csharp" style="color: inherit; text-decoration: inherit;">Foo</a>
</span>
@ -169,6 +178,14 @@ The OverlayResource resource accepts the following [input]({{< relref "/docs/int
{{% choosable language go %}}
<dl class="resources-properties"><dt class="property-optional"
title="Optional">
<span id="bar_go">
<a href="#bar_go" style="color: inherit; text-decoration: inherit;">Bar</a>
</span>
<span class="property-indicator"></span>
<span class="property-type"><a href="#enumoverlay">Enum<wbr>Overlay</a></span>
</dt>
<dd>{{% md %}}{{% /md %}}</dd><dt class="property-optional"
title="Optional">
<span id="foo_go">
<a href="#foo_go" style="color: inherit; text-decoration: inherit;">Foo</a>
</span>
@ -181,6 +198,14 @@ The OverlayResource resource accepts the following [input]({{< relref "/docs/int
{{% choosable language nodejs %}}
<dl class="resources-properties"><dt class="property-optional"
title="Optional">
<span id="bar_nodejs">
<a href="#bar_nodejs" style="color: inherit; text-decoration: inherit;">bar</a>
</span>
<span class="property-indicator"></span>
<span class="property-type"><a href="#enumoverlay">Enum<wbr>Overlay</a></span>
</dt>
<dd>{{% md %}}{{% /md %}}</dd><dt class="property-optional"
title="Optional">
<span id="foo_nodejs">
<a href="#foo_nodejs" style="color: inherit; text-decoration: inherit;">foo</a>
</span>
@ -193,6 +218,14 @@ The OverlayResource resource accepts the following [input]({{< relref "/docs/int
{{% choosable language python %}}
<dl class="resources-properties"><dt class="property-optional"
title="Optional">
<span id="bar_python">
<a href="#bar_python" style="color: inherit; text-decoration: inherit;">bar</a>
</span>
<span class="property-indicator"></span>
<span class="property-type"><a href="#enumoverlay">Enum<wbr>Overlay</a></span>
</dt>
<dd>{{% md %}}{{% /md %}}</dd><dt class="property-optional"
title="Optional">
<span id="foo_python">
<a href="#foo_python" style="color: inherit; text-decoration: inherit;">foo</a>
</span>
@ -317,6 +350,28 @@ All [input](#inputs) properties are implicitly available as output properties. A
<dd>{{% md %}}{{% /md %}}</dd></dl>
{{% /choosable %}}
<h4 id="enumoverlay">Enum<wbr>Overlay</h4>
{{% choosable language csharp %}}
<dl class="tabular"><dt>Some<wbr>Enum<wbr>Value</dt>
<dd>SOME_ENUM_VALUE</dd></dl>
{{% /choosable %}}
{{% choosable language go %}}
<dl class="tabular"><dt>Enum<wbr>Overlay<wbr>Some<wbr>Enum<wbr>Value</dt>
<dd>SOME_ENUM_VALUE</dd></dl>
{{% /choosable %}}
{{% choosable language nodejs %}}
<dl class="tabular"><dt>Some<wbr>Enum<wbr>Value</dt>
<dd>SOME_ENUM_VALUE</dd></dl>
{{% /choosable %}}
{{% choosable language python %}}
<dl class="tabular"><dt>SOME_ENUM_VALUE</dt>
<dd>SOME_ENUM_VALUE</dd></dl>
{{% /choosable %}}
<h2 id="package-details">Package Details</h2>
<dl class="package-details">

View file

@ -66,6 +66,16 @@
},
"type": "object"
},
"example::EnumOverlay": {
"type": "string",
"enum": [
{
"name": "SomeEnumValue",
"value": "SOME_ENUM_VALUE"
}
],
"isOverlay": true
},
"example::ConfigMapOverlay": {
"isOverlay": true,
"properties": {
@ -128,11 +138,17 @@
"properties": {
"foo": {
"$ref": "#/types/example::ConfigMapOverlay"
},
"bar": {
"$ref": "#/types/example::EnumOverlay"
}
},
"inputProperties": {
"foo": {
"$ref": "#/types/example::ConfigMapOverlay"
},
"bar": {
"$ref": "#/types/example::EnumOverlay"
}
},
"type": "object"

View file

@ -2200,9 +2200,11 @@ func generateModuleContextMap(tool string, pkg *schema.Package, extraFiles map[s
case *schema.ObjectType:
types.types = append(types.types, typ)
case *schema.EnumType:
info.ContainsEnums = true
mod := getModFromToken(typ.Token)
mod.enums = append(mod.enums, typ)
if !typ.IsOverlay {
info.ContainsEnums = true
mod := getModFromToken(typ.Token)
mod.enums = append(mod.enums, typ)
}
default:
continue
}

View file

@ -2722,8 +2722,10 @@ func generateModuleContextMap(tool string, pkg *schema.Package, info PackageInfo
mod.types = append(mod.types, typ)
}
case *schema.EnumType:
mod := getModFromToken(typ.Token, pkg)
mod.enums = append(mod.enums, typ)
if !typ.IsOverlay {
mod := getModFromToken(typ.Token, pkg)
mod.enums = append(mod.enums, typ)
}
default:
continue
}

View file

@ -311,7 +311,7 @@
"required": ["environment"]
},
"deprecationMessage": {
"description": "Indicates whether or not the property is deprecated",
"description": "Indicates whether the property is deprecated",
"type": "string"
},
"language": {
@ -340,6 +340,10 @@
"language": {
"description": "Additional language-specific data about the type.",
"type": "object"
},
"isOverlay": {
"description": "Indicates that the implementation of the type should not be generated from the schema, and is instead provided out-of-band by the package author",
"type": "boolean"
}
},
"oneOf": [
@ -409,7 +413,7 @@
"type": ["boolean", "integer", "number", "string"]
},
"deprecationMessage": {
"description": "Indicates whether or not the value is deprecated.",
"description": "Indicates whether the value is deprecated.",
"type": "string"
}
},
@ -472,11 +476,11 @@
}
},
"deprecationMessage": {
"description": "Indicates whether or not the resource is deprecated",
"description": "Indicates whether the resource is deprecated",
"type": "string"
},
"isComponent": {
"description": "Indicates whether or not the resource is a component.",
"description": "Indicates whether the resource is a component.",
"type": "boolean"
},
"methods": {
@ -485,6 +489,10 @@
"additionalProperties": {
"type": "string"
}
},
"isOverlay": {
"description": "Indicates that the implementation of the resource should not be generated from the schema, and is instead provided out-of-band by the package author",
"type": "boolean"
}
}
},
@ -506,12 +514,16 @@
"$ref": "#/$defs/objectTypeSpec"
},
"deprecationMessage": {
"description": "Indicates whether or not the function is deprecated",
"description": "Indicates whether the function is deprecated",
"type": "string"
},
"language": {
"description": "Additional language-specific data about the function.",
"type": "object"
},
"isOverlay": {
"description": "Indicates that the implementation of the function should not be generated from the schema, and is instead provided out-of-band by the package author",
"type": "boolean"
}
}
}

View file

@ -166,6 +166,10 @@ type EnumType struct {
Elements []*Enum
// ElementType is the underlying type for the enum.
ElementType Type
// IsOverlay indicates whether the type is an overlay provided by the package. Overlay code is generated by the
// package rather than using the core Pulumi codegen libraries.
IsOverlay bool
}
// Enum contains information about an enum.
@ -968,8 +972,8 @@ func (pkg *Package) MarshalYAML() ([]byte, error) {
return b.Bytes(), nil
}
func (pkg *Package) marshalObjectData(
comment string, properties []*Property, language map[string]interface{}, plain bool) (ObjectTypeSpec, error) {
func (pkg *Package) marshalObjectData(comment string, properties []*Property, language map[string]interface{},
plain, isOverlay bool) (ObjectTypeSpec, error) {
required, props, err := pkg.marshalProperties(properties, plain)
if err != nil {
@ -987,11 +991,12 @@ func (pkg *Package) marshalObjectData(
Type: "object",
Required: required,
Language: lang,
IsOverlay: isOverlay,
}, nil
}
func (pkg *Package) marshalObject(t *ObjectType, plain bool) (ComplexTypeSpec, error) {
data, err := pkg.marshalObjectData(t.Comment, t.Properties, t.Language, plain)
data, err := pkg.marshalObjectData(t.Comment, t.Properties, t.Language, plain, t.IsOverlay)
if err != nil {
return ComplexTypeSpec{}, err
}
@ -1010,17 +1015,16 @@ func (pkg *Package) marshalEnum(t *EnumType) ComplexTypeSpec {
}
return ComplexTypeSpec{
ObjectTypeSpec: ObjectTypeSpec{Type: pkg.marshalType(t.ElementType, false).Type},
ObjectTypeSpec: ObjectTypeSpec{Type: pkg.marshalType(t.ElementType, false).Type, IsOverlay: t.IsOverlay},
Enum: values,
}
}
func (pkg *Package) marshalResource(r *Resource) (ResourceSpec, error) {
object, err := pkg.marshalObjectData(r.Comment, r.Properties, r.Language, true)
object, err := pkg.marshalObjectData(r.Comment, r.Properties, r.Language, true, r.IsOverlay)
if err != nil {
return ResourceSpec{}, fmt.Errorf("marshaling properties: %w", err)
}
object.IsOverlay = r.IsOverlay
requiredInputs, inputs, err := pkg.marshalProperties(r.InputProperties, false)
if err != nil {
@ -2409,6 +2413,7 @@ func (t *types) bindEnumTypeDetails(enum *EnumType, token string, spec ComplexTy
enum.Elements = values
enum.ElementType = typ
enum.Comment = spec.Description
enum.IsOverlay = spec.IsOverlay
return diags
}

View file

@ -145,17 +145,20 @@ func TestUpdateTarget(t *testing.T) {
// limit to up to 3 resources to destroy. This keeps the test running time under
// control as it only generates a few hundred combinations instead of several thousand.
if len(subset) <= 3 {
updateSpecificTargets(t, subset)
updateSpecificTargets(t, subset, false /*targetDependents*/)
}
}
updateSpecificTargets(t, []string{"A"})
updateSpecificTargets(t, []string{"A"}, false /*targetDependents*/)
// Also update a target that doesn't exist to make sure we don't crash or otherwise go off the rails.
updateInvalidTarget(t)
// We want to check that targetDependents is respected
updateSpecificTargets(t, []string{"C"}, true /*targetDependents*/)
}
func updateSpecificTargets(t *testing.T, targets []string) {
func updateSpecificTargets(t *testing.T, targets []string, targetDependents bool) {
// A
// _________|_________
// B C D
@ -193,6 +196,7 @@ func updateSpecificTargets(t *testing.T, targets []string) {
}
p.Options.Host = deploytest.NewPluginHost(nil, nil, program, loaders...)
p.Options.TargetDependents = targetDependents
updateTargets := []resource.URN{}
for _, target := range targets {
@ -228,6 +232,28 @@ func updateSpecificTargets(t *testing.T, targets []string) {
assert.Contains(t, updated, target)
}
if !targetDependents {
// We should only perform updates on the entries we have targeted.
for _, target := range p.Options.UpdateTargets {
assert.Contains(t, targets, target.Name().String())
}
} else {
// We expect to find at least one other resource updates.
// NOTE: The test is limited to only passing a subset valid behavior. By specifying
// a URN with no dependents, no other urns will be updated and the test will fail
// (incorrectly).
found := false
updateList := []string{}
for target := range updated {
updateList = append(updateList, target.Name().String())
if !contains(targets, target.Name().String()) {
found = true
}
}
assert.True(t, found, "Updates: %v", updateList)
}
for _, target := range p.Options.UpdateTargets {
assert.NotContains(t, sames, target)
}
@ -238,6 +264,15 @@ func updateSpecificTargets(t *testing.T, targets []string) {
p.Run(t, old)
}
func contains(list []string, entry string) bool {
for _, e := range list {
if e == entry {
return true
}
}
return false
}
func updateInvalidTarget(t *testing.T) {
p := &TestPlan{}

View file

@ -72,8 +72,33 @@ func (sg *stepGenerator) isTargetedUpdate() bool {
return sg.updateTargetsOpt != nil || sg.replaceTargetsOpt != nil
}
func (sg *stepGenerator) isTargetedForUpdate(urn resource.URN) bool {
return sg.updateTargetsOpt == nil || sg.updateTargetsOpt[urn]
// isTargetedForUpdate returns if `res` is targeted for update. The function accommodates
// `--target-dependents`. `targetDependentsForUpdate` should probably be called if this function
// returns true.
func (sg *stepGenerator) isTargetedForUpdate(res *resource.State) bool {
if sg.updateTargetsOpt == nil || sg.updateTargetsOpt[res.URN] {
return true
} else if !sg.opts.TargetDependents {
return false
}
if res.Provider != "" {
res, err := providers.ParseReference(res.Provider)
contract.AssertNoError(err)
if sg.updateTargetsOpt[res.URN()] {
return true
}
}
if res.Parent != "" {
if sg.updateTargetsOpt[res.Parent] {
return true
}
}
for _, dep := range res.Dependencies {
if dep != "" && sg.updateTargetsOpt[dep] {
return true
}
}
return false
}
func (sg *stepGenerator) isTargetedReplace(urn resource.URN) bool {
@ -189,7 +214,7 @@ func (sg *stepGenerator) GenerateSteps(event RegisterResourceEvent) ([]Step, res
return steps, nil
}
// We got a set of steps to perfom during a targeted update. If any of the steps are not same steps and depend on
// We got a set of steps to perform during a targeted update. If any of the steps are not same steps and depend on
// creates we skipped because they were not in the --target list, issue an error that that the create was necessary
// and that the user must target the resource to create.
for _, step := range steps {
@ -469,6 +494,11 @@ func (sg *stepGenerator) generateSteps(event RegisterResourceEvent) ([]Step, res
}, nil
}
isTargeted := sg.isTargetedForUpdate(new)
if isTargeted && sg.updateTargetsOpt != nil {
sg.updateTargetsOpt[urn] = true
}
// Case 3: hasOld
// In this case, the resource we are operating upon now exists in the old snapshot.
// It must be an update or a replace. Which operation we do depends on the the specific change made to the
@ -487,8 +517,8 @@ func (sg *stepGenerator) generateSteps(event RegisterResourceEvent) ([]Step, res
contract.Assert(old != nil)
// If the user requested only specific resources to update, and this resource was not in
// that set, then do nothin but create a SameStep for it.
if !sg.isTargetedForUpdate(urn) {
// that set, then do nothing but create a SameStep for it.
if !isTargeted {
logging.V(7).Infof(
"Planner decided not to update '%v' due to not being in target group (same) (inputs=%v)", urn, new.Inputs)
} else {
@ -538,9 +568,7 @@ func (sg *stepGenerator) generateSteps(event RegisterResourceEvent) ([]Step, res
// We will also not record this non-created resource into the checkpoint as it doesn't actually
// exist.
if !sg.isTargetedForUpdate(urn) &&
!providers.IsProviderType(goal.Type) {
if !isTargeted && !providers.IsProviderType(goal.Type) {
sg.sames[urn] = true
sg.skippedCreates[urn] = true
return []Step{NewSkippedCreateStep(sg.deployment, event, new)}, nil

View file

@ -1,4 +1,4 @@
// Copyright 2016-2018, Pulumi Corporation. All rights reserved.
// Copyright 2016-2021, Pulumi Corporation. All rights reserved.
package graph
@ -123,6 +123,67 @@ func (dg *DependencyGraph) DependenciesOf(res *resource.State) ResourceSet {
return set
}
// `TransitiveDependenciesOf` calculates the set of resources that `r` depends
// on, directly or indirectly. This includes as a `Parent`, a member of r's
// `Dependencies` list or as a provider.
//
// This function is linear in the number of resources in the `DependencyGraph`.
func (dg *DependencyGraph) TransitiveDependenciesOf(r *resource.State) ResourceSet {
dependentProviders := make(map[resource.URN]struct{})
urns := make(map[resource.URN]*node, len(dg.resources))
for _, r := range dg.resources {
urns[r.URN] = &node{resource: r}
}
// Linearity is due to short circuiting in the traversal.
markAsDependency(r.URN, urns, dependentProviders)
// This will only trigger if (urn, node) is a provider. The check is implicit
// in the set lookup.
for urn := range urns {
if _, ok := dependentProviders[urn]; ok {
markAsDependency(urn, urns, dependentProviders)
}
}
dependencies := ResourceSet{}
for _, r := range urns {
if r.marked {
dependencies[r.resource] = true
}
}
// We don't want to include `r` as it's own dependency.
delete(dependencies, r)
return dependencies
}
// Mark a resource and its parents as a dependency. This is a helper function for `TransitiveDependenciesOf`.
func markAsDependency(urn resource.URN, urns map[resource.URN]*node, dependedProviders map[resource.URN]struct{}) {
r := urns[urn]
for {
r.marked = true
if r.resource.Provider != "" {
ref, err := providers.ParseReference(r.resource.Provider)
contract.AssertNoError(err)
dependedProviders[ref.URN()] = struct{}{}
}
for _, dep := range r.resource.Dependencies {
markAsDependency(dep, urns, dependedProviders)
}
// If p is already marked, we don't need to continue to traverse. All
// nodes above p will have already been marked. This is a property of
// `resources` being topologically sorted.
if p, ok := urns[r.resource.Parent]; ok && !p.marked {
r = p
} else {
break
}
}
}
// NewDependencyGraph creates a new DependencyGraph from a list of resources.
// The resources should be in topological order with respect to their dependencies, including
// parents appearing before children.
@ -143,3 +204,9 @@ func NewDependencyGraph(resources []*resource.State) *DependencyGraph {
return &DependencyGraph{index, resources, childrenOf}
}
// A node in a graph.
type node struct {
marked bool
resource *resource.State
}

View file

@ -202,6 +202,24 @@ func TestRapidDependingOnOrdered(t *testing.T) {
}
}
func TestRapidTransitiveDependenciesOf(t *testing.T) {
graphCheck(t, func(t *rapid.T, universe []*resource.State) {
expectedInTDepsOf := transitively(universe)(expectedDependenciesOf)
dg := NewDependencyGraph(universe)
for _, a := range universe {
tda := dg.TransitiveDependenciesOf(a)
for _, b := range universe {
assert.Equalf(t,
expectedInTDepsOf(a, b),
tda[b],
"Mismatch on a=%v, b=%b",
a.URN,
b.URN)
}
}
})
}
// Generators --------------------------------------------------------------------------------------
// Generates ordered values of type `[]ResourceState` that:

View file

@ -1,4 +1,4 @@
// Copyright 2016-2018, Pulumi Corporation. All rights reserved.
// Copyright 2016-2021, Pulumi Corporation. All rights reserved.
package graph
@ -229,3 +229,29 @@ func TestDependenciesOfRemoteComponentsNoCycle(t *testing.T) {
assert.True(t, rDependencies[parent])
assert.False(t, rDependencies[child])
}
func TestTransitiveDependenciesOf(t *testing.T) {
aws := NewProviderResource("aws", "default", "0")
parent := NewResource("parent", aws)
greatUncle := NewResource("greatUncle", aws)
uncle := NewResource("r", aws)
uncle.Parent = greatUncle.URN
child := NewResource("child", aws, uncle.URN)
child.Parent = parent.URN
baby := NewResource("baby", aws)
baby.Parent = child.URN
dg := NewDependencyGraph([]*resource.State{
aws,
parent,
greatUncle,
uncle,
child,
baby,
})
// <(relation)- as an alias for depends on via relation
// baby <(Parent)- child <(Dependency)- uncle <(Parent)- greatUncle <(Provider)- aws
set := dg.TransitiveDependenciesOf(baby)
assert.True(t, set[aws], "everything should depend on the provider")
assert.True(t, set[greatUncle], "child depends on greatUncle")
}

View file

@ -1,4 +1,4 @@
// Copyright 2016-2018, Pulumi Corporation.
// Copyright 2016-2021, Pulumi Corporation.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@ -16,6 +16,7 @@ package graph
import (
"github.com/pulumi/pulumi/sdk/v3/go/common/resource"
"sort"
)
// ResourceSet represents a set of Resources.
@ -32,3 +33,62 @@ func (s ResourceSet) Intersect(other ResourceSet) ResourceSet {
return newSet
}
// Returns the contents of the set as an array of resources. To ensure
// determinism, they are sorted by urn.
func (s ResourceSet) ToArray() []*resource.State {
arr := make([]*resource.State, len(s))
i := 0
for r := range s {
arr[i] = r
i++
}
sort.Slice(arr, func(i, j int) bool {
return arr[i].URN < arr[j].URN
})
return arr
}
// Produces a set from an array.
func NewResourceSetFromArray(arr []*resource.State) ResourceSet {
s := ResourceSet{}
for _, r := range arr {
s[r] = true
}
return s
}
// Produces a shallow copy of `s`.
func CopyResourceSet(s ResourceSet) ResourceSet {
result := ResourceSet{}
for k, v := range s {
result[k] = v
}
return result
}
// Computes s - other. Input sets are unchanged. If `other[k] = false`, then `k`
// will not be removed from `s`.
func (s ResourceSet) SetMinus(other ResourceSet) ResourceSet {
result := CopyResourceSet(s)
for k, v := range other {
if v {
delete(result, k)
}
}
return result
}
// Produces a new set with elements from both sets. The original sets are unchanged.
func (s ResourceSet) Union(other ResourceSet) ResourceSet {
result := CopyResourceSet(s)
return result.UnionWith(other)
}
// Alters `s` to include elements of `other`.
func (s ResourceSet) UnionWith(other ResourceSet) ResourceSet {
for k, v := range other {
s[k] = v || s[k]
}
return s
}

View file

@ -1,4 +1,4 @@
// Copyright 2016-2018, Pulumi Corporation.
// Copyright 2016-2021, Pulumi Corporation.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@ -37,3 +37,40 @@ func TestIntersect(t *testing.T) {
assert.True(t, setC[b])
assert.False(t, setC[c])
}
func TestUnion(t *testing.T) {
a := NewResource("a", nil)
b := NewResource("b", nil)
c := NewResource("c", nil)
setA := make(ResourceSet)
setA[a] = true
setA[c] = true
setB := make(ResourceSet)
setB[b] = true
setC := setA.Union(setB)
assert.True(t, setC[a])
assert.True(t, setC[b])
assert.True(t, setC[c])
}
func TestSetMinus(t *testing.T) {
a := NewResource("a", nil)
b := NewResource("b", nil)
c := NewResource("c", nil)
setA := make(ResourceSet)
setA[a] = true
setA[b] = true
setB := make(ResourceSet)
setB[b] = true
setB[c] = true
setC := setA.SetMinus(setB)
assert.True(t, setC[a])
assert.False(t, setC[b])
assert.False(t, setC[c])
}

View file

@ -1248,7 +1248,8 @@ namespace Pulumi.Automation.Tests
() => upTaskWithOutput);
}
[Fact]
// TODO[pulumi/pulumi#8228]: fix flakiness
[Fact(Skip="flaky")]
public async Task InlineProgramExceptionPropagatesToCallerWithServiceProvider()
{
await using var provider = new ServiceCollection()
@ -1434,6 +1435,7 @@ namespace Pulumi.Automation.Tests
}
}
// TODO[pulumi/pulumi#7467]
[Fact(Skip = "Flakey test - https://github.com/pulumi/pulumi/issues/7467")]
public async Task WorkspaceStackSupportsCancel()
{

View file

@ -127,8 +127,8 @@ namespace Pulumi
/// created, these are represented using the special <see cref="Output{T}"/>s type, which
/// internally represents two things:
/// <list type="number">
/// <item>An eventually available value of the output</item>
/// <item>The dependency on the source(s) of the output value</item>
/// <item><description>An eventually available value of the output</description></item>
/// <item><description>The dependency on the source(s) of the output value</description></item>
/// </list>
/// In fact, <see cref="Output{T}"/>s is quite similar to <see cref="Task{TResult}"/>.
/// Additionally, they carry along dependency information.

View file

@ -36,18 +36,18 @@ namespace Pulumi
/// <para/>
/// Conceptually property merging follows these basic rules:
/// <list type="number">
/// <item>
/// <item><description>
/// If the property is a collection, the final value will be a collection containing the
/// values from each options object.
/// </item>
/// <item>
/// </description></item>
/// <item><description>
/// Simple scalar values from <paramref name="options2"/> (i.e. <see cref="string"/>s,
/// <see cref="int"/>s, <see cref="bool"/>s) will replace the values of <paramref
/// name="options1"/>.
/// </item>
/// <item>
/// </description></item>
/// <item><description>
/// <see langword="null"/> values in <paramref name="options2"/> will be ignored.
/// </item>
/// </description></item>
/// </list>
/// </summary>
public static ComponentResourceOptions Merge(ComponentResourceOptions? options1, ComponentResourceOptions? options2)

View file

@ -51,18 +51,18 @@ namespace Pulumi
/// <para/>
/// Conceptually property merging follows these basic rules:
/// <list type="number">
/// <item>
/// <item><description>
/// If the property is a collection, the final value will be a collection containing the
/// values from each options object.
/// </item>
/// <item>
/// </description></item>
/// <item><description>
/// Simple scalar values from <paramref name="options2"/> (i.e. <see cref="string"/>s,
/// <see cref="int"/>s, <see cref="bool"/>s) will replace the values of <paramref
/// name="options1"/>.
/// </item>
/// <item>
/// </description></item>
/// <item><description>
/// <see langword="null"/> values in <paramref name="options2"/> will be ignored.
/// </item>
/// </description></item>
/// </list>
/// </summary>
public static CustomResourceOptions Merge(CustomResourceOptions? options1, CustomResourceOptions? options2)

View file

@ -368,6 +368,7 @@ func findRepositoryRoot() (string, error) {
}
func TestArchiveTarFiles(t *testing.T) {
// TODO[pulumi/pulumi#7976] flaky
t.Skip("Disabled due to flakiness. See #7976.")
repoRoot, err := findRepositoryRoot()
@ -381,6 +382,7 @@ func TestArchiveTarFiles(t *testing.T) {
}
func TestArchiveZipFiles(t *testing.T) {
t.Skip() // TODO[pulumi/pulumi#7147]
repoRoot, err := findRepositoryRoot()
assert.Nil(t, err)

View file

@ -0,0 +1,56 @@
// Copyright 2016-2021, Pulumi Corporation.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package ciutil
import (
"os"
)
// buildkiteCI represents a Buildkite CI/CD system.
type buildkiteCI struct {
baseCI
}
// DetectVars detects the env vars for a Buildkite Build.
func (bci buildkiteCI) DetectVars() Vars {
v := Vars{Name: Buildkite}
// https://buildkite.com/docs/pipelines/environment-variables#bk-env-vars-buildkite-branch
v.BranchName = os.Getenv("BUILDKITE_BRANCH")
// https://buildkite.com/docs/pipelines/environment-variables#bk-env-vars-buildkite-build-id
v.BuildID = os.Getenv("BUILDKITE_BUILD_ID")
// https://buildkite.com/docs/pipelines/environment-variables#bk-env-vars-buildkite-build-number
v.BuildNumber = os.Getenv("BUILDKITE_BUILD_NUMBER")
// https://buildkite.com/docs/pipelines/environment-variables#bk-env-vars-buildkite-build-url
v.BuildURL = os.Getenv("BUILDKITE_BUILD_URL")
// https://buildkite.com/docs/pipelines/environment-variables#bk-env-vars-buildkite-message
// This is usually the commit message but can be other messages.
v.CommitMessage = os.Getenv("BUILDKITE_MESSAGE")
// https://buildkite.com/docs/pipelines/environment-variables#bk-env-vars-buildkite-pull-request
// If Buildkite's PR env var it is a pull request of the supplied number, else the build type is
// whatever Buildkite says it is. Pull requests are webhooks just like a standard push so this allows
// us to differentiate the two.
prNumber := os.Getenv("BUILDKITE_PULL_REQUEST")
if prNumber != "false" {
v.PRNumber = prNumber
v.BuildType = "PullRequest"
} else {
// https://buildkite.com/docs/pipelines/environment-variables#bk-env-vars-buildkite-source
v.BuildType = os.Getenv("BUILDKITE_SOURCE")
}
// https://buildkite.com/docs/pipelines/environment-variables#bk-env-vars-buildkite-commit
v.SHA = os.Getenv("BUILDKITE_COMMIT")
return v
}

View file

@ -48,9 +48,11 @@ var detectors = map[SystemName]system{
EnvVarsToDetect: []string{"TF_BUILD"},
},
},
Buildkite: baseCI{
Name: Buildkite,
EnvVarsToDetect: []string{"BUILDKITE"},
Buildkite: buildkiteCI{
baseCI: baseCI{
Name: Buildkite,
EnvVarsToDetect: []string{"BUILDKITE"},
},
},
CircleCI: circleCICI{
baseCI: baseCI{

View file

@ -35,6 +35,13 @@ func TestDetectVars(t *testing.T) {
"BUILD_BUILDID": buildNumber,
"GITHUB_ACTIONS": "",
},
Buildkite: {
"GITHUB_ACTIONS": "",
"TRAVIS": "",
"BUILDKITE": "true",
"BUILDKITE_BUILD_NUMBER": buildNumber,
"BUILDKITE_BUILD_ID": buildID,
},
CircleCI: {
"TRAVIS": "",
"CIRCLECI": "true",

View file

@ -703,7 +703,13 @@ func newConstructResult(resource ComponentResource) (URNInput, Input, error) {
return resource.URN(), state, nil
}
type callFunc func(ctx *Context, tok string, args map[string]interface{}) (Input, error)
// callFailure indicates that a call to Call failed; it contains the property and reason for the failure.
type callFailure struct {
Property string
Reason string
}
type callFunc func(ctx *Context, tok string, args map[string]interface{}) (Input, []interface{}, error)
// call adapts the gRPC CallRequest/CallResponse to/from the Pulumi Go SDK programming model.
func call(ctx context.Context, req *pulumirpc.CallRequest, engineConn *grpc.ClientConn,
@ -755,7 +761,7 @@ func call(ctx context.Context, req *pulumirpc.CallRequest, engineConn *grpc.Clie
}
}
result, err := callF(pulumiCtx, req.GetTok(), args)
result, failures, err := callF(pulumiCtx, req.GetTok(), args)
if err != nil {
return nil, err
}
@ -798,9 +804,22 @@ func call(ctx context.Context, req *pulumirpc.CallRequest, engineConn *grpc.Clie
}
}
var rpcFailures []*pulumirpc.CheckFailure
if len(failures) > 0 {
rpcFailures = make([]*pulumirpc.CheckFailure, len(failures))
for i, v := range failures {
failure := v.(callFailure)
rpcFailures[i] = &pulumirpc.CheckFailure{
Property: failure.Property,
Reason: failure.Reason,
}
}
}
return &pulumirpc.CallResponse{
Return: rpcProps,
ReturnDependencies: rpcPropertyDeps,
Failures: rpcFailures,
}, nil
}
@ -879,3 +898,11 @@ func newCallResult(result interface{}) (Input, error) {
return ret, nil
}
// newCallFailure creates a call failure.
func newCallFailure(property, reason string) interface{} {
return callFailure{
Property: property,
Reason: reason,
}
}

View file

@ -83,13 +83,20 @@ type CallFunc func(ctx *pulumi.Context, tok string, args CallArgs) (*CallResult,
func Call(ctx context.Context, req *pulumirpc.CallRequest, engineConn *grpc.ClientConn,
call CallFunc) (*pulumirpc.CallResponse, error) {
return linkedCall(ctx, req, engineConn, func(pulumiCtx *pulumi.Context, tok string,
args map[string]interface{}) (pulumi.Input, error) {
args map[string]interface{}) (pulumi.Input, []interface{}, error) {
ca := CallArgs{ctx: pulumiCtx, args: args}
result, err := call(pulumiCtx, tok, ca)
if err != nil {
return nil, err
return nil, nil, err
}
return result.Return, nil
var failures []interface{}
if len(result.Failures) > 0 {
failures = make([]interface{}, len(result.Failures))
for i, v := range result.Failures {
failures[i] = linkedNewCallFailure(v.Property, v.Reason)
}
}
return result.Return, failures, nil
})
}
@ -117,9 +124,18 @@ func (a CallArgs) Self() (pulumi.Resource, error) {
return linkedCallArgsSelf(a.ctx, a.args)
}
// CallFailure indicates that a call to Call failed; it contains the property and reason for the failure.
type CallFailure struct {
Property string // the property that failed checking.
Reason string // the reason the property failed to check.
}
// CallResult is the result of the Call.
type CallResult struct {
// The returned values, if the call was successful.
Return pulumi.Input
// The failures if any arguments didn't pass verification.
Failures []CallFailure
}
// NewCallResult creates a CallResult from the given result.
@ -149,7 +165,7 @@ func linkedConstructInputsCopyTo(ctx *pulumi.Context, inputs map[string]interfac
// linkedNewConstructResult is made available here from ../provider_linked.go via go:linkname.
func linkedNewConstructResult(resource pulumi.ComponentResource) (pulumi.URNInput, pulumi.Input, error)
type callFunc func(ctx *pulumi.Context, tok string, args map[string]interface{}) (pulumi.Input, error)
type callFunc func(ctx *pulumi.Context, tok string, args map[string]interface{}) (pulumi.Input, []interface{}, error)
// linkedCall is made available here from ../provider_linked.go via go:linkname.
func linkedCall(ctx context.Context, req *pulumirpc.CallRequest, engineConn *grpc.ClientConn,
@ -164,3 +180,6 @@ func linkedCallArgsSelf(ctx *pulumi.Context, source map[string]interface{}) (pul
// linkedNewCallResult is made available here from ../provider_linked.go via go:linkname.
func linkedNewCallResult(result interface{}) (pulumi.Input, error)
// linkedNewCallFailure is made available here from ../provider_linked.go via go:linkname.
func linkedNewCallFailure(property, reason string) interface{}

View file

@ -69,3 +69,8 @@ func linkedCallArgsSelf(ctx *Context, source map[string]interface{}) (Resource,
func linkedNewCallResult(result interface{}) (Input, error) {
return newCallResult(result)
}
//go:linkname linkedNewCallFailure github.com/pulumi/pulumi/sdk/v3/go/pulumi/provider.linkedNewCallFailure
func linkedNewCallFailure(property, reason string) interface{} {
return newCallFailure(property, reason)
}

View file

@ -94,6 +94,7 @@ class Server implements grpc.UntypedServiceImplementation {
const resp = new provproto.ConfigureResponse();
resp.setAcceptsecrets(true);
resp.setAcceptresources(true);
resp.setAcceptoutputs(true);
callback(undefined, resp);
}
@ -390,14 +391,17 @@ class Server implements grpc.UntypedServiceImplementation {
const resp = new provproto.CallResponse();
const [ret, retDependencies] = await runtime.serializeResourceProperties(`call(${req.getTok()})`, result.outputs);
const returnDependenciesMap = resp.getReturndependenciesMap();
for (const [key, resources] of retDependencies) {
const deps = new provproto.CallResponse.ReturnDependencies();
deps.setUrnsList(await Promise.all(Array.from(resources).map(r => r.urn.promise())));
returnDependenciesMap.set(key, deps);
if (result.outputs) {
const [ret, retDependencies] =
await runtime.serializeResourceProperties(`call(${req.getTok()})`, result.outputs);
const returnDependenciesMap = resp.getReturndependenciesMap();
for (const [key, resources] of retDependencies) {
const deps = new provproto.CallResponse.ReturnDependencies();
deps.setUrnsList(await Promise.all(Array.from(resources).map(r => r.urn.promise())));
returnDependenciesMap.set(key, deps);
}
resp.setReturn(structproto.Struct.fromJavaScript(ret));
}
resp.setReturn(structproto.Struct.fromJavaScript(ret));
if ((result.failures || []).length !== 0) {
const failureList = [];
@ -481,33 +485,78 @@ function configureRuntime(req: any, engineAddr: string) {
runtime.setAllConfig(pulumiConfig, req.getConfigsecretkeysList());
}
// deserializeInputs deserializes the inputs struct and applies appropriate dependencies.
async function deserializeInputs(inputsStruct: any, inputDependencies: any): Promise<Inputs> {
/**
* deserializeInputs deserializes the inputs struct and applies appropriate dependencies.
* @internal
*/
export async function deserializeInputs(inputsStruct: any, inputDependencies: any): Promise<Inputs> {
const result: Inputs = {};
const deserializedInputs = runtime.deserializeProperties(inputsStruct);
for (const k of Object.keys(deserializedInputs)) {
const inputDeps = inputDependencies.get(k);
const depsUrns: resource.URN[] = inputDeps?.getUrnsList() ?? [];
const deps = depsUrns.map(depUrn => new resource.DependencyResource(depUrn));
const input = deserializedInputs[k];
const isSecret = runtime.isRpcSecret(input);
const isResourceReference = resource.Resource.isInstance(input)
&& depsUrns.length === 1
&& depsUrns[0] === await input.urn.promise();
if (isResourceReference || (!isSecret && deps.length === 0)) {
// If it's a prompt value, return it directly without wrapping it as an output.
const depsUrns: resource.URN[] = inputDependencies.get(k)?.getUrnsList() ?? [];
if (!isSecret && (depsUrns.length === 0 || containsOutputs(input) || await isResourceReference(input, depsUrns))) {
// If the input isn't a secret and either doesn't have any dependencies, already contains Outputs (from
// deserialized output values), or is a resource reference, then we can return it directly without
// wrapping it as an output.
result[k] = input;
} else {
// Otherwise, wrap it in an output so we can handle secrets and/or track dependencies.
// Note: If the value is or contains an unknown value, the Output will mark its value as
// unknown automatically, so we just pass true for isKnown here.
const deps = depsUrns.map(depUrn => new resource.DependencyResource(depUrn));
result[k] = new Output(deps, Promise.resolve(runtime.unwrapRpcSecret(input)), Promise.resolve(true),
Promise.resolve(isSecret), Promise.resolve([]));
}
}
return result;
}
/**
* Returns true if the input is a resource reference.
*/
async function isResourceReference(input: any, deps: string[]): Promise<boolean> {
return resource.Resource.isInstance(input)
&& deps.length === 1
&& deps[0] === await input.urn.promise();
}
/**
* Returns true if the deserialized input contains Outputs (deeply), excluding properties of Resources.
* @internal
*/
export function containsOutputs(input: any): boolean {
if (Array.isArray(input)) {
for (const e of input) {
if (containsOutputs(e)) {
return true;
}
}
}
else if (typeof input === "object") {
if (Output.isInstance(input)) {
return true;
}
else if (resource.Resource.isInstance(input)) {
// Do not drill into instances of Resource because they will have properties that are
// instances of Output (e.g. urn, id, etc.) and we're only looking for instances of
// Output that aren't associated with a Resource.
return false;
}
for (const k of Object.keys(input)) {
if (containsOutputs(input[k])) {
return true;
}
}
}
return false;
}
// grpcResponseFromError creates a gRPC response representing an error from a dynamic provider's
// resource. This is typically either a creation error, in which the API server has (virtually)
// rejected the resource, or an initialization error, where the API server has accepted the

View file

@ -194,7 +194,8 @@ describe("LocalWorkspace", () => {
assert.strictEqual(typeof (info), "undefined");
await ws.removeStack(stackName);
}));
it(`runs through the stack lifecycle with a local program`, asyncTest(async () => {
// TODO[pulumi/pulumi#8220] understand why this test was flaky
xit(`runs through the stack lifecycle with a local program`, asyncTest(async () => {
const stackName = fullyQualifiedStackName(getTestOrg(), "testproj", `int_test${getTestSuffix()}`);
const workDir = upath.joinSafe(__dirname, "data", "testproj");
const stack = await LocalWorkspace.createStack({ stackName, workDir });
@ -536,7 +537,8 @@ describe("LocalWorkspace", () => {
await stack.workspace.removeStack(stackName);
}
}));
it(`supports stack outputs`, asyncTest(async () => {
// TODO[pulumi/pulumi#8061] flaky test
xit(`supports stack outputs`, asyncTest(async () => {
const program = async () => {
const config = new Config();
return {

View file

@ -15,8 +15,41 @@
import * as assert from "assert";
import { asyncTest } from "./util";
import * as pulumi from "..";
import * as internals from "../provider/internals";
const gstruct = require("google-protobuf/google/protobuf/struct_pb.js");
class TestResource extends pulumi.CustomResource {
constructor(name: string, opts?: pulumi.CustomResourceOptions) {
super("test:index:TestResource", name, {}, opts);
}
}
class TestModule implements pulumi.runtime.ResourceModule {
construct(name: string, type: string, urn: string): pulumi.Resource {
switch (type) {
case "test:index:TestResource":
return new TestResource(name, { urn });
default:
throw new Error(`unknown resource type ${type}`);
}
}
}
class TestMocks implements pulumi.runtime.Mocks {
call(args: pulumi.runtime.MockCallArgs): Record<string, any> {
throw new Error(`unknown function ${args.token}`);
}
newResource(args: pulumi.runtime.MockResourceArgs): { id: string | undefined; state: Record<string, any> } {
return {
id: args.name + "_id",
state: args.inputs,
};
}
}
describe("provider", () => {
it("parses arguments generated by --logflow", asyncTest(async () => {
const parsedArgs = internals.parseArgs(["--logtostderr", "-v=9", "--tracing", "127.0.0.1:6007", "127.0.0.1:12345"]);
@ -26,4 +59,477 @@ describe("provider", () => {
assert.fail("failed to parse");
}
}));
describe("deserializeInputs", () => {
beforeEach(() => {
pulumi.runtime._reset();
pulumi.runtime._resetResourcePackages();
pulumi.runtime._resetResourceModules();
});
async function assertOutputEqual(
actual: any, value: ((v: any) => Promise<void>) | any, known: boolean, secret: boolean, deps?: pulumi.URN[]) {
assert.ok(pulumi.Output.isInstance(actual));
if (typeof value === "function") {
await value(await actual.promise());
} else {
assert.deepStrictEqual(await actual.promise(), value);
}
assert.deepStrictEqual(await actual.isKnown, known);
assert.deepStrictEqual(await actual.isSecret, secret);
const actualDeps = new Set<pulumi.URN>();
const resources = await actual.allResources!();
for (const r of resources) {
const urn = await r.urn.promise();
actualDeps.add(urn);
}
assert.deepStrictEqual(actualDeps, new Set<pulumi.URN>(deps ?? []));
}
function createSecret(value: any) {
return {
[pulumi.runtime.specialSigKey]: pulumi.runtime.specialSecretSig,
value,
};
}
function createResourceRef(urn: pulumi.URN, id?: pulumi.ID) {
return {
[pulumi.runtime.specialSigKey]: pulumi.runtime.specialResourceSig,
urn,
...(id && { id }),
};
}
function createOutputValue(value?: any, secret?: boolean, dependencies?: pulumi.URN[]) {
return {
[pulumi.runtime.specialSigKey]: pulumi.runtime.specialOutputValueSig,
...(value !== undefined && { value }),
...(secret && { secret }),
...(dependencies && { dependencies }),
};
}
const testURN = "urn:pulumi:stack::project::test:index:TestResource::name";
const testID = "name_id";
const tests: {
name: string;
input: any;
deps?: string[];
expected?: any;
assert?: (actual: any) => Promise<void>;
}[] = [
{
name: "unknown",
input: pulumi.runtime.unknownValue,
deps: ["fakeURN"],
assert: async(actual) => {
await assertOutputEqual(actual, undefined, false, false, ["fakeURN"]);
},
},
{
name: "array nested unknown",
input: [pulumi.runtime.unknownValue],
deps: ["fakeURN"],
assert: async(actual) => {
await assertOutputEqual(actual, undefined, false, false, ["fakeURN"]);
},
},
{
name: "object nested unknown",
input: { foo: pulumi.runtime.unknownValue },
deps: ["fakeURN"],
assert: async(actual) => {
await assertOutputEqual(actual, undefined, false, false, ["fakeURN"]);
},
},
{
name: "unknown output value",
input: createOutputValue(undefined, false, ["fakeURN"]),
deps: ["fakeURN"],
assert: async(actual) => {
await assertOutputEqual(actual, undefined, false, false, ["fakeURN"]);
},
},
{
name: "unknown output value (no deps)",
input: createOutputValue(),
assert: async(actual) => {
await assertOutputEqual(actual, undefined, false, false);
},
},
{
name: "array nested unknown output value",
input: [createOutputValue(undefined, false, ["fakeURN"])],
deps: ["fakeURN"],
assert: async(actual) => {
assert.ok(Array.isArray(actual));
await assertOutputEqual(actual[0], undefined, false, false, ["fakeURN"]);
},
},
{
name: "array nested unknown output value (no deps)",
input: [createOutputValue(undefined, false, ["fakeURN"])],
assert: async(actual) => {
assert.ok(Array.isArray(actual));
await assertOutputEqual(actual[0], undefined, false, false, ["fakeURN"]);
},
},
{
name: "object nested unknown output value",
input: { foo: createOutputValue(undefined, false, ["fakeURN"]) },
deps: ["fakeURN"],
assert: async(actual) => {
assert.ok(!pulumi.Output.isInstance(actual));
await assertOutputEqual(actual.foo, undefined, false, false, ["fakeURN"]);
},
},
{
name: "object nested unknown output value (no deps)",
input: { foo: createOutputValue(undefined, false, ["fakeURN"]) },
assert: async(actual) => {
assert.ok(!pulumi.Output.isInstance(actual));
await assertOutputEqual(actual.foo, undefined, false, false, ["fakeURN"]);
},
},
{
name: "string value (no deps)",
input: "hi",
expected: "hi",
},
{
name: "array nested string value (no deps)",
input: ["hi"],
expected: ["hi"],
},
{
name: "object nested string value (no deps)",
input: { foo: "hi" },
expected: { foo: "hi" },
},
{
name: "string output value",
input: createOutputValue("hi", false, ["fakeURN"]),
deps: ["fakeURN"],
assert: async (actual) => {
await assertOutputEqual(actual, "hi", true, false, ["fakeURN"]);
},
},
{
name: "string output value (no deps)",
input: createOutputValue("hi"),
assert: async (actual) => {
await assertOutputEqual(actual, "hi", true, false);
},
},
{
name: "array nested string output value",
input: [createOutputValue("hi", false, ["fakeURN"])],
deps: ["fakeURN"],
assert: async (actual) => {
assert.ok(Array.isArray(actual));
await assertOutputEqual(actual[0], "hi", true, false, ["fakeURN"]);
},
},
{
name: "array nested string output value (no deps)",
input: [createOutputValue("hi", false, ["fakeURN"])],
assert: async (actual) => {
assert.ok(Array.isArray(actual));
await assertOutputEqual(actual[0], "hi", true, false, ["fakeURN"]);
},
},
{
name: "object nested string output value",
input: { foo: createOutputValue("hi", false, ["fakeURN"]) },
deps: ["fakeURN"],
assert: async (actual) => {
assert.ok(!pulumi.Output.isInstance(actual));
await assertOutputEqual(actual.foo, "hi", true, false, ["fakeURN"]);
},
},
{
name: "object nested string output value (no deps)",
input: { foo: createOutputValue("hi", false, ["fakeURN"]) },
assert: async (actual) => {
assert.ok(!pulumi.Output.isInstance(actual));
await assertOutputEqual(actual.foo, "hi", true, false, ["fakeURN"]);
},
},
{
name: "string secret (no deps)",
input: createSecret("shh"),
assert: async (actual) => {
await assertOutputEqual(actual, "shh", true, true);
},
},
{
name: "array nested string secret (no deps)",
input: [createSecret("shh")],
assert: async (actual) => {
await assertOutputEqual(actual, ["shh"], true, true);
},
},
{
name: "object nested string secret (no deps)",
input: { foo: createSecret("shh") },
assert: async (actual) => {
await assertOutputEqual(actual, { foo: "shh" }, true, true);
},
},
{
name: "string secret output value (no deps)",
input: createOutputValue("shh", true),
assert: async (actual) => {
await assertOutputEqual(actual, "shh", true, true);
},
},
{
name: "array nested string secret output value (no deps)",
input: [createOutputValue("shh", true)],
assert: async (actual) => {
assert.ok(Array.isArray(actual));
await assertOutputEqual(actual[0], "shh", true, true);
},
},
{
name: "object nested string secret output value (no deps)",
input: { foo: createOutputValue("shh", true) },
assert: async (actual) => {
assert.ok(!pulumi.Output.isInstance(actual));
await assertOutputEqual(actual.foo, "shh", true, true);
},
},
{
name: "string secret output value",
input: createOutputValue("shh", true, ["fakeURN1", "fakeURN2"]),
deps: ["fakeURN1", "fakeURN2"],
assert: async (actual) => {
await assertOutputEqual(actual, "shh", true, true, ["fakeURN1", "fakeURN2"]);
},
},
{
name: "string secret output value (no deps)",
input: createOutputValue("shh", true, ["fakeURN1", "fakeURN2"]),
assert: async (actual) => {
await assertOutputEqual(actual, "shh", true, true, ["fakeURN1", "fakeURN2"]);
},
},
{
name: "array nested string secret output value",
input: [createOutputValue("shh", true, ["fakeURN1", "fakeURN2"])],
deps: ["fakeURN1", "fakeURN2"],
assert: async (actual) => {
assert.ok(Array.isArray(actual));
await assertOutputEqual(actual[0], "shh", true, true, ["fakeURN1", "fakeURN2"]);
},
},
{
name: "array nested string secret output value (no deps)",
input: [createOutputValue("shh", true, ["fakeURN1", "fakeURN2"])],
assert: async (actual) => {
assert.ok(Array.isArray(actual));
await assertOutputEqual(actual[0], "shh", true, true, ["fakeURN1", "fakeURN2"]);
},
},
{
name: "object nested string secret output value",
input: { foo: createOutputValue("shh", true, ["fakeURN1", "fakeURN2"]) },
deps: ["fakeURN1", "fakeURN2"],
assert: async (actual) => {
assert.ok(!pulumi.Output.isInstance(actual));
await assertOutputEqual(actual.foo, "shh", true, true, ["fakeURN1", "fakeURN2"]);
},
},
{
name: "object nested string secret output value (no deps)",
input: { foo: createOutputValue("shh", true, ["fakeURN1", "fakeURN2"]) },
assert: async (actual) => {
assert.ok(!pulumi.Output.isInstance(actual));
await assertOutputEqual(actual.foo, "shh", true, true, ["fakeURN1", "fakeURN2"]);
},
},
{
name: "resource ref",
input: createResourceRef(testURN, testID),
deps: [testURN],
assert: async (actual) => {
assert.ok(actual instanceof TestResource);
assert.deepStrictEqual(await actual.urn.promise(), testURN);
assert.deepStrictEqual(await actual.id.promise(), testID);
},
},
{
name: "resource ref (no deps)",
input: createResourceRef(testURN, testID),
assert: async (actual) => {
assert.ok(actual instanceof TestResource);
assert.deepStrictEqual(await actual.urn.promise(), testURN);
assert.deepStrictEqual(await actual.id.promise(), testID);
},
},
{
name: "array nested resource ref",
input: [createResourceRef(testURN, testID)],
deps: [testURN],
assert: async (actual) => {
await assertOutputEqual(actual, async (v: any) => {
assert.ok(Array.isArray(v));
assert.ok(v[0] instanceof TestResource);
assert.deepStrictEqual(await v[0].urn.promise(), testURN);
assert.deepStrictEqual(await v[0].id.promise(), testID);
}, true, false, [testURN]);
},
},
{
name: "array nested resource ref (no deps)",
input: [createResourceRef(testURN, testID)],
assert: async (actual) => {
assert.ok(Array.isArray(actual));
assert.ok(actual[0] instanceof TestResource);
assert.deepStrictEqual(await actual[0].urn.promise(), testURN);
assert.deepStrictEqual(await actual[0].id.promise(), testID);
},
},
{
name: "object nested resource ref",
input: { foo: createResourceRef(testURN, testID) },
deps: [testURN],
assert: async (actual) => {
await assertOutputEqual(actual, async (v: any) => {
assert.ok(v.foo instanceof TestResource);
assert.deepStrictEqual(await v.foo.urn.promise(), testURN);
assert.deepStrictEqual(await v.foo.id.promise(), testID);
}, true, false, [testURN]);
},
},
{
name: "object nested resource ref (no deps)",
input: { foo: createResourceRef(testURN, testID) },
assert: async (actual) => {
assert.ok(actual.foo instanceof TestResource);
assert.deepStrictEqual(await actual.foo.urn.promise(), testURN);
assert.deepStrictEqual(await actual.foo.id.promise(), testID);
},
},
{
name: "object nested resource ref and secret",
input: {
foo: createResourceRef(testURN, testID),
bar: createSecret("shh"),
},
deps: [testURN],
assert: async (actual) => {
// Because there's a nested secret, the top-level property is an output.
await assertOutputEqual(actual, async (v: any) => {
assert.ok(v.foo instanceof TestResource);
assert.deepStrictEqual(await v.foo.urn.promise(), testURN);
assert.deepStrictEqual(await v.foo.id.promise(), testID);
assert.deepStrictEqual(v.bar, "shh");
}, true, true, [testURN]);
},
},
{
name: "object nested resource ref and secret output value",
input: {
foo: createResourceRef(testURN, testID),
bar: createOutputValue("shh", true),
},
deps: [testURN],
assert: async (actual) => {
assert.ok(!pulumi.Output.isInstance(actual));
assert.ok(actual.foo instanceof TestResource);
assert.deepStrictEqual(await actual.foo.urn.promise(), testURN);
assert.deepStrictEqual(await actual.foo.id.promise(), testID);
await assertOutputEqual(actual.bar, "shh", true, true);
},
},
{
name: "object nested resource ref and secret output value (no deps)",
input: {
foo: createResourceRef(testURN, testID),
bar: createOutputValue("shh", true),
},
assert: async (actual) => {
assert.ok(!pulumi.Output.isInstance(actual));
assert.ok(actual.foo instanceof TestResource);
assert.deepStrictEqual(await actual.foo.urn.promise(), testURN);
assert.deepStrictEqual(await actual.foo.id.promise(), testID);
await assertOutputEqual(actual.bar, "shh", true, true);
},
},
];
for (const test of tests) {
it(`deserializes '${test.name}' correctly`, asyncTest(async () => {
pulumi.runtime.setMocks(new TestMocks(), "project", "stack", true);
pulumi.runtime.registerResourceModule("test", "index", new TestModule());
new TestResource("name"); // Create an instance so it can be deserialized.
const inputs = { value: test.input };
const inputsStruct = gstruct.Struct.fromJavaScript(inputs);
const inputDependencies = {
get: () => ({
getUrnsList: () => test.deps,
}),
};
const result = await pulumi.provider.deserializeInputs(inputsStruct, inputDependencies);
const actual = result["value"];
if (test.assert) {
await test.assert(actual);
} else {
assert.deepStrictEqual(actual, test.expected);
}
}));
}
});
describe("containsOutputs", () => {
const tests: {
name: string;
input: any;
expected: boolean;
}[] = [
{
name: "Output",
input: pulumi.Output.create("hi"),
expected: true,
},
{
name: "[Output]",
input: [pulumi.Output.create("hi")],
expected: true,
},
{
name: "{ foo: Output }",
input: { foo: pulumi.Output.create("hi") },
expected: true,
},
{
name: "Resource",
input: new pulumi.DependencyResource("fakeURN"),
expected: false,
},
{
name: "[Resource]",
input: [new pulumi.DependencyResource("fakeURN")],
expected: false,
},
{
name: "{ foo: Resource }",
input: { foo: new pulumi.DependencyResource("fakeURN") },
expected: false,
},
];
for (const test of tests) {
it(`${test.name} should return ${test.expected}`, () => {
const actual = pulumi.provider.containsOutputs(test.input);
assert.strictEqual(actual, test.expected);
});
}
});
});

View file

@ -152,6 +152,7 @@ class Output(Generic[T_co]):
# The "run" coroutine actually runs the apply.
async def run() -> U:
resources: Set['Resource'] = set()
try:
# Await this output's details.
resources = await self._resources

View file

@ -25,6 +25,7 @@ import sys
import grpc
import grpc.aio
from google.protobuf import struct_pb2
from pulumi.provider.provider import Provider, CallResult, ConstructResult
from pulumi.resource import ProviderResource, Resource, DependencyResource, DependencyProviderResource, \
_parse_resource_reference
@ -81,8 +82,7 @@ class ProviderServicer(ResourceProviderServicer):
preview=request.dryRun)
pulumi.runtime.config.set_all_config(dict(request.config), request.configSecretKeys)
inputs = await self._construct_inputs(request)
inputs = await self._construct_inputs(request.inputs, request.inputDependencies)
result = self.provider.construct(name=request.name,
resource_type=request.type,
@ -102,28 +102,32 @@ class ProviderServicer(ResourceProviderServicer):
return response
@staticmethod
async def _construct_inputs(request: proto.ConstructRequest) -> Dict[str, pulumi.Input[Any]]:
async def _construct_inputs(inputs: struct_pb2.Struct, input_dependencies: Any) -> Dict[str, pulumi.Input[Any]]:
def deps(key: str) -> Set[str]:
return set(urn for urn in
request.inputDependencies.get(
input_dependencies.get(
key,
proto.ConstructRequest.PropertyDependencies()
).urns)
return {
k: await ProviderServicer._create_output(the_input, deps=deps(k))
k: await ProviderServicer._select_value(the_input, deps=deps(k))
for k, the_input in
rpc.deserialize_properties(request.inputs, keep_unknowns=True).items()
rpc.deserialize_properties(inputs, keep_unknowns=True).items()
}
@staticmethod
async def _create_output(the_input: Any, deps: Set[str]) -> Any:
async def _select_value(the_input: Any, deps: Set[str]) -> Any:
is_secret = rpc.is_rpc_secret(the_input)
# If it's a resource reference or a prompt value, return it directly without wrapping
# it as an output.
if await _is_resource_reference(the_input, deps) or (not is_secret and len(deps) == 0):
# If the input isn't a secret and either doesn't have any dependencies, already contains Outputs (from
# deserialized output values), or is a resource reference, then return it directly without wrapping it
# as an output.
if not is_secret and (
len(deps) == 0 or
_contains_outputs(the_input) or
await _is_resource_reference(the_input, deps)):
return the_input
# Otherwise, wrap it as an output so we can handle secrets
@ -220,7 +224,7 @@ class ProviderServicer(ResourceProviderServicer):
).urns)
return {
k: await ProviderServicer._create_output(the_input, deps=deps(k))
k: await ProviderServicer._select_value(the_input, deps=deps(k))
for k, the_input in
# We need to keep_internal, to keep the `__self__` that would normally be filtered because
# it starts with "__".
@ -249,7 +253,7 @@ class ProviderServicer(ResourceProviderServicer):
return proto.CallResponse(**resp)
async def Configure(self, request, context) -> proto.ConfigureResponse: # pylint: disable=invalid-overridden-method
return proto.ConfigureResponse(acceptSecrets=True, acceptResources=True)
return proto.ConfigureResponse(acceptSecrets=True, acceptResources=True, acceptOutputs=True)
async def GetPluginInfo(self, request, context) -> proto.PluginInfo: # pylint: disable=invalid-overridden-method
return proto.PluginInfo(version=self.provider.version)
@ -331,6 +335,25 @@ async def _is_resource_reference(the_input: Any, deps: Set[str]) -> bool:
and next(iter(deps)) == await cast(Resource, the_input).urn.future())
def _contains_outputs(the_input: Any) -> bool:
"""
Returns true if the input contains Outputs (deeply).
"""
if known_types.is_output(the_input):
return True
if isinstance(the_input, list):
for e in the_input:
if _contains_outputs(e):
return True
elif isinstance(the_input, dict):
for k in the_input:
if _contains_outputs(the_input[k]):
return True
return False
def _create_provider_resource(ref: str) -> ProviderResource:
"""
Rehydrate the provider reference into a registered ProviderResource,

View file

@ -1,4 +1,4 @@
# Copyright 2016-2021, Pulumi Corporation.
# Copyright 2016-2018, Pulumi Corporation.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.

View file

@ -114,12 +114,13 @@ class ConfigureResponse:
def __init__(self,
acceptSecrets: bool=False,
supportsPreview: bool=False,
acceptResources: bool=False) -> None: ...
acceptResources: bool=False,
acceptOutputs: bool=False) -> None: ...
acceptSecrets: bool
supportsPreview: bool
acceptResources: bool
acceptOutputs: bool
class GetSchemaRequest:
version: int

View file

@ -12,24 +12,42 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from typing import Dict, Any
import functools
from typing import Dict, Any, Optional, Tuple, List, Set, Callable, Awaitable
from semver import VersionInfo as Version
import os
import pytest
from pulumi.runtime.settings import Settings, configure
from pulumi.provider.server import ProviderServicer
from pulumi.runtime import proto, rpc
from pulumi.runtime import proto, rpc, rpc_manager, ResourceModule, Mocks
from pulumi.resource import CustomResource, ResourceOptions
from pulumi.runtime.proto.provider_pb2 import ConstructRequest
import google.protobuf.struct_pb2 as struct_pb2
from google.protobuf import struct_pb2
import pulumi.output
def pulumi_test(coro):
wrapped = pulumi.runtime.test(coro)
@functools.wraps(wrapped)
def wrapper(*args, **kwargs):
configure(Settings())
rpc._RESOURCE_PACKAGES.clear()
rpc._RESOURCE_MODULES.clear()
rpc_manager.RPC_MANAGER = rpc_manager.RPCManager()
wrapped(*args, **kwargs)
return wrapper
@pytest.mark.asyncio
async def test_construct_inputs_parses_request():
value = 'foobar'
inputs = _as_struct({'echo': value})
req = ConstructRequest(inputs=inputs)
inputs = await ProviderServicer._construct_inputs(req)
inputs = await ProviderServicer._construct_inputs(req.inputs, req.inputDependencies) # pylint: disable=no-member
assert len(inputs) == 1
assert inputs['echo'] == value
@ -39,7 +57,7 @@ async def test_construct_inputs_preserves_unknowns():
unknown = '04da6b54-80e4-46f7-96ec-b56ff0331ba9'
inputs = _as_struct({'echo': unknown})
req = ConstructRequest(inputs=inputs)
inputs = await ProviderServicer._construct_inputs(req)
inputs = await ProviderServicer._construct_inputs(req.inputs, req.inputDependencies) # pylint: disable=no-member
assert len(inputs) == 1
assert isinstance(inputs['echo'], pulumi.output.Unknown)
@ -48,3 +66,487 @@ def _as_struct(key_values: Dict[str, Any]) -> struct_pb2.Struct:
the_struct = struct_pb2.Struct()
the_struct.update(key_values) # pylint: disable=no-member
return the_struct
class MockResource(CustomResource):
def __init__(self, name: str, opts: Optional[ResourceOptions] = None):
CustomResource.__init__(self, "test:index:MockResource", name, opts=opts)
class MockInputDependencies:
""" A mock for ConstructRequest.inputDependencies
We need only support a `get() -> T where T.urns: List[str]` operation.
"""
def __init__(self, urns: Optional[List[str]]):
self.urns = urns if urns else []
def get(self, *args):
#pylint: disable=unused-argument
return self
class TestModule(ResourceModule):
def construct(self, name: str, typ: str, urn: str):
if typ == "test:index:MockResource":
return MockResource(name, opts=ResourceOptions(urn=urn))
raise Exception(f"unknown resource type {typ}")
def version(self) -> Optional[Version]:
return None
class TestMocks(Mocks):
def call(self, args: pulumi.runtime.MockCallArgs) -> Any:
raise Exception(f"unknown function {args.token}")
def new_resource(self, args: pulumi.runtime.MockResourceArgs) -> Tuple[Optional[str], dict]:
return args.name+"_id", args.inputs
def assert_output_equal(value: Any,
known: bool, secret: bool,
deps: Optional[List[str]] = None):
async def check(actual: Any):
assert isinstance(actual, pulumi.Output)
if callable(value):
res = value(await actual.future())
if isinstance(res, Awaitable):
await res
else:
assert (await actual.future()) == value
assert known == await actual.is_known()
assert secret == await actual.is_secret()
actual_deps: Set[Optional[str]] = set()
resources = await actual.resources()
for r in resources:
urn = await r.urn.future()
actual_deps.add(urn)
assert actual_deps == set(deps if deps else [])
return True
return check
def create_secret(value: Any):
return {rpc._special_sig_key: rpc._special_secret_sig, "value": value}
def create_resource_ref(urn: str, id_: Optional[str]):
ref = {rpc._special_sig_key: rpc._special_resource_sig, "urn": urn}
if id_ is not None:
ref["id"] = id_
return ref
def create_output_value(value: Optional[Any] = None,
secret: Optional[bool] = None,
dependencies: Optional[List[str]] = None):
val: Dict[str, Any] = {rpc._special_sig_key: rpc._special_output_value_sig}
if value is not None:
val["value"] = value
if secret is not None:
val["secret"] = secret
if dependencies is not None:
val["dependencies"] = dependencies
return val
test_urn = "urn:pulumi:stack::project::test:index:MockResource::name"
test_id = "name_id"
class UnmarshalOutputTestCase:
def __init__(self,
name: str,
input_: Any,
deps: Optional[List[str]] = None,
expected: Optional[Any] = None,
assert_: Optional[Callable[[Any], Awaitable]] = None):
self.name = name
self.input_ = input_
self.deps = deps
self.expected = expected
self.assert_ = assert_
async def run(self):
pulumi.runtime.set_mocks(TestMocks(), "project", "stack", True)
pulumi.runtime.register_resource_module("test", "index", TestModule())
# This registers the resource purely for the purpose of the test.
pulumi.runtime.settings.get_monitor().resources[test_urn] = \
pulumi.runtime.mocks.MockMonitor.ResourceRegistration(test_urn, test_id, dict())
inputs = { "value": self.input_ }
input_struct = _as_struct(inputs)
req = ConstructRequest(inputs=input_struct)
result = await ProviderServicer._construct_inputs(
req.inputs, MockInputDependencies(self.deps)) # pylint: disable=no-member
actual = result["value"]
if self.assert_:
await self.assert_(actual)
else:
assert actual == self.expected
class Assert:
"""Describes a series of asserts to be performed.
Each assert can be:
- An async value to be awaited and asserted.
assert await val
- A sync function to be called and asserted on. This will be called on the
same set of arguments that the class was called on.
assert fn(actual)
- A plain value to be asserted on.
assert val
"""
def __init__(self, *asserts):
self.asserts = asserts
async def __call__(self, *args, **kargs):
for assert_ in self.asserts:
assert await Assert.__eval(assert_, *args, **kargs)
@staticmethod
async def __eval(a, *args, **kargs) -> Any:
if isinstance(a, Awaitable):
return await a
elif isinstance(a, Callable):
a_res = a(*args, **kargs)
return await Assert.__eval(a_res, *args, **kargs)
return a
@staticmethod
def async_equal(a, b):
"""Asserts that two values are equal when evaluated with async and
given the args that `Asserts` were called on.
"""
async def check(*args, **kargs):
a_res = await Assert.__eval(a, *args, **kargs)
b_res = await Assert.__eval(b, *args, **kargs)
assert a_res == b_res
return True
return check
async def array_nested_resource_ref(actual):
async def helper(v: Any):
assert isinstance(v, list)
assert isinstance(v[0], MockResource)
assert await v[0].urn.future() == test_urn
assert await v[0].id.future() == test_id
await assert_output_equal(helper, True, False, [test_urn])(actual)
async def object_nested_resource_ref(actual):
async def helper(v: Any):
assert isinstance(v["foo"], MockResource)
assert await v["foo"].urn.future() == test_urn
assert await v["foo"].id.future() == test_id
await assert_output_equal(helper, True, False, [test_urn])(actual)
async def object_nested_resource_ref_and_secret(actual):
async def helper(v: Any):
assert isinstance(v["foo"], MockResource)
assert await v["foo"].urn.future() == test_urn
assert await v["foo"].id.future() == test_id
assert v["bar"] == "ssh"
await assert_output_equal(helper, True, True, [test_urn])(actual)
deserialization_tests = [
UnmarshalOutputTestCase(
name="unknown",
input_=rpc.UNKNOWN,
deps=["fakeURN"],
assert_=assert_output_equal(None, False, False, ["fakeURN"]),
),
UnmarshalOutputTestCase(
name="array nested unknown",
input_=[rpc.UNKNOWN],
deps=["fakeURN"],
assert_=assert_output_equal(None, False, False, ["fakeURN"]),
),
UnmarshalOutputTestCase(
name="object nested unknown",
input_={"foo": rpc.UNKNOWN},
deps=["fakeURN"],
assert_=assert_output_equal(None, False, False, ["fakeURN"]),
),
UnmarshalOutputTestCase(
name="unknown output value",
input_=create_output_value(None, False, ["fakeURN"]),
deps=["fakeURN"],
assert_=assert_output_equal(None, False, False, ["fakeURN"]),
),
UnmarshalOutputTestCase(
name="unknown output value (no deps)",
input_=create_output_value(),
assert_=assert_output_equal(None, False, False),
),
UnmarshalOutputTestCase(
name="array nested unknown output value",
input_=[create_output_value(None, False, ["fakeURN"])],
deps=["fakeURN"],
assert_=Assert(
lambda actual: isinstance(actual, list),
lambda actual: assert_output_equal(None, False, False, ["fakeURN"])(actual[0])
),
),
UnmarshalOutputTestCase(
name="array nested unknown output value (no deps)",
input_=[create_output_value(None, False, ["fakeURN"])],
assert_=Assert(
lambda actual: isinstance(actual, list),
lambda actual: assert_output_equal(None, False, False, ["fakeURN"])(actual[0])
),
),
UnmarshalOutputTestCase(
name="object nested unknown output value",
input_= { "foo": create_output_value(None, False, ["fakeURN"]) },
deps=["fakeURN"],
assert_=Assert(
lambda actual: not isinstance(actual, pulumi.Output),
lambda actual: assert_output_equal(None, False, False, ["fakeURN"])(actual["foo"]),
),
),
UnmarshalOutputTestCase(
name="object nested unknown output value (no deps)",
input_= { "foo": create_output_value(None, False, ["fakeURN"]) },
assert_=Assert(
lambda actual: not isinstance(actual, pulumi.Output),
lambda actual: assert_output_equal(None, False, False, ["fakeURN"])(actual["foo"]),
),
),
UnmarshalOutputTestCase(
name="string value (no deps)",
input_="hi",
expected="hi",
),
UnmarshalOutputTestCase(
name="array nested string value (no deps)",
input_=["hi"],
expected=["hi"],
),
UnmarshalOutputTestCase(
name="object nested string value (no deps)",
input_= { "foo": "hi" },
expected= { "foo": "hi" },
),
UnmarshalOutputTestCase(
name="string output value",
input_=create_output_value("hi", False, ["fakeURN"]),
deps=["fakeURN"],
assert_=assert_output_equal("hi", True, False, ["fakeURN"]),
),
UnmarshalOutputTestCase(
name="string output value (no deps)",
input_=create_output_value("hi"),
assert_=assert_output_equal("hi", True, False),
),
UnmarshalOutputTestCase(
name="array nested string output value",
input_=[create_output_value("hi", False, ["fakeURN"])],
deps=["fakeURN"],
assert_=Assert(
lambda actual: isinstance(actual, list),
lambda actual: assert_output_equal("hi", True, False, ["fakeURN"])(actual[0]),
),
),
UnmarshalOutputTestCase(
name="array nested string output value (no deps)",
input_=[create_output_value("hi", False, ["fakeURN"])],
assert_=Assert(
lambda actual: isinstance(actual, list),
lambda actual: assert_output_equal("hi", True, False, ["fakeURN"])(actual[0]),
),
),
UnmarshalOutputTestCase(
name="object nested string output value",
input_={ "foo": create_output_value("hi", False, ["fakeURN"])},
deps=["fakeURN"],
assert_=Assert(
lambda actual: not isinstance(actual, pulumi.Output),
lambda actual: assert_output_equal("hi", True, False, ["fakeURN"])(actual["foo"])
),
),
UnmarshalOutputTestCase(
name="object nested string output value (no deps)",
input_={ "foo": create_output_value("hi", False, ["fakeURN"])},
assert_=Assert(
lambda actual: not isinstance(actual, pulumi.Output),
lambda actual: assert_output_equal("hi", True, False, ["fakeURN"])(actual["foo"])
),
),
UnmarshalOutputTestCase(
name="string secrets (no deps)",
input_=create_secret("shh"),
assert_=assert_output_equal("shh", True, True),
),
UnmarshalOutputTestCase(
name="array nested string secrets (no deps)",
input_=[create_secret("shh")],
assert_=assert_output_equal(["shh"], True, True),
),
UnmarshalOutputTestCase(
name="object nested string secrets (no deps)",
input_={ "foo": create_secret("shh")},
assert_=assert_output_equal({"foo": "shh"}, True, True),
),
UnmarshalOutputTestCase(
name="string secret output value (no deps)",
input_=create_output_value("shh", True),
assert_=assert_output_equal("shh", True, True),
),
UnmarshalOutputTestCase(
name="array nested string secret output value (no deps)",
input_=[create_output_value("shh", True)],
assert_=Assert(
lambda actual: isinstance(actual, list),
lambda actual: assert_output_equal("shh", True, True)(actual[0]),
),
),
UnmarshalOutputTestCase(
name="object nested string secret output value (no deps)",
input_={"foo": create_output_value("shh", True)},
assert_=Assert(
lambda actual: not isinstance(actual, pulumi.Output),
lambda actual: assert_output_equal("shh", True, True)(actual["foo"]),
),
),
UnmarshalOutputTestCase(
name="string secret output value",
input_=create_output_value("shh", True, ["fakeURN1", "fakeURN2"]),
deps=["fakeURN1", "fakeURN2"],
assert_=assert_output_equal("shh", True, True, ["fakeURN1", "fakeURN2"]),
),
UnmarshalOutputTestCase(
name="string secret output value (no deps)",
input_=create_output_value("shh", True, ["fakeURN1", "fakeURN2"]),
assert_=assert_output_equal("shh", True, True, ["fakeURN1", "fakeURN2"]),
),
UnmarshalOutputTestCase(
name="array nested string secret output value",
input_=[create_output_value("shh", True, ["fakeURN1", "fakeURN2"])],
deps=["fakeURN1", "fakeURN2"],
assert_=Assert(
lambda actual: isinstance(actual, list),
lambda actual: assert_output_equal("shh", True, True, ["fakeURN1", "fakeURN2"])(actual[0]),
),
),
UnmarshalOutputTestCase(
name="array nested string secret output value (no deps)",
input_=[create_output_value("shh", True, ["fakeURN1", "fakeURN2"])],
assert_=Assert(
lambda actual: isinstance(actual, list),
lambda actual: assert_output_equal("shh", True, True, ["fakeURN1", "fakeURN2"])(actual[0]),
),
),
UnmarshalOutputTestCase(
name="object nested string secret output value",
input_={ "foo": create_output_value("shh", True, ["fakeURN1", "fakeURN2"])},
deps=["fakeURN1", "fakeURN2"],
assert_=Assert(
lambda actual: not isinstance(actual, pulumi.Output),
lambda actual: assert_output_equal("shh", True, True, ["fakeURN1", "fakeURN2"])(actual["foo"]),
),
),
UnmarshalOutputTestCase(
name="object nested string secret output value (no deps)",
input_={ "foo": create_output_value("shh", True, ["fakeURN1", "fakeURN2"])},
assert_=Assert(
lambda actual: not isinstance(actual, pulumi.Output),
lambda actual: assert_output_equal("shh", True, True, ["fakeURN1", "fakeURN2"])(actual["foo"]),
),
),
UnmarshalOutputTestCase(
name="resource ref",
input_=create_resource_ref(test_urn, test_id),
deps=[test_urn],
assert_=Assert(
lambda actual: isinstance(actual, MockResource),
Assert.async_equal(lambda actual: actual.urn.future(), test_urn),
Assert.async_equal(lambda actual: actual.id.future(), test_id),
),
),
UnmarshalOutputTestCase(
name="resource ref (no deps)",
input_=create_resource_ref(test_urn, test_id),
assert_=Assert(
lambda actual: isinstance(actual, MockResource),
Assert.async_equal(lambda actual: actual.urn.future(), test_urn),
Assert.async_equal(lambda actual: actual.id.future(), test_id),
),
),
UnmarshalOutputTestCase(
name="array nested resource ref",
input_=[create_resource_ref(test_urn, test_id)],
deps=[test_urn],
assert_=array_nested_resource_ref
),
UnmarshalOutputTestCase(
name="array nested resource ref (no deps)",
input_=[create_resource_ref(test_urn, test_id)],
assert_=Assert(
lambda actual: isinstance(actual, list),
lambda actual: isinstance(actual[0], MockResource),
Assert.async_equal(lambda actual: actual[0].urn.future(), test_urn),
Assert.async_equal(lambda actual: actual[0].id.future(), test_id),
),
),
UnmarshalOutputTestCase(
name="object nested resource ref",
input_={ "foo": create_resource_ref(test_urn, test_id) },
deps=[test_urn],
assert_=object_nested_resource_ref
),
UnmarshalOutputTestCase(
name="object nested resource ref (no deps)",
input_={ "foo": create_resource_ref(test_urn, test_id) },
assert_=Assert(
lambda actual: isinstance(actual["foo"], MockResource),
Assert.async_equal(lambda actual: actual["foo"].urn.future(), test_urn),
Assert.async_equal(lambda actual: actual["foo"].id.future(), test_id),
),
),
UnmarshalOutputTestCase(
name="object nested resource ref and secret",
input_={
"foo": create_resource_ref(test_urn, test_id),
"bar": create_secret("ssh"),
},
deps=[test_urn],
assert_=object_nested_resource_ref_and_secret
),
UnmarshalOutputTestCase(
name="object nested resource ref and secret output value",
input_={
"foo": create_resource_ref(test_urn, test_id),
"bar": create_output_value("shh", True),
},
deps=[test_urn],
assert_=Assert(
lambda actual: not isinstance(actual, pulumi.Output),
lambda actual: isinstance(actual["foo"], MockResource),
Assert.async_equal(lambda actual: actual["foo"].urn.future(), test_urn),
Assert.async_equal(lambda actual: actual["foo"].id.future(), test_id),
lambda actual: assert_output_equal("shh", True, True)(actual["bar"]),
),
),
UnmarshalOutputTestCase(
name="object nested resource ref and secret output value (no deps)",
input_={
"foo": create_resource_ref(test_urn, test_id),
"bar": create_output_value("shh", True),
},
assert_=Assert(
lambda actual: not isinstance(actual, pulumi.Output),
lambda actual: isinstance(actual["foo"], MockResource),
Assert.async_equal(lambda actual: actual["foo"].urn.future(), test_urn),
Assert.async_equal(lambda actual: actual["foo"].id.future(), test_id),
lambda actual: assert_output_equal("shh", True, True)(actual["bar"]),
),
),
]
@pytest.mark.parametrize(
"testcase", deserialization_tests, ids=list(map(lambda x: x.name, deserialization_tests)))
@pulumi_test
async def test_deserialize_correctly(testcase):
await testcase.run()

View file

@ -179,7 +179,7 @@ class NextSerializationTests(unittest.TestCase):
self.assertEqual(id, prop["id"])
res = rpc.deserialize_properties(prop)
self.assertTrue(isinstance(res, MyCustomResource))
self.assertIsInstance(res, MyCustomResource)
rpc._RESOURCE_MODULES.clear()
res = rpc.deserialize_properties(prop)
@ -209,7 +209,7 @@ class NextSerializationTests(unittest.TestCase):
self.assertEqual(id, prop["id"])
res = rpc.deserialize_properties(prop)
self.assertTrue(isinstance(res, MyCustomResource))
self.assertIsInstance(res, MyCustomResource)
rpc._RESOURCE_MODULES.clear()
res = rpc.deserialize_properties(prop)

View file

@ -0,0 +1,353 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
##
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
# User-specific files
*.rsuser
*.suo
*.user
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Mono auto generated files
mono_crash.*
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
[Aa][Rr][Mm]/
[Aa][Rr][Mm]64/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/
[Ll]ogs/
# Visual Studio 2015/2017 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# Visual Studio 2017 auto generated files
Generated\ Files/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUnit
*.VisualState.xml
TestResult.xml
nunit-*.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# Benchmark Results
BenchmarkDotNet.Artifacts/
# .NET Core
project.lock.json
project.fragment.lock.json
artifacts/
# StyleCop
StyleCopReport.xml
# Files built by Visual Studio
*_i.c
*_p.c
*_h.h
*.ilk
*.meta
*.obj
*.iobj
*.pch
*.pdb
*.ipdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*_wpftmp.csproj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# Visual Studio Trace Files
*.e2e
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# JustCode is a .NET coding add-in
.JustCode
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# AxoCover is a Code Coverage Tool
.axoCover/*
!.axoCover/settings.json
# Visual Studio code coverage results
*.coverage
*.coveragexml
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# Note: Comment the next line if you want to checkin your web deploy settings,
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj
# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/
# NuGet Packages
*.nupkg
# NuGet Symbol Packages
*.snupkg
# The packages folder can be ignored because of Package Restore
**/[Pp]ackages/*
# except build/, which is used as an MSBuild target.
!**/[Pp]ackages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/[Pp]ackages/repositories.config
# NuGet v3's project.json files produces more ignorable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
*.appx
*.appxbundle
*.appxupload
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!?*.[Cc]ache/
# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
orleans.codegen.cs
# Including strong name files can present a security risk
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
#*.snk
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
ServiceFabricBackup/
*.rptproj.bak
# SQL Server files
*.mdf
*.ldf
*.ndf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
*.rptproj.rsuser
*- [Bb]ackup.rdl
*- [Bb]ackup ([0-9]).rdl
*- [Bb]ackup ([0-9][0-9]).rdl
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
node_modules/
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
*.vbw
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
.paket/paket.exe
paket-files/
# FAKE - F# Make
.fake/
# CodeRush personal settings
.cr/personal
# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc
# Cake - Uncomment if you are using it
# tools/**
# !tools/packages.config
# Tabs Studio
*.tss
# Telerik's JustMock configuration file
*.jmconfig
# BizTalk build output
*.btp.cs
*.btm.cs
*.odx.cs
*.xsd.cs
# OpenCover UI analysis results
OpenCover/
# Azure Stream Analytics local run output
ASALocalRun/
# MSBuild Binary and Structured Log
*.binlog
# NVidia Nsight GPU debugger configuration file
*.nvuser
# MFractors (Xamarin productivity tool) working folder
.mfractor/
# Local History for Visual Studio
.localhistory/
# BeatPulse healthcheck temp database
healthchecksdb
# Backup folder for Package Reference Convert tool in Visual Studio 2017
MigrationBackup/
# Ionide (cross platform F# VS Code tools) working folder
.ionide/

View file

@ -0,0 +1,32 @@
// Copyright 2016-2021, Pulumi Corporation. All rights reserved.
using Pulumi;
class Component : ComponentResource
{
public Component(string name, ComponentResourceOptions? opts = null)
: base("testcomponent:index:Component", name, ResourceArgs.Empty, opts, remote: true)
{
}
public Output<ComponentGetMessageResult> GetMessage(ComponentGetMessageArgs args)
=> Deployment.Instance.Call<ComponentGetMessageResult>("testcomponent:index:Component/getMessage", args, this);
}
public class ComponentGetMessageArgs : CallArgs
{
[Input("echo")]
public Input<string> Echo { get; set; } = null!;
}
[OutputType]
public sealed class ComponentGetMessageResult
{
public readonly string Message;
[OutputConstructor]
private ComponentGetMessageResult(string message)
{
Message = message;
}
}

View file

@ -0,0 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>

View file

@ -0,0 +1,13 @@
// Copyright 2016-2021, Pulumi Corporation. All rights reserved.
using System;
using Pulumi;
class MyStack : Stack
{
public MyStack()
{
var component = new Component("component");
var result = component.GetMessage(new ComponentGetMessageArgs { Echo = "hello" });
}
}

View file

@ -0,0 +1,9 @@
// Copyright 2016-2021, Pulumi Corporation. All rights reserved.
using System.Threading.Tasks;
using Pulumi;
class Program
{
static Task<int> Main() => Deployment.RunAsync<MyStack>();
}

View file

@ -0,0 +1,3 @@
name: construct_component_methods_errors_dotnet
description: A program that constructs remote component resources with a method that returns an error.
runtime: dotnet

View file

@ -0,0 +1,3 @@
name: construct_component_methods_errors_go
description: A program that constructs remote component resources with a method that returns an error.
runtime: go

View file

@ -0,0 +1,67 @@
// Copyright 2016-2021, Pulumi Corporation. All rights reserved.
package main
import (
"reflect"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
type Component struct {
pulumi.ResourceState
}
func NewComponent(
ctx *pulumi.Context, name string, opts ...pulumi.ResourceOption) (*Component, error) {
var resource Component
err := ctx.RegisterRemoteComponentResource("testcomponent:index:Component", name, nil, &resource, opts...)
if err != nil {
return nil, err
}
return &resource, nil
}
func (c *Component) GetMessage(ctx *pulumi.Context, args *ComponentGetMessageArgs) (ComponentGetMessageResultOutput, error) {
out, err := ctx.Call("testcomponent:index:Component/getMessage", args, ComponentGetMessageResultOutput{}, c)
if err != nil {
return ComponentGetMessageResultOutput{}, err
}
return out.(ComponentGetMessageResultOutput), nil
}
type componentGetMessageArgs struct {
Echo string `pulumi:"echo"`
}
type ComponentGetMessageArgs struct {
Echo pulumi.StringInput
}
func (ComponentGetMessageArgs) ElementType() reflect.Type {
return reflect.TypeOf((*componentGetMessageArgs)(nil)).Elem()
}
type ComponentGetMessageResult struct {
Message string `pulumi:"message"`
}
type ComponentGetMessageResultOutput struct{ *pulumi.OutputState }
func (ComponentGetMessageResultOutput) ElementType() reflect.Type {
return reflect.TypeOf((*ComponentGetMessageResult)(nil)).Elem()
}
func (o ComponentGetMessageResultOutput) Message() pulumi.StringOutput {
return o.ApplyT(func(v ComponentGetMessageResult) string { return v.Message }).(pulumi.StringOutput)
}
func (*Component) ElementType() reflect.Type {
return reflect.TypeOf((*Component)(nil))
}
func init() {
pulumi.RegisterOutputType(ComponentGetMessageResultOutput{})
}

View file

@ -0,0 +1,5 @@
module github.com/pulumi/pulumi/tests/construct_component_methods_errors
go 1.16
require github.com/pulumi/pulumi/sdk/v3 v3.0.0-20210322210933-10a6a2caf014

View file

@ -0,0 +1,431 @@
cloud.google.com/go v0.26.0 h1:e0WKqKTd5BnrG8aKH3J3h+QvEIQtSUcf2n5UZ5ZgLtQ=
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/Microsoft/go-winio v0.4.14 h1:+hMXMk01us9KgxGb7ftKQt2Xpf5hH/yky+TDA+qxleU=
github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA=
github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7 h1:uSoVVbwJiQipAclBbw+8quDsfcvFjOpI5iCf4p/cqCs=
github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc h1:cAKDfWh5VpdgMhJosfJnn5/FoN2SRZ4p7fJNX58YPaU=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf h1:qet1QNfXsQxTZqLG4oE62mJzwPIB8+Tee4RNCL9ulrY=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo4JG6LR5AXSUEsOjtdm0kw0FtQtMJA=
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6 h1:G1bPvciwNyF7IUmKXNt9Ak3m6u9DE1rF+RmtIkBpVdA=
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0 h1:HWo1m869IqiPhD389kmkxeTalrjNbbJTC8LXupb+sl0=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ=
github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
github.com/census-instrumentation/opencensus-proto v0.2.1 h1:glEXhBS5PSLLv4IXzLA5yPRVX4bilULVyxxbrfOtDAk=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/cheggaaa/pb v1.0.18 h1:G/DgkKaBP0V5lnBg/vx61nVxxAU+VqU5yMzSc0f2PPE=
github.com/cheggaaa/pb v1.0.18/go.mod h1:pQciLPpbU0oxA0h+VJYYLxO+XeDQb5pZijXscXHm81s=
github.com/client9/misspell v0.3.4 h1:ta993UF76GwbvJcIo3Y68y/M3WxlpEHPWIGDkJYwzJI=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f h1:WBZRG4aNOuI15bLRrCgN8fCq8E5Xuty6jGbmSNEvSsU=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd h1:qMd81Ts1T2OTKmB4acZcyKaMtRnY5Y44NuXGX2GFJ1w=
github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI=
github.com/coreos/bbolt v1.3.2 h1:wZwiHHUieZCquLkDL0B8UhzreNWsPHooDAG3q34zk0s=
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
github.com/coreos/etcd v3.3.10+incompatible h1:jFneRYjIvLMLhDLCzuTuU4rSJUjRplcJQ7pD7MnhC04=
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/go-semver v0.2.0 h1:3Jm3tLmsgAYcjC+4Up7hJrFBPr+n7rAqYeSw/SZazuY=
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e h1:Wf6HqHfScWJN9/ZjdUKyjop4mf3Qdd+1TvvltAvM3m8=
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f h1:lBNOc5arjvs8E5mO2tbpBpLoyyu8B6e44T7hJy6potg=
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/cpuguy83/go-md2man/v2 v2.0.0 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM=
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
github.com/creack/pty v1.1.9 h1:uDmaGzcdjhF4i/plgjmEsriH11Y0o7RKapEf/LDaM3w=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
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/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954 h1:RMLoZVzv4GliuWafOuPuQDKSm1SJph7uCRnnS61JAn4=
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
github.com/djherbis/times v1.2.0 h1:xANXjsC/iBqbO00vkWlYwPWgBgEVU6m6AFYg0Pic+Mc=
github.com/djherbis/times v1.2.0/go.mod h1:CGMZlo255K5r4Yw0b9RRfFQpM2y7uOmxg4jm9HsaVf8=
github.com/emirpasic/gods v1.12.0 h1:QAUIPSaCu4G+POclxeqb3F+WPpdKqFGlw36+yOzGlrg=
github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.4 h1:rEvIZUSZ3fx39WIi3JkQqQBitGwpELBIYWeBVh6wn+E=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
github.com/envoyproxy/protoc-gen-validate v0.1.0 h1:EQciDnbrYxy13PgWoY8AqoxGiPrpgBZ1R8UNe3ddc+A=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/fatih/color v1.9.0 h1:8xPHl4/q1VyqGIPif1F+1V3Y3lSmrq01EabUW3CoW5s=
github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU=
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 h1:BHsljHzVlRcyQhjrss6TZTdY2VfCqZPbv5k3iBFa2ZQ=
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/gliderlabs/ssh v0.2.2 h1:6zsha5zo/TWhRhwqCD3+EarCAgZ2yN28ipRnGPnwkI0=
github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
github.com/go-kit/kit v0.8.0 h1:Wz+5lgoB0kkuqLEc6NVmwRknTKP6dTGbSqvhZtBI/j0=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
github.com/go-logfmt/logfmt v0.4.0 h1:MP4Eh7ZCb31lleYCFuwm0oe4/YGak+5l1vA2NOE80nA=
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/gofrs/flock v0.7.1 h1:DP+LD/t0njgoPBvT5MJLeliUIVQR03hiKR6vezdwHlc=
github.com/gofrs/flock v0.7.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=
github.com/gofrs/uuid v3.3.0+incompatible h1:8K4tyRfvU1CYPgJsveYFQMhpFd/wXNM7iK6rR7UHz84=
github.com/gofrs/uuid v3.3.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls=
github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef h1:veQD95Isof8w9/WXiA+pa3tz3fJXkt5B7QaRBrM62gk=
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/mock v1.1.1 h1:G5FRp8JnTd7RQH5kemVNlMeyXQAztQ3mOWV95KxsXH8=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0=
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.4.1 h1:/exdXoGamhu5ONeUJH0deniYLWYvQwW66yvlfiiKTu0=
github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q=
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0 h1:Iju5GlWwrvL6UBg4zJJt3btmonfrMlCDdsejg4CZE7c=
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho=
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
github.com/grpc-ecosystem/grpc-gateway v1.9.0 h1:bM6ZAFZmc/wPFaRDi0d5L7hGEZEx/2u+Tmr2evNHDiI=
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645 h1:MJG/KsmcqMwFAkh8mTnAwhyKoB+sTAnY4CACC110tbU=
github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645/go.mod h1:6iZfnjpejD4L/4DwD7NryNaJyCQdzwWwH2MWhCA90Kw=
github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-multierror v1.0.0 h1:iVjPR7a6H0tWELX5NxNe7bYopibicUzc7uPribsnS6o=
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
github.com/jessevdk/go-flags v1.4.0 h1:4IU2WS7AumrZ/40jfhf4QVDMsQwqA7VEHozFRrGARJA=
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/jonboulle/clockwork v0.1.0 h1:VKV+ZcuP6l3yW9doeqz6ziZGgcynBVQO+obU0+0hcPo=
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
github.com/julienschmidt/httprouter v1.2.0 h1:TDTW5Yz1mjftljbcKqRcrYhd4XeOoI98t+9HbQbYf7g=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd h1:Coekwdh0v2wtGp9Gmz1Ze3eVRAWJMLokvN3QjdzCHLY=
github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
github.com/kisielk/errcheck v1.2.0 h1:reN85Pxc5larApoH1keMBiu2GWtPqXQ1nc9gx+jOU+E=
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515 h1:T+h1c/A9Gawja4Y9mFVWj2vyii2bbUNDw3kt9VxK2EY=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
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/pty v1.1.8 h1:AkaSdXYQOWeaO3neb8EM634ahkXXe3jYbVh/F9lq+GI=
github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw=
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/magiconair/properties v1.8.0 h1:LLgXmsheXeRoUOBOjtwPQCWIYqM/LU1ayDtDePerRcY=
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-colorable v0.1.6 h1:6Su7aK7lXmJ/U79bYtBjLNaha4Fs1Rg9plHpcH+vvnE=
github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-runewidth v0.0.8 h1:3tS41NlGYSmhhe/8fhGRzc+z3AYCw1Fe1WAyLuujKs0=
github.com/mattn/go-runewidth v0.0.8/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/go-ps v1.0.0 h1:i6ampVEEF4wQFF+bkYfwYgY+F/uYJDktmvLPf7qIgjc=
github.com/mitchellh/go-ps v1.0.0/go.mod h1:J4lOc8z8yJs6vUwklHw2XEIiT4z4C40KtWVN3nvg8Pg=
github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223 h1:F9x/1yl3T2AeKLr2AMdilSD8+f9bvMnNN8VS5iDtovc=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4=
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
github.com/opentracing/basictracer-go v1.0.0 h1:YyUAhaEfjoWXclZVJ9sGoNct7j4TVk7lZWlQw5UXuoo=
github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74=
github.com/opentracing/opentracing-go v1.1.0 h1:pWlfV3Bxv7k65HYwkikxat0+s3pV4bsqf19k25Ur8rU=
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
github.com/pelletier/go-buffruneio v0.2.0 h1:U4t4R6YkofJ5xHm3dJzuRpPZ0mr5MMCoAWooScCR7aA=
github.com/pelletier/go-buffruneio v0.2.0/go.mod h1:JkE26KsDizTr40EUHkXVtNPvgGtbSNq5BcowyYOWdKo=
github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
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/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v0.9.3 h1:9iH4JKXLzFbOAdtqv/a+j8aewx2Y8lAjAydhbaScPF8=
github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4 h1:gQz4mCbXsO+nc9n1hCxHcGA3Zx3Eo+UHZoInFGUIXNM=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
github.com/prometheus/common v0.4.0 h1:7etb9YClo3a6HjLzfl6rIQaU+FDfi0VSX39io3aQ+DM=
github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084 h1:sofwID9zm4tzrgykg80hfFph1mryUeLRsUfoocVVmRY=
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/tsdb v0.7.1 h1:YZcsG11NqnK4czYLrWd9mpEuAJIHVQLwdrleYfszMAA=
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
github.com/pulumi/pulumi/sdk/v3 v3.0.0-20210322210933-10a6a2caf014 h1:WUlOHsRhzO08oUCEjZhWS0VHssiIjCNio89VlAvD9ao=
github.com/pulumi/pulumi/sdk/v3 v3.0.0-20210322210933-10a6a2caf014/go.mod h1:GBHyQ7awNQSRmiKp/p8kIKrGrMOZeA/k2czoM/GOqds=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af h1:gu+uRPtBe88sKxUCEXRoeCvVG90TJmwhiqRpvdhQFng=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/sabhiram/go-gitignore v0.0.0-20180611051255-d3107576ba94 h1:G04eS0JkAIVZfaJLjla9dNxkJCPiKIGZlw9AfOhzOD0=
github.com/sabhiram/go-gitignore v0.0.0-20180611051255-d3107576ba94/go.mod h1:b18R55ulyQ/h3RaWyloPyER7fWQVZvimKKhnI5OfrJQ=
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.1 h1:GL2rEmy6nsikmW0r8opw9JIRScdMF5hA8cOYLH7In1k=
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
github.com/soheilhy/cmux v0.1.4 h1:0HKaf1o97UwFjHH9o5XsHUOF+tqmdA7KEzXLpiyaw0E=
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72 h1:qLC7fQah7D6K1B0ujays3HV9gkFtllcxhzImRR7ArPQ=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/spf13/afero v1.1.2 h1:m8/z1t7/fwjysjQRYbP0RD+bUIF/8tJwPdEZsI83ACI=
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng=
github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cobra v1.0.0 h1:6m/oheQuQ13N9ks4hubMG6BnvwOeaJrqSPLahSnczz8=
github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk=
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/viper v1.4.0 h1:yXHLWeravcrgGyFSyCgdYpXQ9dR9c/WED3pg1RhxqEU=
github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
github.com/src-d/gcfg v1.4.0 h1:xXbNR5AlLSA315x2UO+fTSSAXCDf+Ar38/6oyGbDKQ4=
github.com/src-d/gcfg v1.4.0/go.mod h1:p/UMsR43ujA89BJY9duynAwIpvqEujIH/jFlfL7jWoI=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48=
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/texttheater/golang-levenshtein v0.0.0-20191208221605-eb6844b05fc6 h1:9VTskZOIRf2vKF3UL8TuWElry5pgUpV1tFSe/e/0m/E=
github.com/texttheater/golang-levenshtein v0.0.0-20191208221605-eb6844b05fc6/go.mod h1:XDKHRm5ThF8YJjx001LtgelzsoaEcvnA7lVWz9EeX3g=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5 h1:LnC5Kc/wtumK+WB441p7ynQJzVuNRJiqddSIE3IlSEQ=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/tweekmonster/luser v0.0.0-20161003172636-3fa38070dbd7 h1:X9dsIWPuuEJlPX//UmRKophhOKCGXc46RVIGuttks68=
github.com/tweekmonster/luser v0.0.0-20161003172636-3fa38070dbd7/go.mod h1:UxoP3EypF8JfGEjAII8jx1q8rQyDnX8qdTCs/UQBVIE=
github.com/uber/jaeger-client-go v2.22.1+incompatible h1:NHcubEkVbahf9t3p75TOCR83gdUHXjRJvjoBh1yACsM=
github.com/uber/jaeger-client-go v2.22.1+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk=
github.com/uber/jaeger-lib v2.2.0+incompatible h1:MxZXOiR2JuoANZ3J6DE/U0kSFv/eJ/GfSYVCjK7dyaw=
github.com/uber/jaeger-lib v2.2.0+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U=
github.com/ugorji/go v1.1.4 h1:j4s+tAvLfL3bZyefP2SEWmhBzmuIlH/eqNuPdFPgngw=
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
github.com/xanzy/ssh-agent v0.2.1 h1:TCbipTQL2JiiCprBWx9frJ2eJlCYT00NmctrHxVAr70=
github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5Qo6v2eYzo7kUS51QINcR5jNpbZS8=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77 h1:ESFSdwYZvkeru3RtdrYueztKhOBCSAAzS4Gf+k0tEow=
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
github.com/yuin/goldmark v1.1.27 h1:nqDD4MMMQA0lmWq03Z2/myGPYLQoXtmi0rGVs95ntbo=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
go.etcd.io/bbolt v1.3.2 h1:Z/90sZLPOeCy2PwprqkFa25PdkusRzaj9P8zm/KNyvk=
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/atomic v1.6.0 h1:Ezj3JGmsOnG1MoRWQkPBsKLe9DwWD9QeXzTRzzldNVk=
go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI=
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM=
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200317142112-1b76d66859c6 h1:TjszyFsQsyZNHwdVdZ5m7bjmreu0znc2kRYsEml9/Ww=
golang.org/x/crypto v0.0.0-20200317142112-1b76d66859c6/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4 h1:c2HOrn5iMezYjSlGPncknSEr/8x5LELb/ilJbXi9DEA=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20200302205851-738671d3881b h1:Wh+f8QHJXR411sJR8/vRBTZ7YapZaRvUcLFFJhusH0k=
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200602114024-627f9648deb9 h1:pNX+40auqi2JqRfOP1akLGtYcn15TUbkhwuCO3foqqM=
golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be h1:vEDujvNQGv4jgYKudGeI/+DAX4Jffq6hpD55MmoEvKs=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e h1:vcxGaoTs7kV8m5Np9uUNQin4BrLOthgV7252N8V+FwY=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190221075227-b4e8571b14e0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980 h1:OjiUf46hAmXblsZdnoSXsEUSKU8r1UEzcL5RVZ4gO9Y=
golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190729092621-ff9f1409240a/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI=
golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200608174601-1b747fd94509 h1:MI14dOfl3OG6Zd32w3ugsrvcUO810fDZdWakTq39dH4=
golang.org/x/tools v0.0.0-20200608174601-1b747fd94509/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
google.golang.org/genproto v0.0.0-20200608115520-7c474a2e3482 h1:i+Aiej6cta/Frzp13/swvwz5O00kYcSe0A/C5Wd7zX8=
google.golang.org/genproto v0.0.0-20200608115520-7c474a2e3482/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.29.1 h1:EC2SB8S04d2r73uptxphDSUG+kTKVgjRPF+N3xpxRB4=
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.24.0 h1:UhZDfRO8JRQru4/+LlLE0BRKGF8L+PICnvYZmx/fEGA=
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/cheggaaa/pb.v1 v1.0.28 h1:n1tBJnnK2r7g9OW2btFH91V92STTUevLXYFb8gy9EMk=
gopkg.in/cheggaaa/pb.v1 v1.0.28/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
gopkg.in/resty.v1 v1.12.0 h1:CuXP0Pjfw9rOuY6EP+UvtNvt5DSqHpIxILZKT/quCZI=
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
gopkg.in/src-d/go-billy.v4 v4.3.2 h1:0SQA1pRztfTFx2miS8sA97XvooFeNOmvUenF4o0EcVg=
gopkg.in/src-d/go-billy.v4 v4.3.2/go.mod h1:nDjArDMp+XMs1aFAESLRjfGSgfvoYN0hDfzEk0GjC98=
gopkg.in/src-d/go-git-fixtures.v3 v3.5.0 h1:ivZFOIltbce2Mo8IjzUHAFoq/IylO9WHhNOAJK+LsJg=
gopkg.in/src-d/go-git-fixtures.v3 v3.5.0/go.mod h1:dLBcvytrw/TYZsNTWCnkNF2DSIlzWYqTe3rJR56Ac7g=
gopkg.in/src-d/go-git.v4 v4.13.1 h1:SRtFyV8Kxc0UP7aCHcijOMQGPxHSmMOPrzulQWolkYE=
gopkg.in/src-d/go-git.v4 v4.13.1/go.mod h1:nx5NYcxdKxq5fpltdHnPa2Exj4Sx0EclMWZQbYDu2z8=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME=
gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc h1:/hemPrYIhOhy8zYrNj+069zDB68us2sMGsfkFJO0iZs=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0 h1:ucqkfpjg9WzSUubAO62csmucvxl4/JeW3F4I4909XkM=
sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU=

View file

@ -0,0 +1,23 @@
// Copyright 2016-2021, Pulumi Corporation. All rights reserved.
package main
import (
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
component, err := NewComponent(ctx, "component")
if err != nil {
return err
}
_, err = component.GetMessage(ctx, &ComponentGetMessageArgs{
Echo: pulumi.String("hello"),
})
if err != nil {
return err
}
return nil
})
}

View file

@ -0,0 +1,3 @@
/.pulumi/
/bin/
/node_modules/

View file

@ -0,0 +1,3 @@
name: construct_component_methods_errors_nodejs
description: A program that constructs remote component resources with a method that returns an error.
runtime: nodejs

View file

@ -0,0 +1,26 @@
// Copyright 2016-2021, Pulumi Corporation. All rights reserved.
import * as pulumi from "@pulumi/pulumi";
export class Component extends pulumi.ComponentResource {
constructor(name: string, opts?: pulumi.ComponentResourceOptions) {
super("testcomponent:index:Component", name, undefined, opts, true);
}
getMessage(args: Component.GetMessageArgs): pulumi.Output<Component.GetMessageResult> {
return pulumi.runtime.call("testcomponent:index:Component/getMessage", {
"__self__": this,
"echo": args.echo,
}, this);
}
}
export namespace Component {
export interface GetMessageArgs {
echo: pulumi.Input<string>;
}
export interface GetMessageResult {
message: string;
}
}

View file

@ -0,0 +1,6 @@
// Copyright 2016-2021, Pulumi Corporation. All rights reserved.
import { Component } from "./component"
const component = new Component("component");
const result = component.getMessage({ echo: "hello" });

View file

@ -0,0 +1,11 @@
{
"name": "construct_component_methods_unknown",
"license": "Apache-2.0",
"devDependencies": {
"typescript": "^3.0.0",
"@types/node": "latest"
},
"peerDependencies": {
"@pulumi/pulumi": "latest"
}
}

View file

@ -0,0 +1,5 @@
*.pyc
/.pulumi/
/dist/
/*.egg-info
venv/

View file

@ -0,0 +1,3 @@
name: construct_component_methods_errors_py
description: A program that constructs remote component resources with a method that returns an error.
runtime: python

View file

@ -0,0 +1,7 @@
# Copyright 2016-2021, Pulumi Corporation. All rights reserved.
from component import Component
component = Component("component")
result = component.get_message("hello")

View file

@ -0,0 +1,32 @@
# Copyright 2016-2021, Pulumi Corporation. All rights reserved.
from typing import Optional
import pulumi
class Component(pulumi.ComponentResource):
def __init__(self,
name: str,
opts: Optional[pulumi.ResourceOptions] = None):
super().__init__("testcomponent:index:Component", name, {}, opts, True)
@pulumi.output_type
class GetMessageResult:
def __init__(self, message: str):
if message and not isinstance(message, str):
raise TypeError("Expected argument 'message' to be a str")
pulumi.set(self, "message", message)
@property
@pulumi.getter
def message(self) -> str:
return pulumi.get(self, "message")
def get_message(__self__, echo: pulumi.Input[str]) -> pulumi.Output['Component.GetMessageResult']:
__args__ = dict()
__args__['__self__'] = __self__
__args__['echo'] = echo
return pulumi.runtime.call('testcomponent:index:Component/getMessage',
__args__,
res=__self__,
typ=Component.GetMessageResult)

View file

@ -0,0 +1,2 @@
pulumi-resource-testcomponent
pulumi-resource-testcomponent.exe

View file

@ -0,0 +1,70 @@
// Copyright 2016-2021, Pulumi Corporation. All rights reserved.
package main
import (
"fmt"
"github.com/pulumi/pulumi/pkg/v3/resource/provider"
"github.com/pulumi/pulumi/sdk/v3/go/common/util/cmdutil"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
pulumiprovider "github.com/pulumi/pulumi/sdk/v3/go/pulumi/provider"
)
type Component struct {
pulumi.ResourceState
}
func NewComponent(ctx *pulumi.Context, name string, opts ...pulumi.ResourceOption) (*Component, error) {
component := &Component{}
err := ctx.RegisterComponentResource("testcomponent:index:Component", name, component, opts...)
if err != nil {
return nil, err
}
if err := ctx.RegisterResourceOutputs(component, pulumi.Map{}); err != nil {
return nil, err
}
return component, nil
}
const providerName = "testcomponent"
const version = "0.0.1"
func main() {
if err := provider.MainWithOptions(provider.Options{
Name: providerName,
Version: version,
Construct: func(ctx *pulumi.Context, typ, name string, inputs pulumiprovider.ConstructInputs,
options pulumi.ResourceOption) (*pulumiprovider.ConstructResult, error) {
if typ != "testcomponent:index:Component" {
return nil, fmt.Errorf("unknown resource type %s", typ)
}
component, err := NewComponent(ctx, name, options)
if err != nil {
return nil, fmt.Errorf("creating component: %w", err)
}
return pulumiprovider.NewConstructResult(component)
},
Call: func(ctx *pulumi.Context, tok string, args pulumiprovider.CallArgs) (*pulumiprovider.CallResult, error) {
if tok != "testcomponent:index:Component/getMessage" {
return nil, fmt.Errorf("unknown method %s", tok)
}
return &pulumiprovider.CallResult{
Failures: []pulumiprovider.CallFailure{
{
Property: "the failure property",
Reason: "the failure reason",
},
},
}, nil
},
}); err != nil {
cmdutil.ExitError(err.Error())
}
}

View file

@ -0,0 +1,7 @@
#!/bin/bash
set -euo pipefail
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
exec "$PULUMI_RUNTIME_VIRTUALENV/bin/python" "$SCRIPT_DIR/testcomponent.py" "$@"

View file

@ -0,0 +1,4 @@
@echo off
setlocal
set SCRIPT_DIR=%~dp0
@%PULUMI_RUNTIME_VIRTUALENV%\Scripts\python.exe "%SCRIPT_DIR%/testcomponent.py" %*

View file

@ -0,0 +1,67 @@
# Copyright 2016-2021, Pulumi Corporation.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from typing import Optional
import sys
import pulumi
import pulumi.provider as provider
class Component(pulumi.ComponentResource):
def __init__(self,
resource_name: str,
opts: Optional[pulumi.ResourceOptions] = None) -> None:
super().__init__("testcomponent:index:Component", resource_name, {}, opts)
class Provider(provider.Provider):
VERSION = "0.0.1"
class Module(pulumi.runtime.ResourceModule):
def version(self):
return Provider.VERSION
def construct(self, name: str, typ: str, urn: str) -> pulumi.Resource:
if typ == "testcomponent:index:Component":
return Component(name, pulumi.ResourceOptions(urn=urn))
else:
raise Exception(f"unknown resource type {typ}")
def __init__(self):
super().__init__(Provider.VERSION)
pulumi.runtime.register_resource_module("testcomponent", "index", Provider.Module())
def construct(self, name: str, resource_type: str, inputs: pulumi.Inputs,
options: Optional[pulumi.ResourceOptions] = None) -> provider.ConstructResult:
if resource_type != "testcomponent:index:Component":
raise Exception(f"unknown resource type {resource_type}")
component = Component(name, options)
return provider.ConstructResult(
urn=component.urn,
state=inputs)
def call(self, token: str, args: pulumi.Inputs) -> provider.CallResult:
if token != "testcomponent:index:Component/getMessage":
raise Exception(f'unknown method {token}')
return provider.CallResult(
outputs={},
failures=[provider.CheckFailure(property="the failure property", reason="the failure reason")])
if __name__ == "__main__":
provider.main(Provider(), sys.argv[1:])

View file

@ -0,0 +1,45 @@
// Copyright 2016-2021, Pulumi Corporation. All rights reserved.
import * as pulumi from "@pulumi/pulumi";
import * as provider from "@pulumi/pulumi/provider";
class Component extends pulumi.ComponentResource {
constructor(name: string, opts?: pulumi.ComponentResourceOptions) {
super("testcomponent:index:Component", name, undefined, opts);
}
}
class Provider implements provider.Provider {
public readonly version = "0.0.1";
async construct(name: string, type: string, inputs: pulumi.Inputs,
options: pulumi.ComponentResourceOptions): Promise<provider.ConstructResult> {
if (type != "testcomponent:index:Component") {
throw new Error(`unknown resource type ${type}`);
}
const component = new Component(name, options);
return {
urn: component.urn,
state: inputs,
};
}
async call(token: string, inputs: pulumi.Inputs): Promise<provider.InvokeResult> {
switch (token) {
case "testcomponent:index:Component/getMessage":
return {
failures: [{ property: "the failure property", reason: "the failure reason" }],
};
default:
throw new Error(`unknown method ${token}`);
}
}
}
export function main(args: string[]) {
return provider.main(new Provider(), args);
}
main(process.argv.slice(2));

View file

@ -0,0 +1,11 @@
{
"name": "pulumi-resource-testcomponent",
"main": "index.js",
"devDependencies": {
"typescript": "^3.0.0",
"@types/node": "latest"
},
"peerDependencies": {
"@pulumi/pulumi": "latest"
}
}

View file

@ -0,0 +1,3 @@
#!/bin/bash
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
node $SCRIPT_DIR/bin $@

View file

@ -0,0 +1,4 @@
@echo off
setlocal
set SCRIPT_DIR=%~dp0
@node "%SCRIPT_DIR%/bin" %*

View file

@ -0,0 +1,20 @@
{
"compilerOptions": {
"strict": true,
"outDir": "bin",
"target": "es2016",
"module": "commonjs",
"moduleResolution": "node",
"declaration": true,
"sourceMap": false,
"stripInternal": true,
"experimentalDecorators": true,
"pretty": true,
"noFallthroughCasesInSwitch": true,
"noImplicitReturns": true,
"forceConsistentCasingInFileNames": true
},
"files": [
"index.ts",
]
}

View file

@ -0,0 +1,3 @@
name: construct_component_methods_resources_go
description: A program that constructs remote component resources with methods that create resources.
runtime: go

View file

@ -0,0 +1,60 @@
// Copyright 2016-2021, Pulumi Corporation. All rights reserved.
package main
import (
"reflect"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
type Component struct {
pulumi.ResourceState
}
func NewComponent(ctx *pulumi.Context, name string, opts ...pulumi.ResourceOption) (*Component, error) {
var resource Component
err := ctx.RegisterRemoteComponentResource("testcomponent:index:Component", name, nil, &resource, opts...)
if err != nil {
return nil, err
}
return &resource, nil
}
func (c *Component) CreateRandom(ctx *pulumi.Context, args *ComponentCreateRandomArgs) (ComponentCreateRandomResultOutput, error) {
out, err := ctx.Call("testcomponent:index:Component/createRandom", args, ComponentCreateRandomResultOutput{}, c)
if err != nil {
return ComponentCreateRandomResultOutput{}, err
}
return out.(ComponentCreateRandomResultOutput), nil
}
type componentCreateRandomArgs struct {
Length int `pulumi:"length"`
}
type ComponentCreateRandomArgs struct {
Length pulumi.IntInput
}
func (ComponentCreateRandomArgs) ElementType() reflect.Type {
return reflect.TypeOf((*componentCreateRandomArgs)(nil)).Elem()
}
type ComponentCreateRandomResult struct {
Result string `pulumi:"result"`
}
type ComponentCreateRandomResultOutput struct{ *pulumi.OutputState }
func (ComponentCreateRandomResultOutput) ElementType() reflect.Type {
return reflect.TypeOf((*ComponentCreateRandomResult)(nil)).Elem()
}
func (o ComponentCreateRandomResultOutput) Result() pulumi.StringOutput {
return o.ApplyT(func(v ComponentCreateRandomResult) string { return v.Result }).(pulumi.StringOutput)
}
func init() {
pulumi.RegisterOutputType(ComponentCreateRandomResultOutput{})
}

View file

@ -0,0 +1,5 @@
module github.com/pulumi/pulumi/tests/construct_component_methods_resources
go 1.16
require github.com/pulumi/pulumi/sdk/v3 v3.0.0-20210322210933-10a6a2caf014

View file

@ -0,0 +1,431 @@
cloud.google.com/go v0.26.0 h1:e0WKqKTd5BnrG8aKH3J3h+QvEIQtSUcf2n5UZ5ZgLtQ=
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/Microsoft/go-winio v0.4.14 h1:+hMXMk01us9KgxGb7ftKQt2Xpf5hH/yky+TDA+qxleU=
github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA=
github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7 h1:uSoVVbwJiQipAclBbw+8quDsfcvFjOpI5iCf4p/cqCs=
github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc h1:cAKDfWh5VpdgMhJosfJnn5/FoN2SRZ4p7fJNX58YPaU=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf h1:qet1QNfXsQxTZqLG4oE62mJzwPIB8+Tee4RNCL9ulrY=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo4JG6LR5AXSUEsOjtdm0kw0FtQtMJA=
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6 h1:G1bPvciwNyF7IUmKXNt9Ak3m6u9DE1rF+RmtIkBpVdA=
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0 h1:HWo1m869IqiPhD389kmkxeTalrjNbbJTC8LXupb+sl0=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ=
github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
github.com/census-instrumentation/opencensus-proto v0.2.1 h1:glEXhBS5PSLLv4IXzLA5yPRVX4bilULVyxxbrfOtDAk=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/cheggaaa/pb v1.0.18 h1:G/DgkKaBP0V5lnBg/vx61nVxxAU+VqU5yMzSc0f2PPE=
github.com/cheggaaa/pb v1.0.18/go.mod h1:pQciLPpbU0oxA0h+VJYYLxO+XeDQb5pZijXscXHm81s=
github.com/client9/misspell v0.3.4 h1:ta993UF76GwbvJcIo3Y68y/M3WxlpEHPWIGDkJYwzJI=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f h1:WBZRG4aNOuI15bLRrCgN8fCq8E5Xuty6jGbmSNEvSsU=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd h1:qMd81Ts1T2OTKmB4acZcyKaMtRnY5Y44NuXGX2GFJ1w=
github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI=
github.com/coreos/bbolt v1.3.2 h1:wZwiHHUieZCquLkDL0B8UhzreNWsPHooDAG3q34zk0s=
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
github.com/coreos/etcd v3.3.10+incompatible h1:jFneRYjIvLMLhDLCzuTuU4rSJUjRplcJQ7pD7MnhC04=
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/go-semver v0.2.0 h1:3Jm3tLmsgAYcjC+4Up7hJrFBPr+n7rAqYeSw/SZazuY=
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e h1:Wf6HqHfScWJN9/ZjdUKyjop4mf3Qdd+1TvvltAvM3m8=
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f h1:lBNOc5arjvs8E5mO2tbpBpLoyyu8B6e44T7hJy6potg=
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/cpuguy83/go-md2man/v2 v2.0.0 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM=
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
github.com/creack/pty v1.1.9 h1:uDmaGzcdjhF4i/plgjmEsriH11Y0o7RKapEf/LDaM3w=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
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/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954 h1:RMLoZVzv4GliuWafOuPuQDKSm1SJph7uCRnnS61JAn4=
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
github.com/djherbis/times v1.2.0 h1:xANXjsC/iBqbO00vkWlYwPWgBgEVU6m6AFYg0Pic+Mc=
github.com/djherbis/times v1.2.0/go.mod h1:CGMZlo255K5r4Yw0b9RRfFQpM2y7uOmxg4jm9HsaVf8=
github.com/emirpasic/gods v1.12.0 h1:QAUIPSaCu4G+POclxeqb3F+WPpdKqFGlw36+yOzGlrg=
github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.4 h1:rEvIZUSZ3fx39WIi3JkQqQBitGwpELBIYWeBVh6wn+E=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
github.com/envoyproxy/protoc-gen-validate v0.1.0 h1:EQciDnbrYxy13PgWoY8AqoxGiPrpgBZ1R8UNe3ddc+A=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/fatih/color v1.9.0 h1:8xPHl4/q1VyqGIPif1F+1V3Y3lSmrq01EabUW3CoW5s=
github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU=
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 h1:BHsljHzVlRcyQhjrss6TZTdY2VfCqZPbv5k3iBFa2ZQ=
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/gliderlabs/ssh v0.2.2 h1:6zsha5zo/TWhRhwqCD3+EarCAgZ2yN28ipRnGPnwkI0=
github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
github.com/go-kit/kit v0.8.0 h1:Wz+5lgoB0kkuqLEc6NVmwRknTKP6dTGbSqvhZtBI/j0=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
github.com/go-logfmt/logfmt v0.4.0 h1:MP4Eh7ZCb31lleYCFuwm0oe4/YGak+5l1vA2NOE80nA=
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/gofrs/flock v0.7.1 h1:DP+LD/t0njgoPBvT5MJLeliUIVQR03hiKR6vezdwHlc=
github.com/gofrs/flock v0.7.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=
github.com/gofrs/uuid v3.3.0+incompatible h1:8K4tyRfvU1CYPgJsveYFQMhpFd/wXNM7iK6rR7UHz84=
github.com/gofrs/uuid v3.3.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls=
github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef h1:veQD95Isof8w9/WXiA+pa3tz3fJXkt5B7QaRBrM62gk=
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/mock v1.1.1 h1:G5FRp8JnTd7RQH5kemVNlMeyXQAztQ3mOWV95KxsXH8=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0=
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.4.1 h1:/exdXoGamhu5ONeUJH0deniYLWYvQwW66yvlfiiKTu0=
github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q=
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0 h1:Iju5GlWwrvL6UBg4zJJt3btmonfrMlCDdsejg4CZE7c=
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho=
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
github.com/grpc-ecosystem/grpc-gateway v1.9.0 h1:bM6ZAFZmc/wPFaRDi0d5L7hGEZEx/2u+Tmr2evNHDiI=
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645 h1:MJG/KsmcqMwFAkh8mTnAwhyKoB+sTAnY4CACC110tbU=
github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645/go.mod h1:6iZfnjpejD4L/4DwD7NryNaJyCQdzwWwH2MWhCA90Kw=
github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-multierror v1.0.0 h1:iVjPR7a6H0tWELX5NxNe7bYopibicUzc7uPribsnS6o=
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
github.com/jessevdk/go-flags v1.4.0 h1:4IU2WS7AumrZ/40jfhf4QVDMsQwqA7VEHozFRrGARJA=
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/jonboulle/clockwork v0.1.0 h1:VKV+ZcuP6l3yW9doeqz6ziZGgcynBVQO+obU0+0hcPo=
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
github.com/julienschmidt/httprouter v1.2.0 h1:TDTW5Yz1mjftljbcKqRcrYhd4XeOoI98t+9HbQbYf7g=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd h1:Coekwdh0v2wtGp9Gmz1Ze3eVRAWJMLokvN3QjdzCHLY=
github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
github.com/kisielk/errcheck v1.2.0 h1:reN85Pxc5larApoH1keMBiu2GWtPqXQ1nc9gx+jOU+E=
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515 h1:T+h1c/A9Gawja4Y9mFVWj2vyii2bbUNDw3kt9VxK2EY=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
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/pty v1.1.8 h1:AkaSdXYQOWeaO3neb8EM634ahkXXe3jYbVh/F9lq+GI=
github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw=
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/magiconair/properties v1.8.0 h1:LLgXmsheXeRoUOBOjtwPQCWIYqM/LU1ayDtDePerRcY=
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-colorable v0.1.6 h1:6Su7aK7lXmJ/U79bYtBjLNaha4Fs1Rg9plHpcH+vvnE=
github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-runewidth v0.0.8 h1:3tS41NlGYSmhhe/8fhGRzc+z3AYCw1Fe1WAyLuujKs0=
github.com/mattn/go-runewidth v0.0.8/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/go-ps v1.0.0 h1:i6ampVEEF4wQFF+bkYfwYgY+F/uYJDktmvLPf7qIgjc=
github.com/mitchellh/go-ps v1.0.0/go.mod h1:J4lOc8z8yJs6vUwklHw2XEIiT4z4C40KtWVN3nvg8Pg=
github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223 h1:F9x/1yl3T2AeKLr2AMdilSD8+f9bvMnNN8VS5iDtovc=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4=
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
github.com/opentracing/basictracer-go v1.0.0 h1:YyUAhaEfjoWXclZVJ9sGoNct7j4TVk7lZWlQw5UXuoo=
github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74=
github.com/opentracing/opentracing-go v1.1.0 h1:pWlfV3Bxv7k65HYwkikxat0+s3pV4bsqf19k25Ur8rU=
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
github.com/pelletier/go-buffruneio v0.2.0 h1:U4t4R6YkofJ5xHm3dJzuRpPZ0mr5MMCoAWooScCR7aA=
github.com/pelletier/go-buffruneio v0.2.0/go.mod h1:JkE26KsDizTr40EUHkXVtNPvgGtbSNq5BcowyYOWdKo=
github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
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/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v0.9.3 h1:9iH4JKXLzFbOAdtqv/a+j8aewx2Y8lAjAydhbaScPF8=
github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4 h1:gQz4mCbXsO+nc9n1hCxHcGA3Zx3Eo+UHZoInFGUIXNM=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
github.com/prometheus/common v0.4.0 h1:7etb9YClo3a6HjLzfl6rIQaU+FDfi0VSX39io3aQ+DM=
github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084 h1:sofwID9zm4tzrgykg80hfFph1mryUeLRsUfoocVVmRY=
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/tsdb v0.7.1 h1:YZcsG11NqnK4czYLrWd9mpEuAJIHVQLwdrleYfszMAA=
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
github.com/pulumi/pulumi/sdk/v3 v3.0.0-20210322210933-10a6a2caf014 h1:WUlOHsRhzO08oUCEjZhWS0VHssiIjCNio89VlAvD9ao=
github.com/pulumi/pulumi/sdk/v3 v3.0.0-20210322210933-10a6a2caf014/go.mod h1:GBHyQ7awNQSRmiKp/p8kIKrGrMOZeA/k2czoM/GOqds=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af h1:gu+uRPtBe88sKxUCEXRoeCvVG90TJmwhiqRpvdhQFng=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/sabhiram/go-gitignore v0.0.0-20180611051255-d3107576ba94 h1:G04eS0JkAIVZfaJLjla9dNxkJCPiKIGZlw9AfOhzOD0=
github.com/sabhiram/go-gitignore v0.0.0-20180611051255-d3107576ba94/go.mod h1:b18R55ulyQ/h3RaWyloPyER7fWQVZvimKKhnI5OfrJQ=
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.1 h1:GL2rEmy6nsikmW0r8opw9JIRScdMF5hA8cOYLH7In1k=
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
github.com/soheilhy/cmux v0.1.4 h1:0HKaf1o97UwFjHH9o5XsHUOF+tqmdA7KEzXLpiyaw0E=
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72 h1:qLC7fQah7D6K1B0ujays3HV9gkFtllcxhzImRR7ArPQ=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/spf13/afero v1.1.2 h1:m8/z1t7/fwjysjQRYbP0RD+bUIF/8tJwPdEZsI83ACI=
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng=
github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cobra v1.0.0 h1:6m/oheQuQ13N9ks4hubMG6BnvwOeaJrqSPLahSnczz8=
github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk=
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/viper v1.4.0 h1:yXHLWeravcrgGyFSyCgdYpXQ9dR9c/WED3pg1RhxqEU=
github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
github.com/src-d/gcfg v1.4.0 h1:xXbNR5AlLSA315x2UO+fTSSAXCDf+Ar38/6oyGbDKQ4=
github.com/src-d/gcfg v1.4.0/go.mod h1:p/UMsR43ujA89BJY9duynAwIpvqEujIH/jFlfL7jWoI=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48=
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/texttheater/golang-levenshtein v0.0.0-20191208221605-eb6844b05fc6 h1:9VTskZOIRf2vKF3UL8TuWElry5pgUpV1tFSe/e/0m/E=
github.com/texttheater/golang-levenshtein v0.0.0-20191208221605-eb6844b05fc6/go.mod h1:XDKHRm5ThF8YJjx001LtgelzsoaEcvnA7lVWz9EeX3g=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5 h1:LnC5Kc/wtumK+WB441p7ynQJzVuNRJiqddSIE3IlSEQ=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/tweekmonster/luser v0.0.0-20161003172636-3fa38070dbd7 h1:X9dsIWPuuEJlPX//UmRKophhOKCGXc46RVIGuttks68=
github.com/tweekmonster/luser v0.0.0-20161003172636-3fa38070dbd7/go.mod h1:UxoP3EypF8JfGEjAII8jx1q8rQyDnX8qdTCs/UQBVIE=
github.com/uber/jaeger-client-go v2.22.1+incompatible h1:NHcubEkVbahf9t3p75TOCR83gdUHXjRJvjoBh1yACsM=
github.com/uber/jaeger-client-go v2.22.1+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk=
github.com/uber/jaeger-lib v2.2.0+incompatible h1:MxZXOiR2JuoANZ3J6DE/U0kSFv/eJ/GfSYVCjK7dyaw=
github.com/uber/jaeger-lib v2.2.0+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U=
github.com/ugorji/go v1.1.4 h1:j4s+tAvLfL3bZyefP2SEWmhBzmuIlH/eqNuPdFPgngw=
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
github.com/xanzy/ssh-agent v0.2.1 h1:TCbipTQL2JiiCprBWx9frJ2eJlCYT00NmctrHxVAr70=
github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5Qo6v2eYzo7kUS51QINcR5jNpbZS8=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77 h1:ESFSdwYZvkeru3RtdrYueztKhOBCSAAzS4Gf+k0tEow=
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
github.com/yuin/goldmark v1.1.27 h1:nqDD4MMMQA0lmWq03Z2/myGPYLQoXtmi0rGVs95ntbo=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
go.etcd.io/bbolt v1.3.2 h1:Z/90sZLPOeCy2PwprqkFa25PdkusRzaj9P8zm/KNyvk=
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/atomic v1.6.0 h1:Ezj3JGmsOnG1MoRWQkPBsKLe9DwWD9QeXzTRzzldNVk=
go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI=
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM=
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200317142112-1b76d66859c6 h1:TjszyFsQsyZNHwdVdZ5m7bjmreu0znc2kRYsEml9/Ww=
golang.org/x/crypto v0.0.0-20200317142112-1b76d66859c6/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4 h1:c2HOrn5iMezYjSlGPncknSEr/8x5LELb/ilJbXi9DEA=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20200302205851-738671d3881b h1:Wh+f8QHJXR411sJR8/vRBTZ7YapZaRvUcLFFJhusH0k=
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200602114024-627f9648deb9 h1:pNX+40auqi2JqRfOP1akLGtYcn15TUbkhwuCO3foqqM=
golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be h1:vEDujvNQGv4jgYKudGeI/+DAX4Jffq6hpD55MmoEvKs=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e h1:vcxGaoTs7kV8m5Np9uUNQin4BrLOthgV7252N8V+FwY=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190221075227-b4e8571b14e0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980 h1:OjiUf46hAmXblsZdnoSXsEUSKU8r1UEzcL5RVZ4gO9Y=
golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190729092621-ff9f1409240a/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI=
golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200608174601-1b747fd94509 h1:MI14dOfl3OG6Zd32w3ugsrvcUO810fDZdWakTq39dH4=
golang.org/x/tools v0.0.0-20200608174601-1b747fd94509/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
google.golang.org/genproto v0.0.0-20200608115520-7c474a2e3482 h1:i+Aiej6cta/Frzp13/swvwz5O00kYcSe0A/C5Wd7zX8=
google.golang.org/genproto v0.0.0-20200608115520-7c474a2e3482/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.29.1 h1:EC2SB8S04d2r73uptxphDSUG+kTKVgjRPF+N3xpxRB4=
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.24.0 h1:UhZDfRO8JRQru4/+LlLE0BRKGF8L+PICnvYZmx/fEGA=
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/cheggaaa/pb.v1 v1.0.28 h1:n1tBJnnK2r7g9OW2btFH91V92STTUevLXYFb8gy9EMk=
gopkg.in/cheggaaa/pb.v1 v1.0.28/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
gopkg.in/resty.v1 v1.12.0 h1:CuXP0Pjfw9rOuY6EP+UvtNvt5DSqHpIxILZKT/quCZI=
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
gopkg.in/src-d/go-billy.v4 v4.3.2 h1:0SQA1pRztfTFx2miS8sA97XvooFeNOmvUenF4o0EcVg=
gopkg.in/src-d/go-billy.v4 v4.3.2/go.mod h1:nDjArDMp+XMs1aFAESLRjfGSgfvoYN0hDfzEk0GjC98=
gopkg.in/src-d/go-git-fixtures.v3 v3.5.0 h1:ivZFOIltbce2Mo8IjzUHAFoq/IylO9WHhNOAJK+LsJg=
gopkg.in/src-d/go-git-fixtures.v3 v3.5.0/go.mod h1:dLBcvytrw/TYZsNTWCnkNF2DSIlzWYqTe3rJR56Ac7g=
gopkg.in/src-d/go-git.v4 v4.13.1 h1:SRtFyV8Kxc0UP7aCHcijOMQGPxHSmMOPrzulQWolkYE=
gopkg.in/src-d/go-git.v4 v4.13.1/go.mod h1:nx5NYcxdKxq5fpltdHnPa2Exj4Sx0EclMWZQbYDu2z8=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME=
gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc h1:/hemPrYIhOhy8zYrNj+069zDB68us2sMGsfkFJO0iZs=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0 h1:ucqkfpjg9WzSUubAO62csmucvxl4/JeW3F4I4909XkM=
sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU=

View file

@ -0,0 +1,24 @@
// Copyright 2016-2021, Pulumi Corporation. All rights reserved.
package main
import (
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
component, err := NewComponent(ctx, "component")
if err != nil {
return err
}
result, err := component.CreateRandom(ctx, &ComponentCreateRandomArgs{
Length: pulumi.Int(10),
})
if err != nil {
return err
}
ctx.Export("result", result.Result())
return nil
})
}

View file

@ -0,0 +1,3 @@
/.pulumi/
/bin/
/node_modules/

View file

@ -0,0 +1,3 @@
name: construct_component_methods_resources_nodejs
description: A program that constructs remote component resources with methods that create resources.
runtime: nodejs

View file

@ -0,0 +1,26 @@
// Copyright 2016-2021, Pulumi Corporation. All rights reserved.
import * as pulumi from "@pulumi/pulumi";
export class Component extends pulumi.ComponentResource {
constructor(name: string, opts?: pulumi.ComponentResourceOptions) {
super("testcomponent:index:Component", name, undefined, opts, true);
}
createRandom(args: Component.CreateRandomArgs): pulumi.Output<Component.CreateRandomResult> {
return pulumi.runtime.call("testcomponent:index:Component/createRandom", {
"__self__": this,
"length": args.length,
}, this);
}
}
export namespace Component {
export interface CreateRandomArgs {
length: pulumi.Input<number>;
}
export interface CreateRandomResult {
result: string;
}
}

View file

@ -0,0 +1,7 @@
// Copyright 2016-2021, Pulumi Corporation. All rights reserved.
import { Component } from "./component";
const component = new Component("component");
export const result = component.createRandom({ length: 10 }).result;

View file

@ -0,0 +1,10 @@
{
"name": "steps",
"license": "Apache-2.0",
"devDependencies": {
"typescript": "^3.0.0"
},
"peerDependencies": {
"@pulumi/pulumi": "latest"
}
}

View file

@ -0,0 +1,5 @@
*.pyc
/.pulumi/
/dist/
/*.egg-info
venv/

View file

@ -0,0 +1,3 @@
name: construct_component_methods_resources_py
description: A program that constructs remote component resources with methods that create resources.
runtime: python

View file

@ -0,0 +1,10 @@
# Copyright 2016-2021, Pulumi Corporation. All rights reserved.
import pulumi
from component import Component
component = Component("component")
result = component.create_random(length=10).result
pulumi.export("result", result)

View file

@ -0,0 +1,32 @@
# Copyright 2016-2021, Pulumi Corporation. All rights reserved.
from typing import Optional
import pulumi
class Component(pulumi.ComponentResource):
def __init__(self,
name: str,
opts: Optional[pulumi.ResourceOptions] = None):
super().__init__("testcomponent:index:Component", name, {}, opts, True)
@pulumi.output_type
class CreateRandomResult:
def __init__(self, result: str):
if result and not isinstance(result, str):
raise TypeError("Expected argument 'result' to be a str")
pulumi.set(self, "result", result)
@property
@pulumi.getter
def result(self) -> str:
return pulumi.get(self, "result")
def create_random(__self__, length: pulumi.Input[int]) -> pulumi.Output['Component.CreateRandomResult']:
__args__ = dict()
__args__['__self__'] = __self__
__args__['length'] = length
return pulumi.runtime.call('testcomponent:index:Component/createRandom',
__args__,
res=__self__,
typ=Component.CreateRandomResult)

View file

@ -0,0 +1,2 @@
pulumi-resource-testcomponent
pulumi-resource-testcomponent.exe

View file

@ -0,0 +1,117 @@
// Copyright 2016-2021, Pulumi Corporation. All rights reserved.
package main
import (
"fmt"
"github.com/blang/semver"
"github.com/pulumi/pulumi/pkg/v3/resource/provider"
"github.com/pulumi/pulumi/sdk/v3/go/common/util/cmdutil"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
pulumiprovider "github.com/pulumi/pulumi/sdk/v3/go/pulumi/provider"
)
type Component struct {
pulumi.ResourceState
}
func NewComponent(ctx *pulumi.Context, name string, opts ...pulumi.ResourceOption) (*Component, error) {
component := &Component{}
if err := ctx.RegisterComponentResource("testcomponent:index:Component", name, component, opts...); err != nil {
return nil, err
}
if err := ctx.RegisterResourceOutputs(component, pulumi.Map{}); err != nil {
return nil, err
}
return component, nil
}
type ComponentCreateRandomArgs struct {
Length pulumi.IntInput `pulumi:"length"`
}
type ComponentCreateRandomeResult struct {
Result pulumi.StringOutput `pulumi:"result"`
}
func (c *Component) CreateRandom(ctx *pulumi.Context, args *ComponentCreateRandomArgs) (*ComponentCreateRandomeResult,
error) {
random, err := NewRandom(ctx, "myrandom", &RandomArgs{Length: args.Length}, pulumi.Parent(c))
if err != nil {
return nil, err
}
return &ComponentCreateRandomeResult{
Result: random.Result,
}, nil
}
const providerName = "testcomponent"
const version = "0.0.1"
type module struct {
version semver.Version
}
func (m *module) Version() semver.Version {
return m.version
}
func (m *module) Construct(ctx *pulumi.Context, name, typ, urn string) (r pulumi.Resource, err error) {
switch typ {
case "testcomponent:index:Component":
r = &Component{}
default:
return nil, fmt.Errorf("unknown resource type: %s", typ)
}
err = ctx.RegisterResource(typ, name, nil, r, pulumi.URN_(urn))
return
}
func main() {
// Register any resources that can come back as resource references that need to be rehydrated.
pulumi.RegisterResourceModule("testcomponent", "index", &module{semver.MustParse(version)})
if err := provider.MainWithOptions(provider.Options{
Name: providerName,
Version: version,
Construct: func(ctx *pulumi.Context, typ, name string, inputs pulumiprovider.ConstructInputs,
options pulumi.ResourceOption) (*pulumiprovider.ConstructResult, error) {
if typ != "testcomponent:index:Component" {
return nil, fmt.Errorf("unknown resource type %s", typ)
}
component, err := NewComponent(ctx, name, options)
if err != nil {
return nil, fmt.Errorf("creating component: %w", err)
}
return pulumiprovider.NewConstructResult(component)
},
Call: func(ctx *pulumi.Context, tok string,
args pulumiprovider.CallArgs) (*pulumiprovider.CallResult, error) {
if tok != "testcomponent:index:Component/createRandom" {
return nil, fmt.Errorf("unknown method %s", tok)
}
methodArgs := &ComponentCreateRandomArgs{}
res, err := args.CopyTo(methodArgs)
if err != nil {
return nil, fmt.Errorf("setting args: %w", err)
}
component := res.(*Component)
result, err := component.CreateRandom(ctx, methodArgs)
if err != nil {
return nil, fmt.Errorf("calling method: %w", err)
}
return pulumiprovider.NewCallResult(result)
},
}); err != nil {
cmdutil.ExitError(err.Error())
}
}

View file

@ -0,0 +1,48 @@
// Copyright 2016-2021, Pulumi Corporation. All rights reserved.
// Exposes the Random resource from the testprovider.
// Requires running `make test_build` and having the built provider on PATH.
package main
import (
"errors"
"reflect"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
type Random struct {
pulumi.CustomResourceState
Length pulumi.IntOutput `pulumi:"length"`
Result pulumi.StringOutput `pulumi:"result"`
}
func NewRandom(ctx *pulumi.Context,
name string, args *RandomArgs, opts ...pulumi.ResourceOption) (*Random, error) {
if args == nil || args.Length == nil {
return nil, errors.New("missing required argument 'Length'")
}
if args == nil {
args = &RandomArgs{}
}
var resource Random
err := ctx.RegisterResource("testprovider:index:Random", name, args, &resource, opts...)
if err != nil {
return nil, err
}
return &resource, nil
}
type randomArgs struct {
Length int `pulumi:"length"`
}
type RandomArgs struct {
Length pulumi.IntInput
}
func (RandomArgs) ElementType() reflect.Type {
return reflect.TypeOf((*randomArgs)(nil)).Elem()
}

View file

@ -0,0 +1,5 @@
*.pyc
/.pulumi/
/dist/
/*.egg-info
venv/

View file

@ -0,0 +1,7 @@
#!/bin/bash
set -euo pipefail
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
exec "$PULUMI_RUNTIME_VIRTUALENV/bin/python" "$SCRIPT_DIR/testcomponent.py" "$@"

View file

@ -0,0 +1,4 @@
@echo off
setlocal
set SCRIPT_DIR=%~dp0
@%PULUMI_RUNTIME_VIRTUALENV%\Scripts\python.exe "%SCRIPT_DIR%/testcomponent.py" %*

View file

@ -0,0 +1,26 @@
# Copyright 2016-2021, Pulumi Corporation. All rights reserved.
from typing import Optional
import pulumi
class Random(pulumi.CustomResource):
def __init__(self,
resource_name: str,
length: pulumi.Input[int],
opts: Optional[pulumi.ResourceOptions] = None):
props = {
"length": length,
"result": None,
}
super().__init__("testprovider:index:Random", resource_name, props, opts)
@property
@pulumi.getter
def length(self) -> pulumi.Output[int]:
return pulumi.get(self, "length")
@property
@pulumi.getter
def result(self) -> pulumi.Output[str]:
return pulumi.get(self, "result")

View file

@ -0,0 +1,75 @@
# Copyright 2016-2021, Pulumi Corporation.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from typing import Optional
import sys
import pulumi
import pulumi.provider as provider
from random_ import Random
class Component(pulumi.ComponentResource):
def __init__(self,
resource_name: str,
opts: Optional[pulumi.ResourceOptions] = None) -> None:
super().__init__("testcomponent:index:Component", resource_name, {}, opts)
def create_random(self, length: pulumi.Input[int]) -> pulumi.Output[str]:
r = Random("myrandom", length=length, opts=pulumi.ResourceOptions(parent=self))
return r.result
class Provider(provider.Provider):
VERSION = "0.0.1"
class Module(pulumi.runtime.ResourceModule):
def version(self):
return Provider.VERSION
def construct(self, name: str, typ: str, urn: str) -> pulumi.Resource:
if typ == "testcomponent:index:Component":
return Component(name, pulumi.ResourceOptions(urn=urn))
else:
raise Exception(f"unknown resource type {typ}")
def __init__(self):
super().__init__(Provider.VERSION)
pulumi.runtime.register_resource_module("testcomponent", "index", Provider.Module())
def construct(self, name: str, resource_type: str, inputs: pulumi.Inputs,
options: Optional[pulumi.ResourceOptions] = None) -> provider.ConstructResult:
if resource_type != "testcomponent:index:Component":
raise Exception(f"unknown resource type {resource_type}")
component = Component(name, options)
return provider.ConstructResult(
urn=component.urn,
state=inputs)
def call(self, token: str, args: pulumi.Inputs) -> provider.CallResult:
if token != "testcomponent:index:Component/createRandom":
raise Exception(f'unknown method {token}')
comp: Component = args["__self__"]
outputs = {
"result": comp.create_random(args["length"])
}
return provider.CallResult(outputs=outputs)
if __name__ == "__main__":
provider.main(Provider(), sys.argv[1:])

View file

@ -0,0 +1,64 @@
// Copyright 2016-2021, Pulumi Corporation. All rights reserved.
import * as pulumi from "@pulumi/pulumi";
import * as provider from "@pulumi/pulumi/provider";
import { Random } from "./random"
class Component extends pulumi.ComponentResource {
constructor(name: string, opts?: pulumi.ComponentResourceOptions) {
super("testcomponent:index:Component", name, undefined, opts);
}
createRandom(length: pulumi.Input<number>): pulumi.Output<string> {
const r = new Random("myrandom", { length }, { parent: this });
return r.result;
}
}
class Provider implements provider.Provider {
public readonly version = "0.0.1";
constructor() {
// Register any resources that can come back as resource references that need to be rehydrated.
pulumi.runtime.registerResourceModule("testcomponent", "index", {
version: this.version,
construct: (name, type, urn) => {
switch (type) {
case "testcomponent:index:Component":
return new Component(name, { urn });
default:
throw new Error(`unknown resource type ${type}`);
}
},
});
}
async construct(name: string, type: string, inputs: pulumi.Inputs,
options: pulumi.ComponentResourceOptions): Promise<provider.ConstructResult> {
if (type != "testcomponent:index:Component") {
throw new Error(`unknown resource type ${type}`);
}
const component = new Component(name, options);
return {
urn: component.urn,
state: inputs,
};
}
async call(token: string, inputs: pulumi.Inputs): Promise<provider.InvokeResult> {
if (token != "testcomponent:index:Component/createRandom") {
throw new Error(`unknown method ${token}`);
}
const self: Component = inputs.__self__;
const result = self.createRandom(inputs.length);
return { outputs: { result } };
}
}
export function main(args: string[]) {
return provider.main(new Provider(), args);
}
main(process.argv.slice(2));

View file

@ -0,0 +1,11 @@
{
"name": "pulumi-resource-testcomponent",
"main": "index.js",
"devDependencies": {
"typescript": "^3.0.0",
"@types/node": "latest"
},
"peerDependencies": {
"@pulumi/pulumi": "latest"
}
}

View file

@ -0,0 +1,3 @@
#!/bin/bash
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
node $SCRIPT_DIR/bin $@

View file

@ -0,0 +1,4 @@
@echo off
setlocal
set SCRIPT_DIR=%~dp0
@node "%SCRIPT_DIR%/bin" %*

Some files were not shown because too many files have changed in this diff Show more