Compare commits
6 commits
master
...
justin/goa
Author | SHA1 | Date | |
---|---|---|---|
139cbd60fd | |||
bc4b198070 | |||
8e60459861 | |||
000c9ee301 | |||
4676f4332b | |||
fa49622ca6 |
|
@ -7,7 +7,7 @@ import pulumi
|
|||
import pulumi.runtime
|
||||
from typing import Any, Mapping, Optional, Sequence, Union
|
||||
from . import _utilities, _tables
|
||||
from pulumi_random import RandomPet
|
||||
import pulumi_random
|
||||
|
||||
__all__ = [
|
||||
'PetArgs',
|
||||
|
@ -17,7 +17,7 @@ __all__ = [
|
|||
class PetArgs:
|
||||
def __init__(__self__, *,
|
||||
age: Optional[pulumi.Input[int]] = None,
|
||||
name: Optional[pulumi.Input['RandomPet']] = None):
|
||||
name: Optional[pulumi.Input['pulumi_random.RandomPet']] = None):
|
||||
if age is not None:
|
||||
pulumi.set(__self__, "age", age)
|
||||
if name is not None:
|
||||
|
@ -34,11 +34,11 @@ class PetArgs:
|
|||
|
||||
@property
|
||||
@pulumi.getter
|
||||
def name(self) -> Optional[pulumi.Input['RandomPet']]:
|
||||
def name(self) -> Optional[pulumi.Input['pulumi_random.RandomPet']]:
|
||||
return pulumi.get(self, "name")
|
||||
|
||||
@name.setter
|
||||
def name(self, value: Optional[pulumi.Input['RandomPet']]):
|
||||
def name(self, value: Optional[pulumi.Input['pulumi_random.RandomPet']]):
|
||||
pulumi.set(self, "name", value)
|
||||
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ import pulumi
|
|||
import pulumi.runtime
|
||||
from typing import Any, Mapping, Optional, Sequence, Union
|
||||
from . import _utilities, _tables
|
||||
from pulumi_random import RandomPet
|
||||
import pulumi_random
|
||||
|
||||
__all__ = [
|
||||
'ArgFunctionResult',
|
||||
|
@ -37,7 +37,7 @@ class AwaitableArgFunctionResult(ArgFunctionResult):
|
|||
age=self.age)
|
||||
|
||||
|
||||
def arg_function(name: Optional['RandomPet'] = None,
|
||||
def arg_function(name: Optional['pulumi_random.RandomPet'] = None,
|
||||
opts: Optional[pulumi.InvokeOptions] = None) -> AwaitableArgFunctionResult:
|
||||
"""
|
||||
Use this data source to access information about an existing resource.
|
||||
|
|
|
@ -8,7 +8,7 @@ import pulumi.runtime
|
|||
from typing import Any, Mapping, Optional, Sequence, Union
|
||||
from . import _utilities, _tables
|
||||
from ._inputs import *
|
||||
from pulumi_random import RandomPet
|
||||
import pulumi_random
|
||||
|
||||
__all__ = ['Cat']
|
||||
|
||||
|
|
|
@ -7,9 +7,7 @@ import pulumi
|
|||
import pulumi.runtime
|
||||
from typing import Any, Mapping, Optional, Sequence, Union
|
||||
from . import _utilities, _tables
|
||||
from pulumi_aws import _ec2_securitygroup.SecurityGroup
|
||||
from pulumi_kubernetes import _storage_k8s_io_v1.StorageClass
|
||||
from pulumi_kubernetes import meta_v1 as _meta_v1
|
||||
import pulumi_aws
|
||||
import pulumi_kubernetes
|
||||
|
||||
__all__ = ['Component']
|
||||
|
@ -19,7 +17,7 @@ class Component(pulumi.CustomResource):
|
|||
def __init__(__self__,
|
||||
resource_name: str,
|
||||
opts: Optional[pulumi.ResourceOptions] = None,
|
||||
metadata: Optional[pulumi.Input[pulumi.InputType['_meta_v1.ObjectMetaArgs']]] = None,
|
||||
metadata: Optional[pulumi.Input[pulumi.InputType['pulumi_kubernetes.meta.v1.ObjectMetaArgs']]] = None,
|
||||
__props__=None,
|
||||
__name__=None,
|
||||
__opts__=None):
|
||||
|
@ -80,12 +78,12 @@ class Component(pulumi.CustomResource):
|
|||
|
||||
@property
|
||||
@pulumi.getter(name="securityGroup")
|
||||
def security_group(self) -> pulumi.Output[Optional['_ec2_securitygroup.SecurityGroup']]:
|
||||
def security_group(self) -> pulumi.Output[Optional['pulumi_aws.ec2.SecurityGroup']]:
|
||||
return pulumi.get(self, "security_group")
|
||||
|
||||
@property
|
||||
@pulumi.getter(name="storageClasses")
|
||||
def storage_classes(self) -> pulumi.Output[Optional[Mapping[str, '_storage_k8s_io_v1.StorageClass']]]:
|
||||
def storage_classes(self) -> pulumi.Output[Optional[Mapping[str, 'pulumi_kubernetes.storage.v1.StorageClass']]]:
|
||||
return pulumi.get(self, "storage_classes")
|
||||
|
||||
def translate_output_property(self, prop):
|
||||
|
|
|
@ -7,8 +7,7 @@ import pulumi
|
|||
import pulumi.runtime
|
||||
from typing import Any, Mapping, Optional, Sequence, Union
|
||||
from . import _utilities, _tables
|
||||
from pulumi_kubernetes import core_v1 as _core_v1
|
||||
from pulumi_kubernetes import meta_v1 as _meta_v1
|
||||
import pulumi_kubernetes
|
||||
|
||||
__all__ = ['Workload']
|
||||
|
||||
|
@ -69,7 +68,7 @@ class Workload(pulumi.CustomResource):
|
|||
|
||||
@property
|
||||
@pulumi.getter
|
||||
def pod(self) -> pulumi.Output[Optional['_core_v1.outputs.Pod']]:
|
||||
def pod(self) -> pulumi.Output[Optional['pulumi_kubernetes.core.v1.outputs.Pod']]:
|
||||
return pulumi.get(self, "pod")
|
||||
|
||||
def translate_output_property(self, prop):
|
||||
|
|
|
@ -7,7 +7,7 @@ import pulumi
|
|||
import pulumi.runtime
|
||||
from typing import Any, Mapping, Optional, Sequence, Union
|
||||
from . import _utilities, _tables
|
||||
from . import Resource
|
||||
from .resource import Resource
|
||||
|
||||
__all__ = [
|
||||
'ArgFunctionResult',
|
||||
|
|
|
@ -7,7 +7,7 @@ import pulumi
|
|||
import pulumi.runtime
|
||||
from typing import Any, Mapping, Optional, Sequence, Union
|
||||
from . import _utilities, _tables
|
||||
from . import Resource
|
||||
from .resource import Resource
|
||||
|
||||
__all__ = ['OtherResource']
|
||||
|
||||
|
|
|
@ -58,12 +58,12 @@ func (ss stringSet) has(s string) bool {
|
|||
|
||||
type imports stringSet
|
||||
|
||||
func (imports imports) addType(mod *modContext, tok string, input bool) {
|
||||
imports.addTypeIf(mod, tok, input, nil /*predicate*/)
|
||||
func (imports imports) addType(mod *modContext, t *schema.ObjectType, input bool) {
|
||||
imports.addTypeIf(mod, t, input, nil /*predicate*/)
|
||||
}
|
||||
|
||||
func (imports imports) addTypeIf(mod *modContext, tok string, input bool, predicate func(imp string) bool) {
|
||||
if imp := mod.importTypeFromToken(tok, input); imp != "" && (predicate == nil || predicate(imp)) {
|
||||
func (imports imports) addTypeIf(mod *modContext, t *schema.ObjectType, input bool, predicate func(imp string) bool) {
|
||||
if imp := mod.importObjectType(t, input); imp != "" && (predicate == nil || predicate(imp)) {
|
||||
stringSet(imports).add(imp)
|
||||
}
|
||||
}
|
||||
|
@ -74,8 +74,8 @@ func (imports imports) addEnum(mod *modContext, tok string) {
|
|||
}
|
||||
}
|
||||
|
||||
func (imports imports) addResource(mod *modContext, tok string) {
|
||||
if imp := mod.importResourceFromToken(tok); imp != "" {
|
||||
func (imports imports) addResource(mod *modContext, r *schema.ResourceType) {
|
||||
if imp := mod.importResourceType(r); imp != "" {
|
||||
stringSet(imports).add(imp)
|
||||
}
|
||||
}
|
||||
|
@ -129,8 +129,13 @@ func (mod *modContext) details(t *schema.ObjectType) *typeDetails {
|
|||
return details
|
||||
}
|
||||
|
||||
func (mod *modContext) tokenToType(tok string, input, functionType bool) string {
|
||||
modName, name := mod.tokenToModule(tok), tokenToName(tok)
|
||||
func (mod *modContext) objectType(t *schema.ObjectType, input, functionType bool) string {
|
||||
modName, name := mod.tokenToModule(t.Token), tokenToName(t.Token)
|
||||
|
||||
var prefix string
|
||||
if !input {
|
||||
prefix = "outputs."
|
||||
}
|
||||
|
||||
var suffix string
|
||||
switch {
|
||||
|
@ -140,6 +145,26 @@ func (mod *modContext) tokenToType(tok string, input, functionType bool) string
|
|||
suffix = "Result"
|
||||
}
|
||||
|
||||
// If it's an external type, reference it via fully qualified name.
|
||||
if t.Package != mod.pkg {
|
||||
pkg := t.Package
|
||||
tok := t.Token
|
||||
|
||||
var info PackageInfo
|
||||
contract.AssertNoError(pkg.ImportLanguages(map[string]schema.Language{"python": Importer}))
|
||||
if v, ok := pkg.Language["python"].(PackageInfo); ok {
|
||||
info = v
|
||||
}
|
||||
modName, name := tokenToModule(tok, pkg, info.ModuleNameOverrides), tokenToName(tok)
|
||||
if modName == mod.mod {
|
||||
modName = ""
|
||||
}
|
||||
if modName != "" {
|
||||
modName = strings.ReplaceAll(modName, "/", ".") + "."
|
||||
}
|
||||
return fmt.Sprintf("'%s.%s%s%s%s'", pyPack(pkg.Name), modName, prefix, name, suffix)
|
||||
}
|
||||
|
||||
if modName == "" && modName != mod.mod {
|
||||
rootModName := "_root_outputs."
|
||||
if input {
|
||||
|
@ -155,11 +180,6 @@ func (mod *modContext) tokenToType(tok string, input, functionType bool) string
|
|||
modName = "_" + strings.ReplaceAll(modName, "/", ".") + "."
|
||||
}
|
||||
|
||||
var prefix string
|
||||
if !input {
|
||||
prefix = "outputs."
|
||||
}
|
||||
|
||||
return fmt.Sprintf("'%s%s%s%s'", modName, prefix, name, suffix)
|
||||
}
|
||||
|
||||
|
@ -180,6 +200,38 @@ func (mod *modContext) tokenToEnum(tok string) string {
|
|||
return fmt.Sprintf("'%s%s'", modName, name)
|
||||
}
|
||||
|
||||
func (mod *modContext) resourceType(r *schema.ResourceType) string {
|
||||
if r.Resource == nil || r.Resource.Package == mod.pkg {
|
||||
return mod.tokenToResource(r.Token)
|
||||
}
|
||||
|
||||
// Provider. TODO share code.
|
||||
components := strings.Split(r.Token, ":")
|
||||
contract.Assertf(len(components) == 3, "malformed token %v", r.Token)
|
||||
|
||||
// Is it a provider resource?
|
||||
if components[0] == "pulumi" && components[1] == "providers" {
|
||||
return fmt.Sprintf("pulumi_%s.Provider", components[2])
|
||||
}
|
||||
|
||||
pkg := r.Resource.Package
|
||||
tok := r.Token
|
||||
|
||||
var info PackageInfo
|
||||
contract.AssertNoError(pkg.ImportLanguages(map[string]schema.Language{"python": Importer}))
|
||||
if v, ok := pkg.Language["python"].(PackageInfo); ok {
|
||||
info = v
|
||||
}
|
||||
modName, name := tokenToModule(tok, pkg, info.ModuleNameOverrides), tokenToName(tok)
|
||||
if modName == mod.mod {
|
||||
modName = ""
|
||||
}
|
||||
if modName != "" {
|
||||
modName = strings.ReplaceAll(modName, "/", ".") + "."
|
||||
}
|
||||
return fmt.Sprintf("%s.%s%s", pyPack(pkg.Name), modName, name)
|
||||
}
|
||||
|
||||
func (mod *modContext) tokenToResource(tok string) string {
|
||||
// token := pkg : module : member
|
||||
// module := path/to/module
|
||||
|
@ -583,7 +635,12 @@ func (mod *modContext) genResourceModule(w io.Writer) {
|
|||
fmt.Fprintf(w, "_register_module()\n")
|
||||
}
|
||||
|
||||
func (mod *modContext) importTypeFromToken(tok string, input bool) string {
|
||||
func (mod *modContext) importObjectType(t *schema.ObjectType, input bool) string {
|
||||
if t.Package != mod.pkg {
|
||||
return fmt.Sprintf("import %s", pyPack(t.Package.Name))
|
||||
}
|
||||
|
||||
tok := t.Token
|
||||
parts := strings.Split(tok, ":")
|
||||
contract.Assert(len(parts) == 3)
|
||||
refPkgName := parts[0]
|
||||
|
@ -629,7 +686,12 @@ func (mod *modContext) importEnumFromToken(tok string) string {
|
|||
return fmt.Sprintf("from %s import %s", importPath, components[0])
|
||||
}
|
||||
|
||||
func (mod *modContext) importResourceFromToken(tok string) string {
|
||||
func (mod *modContext) importResourceType(r *schema.ResourceType) string {
|
||||
if r.Resource != nil && r.Resource.Package != mod.pkg {
|
||||
return fmt.Sprintf("import %s", pyPack(r.Resource.Package.Name))
|
||||
}
|
||||
|
||||
tok := r.Token
|
||||
parts := strings.Split(tok, ":")
|
||||
contract.Assert(len(parts) == 3)
|
||||
|
||||
|
@ -647,8 +709,18 @@ func (mod *modContext) importResourceFromToken(tok string) string {
|
|||
importPath = fmt.Sprintf("pulumi_%s", refPkgName)
|
||||
}
|
||||
|
||||
name := PyName(tokenToName(r.Token))
|
||||
if mod.compatibility == kubernetes20 {
|
||||
// To maintain backward compatibility for kubernetes, the file names
|
||||
// need to be CamelCase instead of the standard snake_case.
|
||||
name = tokenToName(r.Token)
|
||||
}
|
||||
if r.Resource != nil && r.Resource.IsProvider {
|
||||
name = "provider"
|
||||
}
|
||||
|
||||
components := strings.Split(modName, "/")
|
||||
return fmt.Sprintf("from %s import %s", importPath, components[0])
|
||||
return fmt.Sprintf("from %s%s import %s", importPath, name, components[0])
|
||||
}
|
||||
|
||||
// emitConfigVariables emits all config variables in the given module, returning the resulting file.
|
||||
|
@ -659,11 +731,11 @@ func (mod *modContext) genConfig(variables []*schema.Property) (string, error) {
|
|||
visitObjectTypesFromProperties(variables, seen, func(t interface{}) {
|
||||
switch T := t.(type) {
|
||||
case *schema.ObjectType:
|
||||
imports.addType(mod, T.Token, false /*input*/)
|
||||
imports.addType(mod, T, false /*input*/)
|
||||
case *schema.EnumType:
|
||||
imports.addEnum(mod, T.Token)
|
||||
case *schema.ResourceType:
|
||||
imports.addResource(mod, T.Token)
|
||||
imports.addResource(mod, T)
|
||||
}
|
||||
})
|
||||
|
||||
|
@ -711,14 +783,14 @@ func (mod *modContext) genTypes(dir string, fs fs) error {
|
|||
visitObjectTypesFromProperties(t.Properties, inputSeen, func(t interface{}) {
|
||||
switch T := t.(type) {
|
||||
case *schema.ObjectType:
|
||||
imports.addTypeIf(mod, T.Token, true /*input*/, func(imp string) bool {
|
||||
imports.addTypeIf(mod, T, true /*input*/, func(imp string) bool {
|
||||
// No need to import `._inputs` inside _inputs.py.
|
||||
return imp != "from ._inputs import *"
|
||||
})
|
||||
case *schema.EnumType:
|
||||
imports.addEnum(mod, T.Token)
|
||||
case *schema.ResourceType:
|
||||
imports.addResource(mod, T.Token)
|
||||
imports.addResource(mod, T)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -726,11 +798,11 @@ func (mod *modContext) genTypes(dir string, fs fs) error {
|
|||
visitObjectTypesFromProperties(t.Properties, outputSeen, func(t interface{}) {
|
||||
switch T := t.(type) {
|
||||
case *schema.ObjectType:
|
||||
imports.addType(mod, T.Token, false /*input*/)
|
||||
imports.addType(mod, T, false /*input*/)
|
||||
case *schema.EnumType:
|
||||
imports.addEnum(mod, T.Token)
|
||||
case *schema.ResourceType:
|
||||
imports.addResource(mod, T.Token)
|
||||
imports.addResource(mod, T)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -866,32 +938,32 @@ func (mod *modContext) genResource(res *schema.Resource) (string, error) {
|
|||
visitObjectTypesFromProperties(res.Properties, outputSeen, func(t interface{}) {
|
||||
switch T := t.(type) {
|
||||
case *schema.ObjectType:
|
||||
imports.addType(mod, T.Token, false /*input*/)
|
||||
imports.addType(mod, T, false /*input*/)
|
||||
case *schema.EnumType:
|
||||
imports.addEnum(mod, T.Token)
|
||||
case *schema.ResourceType:
|
||||
imports.addResource(mod, T.Token)
|
||||
imports.addResource(mod, T)
|
||||
}
|
||||
})
|
||||
visitObjectTypesFromProperties(res.InputProperties, inputSeen, func(t interface{}) {
|
||||
switch T := t.(type) {
|
||||
case *schema.ObjectType:
|
||||
imports.addType(mod, T.Token, true /*input*/)
|
||||
imports.addType(mod, T, true /*input*/)
|
||||
case *schema.EnumType:
|
||||
imports.addEnum(mod, T.Token)
|
||||
case *schema.ResourceType:
|
||||
imports.addResource(mod, T.Token)
|
||||
imports.addResource(mod, T)
|
||||
}
|
||||
})
|
||||
if res.StateInputs != nil {
|
||||
visitObjectTypesFromProperties(res.StateInputs.Properties, inputSeen, func(t interface{}) {
|
||||
switch T := t.(type) {
|
||||
case *schema.ObjectType:
|
||||
imports.addType(mod, T.Token, true /*input*/)
|
||||
imports.addType(mod, T, true /*input*/)
|
||||
case *schema.EnumType:
|
||||
imports.addEnum(mod, T.Token)
|
||||
case *schema.ResourceType:
|
||||
imports.addResource(mod, T.Token)
|
||||
imports.addResource(mod, T)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -1202,11 +1274,11 @@ func (mod *modContext) genFunction(fun *schema.Function) (string, error) {
|
|||
visitObjectTypesFromProperties(fun.Inputs.Properties, inputSeen, func(t interface{}) {
|
||||
switch T := t.(type) {
|
||||
case *schema.ObjectType:
|
||||
imports.addType(mod, T.Token, true /*input*/)
|
||||
imports.addType(mod, T, true /*input*/)
|
||||
case *schema.EnumType:
|
||||
imports.addEnum(mod, T.Token)
|
||||
case *schema.ResourceType:
|
||||
imports.addResource(mod, T.Token)
|
||||
imports.addResource(mod, T)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -1214,11 +1286,11 @@ func (mod *modContext) genFunction(fun *schema.Function) (string, error) {
|
|||
visitObjectTypesFromProperties(fun.Outputs.Properties, outputSeen, func(t interface{}) {
|
||||
switch T := t.(type) {
|
||||
case *schema.ObjectType:
|
||||
imports.addType(mod, T.Token, false /*input*/)
|
||||
imports.addType(mod, T, false /*input*/)
|
||||
case *schema.EnumType:
|
||||
imports.addEnum(mod, T.Token)
|
||||
case *schema.ResourceType:
|
||||
imports.addResource(mod, T.Token)
|
||||
imports.addResource(mod, T)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -1681,7 +1753,8 @@ func buildCaseMappingTables(pkg *schema.Package, snakeCaseToCamelCase, camelCase
|
|||
func recordProperty(prop *schema.Property, snakeCaseToCamelCase, camelCaseToSnakeCase map[string]string, seenTypes codegen.Set) {
|
||||
mapCase := true
|
||||
if python, ok := prop.Language["python"]; ok {
|
||||
mapCase = python.(PropertyInfo).MapCase
|
||||
v, ok := python.(PropertyInfo)
|
||||
mapCase = ok && v.MapCase
|
||||
}
|
||||
if mapCase {
|
||||
snakeCaseName := PyNameLegacy(prop.Name)
|
||||
|
@ -1823,12 +1896,12 @@ func (mod *modContext) typeString(t schema.Type, input, wrapInput, optional, acc
|
|||
case *schema.MapType:
|
||||
typ = fmt.Sprintf("Mapping[str, %s]", mod.typeString(t.ElementType, input, wrapInput, false, acceptMapping))
|
||||
case *schema.ObjectType:
|
||||
typ = mod.tokenToType(t.Token, input, mod.details(t).functionType)
|
||||
typ = mod.objectType(t, input, mod.details(t).functionType)
|
||||
if acceptMapping {
|
||||
typ = fmt.Sprintf("pulumi.InputType[%s]", typ)
|
||||
}
|
||||
case *schema.ResourceType:
|
||||
typ = fmt.Sprintf("'%s'", mod.tokenToResource(t.Token))
|
||||
typ = fmt.Sprintf("'%s'", mod.resourceType(t))
|
||||
case *schema.TokenType:
|
||||
// Use the underlying type for now.
|
||||
if t.UnderlyingType != nil {
|
||||
|
@ -1916,7 +1989,7 @@ func (mod *modContext) pyType(typ schema.Type) string {
|
|||
case *schema.MapType, *schema.ObjectType, *schema.UnionType:
|
||||
return "dict"
|
||||
case *schema.ResourceType:
|
||||
return mod.tokenToResource(typ.Token)
|
||||
return mod.resourceType(typ)
|
||||
case *schema.TokenType:
|
||||
if typ.UnderlyingType != nil {
|
||||
return mod.pyType(typ.UnderlyingType)
|
||||
|
@ -2166,12 +2239,12 @@ func generateModuleContextMap(tool string, pkg *schema.Package, info PackageInfo
|
|||
// group resources, types, and functions into modules
|
||||
modules := map[string]*modContext{}
|
||||
|
||||
var getMod func(modName string) *modContext
|
||||
getMod = func(modName string) *modContext {
|
||||
var getMod func(modName string, p *schema.Package) *modContext
|
||||
getMod = func(modName string, p *schema.Package) *modContext {
|
||||
mod, ok := modules[modName]
|
||||
if !ok {
|
||||
mod = &modContext{
|
||||
pkg: pkg,
|
||||
pkg: p,
|
||||
mod: modName,
|
||||
tool: tool,
|
||||
snakeCaseToCamelCase: snakeCaseToCamelCase,
|
||||
|
@ -2180,29 +2253,33 @@ func generateModuleContextMap(tool string, pkg *schema.Package, info PackageInfo
|
|||
compatibility: info.Compatibility,
|
||||
}
|
||||
|
||||
if modName != "" {
|
||||
if modName != "" && p == pkg {
|
||||
parentName := path.Dir(modName)
|
||||
if parentName == "." {
|
||||
parentName = ""
|
||||
}
|
||||
parent := getMod(parentName)
|
||||
parent := getMod(parentName, p)
|
||||
parent.children = append(parent.children, mod)
|
||||
}
|
||||
|
||||
modules[modName] = mod
|
||||
// Save the module only if it's for the current package.
|
||||
// This way, modules for external packages are not saved.
|
||||
if p == pkg {
|
||||
modules[modName] = mod
|
||||
}
|
||||
}
|
||||
return mod
|
||||
}
|
||||
|
||||
getModFromToken := func(tok string) *modContext {
|
||||
modName := tokenToModule(tok, pkg, info.ModuleNameOverrides)
|
||||
return getMod(modName)
|
||||
getModFromToken := func(tok string, p *schema.Package) *modContext {
|
||||
modName := tokenToModule(tok, p, info.ModuleNameOverrides)
|
||||
return getMod(modName, p)
|
||||
}
|
||||
|
||||
// Create the config module if necessary.
|
||||
if len(pkg.Config) > 0 &&
|
||||
info.Compatibility != kubernetes20 { // k8s SDK doesn't use config.
|
||||
configMod := getMod("config")
|
||||
configMod := getMod("config", pkg)
|
||||
configMod.isConfig = true
|
||||
}
|
||||
|
||||
|
@ -2210,36 +2287,36 @@ func generateModuleContextMap(tool string, pkg *schema.Package, info PackageInfo
|
|||
visitObjectTypesFromProperties(pkg.Config, outputSeen, func(t interface{}) {
|
||||
switch T := t.(type) {
|
||||
case *schema.ObjectType:
|
||||
getModFromToken(T.Token).details(T).outputType = true
|
||||
getModFromToken(T.Token, T.Package).details(T).outputType = true
|
||||
}
|
||||
})
|
||||
|
||||
// Find input and output types referenced by resources.
|
||||
scanResource := func(r *schema.Resource) {
|
||||
mod := getModFromToken(r.Token)
|
||||
mod := getModFromToken(r.Token, pkg)
|
||||
mod.resources = append(mod.resources, r)
|
||||
visitObjectTypesFromProperties(r.Properties, outputSeen, func(t interface{}) {
|
||||
switch T := t.(type) {
|
||||
case *schema.ObjectType:
|
||||
getModFromToken(T.Token).details(T).outputType = true
|
||||
getModFromToken(T.Token, T.Package).details(T).outputType = true
|
||||
}
|
||||
})
|
||||
visitObjectTypesFromProperties(r.InputProperties, inputSeen, func(t interface{}) {
|
||||
switch T := t.(type) {
|
||||
case *schema.ObjectType:
|
||||
if r.IsProvider {
|
||||
getModFromToken(T.Token).details(T).outputType = true
|
||||
getModFromToken(T.Token, T.Package).details(T).outputType = true
|
||||
}
|
||||
getModFromToken(T.Token).details(T).inputType = true
|
||||
getModFromToken(T.Token, T.Package).details(T).inputType = true
|
||||
}
|
||||
})
|
||||
if r.StateInputs != nil {
|
||||
visitObjectTypes(r.StateInputs, inputSeen, func(t interface{}) {
|
||||
switch T := t.(type) {
|
||||
case *schema.ObjectType:
|
||||
getModFromToken(T.Token).details(T).inputType = true
|
||||
getModFromToken(T.Token, T.Package).details(T).inputType = true
|
||||
case *schema.ResourceType:
|
||||
getModFromToken(T.Token)
|
||||
getModFromToken(T.Token, T.Resource.Package)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -2252,16 +2329,16 @@ func generateModuleContextMap(tool string, pkg *schema.Package, info PackageInfo
|
|||
|
||||
// Find input and output types referenced by functions.
|
||||
for _, f := range pkg.Functions {
|
||||
mod := getModFromToken(f.Token)
|
||||
mod := getModFromToken(f.Token, f.Package)
|
||||
mod.functions = append(mod.functions, f)
|
||||
if f.Inputs != nil {
|
||||
visitObjectTypes(f.Inputs, inputSeen, func(t interface{}) {
|
||||
switch T := t.(type) {
|
||||
case *schema.ObjectType:
|
||||
getModFromToken(T.Token).details(T).inputType = true
|
||||
getModFromToken(T.Token).details(T).functionType = true
|
||||
getModFromToken(T.Token, T.Package).details(T).inputType = true
|
||||
getModFromToken(T.Token, T.Package).details(T).functionType = true
|
||||
case *schema.ResourceType:
|
||||
getModFromToken(T.Token)
|
||||
getModFromToken(T.Token, T.Resource.Package)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -2269,10 +2346,10 @@ func generateModuleContextMap(tool string, pkg *schema.Package, info PackageInfo
|
|||
visitObjectTypes(f.Outputs, outputSeen, func(t interface{}) {
|
||||
switch T := t.(type) {
|
||||
case *schema.ObjectType:
|
||||
getModFromToken(T.Token).details(T).outputType = true
|
||||
getModFromToken(T.Token).details(T).functionType = true
|
||||
getModFromToken(T.Token, T.Package).details(T).outputType = true
|
||||
getModFromToken(T.Token, T.Package).details(T).functionType = true
|
||||
case *schema.ResourceType:
|
||||
getModFromToken(T.Token)
|
||||
getModFromToken(T.Token, T.Resource.Package)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -2282,13 +2359,13 @@ func generateModuleContextMap(tool string, pkg *schema.Package, info PackageInfo
|
|||
for _, t := range pkg.Types {
|
||||
switch typ := t.(type) {
|
||||
case *schema.ObjectType:
|
||||
mod := getModFromToken(typ.Token)
|
||||
mod := getModFromToken(typ.Token, typ.Package)
|
||||
d := mod.details(typ)
|
||||
if d.inputType || d.outputType {
|
||||
mod.types = append(mod.types, typ)
|
||||
}
|
||||
case *schema.EnumType:
|
||||
mod := getModFromToken(typ.Token)
|
||||
mod := getModFromToken(typ.Token, pkg)
|
||||
mod.enums = append(mod.enums, typ)
|
||||
default:
|
||||
continue
|
||||
|
@ -2306,7 +2383,7 @@ func generateModuleContextMap(tool string, pkg *schema.Package, info PackageInfo
|
|||
if modName == "/" || modName == "." {
|
||||
modName = ""
|
||||
}
|
||||
mod := getMod(modName)
|
||||
mod := getMod(modName, pkg)
|
||||
mod.extraSourceFiles = append(mod.extraSourceFiles, p)
|
||||
}
|
||||
|
||||
|
|
|
@ -423,7 +423,7 @@ func (p *providerServer) Construct(ctx context.Context,
|
|||
aliases[i] = resource.URN(urn)
|
||||
}
|
||||
dependencies := make([]resource.URN, len(req.GetDependencies()))
|
||||
for i, urn := range req.GetAliases() {
|
||||
for i, urn := range req.GetDependencies() {
|
||||
dependencies[i] = resource.URN(urn)
|
||||
}
|
||||
propertyDependencies := map[resource.PropertyKey][]resource.URN{}
|
||||
|
|
416
sdk/go/pulumi/provider.go
Normal file
416
sdk/go/pulumi/provider.go
Normal file
|
@ -0,0 +1,416 @@
|
|||
// 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 pulumi
|
||||
|
||||
import (
|
||||
"context"
|
||||
"flag"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/pulumi/pulumi/sdk/v2/go/common/resource/plugin"
|
||||
"github.com/pulumi/pulumi/sdk/v2/go/common/util/cmdutil"
|
||||
"github.com/pulumi/pulumi/sdk/v2/go/common/util/logging"
|
||||
"github.com/pulumi/pulumi/sdk/v2/go/common/util/rpcutil"
|
||||
|
||||
pbempty "github.com/golang/protobuf/ptypes/empty"
|
||||
pulumirpc "github.com/pulumi/pulumi/sdk/v2/proto/go"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
func ProviderMain(provider ProviderArgs) error {
|
||||
if provider.Name == "" {
|
||||
return errors.New("provider.Name must not be empty")
|
||||
}
|
||||
if provider.Version == "" {
|
||||
return errors.New("provider.Version must not be empty")
|
||||
}
|
||||
|
||||
var tracing string
|
||||
flag.StringVar(&tracing, "tracing", "", "Emit tracing to a Zipkin-compatible tracing endpoint")
|
||||
flag.Parse()
|
||||
|
||||
// Initialize loggers before going any further.
|
||||
logging.InitLogging(false, 0, false)
|
||||
cmdutil.InitTracing(provider.Name, provider.Name, tracing)
|
||||
|
||||
// Read the non-flags args and connect to the engine.
|
||||
args := flag.Args()
|
||||
if len(args) == 0 {
|
||||
return errors.New("fatal: could not connect to host RPC; missing argument")
|
||||
}
|
||||
|
||||
prov := &providerServer{
|
||||
provider: provider,
|
||||
engineAddr: args[0],
|
||||
}
|
||||
|
||||
// Fire up a gRPC server, letting the kernel choose a free port for us.
|
||||
port, done, err := rpcutil.Serve(0, nil, []func(*grpc.Server) error{
|
||||
func(srv *grpc.Server) error {
|
||||
pulumirpc.RegisterResourceProviderServer(srv, prov)
|
||||
return nil
|
||||
},
|
||||
}, nil)
|
||||
if err != nil {
|
||||
return errors.Errorf("fatal: %v", err)
|
||||
}
|
||||
|
||||
// The resource provider protocol requires that we now write out the port we have chosen to listen on.
|
||||
fmt.Printf("%d\n", port)
|
||||
|
||||
// Finally, wait for the server to stop serving.
|
||||
if err := <-done; err != nil {
|
||||
return errors.Errorf("fatal: %v", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type providerServer struct {
|
||||
provider ProviderArgs
|
||||
engineAddr string
|
||||
}
|
||||
|
||||
type ProviderArgs struct {
|
||||
Name string
|
||||
Version string
|
||||
Schema []byte
|
||||
|
||||
ConstructF func(ctx *Context, typ, name string, inputs *ConstructInputs,
|
||||
options ResourceOption) (ConstructResult, error)
|
||||
|
||||
// TODO add all the other gRPC methods.
|
||||
}
|
||||
|
||||
type constructInput struct {
|
||||
value interface{}
|
||||
secret bool
|
||||
deps []Resource
|
||||
}
|
||||
|
||||
type ConstructInputs struct {
|
||||
inputs map[string]constructInput
|
||||
}
|
||||
|
||||
func (inputs *ConstructInputs) Map() Map {
|
||||
result := Map{}
|
||||
for k, v := range inputs.inputs {
|
||||
output := newOutput(anyOutputType, v.deps...)
|
||||
output.resolve(v.value, true /*known*/, v.secret, nil)
|
||||
result[k] = output
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func (inputs *ConstructInputs) SetArgs(args interface{}) error {
|
||||
if args == nil {
|
||||
return errors.New("args must not be nil")
|
||||
}
|
||||
argsV := reflect.ValueOf(args)
|
||||
typ := argsV.Type()
|
||||
if typ.Kind() != reflect.Ptr || typ.Elem().Kind() != reflect.Struct {
|
||||
return errors.New("args must be a pointer to a struct")
|
||||
}
|
||||
argsV, typ = argsV.Elem(), typ.Elem()
|
||||
|
||||
for k, v := range inputs.inputs {
|
||||
for i := 0; i < typ.NumField(); i++ {
|
||||
fieldV := argsV.Field(i)
|
||||
if !fieldV.CanSet() {
|
||||
continue
|
||||
}
|
||||
field := typ.Field(i)
|
||||
tag, has := field.Tag.Lookup("pulumi")
|
||||
if !has || tag != k {
|
||||
continue
|
||||
}
|
||||
|
||||
toOutputMethodName := "To" + strings.TrimSuffix(field.Type.Name(), "Input") + "OutputWithContext"
|
||||
toOutputMethod, found := field.Type.MethodByName(toOutputMethodName)
|
||||
if !found {
|
||||
continue
|
||||
}
|
||||
mt := toOutputMethod.Type
|
||||
if mt.NumIn() != 1 || mt.In(0) != contextType || mt.NumOut() != 1 {
|
||||
continue
|
||||
}
|
||||
outputType := mt.Out(0)
|
||||
if !outputType.Implements(reflect.TypeOf((*Output)(nil)).Elem()) {
|
||||
continue
|
||||
}
|
||||
|
||||
output := newOutput(outputType, v.deps...)
|
||||
output.resolve(v.value, true /*known*/, v.secret, nil)
|
||||
fieldV.Set(reflect.ValueOf(output))
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type ConstructResult struct {
|
||||
URN URNInput
|
||||
State Input
|
||||
}
|
||||
|
||||
// Construct creates a new instance of the provided component resource and returns its state.
|
||||
func (p *providerServer) Construct(ctx context.Context,
|
||||
req *pulumirpc.ConstructRequest) (*pulumirpc.ConstructResponse, error) {
|
||||
|
||||
if p.provider.ConstructF == nil {
|
||||
return nil, errors.Errorf("unknown resource type %s", req.GetType())
|
||||
}
|
||||
|
||||
// Configure the RunInfo.
|
||||
runInfo := RunInfo{
|
||||
Project: req.GetProject(),
|
||||
Stack: req.GetStack(),
|
||||
Config: req.GetConfig(),
|
||||
Parallel: int(req.GetParallel()),
|
||||
DryRun: req.GetDryRun(),
|
||||
MonitorAddr: req.GetMonitorEndpoint(),
|
||||
EngineAddr: p.engineAddr,
|
||||
Mocks: nil,
|
||||
}
|
||||
pulumiCtx, err := NewContext(ctx, runInfo)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "constructing run context")
|
||||
}
|
||||
|
||||
// Deserialize the inputs and apply appropriate dependencies.
|
||||
inputs := &ConstructInputs{inputs: map[string]constructInput{}}
|
||||
inputDependencies := req.GetInputDependencies()
|
||||
deserializedInputs, err := plugin.UnmarshalProperties(
|
||||
req.GetInputs(),
|
||||
plugin.MarshalOptions{KeepSecrets: true, KeepResources: true, KeepUnknowns: req.GetDryRun()},
|
||||
)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "unmarshaling inputs")
|
||||
}
|
||||
for key, input := range deserializedInputs {
|
||||
k := string(key)
|
||||
var deps []Resource
|
||||
if inputDeps, ok := inputDependencies[k]; ok {
|
||||
deps = make([]Resource, len(inputDeps.GetUrns()))
|
||||
for i, depURN := range inputDeps.GetUrns() {
|
||||
deps[i] = newDependencyResource(URN(depURN))
|
||||
}
|
||||
}
|
||||
|
||||
val, secret, err := unmarshalPropertyValue(pulumiCtx, input)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "unmarshaling input %s", k)
|
||||
}
|
||||
|
||||
inputs.inputs[k] = constructInput{
|
||||
value: val,
|
||||
secret: secret,
|
||||
deps: deps,
|
||||
}
|
||||
}
|
||||
|
||||
// Rebuild the resource options.
|
||||
aliases := make([]Alias, len(req.GetAliases()))
|
||||
for i, urn := range req.GetAliases() {
|
||||
aliases[i] = Alias{URN: URN(urn)}
|
||||
}
|
||||
dependencies := make([]Resource, len(req.GetDependencies()))
|
||||
for i, urn := range req.GetDependencies() {
|
||||
dependencies[i] = newDependencyResource(URN(urn))
|
||||
}
|
||||
providers := make(map[string]ProviderResource, len(req.GetProviders()))
|
||||
for pkg, ref := range req.GetProviders() {
|
||||
// Parse the URN and ID out of the provider reference.
|
||||
lastSep := strings.LastIndex(ref, "::")
|
||||
if lastSep == -1 {
|
||||
return nil, errors.Errorf("expected '::' in provider reference %s", ref)
|
||||
}
|
||||
urn := ref[0:lastSep]
|
||||
id := ref[lastSep+2:]
|
||||
providers[pkg] = newDependencyProviderResource(URN(urn), ID(id))
|
||||
}
|
||||
var parent Resource
|
||||
if req.GetParent() != "" {
|
||||
parent = newDependencyResource(URN(req.GetParent()))
|
||||
}
|
||||
opts := resourceOption(func(ro *resourceOptions) {
|
||||
ro.Aliases = aliases
|
||||
ro.DependsOn = dependencies
|
||||
ro.Protect = req.GetProtect()
|
||||
ro.Providers = providers
|
||||
ro.Parent = parent
|
||||
})
|
||||
|
||||
result, err := p.provider.ConstructF(pulumiCtx, req.GetType(), req.GetName(), inputs, opts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Ensure all outstanding RPCs have completed before proceeding. Also, prevent any new RPCs from happening.
|
||||
pulumiCtx.waitForRPCs()
|
||||
if pulumiCtx.rpcError != nil {
|
||||
return nil, errors.Wrap(pulumiCtx.rpcError, "waiting for RPCs")
|
||||
}
|
||||
|
||||
rpcURN, _, _, err := result.URN.ToURNOutput().awaitURN(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Serialize all state properties, first by awaiting them, and then marshaling them to the requisite gRPC values.
|
||||
resolvedProps, propertyDeps, _, err := marshalInputs(result.State)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "marshaling properties")
|
||||
}
|
||||
|
||||
// Marshal all properties for the RPC call.
|
||||
keepUnknowns := req.GetDryRun()
|
||||
rpcProps, err := plugin.MarshalProperties(
|
||||
resolvedProps,
|
||||
plugin.MarshalOptions{KeepSecrets: true, KeepUnknowns: keepUnknowns, KeepResources: pulumiCtx.keepResources})
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "marshaling properties")
|
||||
}
|
||||
|
||||
// Convert the property dependencies map for RPC and remove duplicates.
|
||||
rpcPropertyDeps := make(map[string]*pulumirpc.ConstructResponse_PropertyDependencies)
|
||||
for k, deps := range propertyDeps {
|
||||
sort.Slice(deps, func(i, j int) bool { return deps[i] < deps[j] })
|
||||
|
||||
urns := make([]string, 0, len(deps))
|
||||
for i, d := range deps {
|
||||
if i > 0 && urns[i-1] == string(d) {
|
||||
continue
|
||||
}
|
||||
urns = append(urns, string(d))
|
||||
}
|
||||
|
||||
rpcPropertyDeps[k] = &pulumirpc.ConstructResponse_PropertyDependencies{
|
||||
Urns: urns,
|
||||
}
|
||||
}
|
||||
|
||||
return &pulumirpc.ConstructResponse{
|
||||
Urn: string(rpcURN),
|
||||
State: rpcProps,
|
||||
StateDependencies: rpcPropertyDeps,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// GetSchema returns the JSON-encoded schema for this provider's package.
|
||||
func (p *providerServer) GetSchema(ctx context.Context,
|
||||
req *pulumirpc.GetSchemaRequest) (*pulumirpc.GetSchemaResponse, error) {
|
||||
if v := req.GetVersion(); v != 0 {
|
||||
return nil, errors.Errorf("unsupported schema version %d", v)
|
||||
}
|
||||
return &pulumirpc.GetSchemaResponse{Schema: string(p.provider.Schema)}, nil
|
||||
}
|
||||
|
||||
// CheckConfig validates the configuration for this provider.
|
||||
func (p *providerServer) CheckConfig(ctx context.Context,
|
||||
req *pulumirpc.CheckRequest) (*pulumirpc.CheckResponse, error) {
|
||||
return nil, status.Error(codes.Unimplemented, "CheckConfig is not yet implemented")
|
||||
}
|
||||
|
||||
// DiffConfig diffs the configuration for this provider.
|
||||
func (p *providerServer) DiffConfig(ctx context.Context, req *pulumirpc.DiffRequest) (*pulumirpc.DiffResponse, error) {
|
||||
return nil, status.Error(codes.Unimplemented, "DiffConfig is not yet implemented")
|
||||
}
|
||||
|
||||
// Configure configures the resource provider with "globals" that control its behavior.
|
||||
func (p *providerServer) Configure(ctx context.Context,
|
||||
req *pulumirpc.ConfigureRequest) (*pulumirpc.ConfigureResponse, error) {
|
||||
return &pulumirpc.ConfigureResponse{
|
||||
AcceptSecrets: true,
|
||||
SupportsPreview: true,
|
||||
AcceptResources: true,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Invoke dynamically executes a built-in function in the provider.
|
||||
func (p *providerServer) Invoke(ctx context.Context, req *pulumirpc.InvokeRequest) (*pulumirpc.InvokeResponse, error) {
|
||||
tok := req.GetTok()
|
||||
return nil, errors.Errorf("unknown Invoke token %q", tok)
|
||||
}
|
||||
|
||||
// StreamInvoke dynamically executes a built-in function in the provider. The result is streamed
|
||||
// back as a series of messages.
|
||||
func (p *providerServer) StreamInvoke(req *pulumirpc.InvokeRequest,
|
||||
server pulumirpc.ResourceProvider_StreamInvokeServer) error {
|
||||
tok := req.GetTok()
|
||||
return errors.Errorf("unknown StreamInvoke token %q", tok)
|
||||
}
|
||||
|
||||
// Check validates that the given property bag is valid for a resource of the given type and returns
|
||||
// the inputs that should be passed to successive calls to Diff, Create, or Update for this
|
||||
// resource. As a rule, the provider inputs returned by a call to Check should preserve the original
|
||||
// representation of the properties as present in the program inputs. Though this rule is not
|
||||
// required for correctness, violations thereof can negatively impact the end-user experience, as
|
||||
// the provider inputs are using for detecting and rendering diffs.
|
||||
func (p *providerServer) Check(ctx context.Context, req *pulumirpc.CheckRequest) (*pulumirpc.CheckResponse, error) {
|
||||
return nil, status.Error(codes.Unimplemented, "Check is not yet implemented")
|
||||
}
|
||||
|
||||
// Diff checks what impacts a hypothetical update will have on the resource's properties.
|
||||
func (p *providerServer) Diff(ctx context.Context, req *pulumirpc.DiffRequest) (*pulumirpc.DiffResponse, error) {
|
||||
return nil, status.Error(codes.Unimplemented, "Diff is not yet implemented")
|
||||
}
|
||||
|
||||
// Create allocates a new instance of the provided resource and returns its unique ID afterwards.
|
||||
// (The input ID must be blank.) If this call fails, the resource must not have been created (i.e.,
|
||||
// it is "transactional").
|
||||
func (p *providerServer) Create(ctx context.Context, req *pulumirpc.CreateRequest) (*pulumirpc.CreateResponse, error) {
|
||||
return nil, status.Error(codes.Unimplemented, "Create is not yet implemented")
|
||||
}
|
||||
|
||||
// Read the current live state associated with a resource. Enough state must be include in the
|
||||
// inputs to uniquely identify the resource; this is typically just the resource ID, but may also
|
||||
// include some properties.
|
||||
func (p *providerServer) Read(ctx context.Context, req *pulumirpc.ReadRequest) (*pulumirpc.ReadResponse, error) {
|
||||
return nil, status.Error(codes.Unimplemented, "Read is not yet implemented")
|
||||
}
|
||||
|
||||
// Update updates an existing resource with new values.
|
||||
func (p *providerServer) Update(ctx context.Context, req *pulumirpc.UpdateRequest) (*pulumirpc.UpdateResponse, error) {
|
||||
return nil, status.Error(codes.Unimplemented, "Update is not yet implemented")
|
||||
}
|
||||
|
||||
// Delete tears down an existing resource with the given ID. If it fails, the resource is assumed
|
||||
// to still exist.
|
||||
func (p *providerServer) Delete(ctx context.Context, req *pulumirpc.DeleteRequest) (*pbempty.Empty, error) {
|
||||
return &pbempty.Empty{}, nil
|
||||
}
|
||||
|
||||
// GetPluginInfo returns generic information about this plugin, like its version.
|
||||
func (p *providerServer) GetPluginInfo(context.Context, *pbempty.Empty) (*pulumirpc.PluginInfo, error) {
|
||||
return &pulumirpc.PluginInfo{
|
||||
Version: p.provider.Version,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Cancel signals the provider to gracefully shut down and abort any ongoing resource operations.
|
||||
// Operations aborted in this way will return an error (e.g., `Update` and `Create` will either a
|
||||
// creation error or an initialization error). Since Cancel is advisory and non-blocking, it is up
|
||||
// to the host to decide how long to wait after Cancel is called before (e.g.)
|
||||
// hard-closing any gRPC connection.
|
||||
func (p *providerServer) Cancel(context.Context, *pbempty.Empty) (*pbempty.Empty, error) {
|
||||
return &pbempty.Empty{}, nil
|
||||
}
|
Loading…
Reference in a new issue