parent
712f8edf9e
commit
6932f9d305
@ -1,4 +1,4 @@
|
|||||||
## Version 4.3.4
|
## Version 4.3.5
|
||||||
|
|
||||||
## Bugfixes
|
## Feature
|
||||||
- Fixed bug with resource decort_cb_extnet: extnet did not switct status to "ENABLED" if field enable=true while resource create.
|
- Added state upgrader for custom_fields field upgrade in kvmvm resource
|
@ -0,0 +1,550 @@
|
|||||||
|
package kvmvm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||||
|
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
|
||||||
|
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants"
|
||||||
|
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/statefuncs"
|
||||||
|
)
|
||||||
|
|
||||||
|
func resourceComputeResourceV1() *schema.Resource {
|
||||||
|
return &schema.Resource{
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"name": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
Description: "Name of this compute. Compute names are case sensitive and must be unique in the resource group.",
|
||||||
|
},
|
||||||
|
"rg_id": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Required: true,
|
||||||
|
ForceNew: true,
|
||||||
|
ValidateFunc: validation.IntAtLeast(1),
|
||||||
|
Description: "ID of the resource group where this compute should be deployed.",
|
||||||
|
},
|
||||||
|
"driver": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
ForceNew: true,
|
||||||
|
StateFunc: statefuncs.StateFuncToUpper,
|
||||||
|
ValidateFunc: validation.StringInSlice([]string{"SVA_KVM_X86", "KVM_X86", "KVM_PPC"}, false), // observe case while validating
|
||||||
|
Description: "Hardware architecture of this compute instance.",
|
||||||
|
},
|
||||||
|
"cpu": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Required: true,
|
||||||
|
ValidateFunc: validation.IntBetween(1, constants.MaxCpusPerCompute),
|
||||||
|
Description: "Number of CPUs to allocate to this compute instance.",
|
||||||
|
},
|
||||||
|
"ram": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Required: true,
|
||||||
|
ValidateFunc: validation.IntAtLeast(constants.MinRamPerCompute),
|
||||||
|
Description: "Amount of RAM in MB to allocate to this compute instance.",
|
||||||
|
},
|
||||||
|
"image_id": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Required: true,
|
||||||
|
//ForceNew: true, //REDEPLOY
|
||||||
|
Description: "ID of the OS image to base this compute instance on.",
|
||||||
|
},
|
||||||
|
"boot_disk_size": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Optional: true,
|
||||||
|
Computed: true,
|
||||||
|
Description: "This compute instance boot disk size in GB. Make sure it is large enough to accomodate selected OS image.",
|
||||||
|
},
|
||||||
|
"affinity_label": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
Description: "Set affinity label for compute",
|
||||||
|
},
|
||||||
|
"affinity_rules": {
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Optional: true,
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"topology": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
ValidateFunc: validation.StringInSlice([]string{"node", "compute"}, false),
|
||||||
|
Description: "compute or node, for whom rule applies",
|
||||||
|
},
|
||||||
|
"policy": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
ValidateFunc: validation.StringInSlice([]string{"RECOMMENDED", "REQUIRED"}, false),
|
||||||
|
Description: "RECOMMENDED or REQUIRED, the degree of 'strictness' of this rule",
|
||||||
|
},
|
||||||
|
"mode": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
ValidateFunc: validation.StringInSlice([]string{"EQ", "NE", "ANY"}, false),
|
||||||
|
Description: "EQ or NE or ANY - the comparison mode is 'value', recorded by the specified 'key'",
|
||||||
|
},
|
||||||
|
"key": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
Description: "key that are taken into account when analyzing this rule will be identified",
|
||||||
|
},
|
||||||
|
"value": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
Description: "value that must match the key to be taken into account when analyzing this rule",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"anti_affinity_rules": {
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Optional: true,
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"topology": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
ValidateFunc: validation.StringInSlice([]string{"node", "compute"}, false),
|
||||||
|
Description: "compute or node, for whom rule applies",
|
||||||
|
},
|
||||||
|
"policy": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
ValidateFunc: validation.StringInSlice([]string{"RECOMMENDED", "REQUIRED"}, false),
|
||||||
|
Description: "RECOMMENDED or REQUIRED, the degree of 'strictness' of this rule",
|
||||||
|
},
|
||||||
|
"mode": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
ValidateFunc: validation.StringInSlice([]string{"EQ", "NE", "ANY"}, false),
|
||||||
|
Description: "EQ or NE or ANY - the comparison mode is 'value', recorded by the specified 'key'",
|
||||||
|
},
|
||||||
|
"key": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
Description: "key that are taken into account when analyzing this rule will be identified",
|
||||||
|
},
|
||||||
|
"value": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
Description: "value that must match the key to be taken into account when analyzing this rule",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"disks": {
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Optional: true,
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: disksSubresourceSchemaMake(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"custom_fields": {
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Computed: true,
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"key": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"val": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"stateless": {
|
||||||
|
Type: schema.TypeBool,
|
||||||
|
Optional: true,
|
||||||
|
Default: false,
|
||||||
|
Description: "Compute will be stateless (SVA_KVM_X86) if set to True",
|
||||||
|
},
|
||||||
|
"with_default_vins": {
|
||||||
|
Type: schema.TypeBool,
|
||||||
|
Optional: true,
|
||||||
|
Default: true,
|
||||||
|
Description: "Create compute with default resgroup ViNS (true) or without any interfaces (false). This parameter is ignored if network block is specified",
|
||||||
|
},
|
||||||
|
"boot_disk": {
|
||||||
|
Type: schema.TypeSet,
|
||||||
|
Computed: true,
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: disksSubresourceSchemaMake(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"sep_id": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Optional: true,
|
||||||
|
Computed: true,
|
||||||
|
ForceNew: true,
|
||||||
|
Description: "ID of SEP to create bootDisk on. Uses image's sepId if not set.",
|
||||||
|
},
|
||||||
|
"pool": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
Computed: true,
|
||||||
|
ForceNew: true,
|
||||||
|
Description: "Pool to use if sepId is set, can be also empty if needed to be chosen by system.",
|
||||||
|
},
|
||||||
|
|
||||||
|
"extra_disks": {
|
||||||
|
Type: schema.TypeSet,
|
||||||
|
Optional: true,
|
||||||
|
MaxItems: constants.MaxExtraDisksPerCompute,
|
||||||
|
Elem: &schema.Schema{
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
},
|
||||||
|
Description: "Optional list of IDs of extra disks to attach to this compute. You may specify several extra disks.",
|
||||||
|
},
|
||||||
|
|
||||||
|
"network": {
|
||||||
|
Type: schema.TypeSet,
|
||||||
|
Optional: true,
|
||||||
|
MinItems: 1,
|
||||||
|
MaxItems: constants.MaxNetworksPerCompute,
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: networkSubresourceSchemaMake(),
|
||||||
|
},
|
||||||
|
Description: "Optional network connection(s) for this compute. You may specify several network blocks, one for each connection.",
|
||||||
|
},
|
||||||
|
|
||||||
|
"tags": {
|
||||||
|
Type: schema.TypeSet,
|
||||||
|
Optional: true,
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: tagsSubresourceSchemaMake(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
"port_forwarding": {
|
||||||
|
Type: schema.TypeSet,
|
||||||
|
Optional: true,
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: portForwardingSubresourceSchemaMake(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
"user_access": {
|
||||||
|
Type: schema.TypeSet,
|
||||||
|
Optional: true,
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: userAccessSubresourceSchemaMake(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
"snapshot": {
|
||||||
|
Type: schema.TypeSet,
|
||||||
|
Optional: true,
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: snapshotSubresourceSchemaMake(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
"rollback": {
|
||||||
|
Type: schema.TypeSet,
|
||||||
|
MaxItems: 1,
|
||||||
|
Optional: true,
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: snapshotRollbackSubresourceSchemaMake(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
"cd": {
|
||||||
|
Type: schema.TypeSet,
|
||||||
|
Optional: true,
|
||||||
|
MaxItems: 1,
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: cdSubresourceSchemaMake(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
"pin_to_stack": {
|
||||||
|
Type: schema.TypeBool,
|
||||||
|
Optional: true,
|
||||||
|
Default: false,
|
||||||
|
},
|
||||||
|
|
||||||
|
"description": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
Description: "Optional text description of this compute instance.",
|
||||||
|
},
|
||||||
|
|
||||||
|
"cloud_init": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
Description: "Optional cloud_init parameters. Applied when creating new compute instance only, ignored in all other cases.",
|
||||||
|
},
|
||||||
|
|
||||||
|
"enabled": {
|
||||||
|
Type: schema.TypeBool,
|
||||||
|
Optional: true,
|
||||||
|
Computed: true,
|
||||||
|
Description: "If true - enable compute, else - disable",
|
||||||
|
},
|
||||||
|
|
||||||
|
"pause": {
|
||||||
|
Type: schema.TypeBool,
|
||||||
|
Optional: true,
|
||||||
|
Default: false,
|
||||||
|
},
|
||||||
|
|
||||||
|
"reset": {
|
||||||
|
Type: schema.TypeBool,
|
||||||
|
Optional: true,
|
||||||
|
Default: false,
|
||||||
|
},
|
||||||
|
|
||||||
|
"auto_start": {
|
||||||
|
Type: schema.TypeBool,
|
||||||
|
Optional: true,
|
||||||
|
Default: false,
|
||||||
|
Description: "Flag for redeploy compute",
|
||||||
|
},
|
||||||
|
"force_stop": {
|
||||||
|
Type: schema.TypeBool,
|
||||||
|
Optional: true,
|
||||||
|
Default: false,
|
||||||
|
Description: "Flag for redeploy compute",
|
||||||
|
},
|
||||||
|
"data_disks": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
ValidateFunc: validation.StringInSlice([]string{"KEEP", "DETACH", "DESTROY"}, false),
|
||||||
|
Default: "DETACH",
|
||||||
|
Description: "Flag for redeploy compute",
|
||||||
|
},
|
||||||
|
"started": {
|
||||||
|
Type: schema.TypeBool,
|
||||||
|
Optional: true,
|
||||||
|
Default: true,
|
||||||
|
Description: "Is compute started.",
|
||||||
|
},
|
||||||
|
"detach_disks": {
|
||||||
|
Type: schema.TypeBool,
|
||||||
|
Optional: true,
|
||||||
|
Default: true,
|
||||||
|
},
|
||||||
|
"permanently": {
|
||||||
|
Type: schema.TypeBool,
|
||||||
|
Optional: true,
|
||||||
|
Default: true,
|
||||||
|
},
|
||||||
|
"is": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
Description: "system name",
|
||||||
|
},
|
||||||
|
"ipa_type": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
Description: "compute purpose",
|
||||||
|
},
|
||||||
|
// The rest are Compute properties, which are "computed" once it is created
|
||||||
|
"account_id": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
Description: "ID of the account this compute instance belongs to.",
|
||||||
|
},
|
||||||
|
"account_name": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
Description: "Name of the account this compute instance belongs to.",
|
||||||
|
},
|
||||||
|
"affinity_weight": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"arch": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"boot_order": {
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Computed: true,
|
||||||
|
Elem: &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"boot_disk_id": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
Description: "This compute instance boot disk ID.",
|
||||||
|
},
|
||||||
|
"clone_reference": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"clones": {
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Computed: true,
|
||||||
|
Elem: &schema.Schema{
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"computeci_id": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"created_by": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"created_time": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"deleted_by": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"deleted_time": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"devices": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"gid": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"guid": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"compute_id": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"interfaces": {
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Computed: true,
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: computeInterfacesSchemaMake(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"lock_status": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"manager_id": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"manager_type": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"migrationjob": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"milestones": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"natable_vins_id": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"natable_vins_ip": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"natable_vins_name": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"natable_vins_network": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"natable_vins_network_name": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"os_users": {
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Computed: true,
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: osUsersSubresourceSchemaMake(),
|
||||||
|
},
|
||||||
|
Description: "Guest OS users provisioned on this compute instance.",
|
||||||
|
},
|
||||||
|
"pinned": {
|
||||||
|
Type: schema.TypeBool,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"reference_id": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"registered": {
|
||||||
|
Type: schema.TypeBool,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"res_name": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"rg_name": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
Description: "Name of the resource group where this compute instance is located.",
|
||||||
|
},
|
||||||
|
"snap_sets": {
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Computed: true,
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: computeSnapSetsSchemaMake(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"stateless_sep_id": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"stateless_sep_type": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"status": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"tech_status": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"updated_by": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"updated_time": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"user_managed": {
|
||||||
|
Type: schema.TypeBool,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"vgpus": {
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Computed: true,
|
||||||
|
Elem: &schema.Schema{
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"virtual_image_id": {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"virtual_image_name": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,33 @@
|
|||||||
|
package kvmvm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
)
|
||||||
|
|
||||||
|
func resourceCompueteStateUpgradeV1(ctx context.Context, rawState map[string]interface{}, meta any) (map[string]interface{}, error) {
|
||||||
|
log.Debug("resourceCompueteStateUpgradeV1: upgrading state")
|
||||||
|
customFields, ok := rawState["custom_fields"]
|
||||||
|
if !ok || customFields == nil {
|
||||||
|
rawState["custom_fields"] = "{}"
|
||||||
|
return rawState, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
b := &strings.Builder{}
|
||||||
|
b.WriteString("{")
|
||||||
|
oldCustomFieldsSlice := customFields.([]interface{})
|
||||||
|
for i := range oldCustomFieldsSlice {
|
||||||
|
oldCustomFields := oldCustomFieldsSlice[i].(map[string]interface{})
|
||||||
|
b.WriteString(fmt.Sprintf(`"%s":"%s"`, oldCustomFields["key"], oldCustomFields["val"]))
|
||||||
|
if i < len(oldCustomFieldsSlice)-1 {
|
||||||
|
b.WriteString(",")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
b.WriteString("}")
|
||||||
|
rawState["custom_fields"] = b.String()
|
||||||
|
|
||||||
|
return rawState, nil
|
||||||
|
}
|
Loading…
Reference in new issue