github.com/r3labs/terraform@v0.8.4/terraform/node_resource_abstract.go (about)

     1  package terraform
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/hashicorp/terraform/config"
     7  	"github.com/hashicorp/terraform/dag"
     8  )
     9  
    10  // ConcreteResourceNodeFunc is a callback type used to convert an
    11  // abstract resource to a concrete one of some type.
    12  type ConcreteResourceNodeFunc func(*NodeAbstractResource) dag.Vertex
    13  
    14  // GraphNodeResource is implemented by any nodes that represent a resource.
    15  // The type of operation cannot be assumed, only that this node represents
    16  // the given resource.
    17  type GraphNodeResource interface {
    18  	ResourceAddr() *ResourceAddress
    19  }
    20  
    21  // NodeAbstractResource represents a resource that has no associated
    22  // operations. It registers all the interfaces for a resource that common
    23  // across multiple operation types.
    24  type NodeAbstractResource struct {
    25  	Addr *ResourceAddress // Addr is the address for this resource
    26  
    27  	// The fields below will be automatically set using the Attach
    28  	// interfaces if you're running those transforms, but also be explicitly
    29  	// set if you already have that information.
    30  
    31  	Config        *config.Resource // Config is the resource in the config
    32  	ResourceState *ResourceState   // ResourceState is the ResourceState for this
    33  
    34  	Targets []ResourceAddress // Set from GraphNodeTargetable
    35  }
    36  
    37  func (n *NodeAbstractResource) Name() string {
    38  	return n.Addr.String()
    39  }
    40  
    41  // GraphNodeSubPath
    42  func (n *NodeAbstractResource) Path() []string {
    43  	return n.Addr.Path
    44  }
    45  
    46  // GraphNodeReferenceable
    47  func (n *NodeAbstractResource) ReferenceableName() []string {
    48  	// We always are referenceable as "type.name" as long as
    49  	// we have a config or address. Determine what that value is.
    50  	var id string
    51  	if n.Config != nil {
    52  		id = n.Config.Id()
    53  	} else if n.Addr != nil {
    54  		addrCopy := n.Addr.Copy()
    55  		addrCopy.Index = -1
    56  		id = addrCopy.String()
    57  	} else {
    58  		// No way to determine our type.name, just return
    59  		return nil
    60  	}
    61  
    62  	var result []string
    63  
    64  	// Always include our own ID. This is primarily for backwards
    65  	// compatibility with states that didn't yet support the more
    66  	// specific dep string.
    67  	result = append(result, id)
    68  
    69  	// We represent all multi-access
    70  	result = append(result, fmt.Sprintf("%s.*", id))
    71  
    72  	// We represent either a specific number, or all numbers
    73  	suffix := "N"
    74  	if n.Addr != nil {
    75  		idx := n.Addr.Index
    76  		if idx == -1 {
    77  			idx = 0
    78  		}
    79  
    80  		suffix = fmt.Sprintf("%d", idx)
    81  	}
    82  	result = append(result, fmt.Sprintf("%s.%s", id, suffix))
    83  
    84  	return result
    85  }
    86  
    87  // GraphNodeReferencer
    88  func (n *NodeAbstractResource) References() []string {
    89  	// If we have a config, that is our source of truth
    90  	if c := n.Config; c != nil {
    91  		// Grab all the references
    92  		var result []string
    93  		result = append(result, c.DependsOn...)
    94  		result = append(result, ReferencesFromConfig(c.RawCount)...)
    95  		result = append(result, ReferencesFromConfig(c.RawConfig)...)
    96  		for _, p := range c.Provisioners {
    97  			result = append(result, ReferencesFromConfig(p.ConnInfo)...)
    98  			result = append(result, ReferencesFromConfig(p.RawConfig)...)
    99  		}
   100  
   101  		return result
   102  	}
   103  
   104  	// If we have state, that is our next source
   105  	if s := n.ResourceState; s != nil {
   106  		return s.Dependencies
   107  	}
   108  
   109  	return nil
   110  }
   111  
   112  // GraphNodeProviderConsumer
   113  func (n *NodeAbstractResource) ProvidedBy() []string {
   114  	// If we have a config we prefer that above all else
   115  	if n.Config != nil {
   116  		return []string{resourceProvider(n.Config.Type, n.Config.Provider)}
   117  	}
   118  
   119  	// If we have state, then we will use the provider from there
   120  	if n.ResourceState != nil && n.ResourceState.Provider != "" {
   121  		return []string{n.ResourceState.Provider}
   122  	}
   123  
   124  	// Use our type
   125  	return []string{resourceProvider(n.Addr.Type, "")}
   126  }
   127  
   128  // GraphNodeProvisionerConsumer
   129  func (n *NodeAbstractResource) ProvisionedBy() []string {
   130  	// If we have no configuration, then we have no provisioners
   131  	if n.Config == nil {
   132  		return nil
   133  	}
   134  
   135  	// Build the list of provisioners we need based on the configuration.
   136  	// It is okay to have duplicates here.
   137  	result := make([]string, len(n.Config.Provisioners))
   138  	for i, p := range n.Config.Provisioners {
   139  		result[i] = p.Type
   140  	}
   141  
   142  	return result
   143  }
   144  
   145  // GraphNodeResource, GraphNodeAttachResourceState
   146  func (n *NodeAbstractResource) ResourceAddr() *ResourceAddress {
   147  	return n.Addr
   148  }
   149  
   150  // GraphNodeAddressable, TODO: remove, used by target, should unify
   151  func (n *NodeAbstractResource) ResourceAddress() *ResourceAddress {
   152  	return n.ResourceAddr()
   153  }
   154  
   155  // GraphNodeTargetable
   156  func (n *NodeAbstractResource) SetTargets(targets []ResourceAddress) {
   157  	n.Targets = targets
   158  }
   159  
   160  // GraphNodeAttachResourceState
   161  func (n *NodeAbstractResource) AttachResourceState(s *ResourceState) {
   162  	n.ResourceState = s
   163  }
   164  
   165  // GraphNodeAttachResourceConfig
   166  func (n *NodeAbstractResource) AttachResourceConfig(c *config.Resource) {
   167  	n.Config = c
   168  }
   169  
   170  // GraphNodeDotter impl.
   171  func (n *NodeAbstractResource) DotNode(name string, opts *dag.DotOpts) *dag.DotNode {
   172  	return &dag.DotNode{
   173  		Name: name,
   174  		Attrs: map[string]string{
   175  			"label": n.Name(),
   176  			"shape": "box",
   177  		},
   178  	}
   179  }