internal/langserver/handlers/command/arm_template_expression.go (93 lines of code) (raw):

package command import ( "fmt" "strings" "github.com/expr-lang/expr" ) func flattenARMExpression(input interface{}) interface{} { if input == nil { return nil } switch v := input.(type) { case map[string]interface{}: res := make(map[string]interface{}) for key, value := range v { res[key] = flattenARMExpression(value) } return res case []interface{}: res := make([]interface{}, 0) for _, value := range v { res = append(res, flattenARMExpression(value)) } return res case string: if strings.HasPrefix(v, "[") && strings.HasSuffix(v, "]") { if output, err := evaluateARMTemplateExpression(v[1 : len(v)-1]); err == nil { return output } } return v default: return v } } func evaluateARMTemplateExpression(input string) (string, error) { env := map[string]interface{}{ "resourceId": func(input ...string) string { resourceType := "" subscriptionId := "var.subscriptionId" resourceGroupName := "var.resourceGroupName" index := -1 for i, v := range input { if strings.Contains(v, "/") { resourceType = v index = i break } } switch index { case -1: return "resourceId" case 1: resourceGroupName = input[0] case 2: subscriptionId = input[0] resourceGroupName = input[1] } scopeId := fmt.Sprintf("/subscriptions/${%s}/resourceGroups/${%s}", subscriptionId, resourceGroupName) parts := strings.Split(resourceType, "/") resourceId := fmt.Sprintf("%s/providers/%s", scopeId, parts[0]) for i := 1; i < len(parts); i++ { name := "" if inputIndex := index + i; inputIndex < len(input) { name = input[inputIndex] } resourceId = fmt.Sprintf("%s/%s/%s", resourceId, parts[i], name) } return resourceId }, "parameters": func(name string) string { return fmt.Sprintf("${var.%s}", name) }, "concat": func(input ...string) string { return strings.Join(input, "") }, } program, err := expr.Compile(input, expr.Env(env)) if err != nil { return "", err } output, err := expr.Run(program, env) if err != nil { return "", err } if output == nil { return "", fmt.Errorf("output is nil") } v, ok := output.(string) if !ok { return "", fmt.Errorf("output is not string") } return v, nil }