Exemplo n.º 1
0
// configGraph turns a configuration structure into a dependency graph.
func graphAddConfigResources(
	g *depgraph.Graph, c *config.Config, s *State) {
	// This tracks all the resource nouns
	nouns := make(map[string]*depgraph.Noun)
	for _, r := range c.Resources {
		resourceNouns := make([]*depgraph.Noun, r.Count)
		for i := 0; i < r.Count; i++ {
			name := r.Id()
			index := -1

			// If we have a count that is more than one, then make sure
			// we suffix with the number of the resource that this is.
			if r.Count > 1 {
				name = fmt.Sprintf("%s.%d", name, i)
				index = i
			}

			// Determine if this resource is tainted
			tainted := false
			if s != nil && s.Tainted != nil {
				_, tainted = s.Tainted[r.Id()]
			}

			var state *ResourceState
			if s != nil {
				state = s.Resources[name]

				if state == nil {
					if r.Count == 1 {
						// If the count is one, check the state for ".0"
						// appended, which might exist if we go from
						// count > 1 to count == 1.
						state = s.Resources[r.Id()+".0"]
					} else if i == 0 {
						// If count is greater than one, check for state
						// with just the ID, which might exist if we go
						// from count == 1 to count > 1
						state = s.Resources[r.Id()]
					}
				}
			}
			if state == nil {
				state = &ResourceState{
					Type: r.Type,
				}
			}

			resourceNouns[i] = &depgraph.Noun{
				Name: name,
				Meta: &GraphNodeResource{
					Index:  index,
					Type:   r.Type,
					Config: r,
					Resource: &Resource{
						Id:      name,
						State:   state,
						Config:  NewResourceConfig(r.RawConfig),
						Tainted: tainted,
					},
				},
			}
		}

		// If we have more than one, then create a meta node to track
		// the resources.
		if r.Count > 1 {
			metaNoun := &depgraph.Noun{
				Name: r.Id(),
				Meta: &GraphNodeResourceMeta{
					ID:    r.Id(),
					Name:  r.Name,
					Type:  r.Type,
					Count: r.Count,
				},
			}

			// Create the dependencies on this noun
			for _, n := range resourceNouns {
				metaNoun.Deps = append(metaNoun.Deps, &depgraph.Dependency{
					Name:   n.Name,
					Source: metaNoun,
					Target: n,
				})
			}

			// Assign it to the map so that we have it
			nouns[metaNoun.Name] = metaNoun
		}

		for _, n := range resourceNouns {
			nouns[n.Name] = n
		}
	}

	// Build the list of nouns that we iterate over
	nounsList := make([]*depgraph.Noun, 0, len(nouns))
	for _, n := range nouns {
		nounsList = append(nounsList, n)
	}

	g.Name = "terraform"
	g.Nouns = append(g.Nouns, nounsList...)
}