diff --git a/cancom/services/ipam/migration_v1.go b/cancom/services/ipam/migration_v1.go new file mode 100644 index 0000000..4f6a32f --- /dev/null +++ b/cancom/services/ipam/migration_v1.go @@ -0,0 +1,248 @@ +package ipam + +import ( + "context" + "fmt" + "strconv" + "time" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +var resourceSchemaInstanceV0 = &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeString, + Computed: true, + }, + "name_tag": { + Type: schema.TypeString, + Computed: false, + Required: true, + }, + "managed_by": { + Type: schema.TypeString, + Computed: false, + Required: true, + }, + "description": { + Type: schema.TypeString, + Computed: false, + Optional: true, + }, + "release_wait_time": { + Type: schema.TypeString, + Optional: true, + }, + "created_at": { + Type: schema.TypeString, + Computed: true, + }, + "updated_at": { + Type: schema.TypeString, + Computed: true, + }, + }, +} + +func instanceUpgradeV0() schema.StateUpgrader { + return schema.StateUpgrader{ + Type: resourceSchemaInstanceV0.CoreConfigSchema().ImpliedType(), + Version: 0, + Upgrade: func(ctx context.Context, rawState map[string]interface{}, meta interface{}) (map[string]interface{}, error) { + if val, ok := rawState["updated_at"].(string); ok { + if val != "" { + i, err := time.Parse("2006-01-02T15:04:05", val) + if err != nil { + return rawState, fmt.Errorf("error converting updated_at to int: %w", err) + } + rawState["updated_at"] = int(i.Unix()) + } else { + rawState["updated_at"] = nil + } + } + + if val, ok := rawState["created_at"].(string); ok { + if val != "" { + i, err := time.Parse("2006-01-02T15:04:05", val) + if err != nil { + return rawState, fmt.Errorf("error converting created_at to int: %w", err) + } + rawState["created_at"] = int(i.Unix()) + } else { + rawState["created_at"] = nil + } + } + + if val, ok := rawState["release_wait_time"].(string); ok { + i, err := strconv.Atoi(val) + if err != nil { + return rawState, fmt.Errorf("failed to convert release_wait_time from string to int: %w", err) + } + rawState["release_wait_time"] = i + } + + return rawState, nil + }, + } +} + +var resourceSchemaNetworkV0 = &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeString, + Computed: true, + }, + "supernet_id": { + Type: schema.TypeString, + Computed: false, + Required: true, + ForceNew: true, + }, + "name_tag": { + Type: schema.TypeString, + Computed: false, + Required: true, + }, + "description": { + Type: schema.TypeString, + Computed: false, + Optional: true, + }, + "request": { + Type: schema.TypeString, + Computed: false, + Required: true, + ForceNew: true, + }, + "host_assign": { + Type: schema.TypeBool, + Computed: false, + Optional: true, + Default: true, + }, + "prefix_str": { + Type: schema.TypeString, + Computed: true, + }, + "created_at": { + Type: schema.TypeString, + Computed: true, + }, + "updated_at": { + Type: schema.TypeString, + Computed: true, + }, + }, +} + +func networkUpgradeV0() schema.StateUpgrader { + return schema.StateUpgrader{ + Type: resourceSchemaNetworkV0.CoreConfigSchema().ImpliedType(), + Version: 0, + Upgrade: func(ctx context.Context, rawState map[string]interface{}, meta interface{}) (map[string]interface{}, error) { + if val, ok := rawState["updated_at"].(string); ok { + if val != "" { + i, err := time.Parse("2006-01-02T15:04:05", val) + if err != nil { + return rawState, fmt.Errorf("error converting updated_at to int: %w", err) + } + rawState["updated_at"] = int(i.Unix()) + } else { + rawState["updated_at"] = nil + } + } + + if val, ok := rawState["created_at"].(string); ok { + if val != "" { + i, err := time.Parse("2006-01-02T15:04:05", val) + if err != nil { + return rawState, fmt.Errorf("error converting created_at to int: %w", err) + } + rawState["created_at"] = int(i.Unix()) + } else { + rawState["created_at"] = nil + } + } + + return rawState, nil + }, + } +} + +var resourceSchemaSupernetV0 = &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeString, + Computed: true, + }, + "instance_id": { + Type: schema.TypeString, + Computed: false, + Required: true, + }, + "name_tag": { + Type: schema.TypeString, + Computed: false, + Required: true, + }, + "description": { + Type: schema.TypeString, + Computed: false, + Optional: true, + }, + "supernet_cidr": { + Type: schema.TypeString, + Computed: false, + Required: true, + ForceNew: true, + }, + "created_at": { + Type: schema.TypeString, + Computed: true, + Optional: true, + }, + "updated_at": { + Type: schema.TypeString, + Computed: true, + Optional: true, + }, + }, +} + +func supernetUpgradeV0() schema.StateUpgrader { + return schema.StateUpgrader{ + + Type: resourceSchemaSupernetV0.CoreConfigSchema().ImpliedType(), + Version: 0, + Upgrade: func(ctx context.Context, rawState map[string]interface{}, meta interface{}) (map[string]interface{}, error) { + if val, ok := rawState["updated_at"].(string); ok { + if val != "" { + i, err := time.Parse("2006-01-02T15:04:05", val) + if err != nil { + return rawState, fmt.Errorf("error converting updated_at to int: %w", err) + } + rawState["updated_at"] = int(i.Unix()) + } else { + + rawState["updated_at"] = 0 + } + + } + + if val, ok := rawState["created_at"].(string); ok { + if val != "" { + i, err := time.Parse("2006-01-02T15:04:05", val) + if err != nil { + return rawState, fmt.Errorf("error converting created_at to int: %w", err) + } + rawState["created_at"] = int(i.Unix()) + } else { + rawState["created_at"] = nil + } + } + + return rawState, nil + }, + } +} diff --git a/cancom/services/ipam/resource_host.go b/cancom/services/ipam/resource_host.go index f44dfd5..d7bcdf0 100644 --- a/cancom/services/ipam/resource_host.go +++ b/cancom/services/ipam/resource_host.go @@ -91,7 +91,7 @@ func resourceHostCreate(ctx context.Context, d *schema.ResourceData, m interface host := &client_ipam.HostCreateRequest{ NetworkCrn: d.Get("network_crn").(string), NameTag: d.Get("name_tag").(string), - Operation: "assign_address", + Operation: "assignAddress", Description: d.Get("description").(string), Qualifier: d.Get("qualifier").(string), } diff --git a/cancom/services/ipam/resource_instance.go b/cancom/services/ipam/resource_instance.go index e3be59f..517de54 100644 --- a/cancom/services/ipam/resource_instance.go +++ b/cancom/services/ipam/resource_instance.go @@ -16,6 +16,7 @@ func resourceInstance() *schema.Resource { ReadContext: resourceInstanceRead, UpdateContext: resourceInstanceUpdate, DeleteContext: resourceInstanceDelete, + SchemaVersion: 1, Schema: map[string]*schema.Schema{ "id": { Type: schema.TypeString, @@ -37,18 +38,22 @@ func resourceInstance() *schema.Resource { Optional: true, }, "release_wait_time": { - Type: schema.TypeString, + Type: schema.TypeInt, + Default: 0, Optional: true, }, "created_at": { - Type: schema.TypeString, + Type: schema.TypeInt, Computed: true, }, "updated_at": { - Type: schema.TypeString, + Type: schema.TypeInt, Computed: true, }, }, + StateUpgraders: []schema.StateUpgrader{ + instanceUpgradeV0(), + }, } } @@ -90,7 +95,7 @@ func resourceInstanceCreate(ctx context.Context, d *schema.ResourceData, m inter instance := &client_ipam.InstanceCreateRequest{ NameTag: d.Get("name_tag").(string), ManagedBy: d.Get("managed_by").(string), - ReleaseWaitTime: d.Get("release_wait_time").(string), + ReleaseWaitTime: d.Get("release_wait_time").(int), Description: d.Get("description").(string), } @@ -123,7 +128,7 @@ func resourceInstanceUpdate(ctx context.Context, d *schema.ResourceData, m inter instance := &client_ipam.InstanceUpdateRequest{ NameTag: d.Get("name_tag").(string), ManagedBy: d.Get("managed_by").(string), - ReleaseWaitTime: d.Get("release_wait_time").(string), + ReleaseWaitTime: d.Get("release_wait_time").(int), Description: d.Get("description").(string), } diff --git a/cancom/services/ipam/resource_network.go b/cancom/services/ipam/resource_network.go index af5f628..4a8de5c 100644 --- a/cancom/services/ipam/resource_network.go +++ b/cancom/services/ipam/resource_network.go @@ -16,6 +16,7 @@ func resourceNetwork() *schema.Resource { ReadContext: resourceNetworkRead, UpdateContext: resourceNetworkUpdate, DeleteContext: resourceNetworkDelete, + SchemaVersion: 1, Schema: map[string]*schema.Schema{ "id": { Type: schema.TypeString, @@ -54,14 +55,17 @@ func resourceNetwork() *schema.Resource { Computed: true, }, "created_at": { - Type: schema.TypeString, + Type: schema.TypeInt, Computed: true, }, "updated_at": { - Type: schema.TypeString, + Type: schema.TypeInt, Computed: true, }, }, + StateUpgraders: []schema.StateUpgrader{ + networkUpgradeV0(), + }, } } diff --git a/cancom/services/ipam/resource_supernet.go b/cancom/services/ipam/resource_supernet.go index 8e7bc88..a075b70 100644 --- a/cancom/services/ipam/resource_supernet.go +++ b/cancom/services/ipam/resource_supernet.go @@ -16,6 +16,7 @@ func resourceSupernet() *schema.Resource { ReadContext: resourceSupernetRead, UpdateContext: resourceSupernetUpdate, DeleteContext: resourceSupernetDelete, + SchemaVersion: 1, Schema: map[string]*schema.Schema{ "id": { Type: schema.TypeString, @@ -43,14 +44,17 @@ func resourceSupernet() *schema.Resource { ForceNew: true, }, "created_at": { - Type: schema.TypeString, + Type: schema.TypeInt, Computed: true, }, "updated_at": { - Type: schema.TypeString, + Type: schema.TypeInt, Computed: true, }, }, + StateUpgraders: []schema.StateUpgrader{ + supernetUpgradeV0(), + }, } } diff --git a/client/services/ipam/ipam.go b/client/services/ipam/ipam.go index 9911e28..5becf56 100644 --- a/client/services/ipam/ipam.go +++ b/client/services/ipam/ipam.go @@ -431,7 +431,7 @@ func (c *Client) DeleteHost(hostId string) error { return err } // included to find a sporadic problem leading to resources not released in the backend - if delResponse.Message != "released successfully" { + if delResponse.Message != "Item released successfully" && delResponse.Message != "released successfully" { return errors.New("message: " + delResponse.Message) } diff --git a/client/services/ipam/models.go b/client/services/ipam/models.go index 9e5b3d8..beaf250 100644 --- a/client/services/ipam/models.go +++ b/client/services/ipam/models.go @@ -23,7 +23,7 @@ type HostCreateRequest struct { type HostUpdateRequest struct { ID string `json:"crn,omitempty"` Operation string `json:"operation"` - Address string `json:"address"` + Address string `json:"address,omitempty"` Qualifier string `json:"qualifier"` NetworkCrn string `json:"networkCrn"` NameTag string `json:"nameTag"` @@ -40,16 +40,16 @@ type Instance struct { Description string `json:"description"` NameTag string `json:"nameTag"` ManagedBy string `json:"managedBy"` - ReleaseWaitTime string `json:"releaseWaitTime"` - CreatedAt string `json:"createdAt"` - UpdatedAt string `json:"updatedAt"` + ReleaseWaitTime int `json:"releaseWaitTime"` + CreatedAt int `json:"createdAt"` + UpdatedAt int `json:"updatedAt"` } type InstanceCreateRequest struct { NameTag string `json:"nameTag"` ManagedBy string `json:"managedBy"` Description string `json:"description"` - ReleaseWaitTime string `json:"releaseWaitTime"` + ReleaseWaitTime int `json:"releaseWaitTime"` } type InstanceUpdateRequest struct { @@ -57,7 +57,7 @@ type InstanceUpdateRequest struct { ManagedBy string `json:"managedBy"` ID string `json:"crn,omitempty"` Description string `json:"description"` - ReleaseWaitTime string `json:"releaseWaitTime"` + ReleaseWaitTime int `json:"releaseWaitTime"` } type InstanceDeleteResponse struct { @@ -70,9 +70,9 @@ type Supernet struct { InstanceId string `json:"parent"` Description string `json:"description"` NameTag string `json:"nameTag"` - SupernetCidr string `json:"supernetCidr"` - CreatedAt string `json:"createdAt"` - UpdatedAt string `json:"updatedAt"` + SupernetCidr string `json:"prefixStr"` + CreatedAt int `json:"createdAt"` + UpdatedAt int `json:"updatedAt"` } type SupernetCreateRequest struct { @@ -80,7 +80,7 @@ type SupernetCreateRequest struct { InstanceId string `json:"parent"` Description string `json:"description"` NameTag string `json:"nameTag"` - SupernetCidr string `json:"supernetCidr"` + SupernetCidr string `json:"prefixStr"` } type SupernetUpdateRequest struct { @@ -88,7 +88,7 @@ type SupernetUpdateRequest struct { InstanceId string `json:"parent"` Description string `json:"description"` NameTag string `json:"nameTag"` - SupernetCidr string `json:"supernetCidr"` + SupernetCidr string `json:"prefixStr"` } type SupernetDeleteResponse struct { @@ -103,8 +103,8 @@ type Network struct { NameTag string `json:"nameTag"` PrefixStr string `json:"prefixStr"` HostAssign bool `json:"hostAssign"` - CreatedAt string `json:"createdAt"` - UpdatedAt string `json:"updatedAt"` + CreatedAt int `json:"createdAt"` + UpdatedAt int `json:"updatedAt"` //HostAssign bool `json:hostAssign` } diff --git a/docs/resources/ipam_instance.md b/docs/resources/ipam_instance.md index d918d15..88b9155 100644 --- a/docs/resources/ipam_instance.md +++ b/docs/resources/ipam_instance.md @@ -31,10 +31,10 @@ resource "cancom_ipam_instance" "tfcreated01" { ### Optional - `description` (String) -- `release_wait_time` (String) +- `release_wait_time` (Number) ### Read-Only -- `created_at` (String) +- `created_at` (Number) - `id` (String) The ID of this resource. -- `updated_at` (String) +- `updated_at` (Number) diff --git a/docs/resources/ipam_network.md b/docs/resources/ipam_network.md index 5815617..3c066c8 100644 --- a/docs/resources/ipam_network.md +++ b/docs/resources/ipam_network.md @@ -46,7 +46,7 @@ resource "cancom_ipam_network" "tfnetwork01" { ### Read-Only -- `created_at` (String) +- `created_at` (Number) - `id` (String) The ID of this resource. - `prefix_str` (String) -- `updated_at` (String) +- `updated_at` (Number) diff --git a/docs/resources/ipam_supernet.md b/docs/resources/ipam_supernet.md index bd1a017..880c23f 100644 --- a/docs/resources/ipam_supernet.md +++ b/docs/resources/ipam_supernet.md @@ -43,6 +43,6 @@ resource "cancom_ipam_supernet" "tfsupernet01" { ### Read-Only -- `created_at` (String) +- `created_at` (Number) - `id` (String) The ID of this resource. -- `updated_at` (String) +- `updated_at` (Number)