Skip to content

Commit

Permalink
send resource identities to provider calls
Browse files Browse the repository at this point in the history
  • Loading branch information
DanielMSchmidt committed Mar 6, 2025
1 parent 78b6847 commit 7d1faf5
Show file tree
Hide file tree
Showing 32 changed files with 2,060 additions and 438 deletions.
4 changes: 3 additions & 1 deletion internal/command/jsonformat/plan_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8234,7 +8234,9 @@ func TestResourceChange_deferredActions(t *testing.T) {
}
var changes []*plans.DeferredResourceInstanceChangeSrc
for _, change := range tc.changes {
changeSrc, err := change.Encode(blockSchema.ImpliedType())
changeSrc, err := change.Encode(providers.Schema{
Body: blockSchema,
})
if err != nil {
t.Fatalf("Failed to encode change: %s", err)
}
Expand Down
2 changes: 1 addition & 1 deletion internal/command/jsonplan/plan.go
Original file line number Diff line number Diff line change
Expand Up @@ -433,7 +433,7 @@ func marshalResourceChange(rc *plans.ResourceInstanceChangeSrc, schemas *terrafo
return r, fmt.Errorf("no schema found for %s (in provider %s)", r.Address, rc.ProviderAddr.Provider)
}

changeV, err := rc.Decode(schema.Body.ImpliedType())
changeV, err := rc.Decode(schema)
if err != nil {
return r, err
}
Expand Down
2 changes: 1 addition & 1 deletion internal/command/jsonplan/values.go
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ func marshalPlanResources(changes *plans.ChangesSrc, ris []addrs.AbsResourceInst
return nil, fmt.Errorf("no schema found for %s", r.Addr.String())
}
resource.SchemaVersion = uint64(schema.Version)
changeV, err := r.Decode(schema.Body.ImpliedType())
changeV, err := r.Decode(schema)
if err != nil {
return nil, err
}
Expand Down
9 changes: 4 additions & 5 deletions internal/command/views/operation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ func TestOperation_planNoChanges(t *testing.T) {
}),
},
}
rcs, err := rc.Encode(ty)
rcs, err := rc.Encode(schema)
if err != nil {
panic(err)
}
Expand Down Expand Up @@ -180,7 +180,7 @@ func TestOperation_planNoChanges(t *testing.T) {
}),
},
}
rcs, err := rc.Encode(ty)
rcs, err := rc.Encode(schema)
if err != nil {
panic(err)
}
Expand Down Expand Up @@ -227,7 +227,7 @@ func TestOperation_planNoChanges(t *testing.T) {
}),
},
}
rcs, err := rc.Encode(ty)
rcs, err := rc.Encode(schema)
if err != nil {
panic(err)
}
Expand Down Expand Up @@ -257,7 +257,6 @@ func TestOperation_planNoChanges(t *testing.T) {
addr.Resource.Resource.Mode,
addr.Resource.Resource.Type,
)
ty := schema.Body.ImpliedType()
rc := &plans.ResourceInstanceChange{
Addr: addr,
PrevRunAddr: addrPrev,
Expand All @@ -276,7 +275,7 @@ func TestOperation_planNoChanges(t *testing.T) {
}),
},
}
rcs, err := rc.Encode(ty)
rcs, err := rc.Encode(schema)
if err != nil {
panic(err)
}
Expand Down
180 changes: 168 additions & 12 deletions internal/grpcwrap/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -234,11 +234,25 @@ func (p *provider) ReadResource(_ context.Context, req *tfplugin5.ReadResource_R
return resp, nil
}

var currentIdentity cty.Value
if req.CurrentIdentity != nil && req.CurrentIdentity.IdentityData != nil {
identitySchema, ok := p.identitySchemas.IdentityTypes[req.TypeName]
if !ok {
return resp, fmt.Errorf("identity schema not found for type %s", req.TypeName)
}
currentIdentity, err = decodeDynamicValue(req.CurrentIdentity.IdentityData, identitySchema.Body.ImpliedType())
if err != nil {
resp.Diagnostics = convert.AppendProtoDiag(resp.Diagnostics, err)
return resp, nil
}
}

readResp := p.provider.ReadResource(providers.ReadResourceRequest{
TypeName: req.TypeName,
PriorState: stateVal,
Private: req.Private,
ProviderMeta: metaVal,
TypeName: req.TypeName,
PriorState: stateVal,
Private: req.Private,
ProviderMeta: metaVal,
CurrentIdentity: currentIdentity,
})
resp.Diagnostics = convert.AppendProtoDiag(resp.Diagnostics, readResp.Diagnostics)
if readResp.Diagnostics.HasErrors() {
Expand All @@ -253,6 +267,21 @@ func (p *provider) ReadResource(_ context.Context, req *tfplugin5.ReadResource_R
}
resp.NewState = dv

if !readResp.Identity.IsNull() {
identitySchema, ok := p.identitySchemas.IdentityTypes[req.TypeName]
if !ok {
return resp, fmt.Errorf("identity schema not found for type %s", req.TypeName)
}

identity, err := encodeDynamicValue(readResp.Identity, identitySchema.Body.ImpliedType())
if err != nil {
resp.Diagnostics = convert.AppendProtoDiag(resp.Diagnostics, err)
return resp, nil
}
resp.NewIdentity = &tfplugin5.ResourceIdentityData{
IdentityData: identity,
}
}
return resp, nil
}

Expand Down Expand Up @@ -285,13 +314,28 @@ func (p *provider) PlanResourceChange(_ context.Context, req *tfplugin5.PlanReso
return resp, nil
}

var priorIdentity cty.Value
if req.PriorIdentity != nil && req.PriorIdentity.IdentityData != nil {
priorIdentitySchema, ok := p.identitySchemas.IdentityTypes[req.TypeName]
if !ok {
return resp, fmt.Errorf("identity schema not found for type %s", req.TypeName)
}

priorIdentity, err = decodeDynamicValue(req.PriorIdentity.IdentityData, priorIdentitySchema.Body.ImpliedType())
if err != nil {
resp.Diagnostics = convert.AppendProtoDiag(resp.Diagnostics, err)
return resp, nil
}
}

planResp := p.provider.PlanResourceChange(providers.PlanResourceChangeRequest{
TypeName: req.TypeName,
PriorState: priorStateVal,
ProposedNewState: proposedStateVal,
Config: configVal,
PriorPrivate: req.PriorPrivate,
ProviderMeta: metaVal,
PriorIdentity: priorIdentity,
})
resp.Diagnostics = convert.AppendProtoDiag(resp.Diagnostics, planResp.Diagnostics)
if planResp.Diagnostics.HasErrors() {
Expand All @@ -310,6 +354,23 @@ func (p *provider) PlanResourceChange(_ context.Context, req *tfplugin5.PlanReso
resp.RequiresReplace = append(resp.RequiresReplace, convert.PathToAttributePath(path))
}

if !planResp.PlannedIdentity.IsNull() {
plannedIdentitySchema, ok := p.identitySchemas.IdentityTypes[req.TypeName]
if !ok {
return resp, fmt.Errorf("identity schema not found for type %s", req.TypeName)
}

plannedIdentity, err := encodeDynamicValue(planResp.PlannedIdentity, plannedIdentitySchema.Body.ImpliedType())
if err != nil {
resp.Diagnostics = convert.AppendProtoDiag(resp.Diagnostics, err)
return resp, nil
}

resp.PlannedIdentity = &tfplugin5.ResourceIdentityData{
IdentityData: plannedIdentity,
}
}

return resp, nil
}

Expand Down Expand Up @@ -342,13 +403,28 @@ func (p *provider) ApplyResourceChange(_ context.Context, req *tfplugin5.ApplyRe
return resp, nil
}

var plannedIdentity cty.Value
if req.PlannedIdentity != nil && req.PlannedIdentity.IdentityData != nil {
plannedIdentitySchema, ok := p.identitySchemas.IdentityTypes[req.TypeName]
if !ok {
return resp, fmt.Errorf("identity schema not found for type %s", req.TypeName)
}

plannedIdentity, err = decodeDynamicValue(req.PlannedIdentity.IdentityData, plannedIdentitySchema.Body.ImpliedType())
if err != nil {
resp.Diagnostics = convert.AppendProtoDiag(resp.Diagnostics, err)
return resp, nil
}
}

applyResp := p.provider.ApplyResourceChange(providers.ApplyResourceChangeRequest{
TypeName: req.TypeName,
PriorState: priorStateVal,
PlannedState: plannedStateVal,
Config: configVal,
PlannedPrivate: req.PlannedPrivate,
ProviderMeta: metaVal,
TypeName: req.TypeName,
PriorState: priorStateVal,
PlannedState: plannedStateVal,
Config: configVal,
PlannedPrivate: req.PlannedPrivate,
ProviderMeta: metaVal,
PlannedIdentity: plannedIdentity,
})

resp.Diagnostics = convert.AppendProtoDiag(resp.Diagnostics, applyResp.Diagnostics)
Expand All @@ -363,15 +439,46 @@ func (p *provider) ApplyResourceChange(_ context.Context, req *tfplugin5.ApplyRe
return resp, nil
}

if !applyResp.NewIdentity.IsNull() {
newIdentitySchema, ok := p.identitySchemas.IdentityTypes[req.TypeName]
if !ok {
return resp, fmt.Errorf("identity schema not found for type %s", req.TypeName)
}

newIdentity, err := encodeDynamicValue(applyResp.NewIdentity, newIdentitySchema.Body.ImpliedType())
if err != nil {
resp.Diagnostics = convert.AppendProtoDiag(resp.Diagnostics, err)
return resp, nil
}
resp.NewIdentity = &tfplugin5.ResourceIdentityData{
IdentityData: newIdentity,
}
}

return resp, nil
}

func (p *provider) ImportResourceState(_ context.Context, req *tfplugin5.ImportResourceState_Request) (*tfplugin5.ImportResourceState_Response, error) {
resp := &tfplugin5.ImportResourceState_Response{}
var identity cty.Value
var err error
if req.Identity != nil && req.Identity.IdentityData != nil {
identitySchema, ok := p.identitySchemas.IdentityTypes[req.TypeName]
if !ok {
return resp, fmt.Errorf("identity schema not found for type %s", req.TypeName)
}

identity, err = decodeDynamicValue(req.Identity.IdentityData, identitySchema.Body.ImpliedType())
if err != nil {
resp.Diagnostics = convert.AppendProtoDiag(resp.Diagnostics, err)
return resp, nil
}
}

importResp := p.provider.ImportResourceState(providers.ImportResourceStateRequest{
TypeName: req.TypeName,
ID: req.Id,
Identity: identity,
})
resp.Diagnostics = convert.AppendProtoDiag(resp.Diagnostics, importResp.Diagnostics)

Expand All @@ -383,11 +490,28 @@ func (p *provider) ImportResourceState(_ context.Context, req *tfplugin5.ImportR
continue
}

resp.ImportedResources = append(resp.ImportedResources, &tfplugin5.ImportResourceState_ImportedResource{
resource := &tfplugin5.ImportResourceState_ImportedResource{
TypeName: res.TypeName,
State: state,
Private: res.Private,
})
}

if !res.Identity.IsNull() {
identitySchema, ok := p.identitySchemas.IdentityTypes[res.TypeName]
if !ok {
return nil, fmt.Errorf("identity schema not found for type %s", res.TypeName)
}
identity, err := encodeDynamicValue(res.Identity, identitySchema.Body.ImpliedType())
if err != nil {
resp.Diagnostics = convert.AppendProtoDiag(resp.Diagnostics, err)
continue
}
resource.Identity = &tfplugin5.ResourceIdentityData{
IdentityData: identity,
}
}

resp.ImportedResources = append(resp.ImportedResources, resource)
}

return resp, nil
Expand All @@ -396,12 +520,28 @@ func (p *provider) ImportResourceState(_ context.Context, req *tfplugin5.ImportR
func (p *provider) MoveResourceState(_ context.Context, request *tfplugin5.MoveResourceState_Request) (*tfplugin5.MoveResourceState_Response, error) {
resp := &tfplugin5.MoveResourceState_Response{}

var sourceIdentity cty.Value
var err error
if request.SourceIdentity != nil && request.SourceIdentity.IdentityData != nil {
sourceIdentitySchema, ok := p.identitySchemas.IdentityTypes[request.SourceTypeName]
if !ok {
return resp, fmt.Errorf("identity schema not found for type %s", request.SourceTypeName)
}

sourceIdentity, err = decodeDynamicValue(request.SourceIdentity.IdentityData, sourceIdentitySchema.Body.ImpliedType())
if err != nil {
resp.Diagnostics = convert.AppendProtoDiag(resp.Diagnostics, err)
return resp, nil
}
}

moveResp := p.provider.MoveResourceState(providers.MoveResourceStateRequest{
SourceProviderAddress: request.SourceProviderAddress,
SourceTypeName: request.SourceTypeName,
SourceSchemaVersion: request.SourceSchemaVersion,
SourceStateJSON: request.SourceState.Json,
SourcePrivate: request.SourcePrivate,
SourceIdentity: sourceIdentity,
TargetTypeName: request.TargetTypeName,
})
resp.Diagnostics = convert.AppendProtoDiag(resp.Diagnostics, moveResp.Diagnostics)
Expand All @@ -417,6 +557,22 @@ func (p *provider) MoveResourceState(_ context.Context, request *tfplugin5.MoveR
}
resp.TargetState = targetState
resp.TargetPrivate = moveResp.TargetPrivate

if !moveResp.TargetIdentity.IsNull() {
targetIdentitySchema, ok := p.identitySchemas.IdentityTypes[request.TargetTypeName]
if !ok {
return resp, fmt.Errorf("identity schema not found for type %s", request.TargetTypeName)
}
targetIdentity, err := encodeDynamicValue(moveResp.TargetIdentity, targetIdentitySchema.Body.ImpliedType())
if err != nil {
resp.Diagnostics = convert.AppendProtoDiag(resp.Diagnostics, err)
return resp, nil
}
resp.TargetIdentity = &tfplugin5.ResourceIdentityData{
IdentityData: targetIdentity,
}
}

return resp, nil
}

Expand Down
Loading

0 comments on commit 7d1faf5

Please sign in to comment.