diff --git a/internal/grpcwrap/provider.go b/internal/grpcwrap/provider.go index dbedecf953cb..30a8f8947757 100644 --- a/internal/grpcwrap/provider.go +++ b/internal/grpcwrap/provider.go @@ -23,14 +23,16 @@ import ( // implementation. func Provider(p providers.Interface) tfplugin5.ProviderServer { return &provider{ - provider: p, - schema: p.GetProviderSchema(), + provider: p, + schema: p.GetProviderSchema(), + identitySchemas: p.GetResourceIdentitySchemas(), } } type provider struct { - provider providers.Interface - schema providers.GetProviderSchemaResponse + provider providers.Interface + schema providers.GetProviderSchemaResponse + identitySchemas providers.GetResourceIdentitySchemasResponse } func (p *provider) GetMetadata(_ context.Context, req *tfplugin5.GetMetadata_Request) (*tfplugin5.GetMetadata_Response, error) { @@ -540,7 +542,17 @@ func (p *provider) CallFunction(_ context.Context, req *tfplugin5.CallFunction_R } func (p *provider) GetResourceIdentitySchemas(_ context.Context, req *tfplugin5.GetResourceIdentitySchemas_Request) (*tfplugin5.GetResourceIdentitySchemas_Response, error) { - panic("Not implemented yet") + resp := &tfplugin5.GetResourceIdentitySchemas_Response{ + IdentitySchemas: map[string]*tfplugin5.ResourceIdentitySchema{}, + Diagnostics: []*tfplugin5.Diagnostic{}, + } + + for name, schema := range p.identitySchemas.IdentityTypes { + resp.IdentitySchemas[name] = convert.ResourceIdentitySchemaToProto(schema) + } + + resp.Diagnostics = convert.AppendProtoDiag(resp.Diagnostics, p.identitySchemas.Diagnostics) + return resp, nil } func (p *provider) UpgradeResourceIdentity(_ context.Context, req *tfplugin5.UpgradeResourceIdentity_Request) (*tfplugin5.UpgradeResourceIdentity_Response, error) { diff --git a/internal/grpcwrap/provider6.go b/internal/grpcwrap/provider6.go index fb4ce245747a..e971f00cf75e 100644 --- a/internal/grpcwrap/provider6.go +++ b/internal/grpcwrap/provider6.go @@ -24,14 +24,16 @@ import ( // internal provider implementation. func Provider6(p providers.Interface) tfplugin6.ProviderServer { return &provider6{ - provider: p, - schema: p.GetProviderSchema(), + provider: p, + schema: p.GetProviderSchema(), + identitySchemas: p.GetResourceIdentitySchemas(), } } type provider6 struct { - provider providers.Interface - schema providers.GetProviderSchemaResponse + provider providers.Interface + schema providers.GetProviderSchemaResponse + identitySchemas providers.GetResourceIdentitySchemasResponse } func (p *provider6) GetMetadata(_ context.Context, req *tfplugin6.GetMetadata_Request) (*tfplugin6.GetMetadata_Response, error) { @@ -590,7 +592,17 @@ func (p *provider6) CallFunction(_ context.Context, req *tfplugin6.CallFunction_ } func (p *provider6) GetResourceIdentitySchemas(_ context.Context, req *tfplugin6.GetResourceIdentitySchemas_Request) (*tfplugin6.GetResourceIdentitySchemas_Response, error) { - panic("Not implemented yet") + resp := &tfplugin6.GetResourceIdentitySchemas_Response{ + IdentitySchemas: map[string]*tfplugin6.ResourceIdentitySchema{}, + Diagnostics: []*tfplugin6.Diagnostic{}, + } + + for name, schema := range p.identitySchemas.IdentityTypes { + resp.IdentitySchemas[name] = convert.ResourceIdentitySchemaToProto(schema) + } + + resp.Diagnostics = convert.AppendProtoDiag(resp.Diagnostics, p.identitySchemas.Diagnostics) + return resp, nil } func (p *provider6) UpgradeResourceIdentity(_ context.Context, req *tfplugin6.UpgradeResourceIdentity_Request) (*tfplugin6.UpgradeResourceIdentity_Response, error) { diff --git a/internal/plugin/convert/schema.go b/internal/plugin/convert/schema.go index 138838ce731e..be732e6b9c23 100644 --- a/internal/plugin/convert/schema.go +++ b/internal/plugin/convert/schema.go @@ -225,3 +225,31 @@ func ProtoToResourceIdentitySchema(s *proto.ResourceIdentitySchema) (providers.I return schema, diags } + +func ResourceIdentitySchemaToProto(b providers.IdentitySchema) *proto.ResourceIdentitySchema { + attrs := []*proto.ResourceIdentitySchema_IdentityAttribute{} + for _, name := range sortedKeys(b.Attributes) { + a := b.Attributes[name] + + attr := &proto.ResourceIdentitySchema_IdentityAttribute{ + Name: name, + Description: a.Description, + RequiredForImport: a.RequiredForImport, + OptionalForImport: a.OptionalForImport, + } + + ty, err := json.Marshal(a.Type) + if err != nil { + panic(err) + } + + attr.Type = ty + + attrs = append(attrs, attr) + } + + return &proto.ResourceIdentitySchema{ + Version: b.Version, + IdentityAttributes: attrs, + } +} diff --git a/internal/plugin6/convert/schema.go b/internal/plugin6/convert/schema.go index bc3ad67c69cb..3e2338a9c7ab 100644 --- a/internal/plugin6/convert/schema.go +++ b/internal/plugin6/convert/schema.go @@ -338,3 +338,32 @@ func configschemaObjectToProto(b *configschema.Object) *proto.Schema_Object { Nesting: nesting, } } + +func ResourceIdentitySchemaToProto(schema providers.IdentitySchema) *proto.ResourceIdentitySchema { + identityAttributes := []*proto.ResourceIdentitySchema_IdentityAttribute{} + + for _, name := range sortedKeys(schema.Attributes) { + a := schema.Attributes[name] + attr := &proto.ResourceIdentitySchema_IdentityAttribute{ + Name: name, + Description: a.Description, + RequiredForImport: a.RequiredForImport, + OptionalForImport: a.OptionalForImport, + } + + if a.Type != cty.NilType { + ty, err := json.Marshal(a.Type) + if err != nil { + panic(err) + } + attr.Type = ty + } + + identityAttributes = append(identityAttributes, attr) + } + + return &proto.ResourceIdentitySchema{ + Version: schema.Version, + IdentityAttributes: identityAttributes, + } +} diff --git a/internal/provider-simple/provider.go b/internal/provider-simple/provider.go index 14ea0946f99d..2a92b4cd04b9 100644 --- a/internal/provider-simple/provider.go +++ b/internal/provider-simple/provider.go @@ -66,6 +66,7 @@ func (s simple) GetResourceIdentitySchemas() providers.GetResourceIdentitySchema "id": { Type: cty.String, RequiredForImport: true, + OptionalForImport: false, }, }, }, diff --git a/internal/providers/mock.go b/internal/providers/mock.go index b8c4dfa9b0c4..c6dbd725103e 100644 --- a/internal/providers/mock.go +++ b/internal/providers/mock.go @@ -37,7 +37,8 @@ type Mock struct { Provider Interface Data *configs.MockData - schema *GetProviderSchemaResponse + schema *GetProviderSchemaResponse + identitySchema *GetResourceIdentitySchemasResponse } func (m *Mock) GetProviderSchema() GetProviderSchemaResponse { @@ -67,8 +68,13 @@ func (m *Mock) GetProviderSchema() GetProviderSchemaResponse { } func (m *Mock) GetResourceIdentitySchemas() GetResourceIdentitySchemasResponse { - // TODO - return GetResourceIdentitySchemasResponse{} + if m.identitySchema == nil { + // Cache the schema, it's not changing. + schema := m.Provider.GetResourceIdentitySchemas() + + m.identitySchema = &schema + } + return *m.identitySchema } func (m *Mock) ValidateProviderConfig(request ValidateProviderConfigRequest) (response ValidateProviderConfigResponse) {