Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extend how to upgrade RabbitMQ version #295

Merged
merged 3 commits into from
Aug 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 43 additions & 10 deletions api/upgrade_rabbitmq.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,23 +29,59 @@ func (api *API) ReadVersions(instanceID int) (map[string]any, error) {
}
}

// UpgradeRabbitMQ - Upgrade to latest possible versions for both RabbitMQ and Erlang.
func (api *API) UpgradeRabbitMQ(instanceID int) (string, error) {
// UpgradeRabbitMQ - Upgrade to latest possible version or a specific available version
func (api *API) UpgradeRabbitMQ(instanceID int, current_version, new_version string) (string, error) {
log.Printf("[DEBUG] api::upgrade_rabbitmq#upgrade_rabbitmq instanceID: %d, current_version: %s"+
", new_version: %s", instanceID, current_version, new_version)

// Keep old behaviour
if current_version == "" && new_version == "" {
return api.UpgradeToLatestVersion(instanceID)
} else if current_version != "" {
return api.UpgradeToLatestVersion(instanceID)
} else {
return api.UpgradeToSpecificVersion(instanceID, new_version)
}
}

func (api *API) UpgradeToSpecificVersion(instanceID int, version string) (string, error) {
var (
data map[string]any
failed map[string]any
path = fmt.Sprintf("api/instances/%d/actions/upgrade-rabbitmq", instanceID)
params = make(map[string]any)
)

params["version"] = version
log.Printf("[DEBUG] api::upgrade_rabbitmq#upgrade_to_specific_version path: %s, params: %v",
path, params)
response, err := api.sling.New().Post(path).BodyJSON(params).Receive(&data, &failed)
if err != nil {
return "", err
}

switch response.StatusCode {
case 200:
return api.waitUntilUpgraded(instanceID)
default:
return "", fmt.Errorf("upgrade RabbitMQ failed, status: %d, message: %s",
response.StatusCode, failed)
}
}

func (api *API) UpgradeToLatestVersion(instanceID int) (string, error) {
var (
data map[string]any
failed map[string]any
path = fmt.Sprintf("api/instances/%d/actions/upgrade-rabbitmq-erlang", instanceID)
)

log.Printf("[DEBUG] api::upgrade_rabbitmq#upgrade_rabbitmq path: %s", path)
log.Printf("[DEBUG] api::upgrade_rabbitmq#upgrade_to_latest_version path: %s", path)
response, err := api.sling.New().Post(path).Receive(&data, &failed)
if err != nil {
return "", err
}

log.Printf("[DEBUG] api::upgrade_rabbitmq::upgrade_rabbitmq_mq data: %v, status code: %d",
data, response.StatusCode)

switch response.StatusCode {
case 200:
return "Already at highest possible version", nil
Expand All @@ -69,15 +105,12 @@ func (api *API) waitUntilUpgraded(instanceID int) (string, error) {
if err != nil {
return "", err
}
log.Printf("[DEBUG] api::upgrade_rabbitmq#waitUntilUpgraded numberOfNodes: %d", len(data))

log.Printf("[DEBUG] api::upgrade_rabbitmq#waitUntilUpgraded data: %v", data)
ready := true
for _, node := range data {
log.Printf("[DEBUG] api::upgrade_rabbitmq#waitUntilUpgraded ready: %v, configured: %v",
ready, node["configured"])
ready = ready && node["configured"].(bool)
}
log.Printf("[DEBUG] api::upgrade_rabbitmq#waitUntilUpgraded ready: %v", ready)
if ready {
return "", nil
}
Expand Down
32 changes: 27 additions & 5 deletions cloudamqp/resource_cloudamqp_upgrade_rabbitmq.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,26 +12,44 @@ func resourceUpgradeRabbitMQ() *schema.Resource {
return &schema.Resource{
Create: resourceUpgradeRabbitMQInvoke,
Read: resourceUpgradeRabbitMQRead,
Update: resourceUpgradeRabbitMQUpdate,
Delete: resourceUpgradeRabbitMQRemove,
Schema: map[string]*schema.Schema{
"instance_id": {
Type: schema.TypeInt,
ForceNew: true,
Required: true,
Description: "The CloudAMQP instance identifier",
},
"current_version": {
Type: schema.TypeString,
Optional: true,
Description: "Helper argument to change upgrade behaviour to latest possible version",
},
"new_version": {
Type: schema.TypeString,
ForceNew: true,
Optional: true,
Description: "The new version to upgrade to",
},
},
}
}

func resourceUpgradeRabbitMQInvoke(d *schema.ResourceData, meta interface{}) error {
api := meta.(*api.API)
response, err := api.UpgradeRabbitMQ(d.Get("instance_id").(int))
var (
api = meta.(*api.API)
instanceID = d.Get("instance_id").(int)
current_version = d.Get("current_version").(string)
new_version = d.Get("new_version").(string)
)

log.Printf("[DEBUG] - Upgrading RabbitMQ instance %d to version %s", instanceID, new_version)
response, err := api.UpgradeRabbitMQ(instanceID, current_version, new_version)
if err != nil {
return err
}
id := strconv.Itoa(d.Get("instance_id").(int))
d.SetId(id)

d.SetId(strconv.Itoa(instanceID))

if len(response) > 0 {
log.Printf("[INFO] - " + response)
Expand All @@ -44,6 +62,10 @@ func resourceUpgradeRabbitMQRead(d *schema.ResourceData, meta interface{}) error
return nil
}

func resourceUpgradeRabbitMQUpdate(d *schema.ResourceData, meta interface{}) error {
return nil
}

func resourceUpgradeRabbitMQRemove(d *schema.ResourceData, meta interface{}) error {
return nil
}
193 changes: 193 additions & 0 deletions cloudamqp/resource_cloudamqp_upgrade_rabbitmq_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
package cloudamqp

import (
"fmt"
"testing"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"

"github.com/cloudamqp/terraform-provider-cloudamqp/cloudamqp/vcr-testing/configuration"
"github.com/cloudamqp/terraform-provider-cloudamqp/cloudamqp/vcr-testing/converter"
)

// TestAccUpgradeRabbitMQ_Latest: Upgrade RabbitMQ to latest possible version, from 3.12.2 -> 3.13.2
// Extra checks are needed when comparing versions, because next step is executed before backend
// have been updated. Same reason unable to use cloudamqp_upgradable_versions data source correctly.
func TestAccUpgradeRabbitMQ_Latest(t *testing.T) {
var (
fileNames = []string{"instance_with_version", "data_source/nodes"}
instanceResourceName = "cloudamqp_instance.instance"
dataSourceNodesName = "data.cloudamqp_nodes.nodes"

params = map[string]string{
"InstanceName": "TestAccUpgradeRabbitMQ_Latest",
"InstanceTags": converter.CommaStringArray([]string{"terraform"}),
"InstanceID": fmt.Sprintf("%s.id", instanceResourceName),
"InstanceRmqVersion": "3.12.2",
}

fileNamesUpgrade = []string{"instance", "data_source/nodes", "upgrade_rabbitmq_latest"}

paramsUpgrade01 = map[string]string{
"InstanceName": "TestAccUpgradeRabbitMQ_Latest",
"InstanceTags": converter.CommaStringArray([]string{"terraform"}),
"InstanceID": fmt.Sprintf("%s.id", instanceResourceName),
"UpgradeRabbitMQCurrentVersion": "3.12.2",
"UpgradeRabbitMQNewVersion": "3.12.13",
}

paramsUpgrade02 = map[string]string{
"InstanceName": "TestAccUpgradeRabbitMQ_Latest",
"InstanceTags": converter.CommaStringArray([]string{"terraform"}),
"InstanceID": fmt.Sprintf("%s.id", instanceResourceName),
"UpgradeRabbitMQCurrentVersion": "3.12.13",
"UpgradeRabbitMQNewVersion": "3.13.2",
}

fileNamesCheckUpgrade = []string{"instance", "data_source/nodes"}
paramsCheck = map[string]string{
"InstanceName": "TestAccUpgradeRabbitMQ_Latest",
"InstanceTags": converter.CommaStringArray([]string{"terraform"}),
"InstanceID": fmt.Sprintf("%s.id", instanceResourceName),
}
)

cloudamqpResourceTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
ProviderFactories: testAccProviderFactory,
Steps: []resource.TestStep{
{
Config: configuration.GetTemplatedConfig(t, fileNames, params),
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttr(instanceResourceName, "name", params["InstanceName"]),
resource.TestCheckResourceAttr(instanceResourceName, "plan", "bunny-1"),
resource.TestCheckResourceAttr(instanceResourceName, "region", "amazon-web-services::us-east-1"),
resource.TestCheckResourceAttr(instanceResourceName, "rmq_version", params["InstanceRmqVersion"]),
resource.TestCheckResourceAttr(instanceResourceName, "tags.#", "1"),
resource.TestCheckResourceAttr(instanceResourceName, "tags.0", "terraform"),
resource.TestCheckResourceAttr(instanceResourceName, "nodes", "1"),
resource.TestCheckResourceAttr(dataSourceNodesName, "nodes.#", "1"),
resource.TestCheckResourceAttr(dataSourceNodesName, "nodes.0.rabbitmq_version", params["InstanceRmqVersion"]),
),
},
{
Config: configuration.GetTemplatedConfig(t, fileNamesUpgrade, paramsUpgrade01),
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttr(dataSourceNodesName, "nodes.#", "1"),
resource.TestCheckResourceAttr(dataSourceNodesName, "nodes.0.rabbitmq_version", "3.12.2"),
),
},
{
Config: configuration.GetTemplatedConfig(t, fileNamesCheckUpgrade, paramsCheck),
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttr(dataSourceNodesName, "nodes.#", "1"),
resource.TestCheckResourceAttr(dataSourceNodesName, "nodes.0.rabbitmq_version", "3.12.13"),
),
},
{
Config: configuration.GetTemplatedConfig(t, fileNamesUpgrade, paramsUpgrade02),
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttr(dataSourceNodesName, "nodes.#", "1"),
resource.TestCheckResourceAttr(dataSourceNodesName, "nodes.0.rabbitmq_version", "3.12.13"),
),
},
{
Config: configuration.GetTemplatedConfig(t, fileNamesCheckUpgrade, paramsCheck),
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttr(dataSourceNodesName, "nodes.#", "1"),
resource.TestCheckResourceAttr(dataSourceNodesName, "nodes.0.rabbitmq_version", "3.13.2"),
),
},
},
})
}

// TestAccUpgradeRabbitMQ_Specific: Upgrade RabbitMQ to a specific version, from 3.12.2 -> 3.13.2
// Extra checks are needed when comparing versions, because next step is executed before backend
// have been updated.
func TestAccUpgradeRabbitMQ_Specific(t *testing.T) {
var (
fileNames = []string{"instance_with_version", "data_source/nodes"}
instanceResourceName = "cloudamqp_instance.instance"
dataSourceNodesName = "data.cloudamqp_nodes.nodes"

params = map[string]string{
"InstanceName": "TestAccUpgradeRabbitMQ_Latest",
"InstanceTags": converter.CommaStringArray([]string{"terraform"}),
"InstanceID": fmt.Sprintf("%s.id", instanceResourceName),
"InstanceRmqVersion": "3.12.2",
}

fileNamesUpgrade = []string{"instance", "data_source/nodes", "upgrade_rabbitmq_latest"}

paramsUpgrade01 = map[string]string{
"InstanceName": "TestAccUpgradeRabbitMQ_Latest",
"InstanceTags": converter.CommaStringArray([]string{"terraform"}),
"InstanceID": fmt.Sprintf("%s.id", instanceResourceName),
"UpgradeRabbitMQNewVersion": "3.12.13",
}

paramsUpgrade02 = map[string]string{
"InstanceName": "TestAccUpgradeRabbitMQ_Latest",
"InstanceTags": converter.CommaStringArray([]string{"terraform"}),
"InstanceID": fmt.Sprintf("%s.id", instanceResourceName),
"UpgradeRabbitMQNewVersion": "3.13.2",
}

fileNamesCheckUpgrade = []string{"instance", "data_source/nodes"}
paramsCheck = map[string]string{
"InstanceName": "TestAccUpgradeRabbitMQ_Latest",
"InstanceTags": converter.CommaStringArray([]string{"terraform"}),
"InstanceID": fmt.Sprintf("%s.id", instanceResourceName),
}
)

cloudamqpResourceTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
ProviderFactories: testAccProviderFactory,
Steps: []resource.TestStep{
{
Config: configuration.GetTemplatedConfig(t, fileNames, params),
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttr(instanceResourceName, "name", params["InstanceName"]),
resource.TestCheckResourceAttr(instanceResourceName, "plan", "bunny-1"),
resource.TestCheckResourceAttr(instanceResourceName, "region", "amazon-web-services::us-east-1"),
resource.TestCheckResourceAttr(instanceResourceName, "rmq_version", params["InstanceRmqVersion"]),
resource.TestCheckResourceAttr(instanceResourceName, "tags.#", "1"),
resource.TestCheckResourceAttr(instanceResourceName, "tags.0", "terraform"),
resource.TestCheckResourceAttr(instanceResourceName, "nodes", "1"),
resource.TestCheckResourceAttr(dataSourceNodesName, "nodes.#", "1"),
resource.TestCheckResourceAttr(dataSourceNodesName, "nodes.0.rabbitmq_version", params["InstanceRmqVersion"]),
),
},
{
Config: configuration.GetTemplatedConfig(t, fileNamesUpgrade, paramsUpgrade01),
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttr(dataSourceNodesName, "nodes.#", "1"),
resource.TestCheckResourceAttr(dataSourceNodesName, "nodes.0.rabbitmq_version", "3.12.2"),
),
},
{
Config: configuration.GetTemplatedConfig(t, fileNamesCheckUpgrade, paramsCheck),
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttr(dataSourceNodesName, "nodes.#", "1"),
resource.TestCheckResourceAttr(dataSourceNodesName, "nodes.0.rabbitmq_version", "3.12.13"),
),
},
{
Config: configuration.GetTemplatedConfig(t, fileNamesUpgrade, paramsUpgrade02),
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttr(dataSourceNodesName, "nodes.#", "1"),
resource.TestCheckResourceAttr(dataSourceNodesName, "nodes.0.rabbitmq_version", "3.12.13"),
),
},
{
Config: configuration.GetTemplatedConfig(t, fileNamesCheckUpgrade, paramsCheck),
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttr(dataSourceNodesName, "nodes.#", "1"),
resource.TestCheckResourceAttr(dataSourceNodesName, "nodes.0.rabbitmq_version", "3.13.2"),
),
},
},
})
}
Loading