Esempio n. 1
0
// State returns the new InstanceState after the diff and any Set
// calls.
func (d *ResourceData) State() *terraform.InstanceState {
	var result terraform.InstanceState
	result.ID = d.Id()
	result.Meta = d.meta

	// If we have no ID, then this resource doesn't exist and we just
	// return nil.
	if result.ID == "" {
		return nil
	}

	// Look for a magic key in the schema that determines we skip the
	// integrity check of fields existing in the schema, allowing dynamic
	// keys to be created.
	hasDynamicAttributes := false
	for k, _ := range d.schema {
		if k == "__has_dynamic_attributes" {
			hasDynamicAttributes = true
			log.Printf("[INFO] Resource %s has dynamic attributes", result.ID)
		}
	}

	// In order to build the final state attributes, we read the full
	// attribute set as a map[string]interface{}, write it to a MapFieldWriter,
	// and then use that map.
	rawMap := make(map[string]interface{})
	for k := range d.schema {
		source := getSourceSet
		if d.partial {
			source = getSourceState
			if _, ok := d.partialMap[k]; ok {
				source = getSourceSet
			}
		}

		raw := d.get([]string{k}, source)
		if raw.Exists && !raw.Computed {
			rawMap[k] = raw.Value
			if raw.ValueProcessed != nil {
				rawMap[k] = raw.ValueProcessed
			}
		}
	}

	mapW := &MapFieldWriter{Schema: d.schema}
	if err := mapW.WriteField(nil, rawMap); err != nil {
		return nil
	}

	result.Attributes = mapW.Map()

	if hasDynamicAttributes {
		// If we have dynamic attributes, just copy the attributes map
		// one for one into the result attributes.
		for k, v := range d.setWriter.Map() {
			// Don't clobber schema values. This limits usage of dynamic
			// attributes to names which _do not_ conflict with schema
			// keys!
			if _, ok := result.Attributes[k]; !ok {
				result.Attributes[k] = v
			}
		}
	}

	if d.newState != nil {
		result.Ephemeral = d.newState.Ephemeral
	}

	// TODO: This is hacky and we can remove this when we have a proper
	// state writer. We should instead have a proper StateFieldWriter
	// and use that.
	for k, schema := range d.schema {
		if schema.Type != TypeMap {
			continue
		}

		if result.Attributes[k] == "" {
			delete(result.Attributes, k)
		}
	}

	if v := d.Id(); v != "" {
		result.Attributes["id"] = d.Id()
	}

	if d.state != nil {
		result.Tainted = d.state.Tainted
	}

	return &result
}
Esempio n. 2
0
// State returns the new InstanceState after the diff and any Set
// calls.
func (d *ResourceData) State() *terraform.InstanceState {
	var result terraform.InstanceState
	result.ID = d.Id()
	result.Meta = d.meta

	// If we have no ID, then this resource doesn't exist and we just
	// return nil.
	if result.ID == "" {
		return nil
	}

	// In order to build the final state attributes, we read the full
	// attribute set as a map[string]interface{}, write it to a MapFieldWriter,
	// and then use that map.
	rawMap := make(map[string]interface{})
	for k := range d.schema {
		source := getSourceSet
		if d.partial {
			source = getSourceState
			if _, ok := d.partialMap[k]; ok {
				source = getSourceSet
			}
		}

		raw := d.get([]string{k}, source)
		if raw.Exists && !raw.Computed {
			rawMap[k] = raw.Value
			if raw.ValueProcessed != nil {
				rawMap[k] = raw.ValueProcessed
			}
		}
	}
	mapW := &MapFieldWriter{Schema: d.schema}
	if err := mapW.WriteField(nil, rawMap); err != nil {
		return nil
	}

	result.Attributes = mapW.Map()
	if d.newState != nil {
		result.Ephemeral = d.newState.Ephemeral
	}

	// TODO: This is hacky and we can remove this when we have a proper
	// state writer. We should instead have a proper StateFieldWriter
	// and use that.
	for k, schema := range d.schema {
		if schema.Type != TypeMap {
			continue
		}

		if result.Attributes[k] == "" {
			delete(result.Attributes, k)
		}
	}

	if v := d.Id(); v != "" {
		result.Attributes["id"] = d.Id()
	}

	if d.state != nil {
		result.Tainted = d.state.Tainted
	}

	return &result
}