Skip to content

Commit

Permalink
feat(Cloud Database): support offline restore for MongoDB EE PITR (#4601
Browse files Browse the repository at this point in the history
)

* feature(Cloud Database): support Offline Restore for MongoDB EE
* add documentation
* cross region tests
* replace IcdDbRegion with region set in provider
* revert to v4 api
  • Loading branch information
alexhemard authored Nov 10, 2023
1 parent a85a3c9 commit cf3b4e2
Show file tree
Hide file tree
Showing 19 changed files with 382 additions and 198 deletions.
24 changes: 12 additions & 12 deletions .secrets.baseline
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"files": "go.mod|go.sum|.*.map|^.secrets.baseline$",
"lines": null
},
"generated_at": "2023-10-30T15:56:24Z",
"generated_at": "2023-11-09T17:56:16Z",
"plugins_used": [
{
"name": "AWSKeyDetector"
Expand Down Expand Up @@ -752,23 +752,23 @@
"hashed_secret": "731438016c5ab94431f61820f35e3ae5f8ad6004",
"is_secret": false,
"is_verified": false,
"line_number": 401,
"line_number": 402,
"type": "Secret Keyword",
"verified_result": null
},
{
"hashed_secret": "12da2e35d6b50c902c014f1ab9e3032650368df7",
"is_secret": false,
"is_verified": false,
"line_number": 407,
"line_number": 408,
"type": "Secret Keyword",
"verified_result": null
},
{
"hashed_secret": "813274ccae5b6b509379ab56982d862f7b5969b6",
"is_secret": false,
"is_verified": false,
"line_number": 1118,
"line_number": 1120,
"type": "Base64 High Entropy String",
"verified_result": null
}
Expand Down Expand Up @@ -856,15 +856,15 @@
"hashed_secret": "c8b6f5ef11b9223ac35a5663975a466ebe7ebba9",
"is_secret": false,
"is_verified": false,
"line_number": 1800,
"line_number": 1797,
"type": "Secret Keyword",
"verified_result": null
},
{
"hashed_secret": "8abf4899c01104241510ba87685ad4de76b0c437",
"is_secret": false,
"is_verified": false,
"line_number": 1806,
"line_number": 1803,
"type": "Secret Keyword",
"verified_result": null
}
Expand Down Expand Up @@ -2080,31 +2080,31 @@
"hashed_secret": "deab23f996709b4e3d14e5499d1cc2de677bfaa8",
"is_secret": false,
"is_verified": false,
"line_number": 1340,
"line_number": 1357,
"type": "Secret Keyword",
"verified_result": null
},
{
"hashed_secret": "20a25bac21219ffff1904bde871ded4027eca2f8",
"is_secret": false,
"is_verified": false,
"line_number": 1927,
"line_number": 1944,
"type": "Secret Keyword",
"verified_result": null
},
{
"hashed_secret": "b732fb611fd46a38e8667f9972e0cde777fbe37f",
"is_secret": false,
"is_verified": false,
"line_number": 1946,
"line_number": 1963,
"type": "Secret Keyword",
"verified_result": null
},
{
"hashed_secret": "1f5e25be9b575e9f5d39c82dfd1d9f4d73f1975c",
"is_secret": false,
"is_verified": false,
"line_number": 2186,
"line_number": 2203,
"type": "Secret Keyword",
"verified_result": null
}
Expand Down Expand Up @@ -2164,15 +2164,15 @@
"hashed_secret": "68ab9ef0953865fef0558010a9f7afcef110d5b8",
"is_secret": false,
"is_verified": false,
"line_number": 215,
"line_number": 270,
"type": "Secret Keyword",
"verified_result": null
},
{
"hashed_secret": "10c28f9cf0668595d45c1090a7b4a2ae98edfa58",
"is_secret": false,
"is_verified": false,
"line_number": 280,
"line_number": 335,
"type": "Secret Keyword",
"verified_result": null
}
Expand Down
75 changes: 67 additions & 8 deletions ibm/acctest/acctest.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,25 @@
package acctest

import (
"context"
"fmt"
"os"
"strconv"
"strings"
"sync"
"testing"

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

"github.com/IBM-Cloud/terraform-provider-ibm/ibm/provider"
)

const (
ProviderName = "ibm"
ProviderNameAlternate = "ibmalternate"
)

var (
AppIDTenantID string
AppIDTestUserEmail string
Expand Down Expand Up @@ -146,7 +155,6 @@ var (
IksClusterVpcID string
IksClusterSubnetID string
IksClusterResourceGroupID string
IcdDbRegion string
IcdDbDeploymentId string
IcdDbBackupId string
IcdDbTaskId string
Expand Down Expand Up @@ -858,12 +866,6 @@ func init() {
fmt.Println("[INFO] Set the environment variable ISSnapshotCRN for ibm_is_snapshot resource else it is set to default value 'crn:v1:bluemix:public:is:ca-tor:a/xxxxxxxx::snapshot:xxxx-xxxxc-xxx-xxxx-xxxx-xxxxxxxxxx'")
}

IcdDbRegion = os.Getenv("ICD_DB_REGION")
if IcdDbRegion == "" {
IcdDbRegion = "eu-gb"
fmt.Println("[INFO] Set the environment variable ICD_DB_REGION for testing ibm_cloud_databases else it is set to default value 'eu-gb'")
}

IcdDbDeploymentId = os.Getenv("ICD_DB_DEPLOYMENT_ID")
if IcdDbDeploymentId == "" {
IcdDbDeploymentId = "crn:v1:bluemix:public:databases-for-redis:au-syd:a/40ddc34a953a8c02f10987b59085b60e:5042afe1-72c2-4231-89cc-c949e5d56251::"
Expand Down Expand Up @@ -1530,10 +1532,18 @@ var (
TestAccProvider *schema.Provider
)

// testAccProviderConfigure ensures Provider is only configured once
//
// The PreCheck(t) function is invoked for every test and this prevents
// extraneous reconfiguration to the same values each time. However, this does
// not prevent reconfiguration that may happen should the address of
// Provider be errantly reused in ProviderFactories.
var testAccProviderConfigure sync.Once

func init() {
TestAccProvider = provider.Provider()
TestAccProviders = map[string]*schema.Provider{
"ibm": TestAccProvider,
ProviderName: TestAccProvider,
}
}

Expand All @@ -1557,6 +1567,13 @@ func TestAccPreCheck(t *testing.T) {
if v := os.Getenv("IAAS_CLASSIC_USERNAME"); v == "" {
t.Fatal("IAAS_CLASSIC_USERNAME must be set for acceptance tests")
}

testAccProviderConfigure.Do(func() {
diags := TestAccProvider.Configure(context.Background(), terraformsdk.NewResourceConfigRaw(nil))
if diags.HasError() {
t.Fatalf("configuring provider: %s", diags[0].Summary)
}
})
}

func TestAccPreCheckEnterprise(t *testing.T) {
Expand Down Expand Up @@ -1696,3 +1713,45 @@ func TestAccPreCheckScc(t *testing.T) {
t.Fatal("IBMCLOUD_SCC_REPORT_ID missing. Set the environment variable IBMCLOUD_SCC_REPORT_ID with a VALID REPORT_ID")
}
}

func TestAccProviderFactories() map[string]func() (*schema.Provider, error) {
return map[string]func() (*schema.Provider, error){
ProviderName: func() (*schema.Provider, error) { return provider.Provider(), nil },
ProviderNameAlternate: func() (*schema.Provider, error) { return provider.Provider(), nil },
}
}

func Region() string {
region, _ := schema.MultiEnvDefaultFunc([]string{"IC_REGION", "IBMCLOUD_REGION", "BM_REGION", "BLUEMIX_REGION"}, "us-south")()

return region.(string)
}

func RegionAlternate() string {
region, _ := schema.MultiEnvDefaultFunc([]string{"IC_REGION_ALTERNATE", "IBMCLOUD_REGION_ALTERNATE"}, "eu-gb")()

return region.(string)
}

func ConfigAlternateRegionProvider() string {
return configNamedRegionalProvider(ProviderNameAlternate, RegionAlternate())
}

// ConfigCompose can be called to concatenate multiple strings to build test configurations
func ConfigCompose(config ...string) string {
var str strings.Builder

for _, conf := range config {
str.WriteString(conf)
}

return str.String()
}

func configNamedRegionalProvider(providerName string, region string) string {
return fmt.Sprintf(`
provider %[1]q {
region = %[2]q
}
`, providerName, region)
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ func testAccCheckIBMDatabaseDataSourceConfig3(name string) string {
tags = ["one:two"]
}
`, name, acc.IcdDbRegion)
`, name, acc.Region())
}

func testAccCheckIBMDatabasePitrDataSourceConfigBasic(name string) string {
Expand Down
4 changes: 2 additions & 2 deletions ibm/service/database/data_source_ibm_database_remotes_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ func testAccCheckIBMDatabaseDataSourceConfig4(name string) string {
]
}
`, name, acc.IcdDbRegion)
`, name, acc.Region())
}

func testAccCheckIBMDatabaseRemotesDataSourceConfigBasic(name string) string {
Expand All @@ -82,7 +82,7 @@ func testAccCheckIBMDatabaseRemotesDataSourceConfigBasic(name string) string {
data "ibm_database_remotes" "database_remotes" {
deployment_id = ibm_database.db.id
depends_on = [
ibm_database.db_replica,
]
Expand Down
4 changes: 2 additions & 2 deletions ibm/service/database/data_source_ibm_database_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ func TestAccIBMDatabaseDataSource_basic(t *testing.T) {
resource.TestCheckResourceAttr(dataName, "name", testName),
resource.TestCheckResourceAttr(dataName, "service", "databases-for-postgresql"),
resource.TestCheckResourceAttr(dataName, "plan", "standard"),
resource.TestCheckResourceAttr(dataName, "location", acc.IcdDbRegion),
resource.TestCheckResourceAttr(dataName, "location", acc.Region()),
resource.TestCheckResourceAttr(dataName, "adminuser", "admin"),
resource.TestCheckResourceAttr(dataName, "groups.0.memory.0.allocation_mb", "2048"),
resource.TestCheckResourceAttr(dataName, "groups.0.disk.0.allocation_mb", "10240"),
Expand Down Expand Up @@ -66,5 +66,5 @@ func testAccCheckIBMDatabaseDataSourceConfig(databaseResourceGroup string, name
tags = ["one:two"]
}
`, databaseResourceGroup, name, acc.IcdDbRegion)
`, databaseResourceGroup, name, acc.Region())
}
18 changes: 17 additions & 1 deletion ibm/service/database/resource_ibm_database.go
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,12 @@ func ResourceIBMDatabaseInstance() *schema.Resource {
Optional: true,
DiffSuppressFunc: flex.ApplyOnce,
},
"offline_restore": {
Description: "Set offline restore mode for MongoDB Enterprise Edition",
Type: schema.TypeBool,
Optional: true,
DiffSuppressFunc: flex.ApplyOnce,
},
"users": {
Type: schema.TypeSet,
Optional: true,
Expand Down Expand Up @@ -872,6 +878,7 @@ type Params struct {
RemoteLeaderID string `json:"remote_leader_id,omitempty"`
PITRDeploymentID string `json:"point_in_time_recovery_deployment_id,omitempty"`
PITRTimeStamp *string `json:"point_in_time_recovery_time,omitempty"`
OfflineRestore bool `json:"offline_restore,omitempty"`
}

type Group struct {
Expand Down Expand Up @@ -1030,6 +1037,7 @@ func resourceIBMDatabaseInstanceDiff(_ context.Context, diff *schema.ResourceDif
}

service := diff.Get("service").(string)
plan := diff.Get("plan").(string)

_, logicalReplicationSet := diff.GetOk("logical_replication_slot")

Expand Down Expand Up @@ -1086,6 +1094,11 @@ func resourceIBMDatabaseInstanceDiff(_ context.Context, diff *schema.ResourceDif
}
}

_, offlineRestoreOk := diff.GetOk("offline_restore")
if offlineRestoreOk && service != "databases-for-mongodb" && plan != "enterprise" {
return fmt.Errorf("[ERROR] offline_restore is only supported for databases-for-mongodb enterprise")
}

return nil
}

Expand Down Expand Up @@ -1219,6 +1232,10 @@ func resourceIBMDatabaseInstanceCreate(context context.Context, d *schema.Resour
params.PITRTimeStamp = &pitrTimeTrimmed
}

if offlineRestore, ok := d.GetOk("offline_restore"); ok {
params.OfflineRestore = offlineRestore.(bool)
}

serviceEndpoint := d.Get("service_endpoints").(string)
params.ServiceEndpoints = serviceEndpoint
parameters, _ := json.Marshal(params)
Expand Down Expand Up @@ -2330,7 +2347,6 @@ func waitForDatabaseInstanceCreate(d *schema.ResourceData, meta interface{}, ins
waitErr := waitForICDReady(meta, instanceID)
if waitErr != nil {
return false, fmt.Errorf("[ERROR] Error ICD interface not ready after create: %s with error %s\n", instanceID, waitErr)

}

return stateConf.WaitForState()
Expand Down
Loading

0 comments on commit cf3b4e2

Please sign in to comment.