2015-03-24 11:18:15 -05:00
|
|
|
package terraform
|
|
|
|
|
2015-05-01 11:01:49 -05:00
|
|
|
import (
|
|
|
|
"log"
|
|
|
|
|
2021-05-17 14:00:50 -05:00
|
|
|
"github.com/hashicorp/terraform/internal/addrs"
|
2021-05-17 11:30:37 -05:00
|
|
|
"github.com/hashicorp/terraform/internal/dag"
|
2015-05-01 11:01:49 -05:00
|
|
|
)
|
2015-03-24 11:18:15 -05:00
|
|
|
|
2017-01-26 22:16:06 -06:00
|
|
|
// GraphNodeTargetable is an interface for graph nodes to implement when they
|
|
|
|
// need to be told about incoming targets. This is useful for nodes that need
|
|
|
|
// to respect targets as they dynamically expand. Note that the list of targets
|
|
|
|
// provided will contain every target provided, and each implementing graph
|
|
|
|
// node must filter this list to targets considered relevant.
|
|
|
|
type GraphNodeTargetable interface {
|
terraform: ugly huge change to weave in new HCL2-oriented types
Due to how deeply the configuration types go into Terraform Core, there
isn't a great way to switch out to HCL2 gradually. As a consequence, this
huge commit gets us from the old state to a _compilable_ new state, but
does not yet attempt to fix any tests and has a number of known missing
parts and bugs. We will continue to iterate on this in forthcoming
commits, heading back towards passing tests and making Terraform
fully-functional again.
The three main goals here are:
- Use the configuration models from the "configs" package instead of the
older models in the "config" package, which is now deprecated and
preserved only to help us write our migration tool.
- Do expression inspection and evaluation using the functionality of the
new "lang" package, instead of the Interpolator type and related
functionality in the main "terraform" package.
- Represent addresses of various objects using types in the addrs package,
rather than hand-constructed strings. This is not critical to support
the above, but was a big help during the implementation of these other
points since it made it much more explicit what kind of address is
expected in each context.
Since our new packages are built to accommodate some future planned
features that are not yet implemented (e.g. the "for_each" argument on
resources, "count"/"for_each" on modules), and since there's still a fair
amount of functionality still using old-style APIs, there is a moderate
amount of shimming here to connect new assumptions with old, hopefully in
a way that makes it easier to find and eliminate these shims later.
I apologize in advance to the person who inevitably just found this huge
commit while spelunking through the commit history.
2018-04-30 12:33:53 -05:00
|
|
|
SetTargets([]addrs.Targetable)
|
2017-01-26 22:16:06 -06:00
|
|
|
}
|
|
|
|
|
2015-03-24 11:18:15 -05:00
|
|
|
// TargetsTransformer is a GraphTransformer that, when the user specifies a
|
|
|
|
// list of resources to target, limits the graph to only those resources and
|
|
|
|
// their dependencies.
|
|
|
|
type TargetsTransformer struct {
|
|
|
|
// List of targeted resource names specified by the user
|
terraform: ugly huge change to weave in new HCL2-oriented types
Due to how deeply the configuration types go into Terraform Core, there
isn't a great way to switch out to HCL2 gradually. As a consequence, this
huge commit gets us from the old state to a _compilable_ new state, but
does not yet attempt to fix any tests and has a number of known missing
parts and bugs. We will continue to iterate on this in forthcoming
commits, heading back towards passing tests and making Terraform
fully-functional again.
The three main goals here are:
- Use the configuration models from the "configs" package instead of the
older models in the "config" package, which is now deprecated and
preserved only to help us write our migration tool.
- Do expression inspection and evaluation using the functionality of the
new "lang" package, instead of the Interpolator type and related
functionality in the main "terraform" package.
- Represent addresses of various objects using types in the addrs package,
rather than hand-constructed strings. This is not critical to support
the above, but was a big help during the implementation of these other
points since it made it much more explicit what kind of address is
expected in each context.
Since our new packages are built to accommodate some future planned
features that are not yet implemented (e.g. the "for_each" argument on
resources, "count"/"for_each" on modules), and since there's still a fair
amount of functionality still using old-style APIs, there is a moderate
amount of shimming here to connect new assumptions with old, hopefully in
a way that makes it easier to find and eliminate these shims later.
I apologize in advance to the person who inevitably just found this huge
commit while spelunking through the commit history.
2018-04-30 12:33:53 -05:00
|
|
|
Targets []addrs.Targetable
|
2015-03-24 11:18:15 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
func (t *TargetsTransformer) Transform(g *Graph) error {
|
terraform: ugly huge change to weave in new HCL2-oriented types
Due to how deeply the configuration types go into Terraform Core, there
isn't a great way to switch out to HCL2 gradually. As a consequence, this
huge commit gets us from the old state to a _compilable_ new state, but
does not yet attempt to fix any tests and has a number of known missing
parts and bugs. We will continue to iterate on this in forthcoming
commits, heading back towards passing tests and making Terraform
fully-functional again.
The three main goals here are:
- Use the configuration models from the "configs" package instead of the
older models in the "config" package, which is now deprecated and
preserved only to help us write our migration tool.
- Do expression inspection and evaluation using the functionality of the
new "lang" package, instead of the Interpolator type and related
functionality in the main "terraform" package.
- Represent addresses of various objects using types in the addrs package,
rather than hand-constructed strings. This is not critical to support
the above, but was a big help during the implementation of these other
points since it made it much more explicit what kind of address is
expected in each context.
Since our new packages are built to accommodate some future planned
features that are not yet implemented (e.g. the "for_each" argument on
resources, "count"/"for_each" on modules), and since there's still a fair
amount of functionality still using old-style APIs, there is a moderate
amount of shimming here to connect new assumptions with old, hopefully in
a way that makes it easier to find and eliminate these shims later.
I apologize in advance to the person who inevitably just found this huge
commit while spelunking through the commit history.
2018-04-30 12:33:53 -05:00
|
|
|
if len(t.Targets) > 0 {
|
|
|
|
targetedNodes, err := t.selectTargetedNodes(g, t.Targets)
|
2015-03-24 11:18:15 -05:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, v := range g.Vertices() {
|
2020-06-24 09:27:52 -05:00
|
|
|
if !targetedNodes.Include(v) {
|
2016-07-29 10:53:13 -05:00
|
|
|
log.Printf("[DEBUG] Removing %q, filtered by targeting.", dag.VertexName(v))
|
|
|
|
g.Remove(v)
|
2015-03-24 11:18:15 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2016-10-20 20:59:02 -05:00
|
|
|
|
2015-03-24 11:18:15 -05:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
terraform: ugly huge change to weave in new HCL2-oriented types
Due to how deeply the configuration types go into Terraform Core, there
isn't a great way to switch out to HCL2 gradually. As a consequence, this
huge commit gets us from the old state to a _compilable_ new state, but
does not yet attempt to fix any tests and has a number of known missing
parts and bugs. We will continue to iterate on this in forthcoming
commits, heading back towards passing tests and making Terraform
fully-functional again.
The three main goals here are:
- Use the configuration models from the "configs" package instead of the
older models in the "config" package, which is now deprecated and
preserved only to help us write our migration tool.
- Do expression inspection and evaluation using the functionality of the
new "lang" package, instead of the Interpolator type and related
functionality in the main "terraform" package.
- Represent addresses of various objects using types in the addrs package,
rather than hand-constructed strings. This is not critical to support
the above, but was a big help during the implementation of these other
points since it made it much more explicit what kind of address is
expected in each context.
Since our new packages are built to accommodate some future planned
features that are not yet implemented (e.g. the "for_each" argument on
resources, "count"/"for_each" on modules), and since there's still a fair
amount of functionality still using old-style APIs, there is a moderate
amount of shimming here to connect new assumptions with old, hopefully in
a way that makes it easier to find and eliminate these shims later.
I apologize in advance to the person who inevitably just found this huge
commit while spelunking through the commit history.
2018-04-30 12:33:53 -05:00
|
|
|
// Returns a set of targeted nodes. A targeted node is either addressed
|
|
|
|
// directly, address indirectly via its container, or it's a dependency of a
|
2020-06-10 14:39:29 -05:00
|
|
|
// targeted node.
|
2020-01-07 16:49:34 -06:00
|
|
|
func (t *TargetsTransformer) selectTargetedNodes(g *Graph, addrs []addrs.Targetable) (dag.Set, error) {
|
|
|
|
targetedNodes := make(dag.Set)
|
2017-05-10 20:27:49 -05:00
|
|
|
|
|
|
|
vertices := g.Vertices()
|
|
|
|
|
|
|
|
for _, v := range vertices {
|
2015-04-15 13:53:32 -05:00
|
|
|
if t.nodeIsTarget(v, addrs) {
|
|
|
|
targetedNodes.Add(v)
|
2015-03-24 11:18:15 -05:00
|
|
|
|
2015-04-15 13:53:32 -05:00
|
|
|
// We inform nodes that ask about the list of targets - helps for nodes
|
|
|
|
// that need to dynamically expand. Note that this only occurs for nodes
|
|
|
|
// that are already directly targeted.
|
|
|
|
if tn, ok := v.(GraphNodeTargetable); ok {
|
|
|
|
tn.SetTargets(addrs)
|
2015-03-30 19:02:36 -05:00
|
|
|
}
|
2015-03-24 11:18:15 -05:00
|
|
|
|
2020-06-24 09:27:52 -05:00
|
|
|
deps, _ := g.Ancestors(v)
|
2020-01-07 16:49:34 -06:00
|
|
|
for _, d := range deps {
|
2015-03-24 11:18:15 -05:00
|
|
|
targetedNodes.Add(d)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2016-10-20 20:59:02 -05:00
|
|
|
|
2020-06-24 09:27:52 -05:00
|
|
|
// It is expected that outputs which are only derived from targeted
|
|
|
|
// resources are also updated. While we don't include any other possible
|
|
|
|
// side effects from the targeted nodes, these are added because outputs
|
|
|
|
// cannot be targeted on their own.
|
|
|
|
// Start by finding the root module output nodes themselves
|
|
|
|
for _, v := range vertices {
|
|
|
|
// outputs are all temporary value types
|
|
|
|
tv, ok := v.(graphNodeTemporaryValue)
|
|
|
|
if !ok {
|
|
|
|
continue
|
|
|
|
}
|
2017-05-10 20:27:49 -05:00
|
|
|
|
2020-06-24 09:27:52 -05:00
|
|
|
// root module outputs indicate that while they are an output type,
|
|
|
|
// they not temporary and will return false here.
|
|
|
|
if tv.temporaryValue() {
|
|
|
|
continue
|
|
|
|
}
|
2017-05-10 20:27:49 -05:00
|
|
|
|
2020-06-24 09:27:52 -05:00
|
|
|
// If this output is descended only from targeted resources, then we
|
|
|
|
// will keep it
|
|
|
|
deps, _ := g.Ancestors(v)
|
|
|
|
found := 0
|
|
|
|
for _, d := range deps {
|
|
|
|
switch d.(type) {
|
|
|
|
case GraphNodeResourceInstance:
|
|
|
|
case GraphNodeConfigResource:
|
|
|
|
default:
|
2017-05-10 20:27:49 -05:00
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
2020-06-24 09:27:52 -05:00
|
|
|
if !targetedNodes.Include(d) {
|
|
|
|
// this dependency isn't being targeted, so we can't process this
|
|
|
|
// output
|
|
|
|
found = 0
|
|
|
|
break
|
2017-05-10 20:27:49 -05:00
|
|
|
}
|
2017-09-27 17:59:48 -05:00
|
|
|
|
2020-06-24 09:27:52 -05:00
|
|
|
found++
|
2017-09-27 17:59:48 -05:00
|
|
|
}
|
2018-03-19 20:20:06 -05:00
|
|
|
|
2020-06-24 09:27:52 -05:00
|
|
|
if found > 0 {
|
|
|
|
// we found an output we can keep; add it, and all it's dependencies
|
|
|
|
targetedNodes.Add(v)
|
|
|
|
for _, d := range deps {
|
|
|
|
targetedNodes.Add(d)
|
|
|
|
}
|
2018-03-19 20:20:06 -05:00
|
|
|
}
|
2017-09-27 17:59:48 -05:00
|
|
|
}
|
|
|
|
|
2020-06-24 09:27:52 -05:00
|
|
|
return targetedNodes, nil
|
2015-03-24 11:18:15 -05:00
|
|
|
}
|
|
|
|
|
terraform: ugly huge change to weave in new HCL2-oriented types
Due to how deeply the configuration types go into Terraform Core, there
isn't a great way to switch out to HCL2 gradually. As a consequence, this
huge commit gets us from the old state to a _compilable_ new state, but
does not yet attempt to fix any tests and has a number of known missing
parts and bugs. We will continue to iterate on this in forthcoming
commits, heading back towards passing tests and making Terraform
fully-functional again.
The three main goals here are:
- Use the configuration models from the "configs" package instead of the
older models in the "config" package, which is now deprecated and
preserved only to help us write our migration tool.
- Do expression inspection and evaluation using the functionality of the
new "lang" package, instead of the Interpolator type and related
functionality in the main "terraform" package.
- Represent addresses of various objects using types in the addrs package,
rather than hand-constructed strings. This is not critical to support
the above, but was a big help during the implementation of these other
points since it made it much more explicit what kind of address is
expected in each context.
Since our new packages are built to accommodate some future planned
features that are not yet implemented (e.g. the "for_each" argument on
resources, "count"/"for_each" on modules), and since there's still a fair
amount of functionality still using old-style APIs, there is a moderate
amount of shimming here to connect new assumptions with old, hopefully in
a way that makes it easier to find and eliminate these shims later.
I apologize in advance to the person who inevitably just found this huge
commit while spelunking through the commit history.
2018-04-30 12:33:53 -05:00
|
|
|
func (t *TargetsTransformer) nodeIsTarget(v dag.Vertex, targets []addrs.Targetable) bool {
|
|
|
|
var vertexAddr addrs.Targetable
|
|
|
|
switch r := v.(type) {
|
|
|
|
case GraphNodeResourceInstance:
|
|
|
|
vertexAddr = r.ResourceInstanceAddr()
|
2020-03-15 10:32:06 -05:00
|
|
|
case GraphNodeConfigResource:
|
terraform: ugly huge change to weave in new HCL2-oriented types
Due to how deeply the configuration types go into Terraform Core, there
isn't a great way to switch out to HCL2 gradually. As a consequence, this
huge commit gets us from the old state to a _compilable_ new state, but
does not yet attempt to fix any tests and has a number of known missing
parts and bugs. We will continue to iterate on this in forthcoming
commits, heading back towards passing tests and making Terraform
fully-functional again.
The three main goals here are:
- Use the configuration models from the "configs" package instead of the
older models in the "config" package, which is now deprecated and
preserved only to help us write our migration tool.
- Do expression inspection and evaluation using the functionality of the
new "lang" package, instead of the Interpolator type and related
functionality in the main "terraform" package.
- Represent addresses of various objects using types in the addrs package,
rather than hand-constructed strings. This is not critical to support
the above, but was a big help during the implementation of these other
points since it made it much more explicit what kind of address is
expected in each context.
Since our new packages are built to accommodate some future planned
features that are not yet implemented (e.g. the "for_each" argument on
resources, "count"/"for_each" on modules), and since there's still a fair
amount of functionality still using old-style APIs, there is a moderate
amount of shimming here to connect new assumptions with old, hopefully in
a way that makes it easier to find and eliminate these shims later.
I apologize in advance to the person who inevitably just found this huge
commit while spelunking through the commit history.
2018-04-30 12:33:53 -05:00
|
|
|
vertexAddr = r.ResourceAddr()
|
2020-08-05 16:50:23 -05:00
|
|
|
|
terraform: ugly huge change to weave in new HCL2-oriented types
Due to how deeply the configuration types go into Terraform Core, there
isn't a great way to switch out to HCL2 gradually. As a consequence, this
huge commit gets us from the old state to a _compilable_ new state, but
does not yet attempt to fix any tests and has a number of known missing
parts and bugs. We will continue to iterate on this in forthcoming
commits, heading back towards passing tests and making Terraform
fully-functional again.
The three main goals here are:
- Use the configuration models from the "configs" package instead of the
older models in the "config" package, which is now deprecated and
preserved only to help us write our migration tool.
- Do expression inspection and evaluation using the functionality of the
new "lang" package, instead of the Interpolator type and related
functionality in the main "terraform" package.
- Represent addresses of various objects using types in the addrs package,
rather than hand-constructed strings. This is not critical to support
the above, but was a big help during the implementation of these other
points since it made it much more explicit what kind of address is
expected in each context.
Since our new packages are built to accommodate some future planned
features that are not yet implemented (e.g. the "for_each" argument on
resources, "count"/"for_each" on modules), and since there's still a fair
amount of functionality still using old-style APIs, there is a moderate
amount of shimming here to connect new assumptions with old, hopefully in
a way that makes it easier to find and eliminate these shims later.
I apologize in advance to the person who inevitably just found this huge
commit while spelunking through the commit history.
2018-04-30 12:33:53 -05:00
|
|
|
default:
|
|
|
|
// Only resource and resource instance nodes can be targeted.
|
|
|
|
return false
|
|
|
|
}
|
2016-10-20 20:59:02 -05:00
|
|
|
|
terraform: ugly huge change to weave in new HCL2-oriented types
Due to how deeply the configuration types go into Terraform Core, there
isn't a great way to switch out to HCL2 gradually. As a consequence, this
huge commit gets us from the old state to a _compilable_ new state, but
does not yet attempt to fix any tests and has a number of known missing
parts and bugs. We will continue to iterate on this in forthcoming
commits, heading back towards passing tests and making Terraform
fully-functional again.
The three main goals here are:
- Use the configuration models from the "configs" package instead of the
older models in the "config" package, which is now deprecated and
preserved only to help us write our migration tool.
- Do expression inspection and evaluation using the functionality of the
new "lang" package, instead of the Interpolator type and related
functionality in the main "terraform" package.
- Represent addresses of various objects using types in the addrs package,
rather than hand-constructed strings. This is not critical to support
the above, but was a big help during the implementation of these other
points since it made it much more explicit what kind of address is
expected in each context.
Since our new packages are built to accommodate some future planned
features that are not yet implemented (e.g. the "for_each" argument on
resources, "count"/"for_each" on modules), and since there's still a fair
amount of functionality still using old-style APIs, there is a moderate
amount of shimming here to connect new assumptions with old, hopefully in
a way that makes it easier to find and eliminate these shims later.
I apologize in advance to the person who inevitably just found this huge
commit while spelunking through the commit history.
2018-04-30 12:33:53 -05:00
|
|
|
for _, targetAddr := range targets {
|
2020-08-05 16:50:23 -05:00
|
|
|
switch vertexAddr.(type) {
|
|
|
|
case addrs.ConfigResource:
|
|
|
|
// Before expansion happens, we only have nodes that know their
|
|
|
|
// ConfigResource address. We need to take the more specific
|
|
|
|
// target addresses and generalize them in order to compare with a
|
|
|
|
// ConfigResource.
|
|
|
|
switch target := targetAddr.(type) {
|
2020-06-10 14:39:29 -05:00
|
|
|
case addrs.AbsResourceInstance:
|
2020-08-05 16:50:23 -05:00
|
|
|
targetAddr = target.ContainingResource().Config()
|
|
|
|
case addrs.AbsResource:
|
|
|
|
targetAddr = target.Config()
|
2020-08-10 11:16:20 -05:00
|
|
|
case addrs.ModuleInstance:
|
|
|
|
targetAddr = target.Module()
|
terraform: ugly huge change to weave in new HCL2-oriented types
Due to how deeply the configuration types go into Terraform Core, there
isn't a great way to switch out to HCL2 gradually. As a consequence, this
huge commit gets us from the old state to a _compilable_ new state, but
does not yet attempt to fix any tests and has a number of known missing
parts and bugs. We will continue to iterate on this in forthcoming
commits, heading back towards passing tests and making Terraform
fully-functional again.
The three main goals here are:
- Use the configuration models from the "configs" package instead of the
older models in the "config" package, which is now deprecated and
preserved only to help us write our migration tool.
- Do expression inspection and evaluation using the functionality of the
new "lang" package, instead of the Interpolator type and related
functionality in the main "terraform" package.
- Represent addresses of various objects using types in the addrs package,
rather than hand-constructed strings. This is not critical to support
the above, but was a big help during the implementation of these other
points since it made it much more explicit what kind of address is
expected in each context.
Since our new packages are built to accommodate some future planned
features that are not yet implemented (e.g. the "for_each" argument on
resources, "count"/"for_each" on modules), and since there's still a fair
amount of functionality still using old-style APIs, there is a moderate
amount of shimming here to connect new assumptions with old, hopefully in
a way that makes it easier to find and eliminate these shims later.
I apologize in advance to the person who inevitably just found this huge
commit while spelunking through the commit history.
2018-04-30 12:33:53 -05:00
|
|
|
}
|
core: -target option to also select resources in descendant modules
Previously the behavior for -target when given a module address was to
target only resources directly within that module, ignoring any resources
defined in child modules.
This behavior turned out to be counter-intuitive, since users expected
the -target address to be interpreted hierarchically.
We'll now use the new "Contains" function for addresses, which provides
a hierarchical "containment" concept that is more consistent with user
expectations. In particular, it allows module.foo to match
module.foo.module.bar.aws_instance.baz, where before that would not have
been true.
Since Contains isn't commutative (unlike Equals) this requires some
special handling for targeting specific indices. When given an argument
like -target=aws_instance.foo[0], the initial graph construction (for
both plan and refresh) is for the resource nodes from configuration, which
have not yet been expanded to separate indexed instances. Thus we need
to do the first pass of TargetsTransformer in mode where indices are
ignored, with the work then completed by the DynamicExpand method which
re-applies the TargetsTransformer in index-sensitive mode.
This is a breaking change for anyone depending on the previous behavior
of -target, since it will now select more resources than before. There is
no way provided to obtain the previous behavior. Eventually we may support
negative targeting, which could then combine with positive targets to
regain the previous behavior as an explicit choice.
2017-06-15 20:15:41 -05:00
|
|
|
}
|
2020-08-05 16:50:23 -05:00
|
|
|
|
terraform: ugly huge change to weave in new HCL2-oriented types
Due to how deeply the configuration types go into Terraform Core, there
isn't a great way to switch out to HCL2 gradually. As a consequence, this
huge commit gets us from the old state to a _compilable_ new state, but
does not yet attempt to fix any tests and has a number of known missing
parts and bugs. We will continue to iterate on this in forthcoming
commits, heading back towards passing tests and making Terraform
fully-functional again.
The three main goals here are:
- Use the configuration models from the "configs" package instead of the
older models in the "config" package, which is now deprecated and
preserved only to help us write our migration tool.
- Do expression inspection and evaluation using the functionality of the
new "lang" package, instead of the Interpolator type and related
functionality in the main "terraform" package.
- Represent addresses of various objects using types in the addrs package,
rather than hand-constructed strings. This is not critical to support
the above, but was a big help during the implementation of these other
points since it made it much more explicit what kind of address is
expected in each context.
Since our new packages are built to accommodate some future planned
features that are not yet implemented (e.g. the "for_each" argument on
resources, "count"/"for_each" on modules), and since there's still a fair
amount of functionality still using old-style APIs, there is a moderate
amount of shimming here to connect new assumptions with old, hopefully in
a way that makes it easier to find and eliminate these shims later.
I apologize in advance to the person who inevitably just found this huge
commit while spelunking through the commit history.
2018-04-30 12:33:53 -05:00
|
|
|
if targetAddr.TargetContains(vertexAddr) {
|
2015-03-24 11:18:15 -05:00
|
|
|
return true
|
|
|
|
}
|
|
|
|
}
|
2016-10-20 20:59:02 -05:00
|
|
|
|
2015-03-24 11:18:15 -05:00
|
|
|
return false
|
|
|
|
}
|