func()

in resource/context.go [119:259]


func (c *Context) AddAzapiDefinition(input types.AzapiDefinition) error {
	logrus.Debugf("adding azapi definition: \n%v", input)
	if c.azapiAddingMap[input.Identifier()] {
		return fmt.Errorf("azapi definition already added: %v", input.Identifier())
	}
	c.azapiAddingMap[input.Identifier()] = true
	defer func() {
		c.azapiAddingMap[input.Identifier()] = false
	}()
	def := input.DeepCopy()
	// find all id placeholders from def
	placeHolders := make([]types.PropertyDependencyMapping, 0)
	rootFields := []string{"parent_id", "resource_id"}
	for _, field := range rootFields {
		if value, ok := def.AdditionalFields[field]; ok {
			if literalValue, ok := value.(types.StringLiteralValue); ok {
				placeHolders = append(placeHolders, types.PropertyDependencyMapping{
					ValuePath:    field,
					LiteralValue: literalValue.Literal,
				})
			}
		}
	}
	if def.Body != nil {
		mappings := GetKeyValueMappings(def.Body, "")
		for _, mapping := range mappings {
			if utils.IsResourceId(mapping.LiteralValue) {
				placeHolders = append(placeHolders, mapping)
			}
		}
	}
	logrus.Debugf("found %d id placeholders", len(placeHolders))

	// find all dependencies that match the id placeholders
	for i, placeHolder := range placeHolders {
		logrus.Debugf("processing id placeholder: %s", placeHolder.LiteralValue)
		if utils.IsAction(placeHolder.LiteralValue) {
			logrus.Debugf("skip action: %s", placeHolder.LiteralValue)
			continue
		}

		pattern := dependency.NewPattern(placeHolder.LiteralValue)

		for _, resolver := range c.ReferenceResolvers {
			result, err := resolver.Resolve(pattern)
			if err != nil {
				return err
			}
			if result == nil {
				continue
			}
			logrus.Debugf("found dependency by resolver: %T", resolver)
			switch {
			case result.Reference.IsKnown():
				placeHolders[i].Reference = result.Reference
				logrus.Debugf("dependency resolved, ref: %v", result.Reference)
			case result.HclToAdd != "":
				logrus.Debugf("found dependency:\n %v", result.HclToAdd)
				ref, err := c.AddHcl(result.HclToAdd, true)
				if err != nil {
					logrus.Warnf("failed to add hcl as a dependency, will continue to try other dependency resolvers: %v", err)
					continue
				}
				c.KnownPatternMap[pattern.String()] = *ref
				placeHolders[i].Reference = ref
				logrus.Debugf("dependency resolved, ref: %v", ref)
			case result.AzapiDefinitionToAdd != nil:
				logrus.Debugf("found dependency:\n %v", result.AzapiDefinitionToAdd)
				err = c.AddAzapiDefinition(*result.AzapiDefinitionToAdd)
				if err != nil {
					logrus.Warnf("failed to add azapi definition as a dependency, will continue to try other dependency resolvers: %v", err)
					continue
				}
				ref := c.KnownPatternMap[pattern.String()]
				if !ref.IsKnown() {
					return fmt.Errorf("resource type address not found: %v after adding azapi definition to the context, azapi def: %v", pattern, result.AzapiDefinitionToAdd)
				}
				placeHolders[i].Reference = &ref
				logrus.Debugf("dependency resolved, ref: %v", ref)
			}
			break
		}
	}

	// replace the id placeholders with the dependency address
	logrus.Debugf("replacing id placeholders with dependency address...")
	for _, filed := range rootFields {
		for _, placeHolder := range placeHolders {
			if placeHolder.ValuePath == filed && placeHolder.Reference.IsKnown() {
				def.AdditionalFields[filed] = types.NewReferenceValue(placeHolder.Reference.String())
				break
			}
		}
	}
	if def.Body != nil {
		replacements := make(map[string]string)
		for _, placeHolder := range placeHolders {
			if !placeHolder.Reference.IsKnown() {
				continue
			}
			valuePath := placeHolder.ValuePath
			if placeHolder.IsKey {
				valuePath = fmt.Sprintf("key:%s", placeHolder.ValuePath)
			}
			replacements[valuePath] = fmt.Sprintf(`${%s}`, placeHolder.Reference)
		}
		def.Body = utils.UpdatedBody(def.Body, replacements, "")
	}

	// add extra dependencies
	if def.ResourceName == "azapi_resource_list" {
		logrus.Debugf("adding extra dependencies for azapi_resource_list...")
		var ref *types.Reference
		for pattern, r := range c.KnownPatternMap {
			if strings.HasSuffix(pattern, strings.ToLower(":"+def.AzureResourceType)) {
				ref = &r
				break
			}
		}
		if ref.IsKnown() {
			addr := fmt.Sprintf(`%s.%s`, ref.Name, ref.Label)
			if ref.Kind == "data" {
				addr = fmt.Sprintf(`data.%s.%s`, ref.Name, ref.Label)
			}
			def.AdditionalFields["depends_on"] = types.NewRawValue(fmt.Sprintf(`[%s]`, addr))
		} else {
			logrus.Debugf("no `depends_on` dependency found for azapi_resource_list: %v", def)
		}
	}

	ref, err := c.AddHcl(def.String(), false)
	if err != nil {
		return err
	}
	if def.AdditionalFields["action"] == nil && def.ResourceName != "azapi_resource_list" {
		pattern := dependency.NewPattern(def.Id)
		c.KnownPatternMap[pattern.String()] = *ref
		logrus.Debugf("adding known pattern: %s, ref: %s", pattern, *ref)
	}
	return nil
}