mirror of
https://github.com/opentofu/opentofu.git
synced 2025-02-25 18:45:20 -06:00
terraform: Fixing up context
This commit is contained in:
parent
9cbd71b88d
commit
3963b42625
@ -505,6 +505,9 @@ func (c *Context) applyWalkFn() depgraph.WalkFunc {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Ensure the state is initialized
|
||||||
|
r.State.init()
|
||||||
|
|
||||||
if !diff.Destroy {
|
if !diff.Destroy {
|
||||||
// Since we need the configuration, interpolate the variables
|
// Since we need the configuration, interpolate the variables
|
||||||
if err := r.Config.interpolate(c); err != nil {
|
if err := r.Config.interpolate(c); err != nil {
|
||||||
@ -543,11 +546,6 @@ func (c *Context) applyWalkFn() depgraph.WalkFunc {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we do not have any connection info, initialize
|
|
||||||
if r.State.Primary.Ephemeral.ConnInfo == nil {
|
|
||||||
r.State.Primary.Ephemeral.init()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove any output values from the diff
|
// Remove any output values from the diff
|
||||||
for k, ad := range diff.Attributes {
|
for k, ad := range diff.Attributes {
|
||||||
if ad.Type == DiffAttrOutput {
|
if ad.Type == DiffAttrOutput {
|
||||||
@ -571,42 +569,36 @@ func (c *Context) applyWalkFn() depgraph.WalkFunc {
|
|||||||
// Make sure the result is instantiated
|
// Make sure the result is instantiated
|
||||||
if rs == nil {
|
if rs == nil {
|
||||||
rs = new(ResourceState)
|
rs = new(ResourceState)
|
||||||
|
rs.init()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Force the resource state type to be our type
|
// Force the resource state type to be our type
|
||||||
rs.Type = r.State.Type
|
rs.Type = r.State.Type
|
||||||
|
|
||||||
// Force the "id" attribute to be our ID
|
// Force the "id" attribute to be our ID
|
||||||
if rs.ID != "" {
|
if rs.Primary.ID != "" {
|
||||||
if rs.Attributes == nil {
|
rs.Primary.Attributes["id"] = rs.Primary.ID
|
||||||
rs.Attributes = make(map[string]string)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
rs.Attributes["id"] = rs.ID
|
for ak, av := range rs.Primary.Attributes {
|
||||||
}
|
|
||||||
|
|
||||||
for ak, av := range rs.Attributes {
|
|
||||||
// If the value is the unknown variable value, then it is an error.
|
// If the value is the unknown variable value, then it is an error.
|
||||||
// In this case we record the error and remove it from the state
|
// In this case we record the error and remove it from the state
|
||||||
if av == config.UnknownVariableValue {
|
if av == config.UnknownVariableValue {
|
||||||
errs = append(errs, fmt.Errorf(
|
errs = append(errs, fmt.Errorf(
|
||||||
"Attribute with unknown value: %s", ak))
|
"Attribute with unknown value: %s", ak))
|
||||||
delete(rs.Attributes, ak)
|
delete(rs.Primary.Attributes, ak)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the resulting diff
|
// Update the resulting diff
|
||||||
c.sl.Lock()
|
c.sl.Lock()
|
||||||
if rs.ID == "" {
|
|
||||||
delete(c.state.Resources, r.Id)
|
|
||||||
delete(c.state.Tainted, r.Id)
|
|
||||||
} else {
|
|
||||||
c.state.Resources[r.Id] = rs
|
|
||||||
|
|
||||||
// We always mark the resource as tainted here in case a
|
// TODO: Get other modules
|
||||||
// hook below during provisioning does HookActionStop. This
|
mod := c.state.RootModule()
|
||||||
// way, we keep the resource tainted.
|
if rs.Primary.ID == "" && len(rs.Tainted) == 0 {
|
||||||
c.state.Tainted[r.Id] = struct{}{}
|
delete(mod.Resources, r.Id)
|
||||||
|
} else {
|
||||||
|
mod.Resources[r.Id] = rs
|
||||||
}
|
}
|
||||||
c.sl.Unlock()
|
c.sl.Unlock()
|
||||||
|
|
||||||
@ -617,7 +609,7 @@ func (c *Context) applyWalkFn() depgraph.WalkFunc {
|
|||||||
// Additionally, we need to be careful to not run this if there
|
// Additionally, we need to be careful to not run this if there
|
||||||
// was an error during the provider apply.
|
// was an error during the provider apply.
|
||||||
tainted := false
|
tainted := false
|
||||||
if applyerr == nil && r.State.ID == "" && len(r.Provisioners) > 0 {
|
if applyerr == nil && r.State.Primary.ID == "" && len(r.Provisioners) > 0 {
|
||||||
for _, h := range c.hooks {
|
for _, h := range c.hooks {
|
||||||
handleHook(h.PreProvisionResource(r.Id, r.State))
|
handleHook(h.PreProvisionResource(r.Id, r.State))
|
||||||
}
|
}
|
||||||
@ -635,9 +627,8 @@ func (c *Context) applyWalkFn() depgraph.WalkFunc {
|
|||||||
c.sl.Lock()
|
c.sl.Lock()
|
||||||
if tainted {
|
if tainted {
|
||||||
log.Printf("[DEBUG] %s: Marking as tainted", r.Id)
|
log.Printf("[DEBUG] %s: Marking as tainted", r.Id)
|
||||||
c.state.Tainted[r.Id] = struct{}{}
|
rs.Tainted = append(rs.Tainted, rs.Primary)
|
||||||
} else {
|
rs.Primary = nil
|
||||||
delete(c.state.Tainted, r.Id)
|
|
||||||
}
|
}
|
||||||
c.sl.Unlock()
|
c.sl.Unlock()
|
||||||
|
|
||||||
@ -665,9 +656,9 @@ func (c *Context) applyWalkFn() depgraph.WalkFunc {
|
|||||||
// defined after the resource creation has already completed.
|
// defined after the resource creation has already completed.
|
||||||
func (c *Context) applyProvisioners(r *Resource, rs *ResourceState) error {
|
func (c *Context) applyProvisioners(r *Resource, rs *ResourceState) error {
|
||||||
// Store the original connection info, restore later
|
// Store the original connection info, restore later
|
||||||
origConnInfo := rs.ConnInfo
|
origConnInfo := rs.Primary.Ephemeral.ConnInfo
|
||||||
defer func() {
|
defer func() {
|
||||||
rs.ConnInfo = origConnInfo
|
rs.Primary.Ephemeral.ConnInfo = origConnInfo
|
||||||
}()
|
}()
|
||||||
|
|
||||||
for _, prov := range r.Provisioners {
|
for _, prov := range r.Provisioners {
|
||||||
@ -710,7 +701,7 @@ func (c *Context) applyProvisioners(r *Resource, rs *ResourceState) error {
|
|||||||
overlay[k] = fmt.Sprintf("%v", vt)
|
overlay[k] = fmt.Sprintf("%v", vt)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rs.ConnInfo = overlay
|
rs.Primary.Ephemeral.ConnInfo = overlay
|
||||||
|
|
||||||
// Invoke the Provisioner
|
// Invoke the Provisioner
|
||||||
for _, h := range c.hooks {
|
for _, h := range c.hooks {
|
||||||
@ -778,16 +769,16 @@ func (c *Context) planWalkFn(result *Plan) depgraph.WalkFunc {
|
|||||||
diff.Destroy = true
|
diff.Destroy = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if diff.RequiresNew() && r.State.ID != "" {
|
if diff.RequiresNew() && r.State.Primary.ID != "" {
|
||||||
// This will also require a destroy
|
// This will also require a destroy
|
||||||
diff.Destroy = true
|
diff.Destroy = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if diff.RequiresNew() || r.State.ID == "" {
|
if diff.RequiresNew() || r.State.Primary.ID == "" {
|
||||||
// Add diff to compute new ID
|
// Add diff to compute new ID
|
||||||
diff.init()
|
diff.init()
|
||||||
diff.Attributes["id"] = &ResourceAttrDiff{
|
diff.Attributes["id"] = &ResourceAttrDiff{
|
||||||
Old: r.State.Attributes["id"],
|
Old: r.State.Primary.Attributes["id"],
|
||||||
NewComputed: true,
|
NewComputed: true,
|
||||||
RequiresNew: true,
|
RequiresNew: true,
|
||||||
Type: DiffAttrOutput,
|
Type: DiffAttrOutput,
|
||||||
@ -812,7 +803,10 @@ func (c *Context) planWalkFn(result *Plan) depgraph.WalkFunc {
|
|||||||
// Update our internal state so that variable computation works
|
// Update our internal state so that variable computation works
|
||||||
c.sl.Lock()
|
c.sl.Lock()
|
||||||
defer c.sl.Unlock()
|
defer c.sl.Unlock()
|
||||||
c.state.Resources[r.Id] = r.State
|
|
||||||
|
// TODO: Handle other modules
|
||||||
|
mod := c.state.RootModule()
|
||||||
|
mod.Resources[r.Id] = r.State
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -833,7 +827,7 @@ func (c *Context) planDestroyWalkFn(result *Plan) depgraph.WalkFunc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
r := rn.Resource
|
r := rn.Resource
|
||||||
if r.State.ID != "" {
|
if r.State.Primary.ID != "" {
|
||||||
log.Printf("[DEBUG] %s: Making for destroy", r.Id)
|
log.Printf("[DEBUG] %s: Making for destroy", r.Id)
|
||||||
|
|
||||||
l.Lock()
|
l.Lock()
|
||||||
@ -849,7 +843,7 @@ func (c *Context) planDestroyWalkFn(result *Plan) depgraph.WalkFunc {
|
|||||||
|
|
||||||
func (c *Context) refreshWalkFn() depgraph.WalkFunc {
|
func (c *Context) refreshWalkFn() depgraph.WalkFunc {
|
||||||
cb := func(r *Resource) error {
|
cb := func(r *Resource) error {
|
||||||
if r.State.ID == "" {
|
if r.State.Primary.ID == "" {
|
||||||
log.Printf("[DEBUG] %s: Not refreshing, ID is empty", r.Id)
|
log.Printf("[DEBUG] %s: Not refreshing, ID is empty", r.Id)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -870,10 +864,13 @@ func (c *Context) refreshWalkFn() depgraph.WalkFunc {
|
|||||||
rs.Type = r.State.Type
|
rs.Type = r.State.Type
|
||||||
|
|
||||||
c.sl.Lock()
|
c.sl.Lock()
|
||||||
if rs.ID == "" {
|
|
||||||
delete(c.state.Resources, r.Id)
|
// TODO: Handle other moduels
|
||||||
|
mod := c.state.RootModule()
|
||||||
|
if rs.Primary.ID == "" {
|
||||||
|
delete(mod.Resources, r.Id)
|
||||||
} else {
|
} else {
|
||||||
c.state.Resources[r.Id] = rs
|
mod.Resources[r.Id] = rs
|
||||||
}
|
}
|
||||||
c.sl.Unlock()
|
c.sl.Unlock()
|
||||||
|
|
||||||
|
@ -5,6 +5,8 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform/config"
|
||||||
)
|
)
|
||||||
|
|
||||||
// rootModulePath is the path of the root module
|
// rootModulePath is the path of the root module
|
||||||
@ -82,6 +84,15 @@ type ModuleState struct {
|
|||||||
Resources map[string]*ResourceState `json:"resources"`
|
Resources map[string]*ResourceState `json:"resources"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *ModuleState) init() {
|
||||||
|
if m.Outputs == nil {
|
||||||
|
m.Outputs = make(map[string]stirng)
|
||||||
|
}
|
||||||
|
if m.Resources == nil {
|
||||||
|
m.Resources = make(map[string]*ResourceState)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (m *ModuleState) deepcopy() *ModuleState {
|
func (m *ModuleState) deepcopy() *ModuleState {
|
||||||
n := &ModuleState{
|
n := &ModuleState{
|
||||||
Path: make([]string, len(m.Path)),
|
Path: make([]string, len(m.Path)),
|
||||||
@ -154,6 +165,13 @@ type ResourceState struct {
|
|||||||
Tainted []*InstanceState `json:"tainted,omitempty"`
|
Tainted []*InstanceState `json:"tainted,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *ResourceState) init() {
|
||||||
|
if i.Primary == nil {
|
||||||
|
i.Primary = &InstanceState{}
|
||||||
|
i.Primary.init()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (r *ResourceState) deepcopy() *ResourceState {
|
func (r *ResourceState) deepcopy() *ResourceState {
|
||||||
n := &ResourceState{
|
n := &ResourceState{
|
||||||
Type: r.Type,
|
Type: r.Type,
|
||||||
@ -181,6 +199,44 @@ func (r *ResourceState) prune() {
|
|||||||
r.Instances = r.Instances[:n]
|
r.Instances = r.Instances[:n]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MergeDiff takes a ResourceDiff and merges the attributes into
|
||||||
|
// this resource state in order to generate a new state. This new
|
||||||
|
// state can be used to provide updated attribute lookups for
|
||||||
|
// variable interpolation.
|
||||||
|
//
|
||||||
|
// If the diff attribute requires computing the value, and hence
|
||||||
|
// won't be available until apply, the value is replaced with the
|
||||||
|
// computeID.
|
||||||
|
func (s *ResourceState) MergeDiff(d *ResourceDiff) *ResourceState {
|
||||||
|
var result ResourceState
|
||||||
|
if s != nil {
|
||||||
|
result = *s
|
||||||
|
}
|
||||||
|
result.init()
|
||||||
|
|
||||||
|
if s != nil {
|
||||||
|
for k, v := range s.Primary.Attributes {
|
||||||
|
result.Primary.Attributes[k] = v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if d != nil {
|
||||||
|
for k, diff := range d.Attributes {
|
||||||
|
if diff.NewRemoved {
|
||||||
|
delete(result.Primary.Attributes, k)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if diff.NewComputed {
|
||||||
|
result.Primary.Attributes[k] = config.UnknownVariableValue
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
result.Primary.Attributes[k] = diff.New
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return &result
|
||||||
|
}
|
||||||
|
|
||||||
// InstanceState is used to track the unique state information belonging
|
// InstanceState is used to track the unique state information belonging
|
||||||
// to a given instance.
|
// to a given instance.
|
||||||
type InstanceState struct {
|
type InstanceState struct {
|
||||||
@ -204,6 +260,13 @@ type InstanceState struct {
|
|||||||
Ephemeral EphemeralState `json:"-"`
|
Ephemeral EphemeralState `json:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (i *InstanceState) init() {
|
||||||
|
if i.Attributes == nil {
|
||||||
|
i.Attributes = make(map[string]string)
|
||||||
|
}
|
||||||
|
i.Ephemeral.init()
|
||||||
|
}
|
||||||
|
|
||||||
func (i *InstanceState) deepcopy() *InstanceState {
|
func (i *InstanceState) deepcopy() *InstanceState {
|
||||||
n := &InstanceState{
|
n := &InstanceState{
|
||||||
ID: i.ID,
|
ID: i.ID,
|
||||||
|
Loading…
Reference in New Issue
Block a user