Skip to content

Commit

Permalink
Feature(share-crr): Share cross region replication (#4995)
Browse files Browse the repository at this point in the history
* feature(share-crr): Share cross region replication

* sdk updates

* updated last sync options

* updated sdk and latest_sync

* updated schema and doc

* tf example

* doc and schema correction

* acceptance test

* sdk changes

* updated sdk

* added nil check

* doc link added

* remove common folder sdk

* doc update
  • Loading branch information
deepaksibm authored Dec 18, 2023
1 parent c72e9f8 commit fc7ba35
Show file tree
Hide file tree
Showing 11 changed files with 236 additions and 28 deletions.
9 changes: 8 additions & 1 deletion examples/ibm-is-ng/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -1408,7 +1408,14 @@ resource "ibm_is_image_obsolete" "example" {
image = ibm_is_image.image1.id
}


resource "ibm_is_share" "share" {
zone = "us-east-1"
source_share_crn = "crn:v1:staging:public:is:us-south-1:a/efe5afc483594adaa8325e2b4d1290df::share:r134-d8c8821c-a227-451d-a9ed-0c0cd2358829"
encryption_key = "crn:v1:staging:public:kms:us-south:a/efe5afc483594adaa8325e2b4d1290df:1be45161-6dae-44ca-b248-837f98004057:key:3dd21cc5-cc20-4f7c-bc62-8ec9a8a3d1bd"
replication_cron_spec = "5 * * * *"
name = "tfp-temp-crr"
profile = "dp2"
}
//snapshot consistency group

resource "ibm_is_snapshot_consistency_group" "is_snapshot_consistency_group_instance" {
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ require (
github.com/IBM/schematics-go-sdk v0.2.2
github.com/IBM/secrets-manager-go-sdk/v2 v2.0.2
github.com/IBM/vpc-beta-go-sdk v0.6.0
github.com/IBM/vpc-go-sdk v0.45.0
github.com/IBM/vpc-go-sdk v0.46.0
github.com/ScaleFT/sshkeys v0.0.0-20200327173127-6142f742bca5
github.com/akamai/AkamaiOPEN-edgegrid-golang v1.2.2
github.com/akamai/AkamaiOPEN-edgegrid-golang/v5 v5.0.0
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,8 @@ github.com/IBM/vpc-beta-go-sdk v0.6.0 h1:wfM3AcW3zOM3xsRtZ+EA6+sESlGUjQ6Yf4n5QQy
github.com/IBM/vpc-beta-go-sdk v0.6.0/go.mod h1:fzHDAQIqH/5yJmYsKodKHLcqxMDT+yfH6vZjdiw8CQA=
github.com/IBM/vpc-go-sdk v0.45.0 h1:RFbUZH5vBRGAEW5+jRzbDlxB+a+GvG9EBhyYO52Tvrs=
github.com/IBM/vpc-go-sdk v0.45.0/go.mod h1:4Hs5d/aClmsxAzwDQkwG+ri0vW2ykPJdpM6hDLRwKcA=
github.com/IBM/vpc-go-sdk v0.46.0 h1:OwXH3oaYgYmzt559n77AteSpNsW4H1PoeHcR4EOolzk=
github.com/IBM/vpc-go-sdk v0.46.0/go.mod h1:4Hs5d/aClmsxAzwDQkwG+ri0vW2ykPJdpM6hDLRwKcA=
github.com/Jeffail/gabs v1.1.1 h1:V0uzR08Hj22EX8+8QMhyI9sX2hwRu+/RJhJUmnwda/E=
github.com/Jeffail/gabs v1.1.1/go.mod h1:6xMvQMK4k33lb7GUUpaAPh6nKMmemQeg5d4gn7/bOXc=
github.com/Logicalis/asn1 v0.0.0-20190312173541-d60463189a56 h1:vuquMR410psHNax14XKNWa0Ae/kYgWJcXi0IFuX60N0=
Expand Down
14 changes: 14 additions & 0 deletions ibm/acctest/acctest.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@ var (
DedicatedHostGroupFamily string
DedicatedHostGroupClass string
ShareProfileName string
SourceShareCRN string
ShareEncryptionKey string
VNIId string
VolumeProfileName string
VSIUnattachedBootVolumeID string
Expand Down Expand Up @@ -848,6 +850,18 @@ func init() {
fmt.Println("[INFO] Set the environment variable IS_SHARE_PROFILE for testing ibm_is_instance resource else it is set to default value 'tier-3iops'")
}

SourceShareCRN = os.Getenv("IS_SOURCE_SHARE_CRN")
if SourceShareCRN == "" {
SourceShareCRN = "crn:v1:staging:public:is:us-east-1:a/efe5afc483594adaa8325e2b4d1290df::share:r142-a106f162-86e4-4d7f-be75-193cc55a93e9" // for next gen infrastructure
fmt.Println("[INFO] Set the environment variable IS_SHARE_PROFILE for testing ibm_is_instance resource else it is set to default value")
}

ShareEncryptionKey = os.Getenv("IS_SHARE_ENCRYPTION_KEY")
if ShareEncryptionKey == "" {
ShareEncryptionKey = "crn:v1:staging:public:kms:us-south:a/efe5afc483594adaa8325e2b4d1290df:1be45161-6dae-44ca-b248-837f98004057:key:3dd21cc5-cc20-4f7c-bc62-8ec9a8a3d1bd" // for next gen infrastructure
fmt.Println("[INFO] Set the environment variable IS_SHARE_PROFILE for testing ibm_is_instance resource else it is set to default value")
}

VolumeProfileName = os.Getenv("IS_VOLUME_PROFILE")
if VolumeProfileName == "" {
VolumeProfileName = "general-purpose"
Expand Down
36 changes: 35 additions & 1 deletion ibm/service/vpc/data_source_ibm_is_share.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,30 @@ func DataSourceIbmIsShare() *schema.Resource {
Computed: true,
Description: "The maximum input/output operation performance bandwidth per second for the file share.",
},
"latest_sync": &schema.Schema{
Type: schema.TypeList,
Computed: true,
Description: "Information about the latest synchronization for this file share.",
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"completed_at": &schema.Schema{
Type: schema.TypeString,
Computed: true,
Description: "The completed date and time of last synchronization between the replica share and its source.",
},
"data_transferred": &schema.Schema{
Type: schema.TypeInt,
Computed: true,
Description: "The data transferred (in bytes) in the last synchronization between the replica and its source.",
},
"started_at": &schema.Schema{
Type: schema.TypeString,
Computed: true,
Description: "The start date and time of last synchronization between the replica share and its source.",
},
},
},
},
"latest_job": &schema.Schema{
Type: schema.TypeList,
Computed: true,
Expand Down Expand Up @@ -410,7 +434,17 @@ func dataSourceIbmIsShareRead(context context.Context, d *schema.ResourceData, m
if err = d.Set("iops", share.Iops); err != nil {
return diag.FromErr(fmt.Errorf("Error setting iops: %s", err))
}

latest_syncs := []map[string]interface{}{}
if share.LatestSync != nil {
latest_sync := make(map[string]interface{})
latest_sync["completed_at"] = flex.DateTimeToString(share.LatestSync.CompletedAt)
if share.LatestSync.DataTransferred != nil {
latest_sync["data_transferred"] = *share.LatestSync.DataTransferred
}
latest_sync["started_at"] = flex.DateTimeToString(share.LatestSync.CompletedAt)
latest_syncs = append(latest_syncs, latest_sync)
}
d.Set("latest_sync", latest_syncs)
if share.LatestJob != nil {
err = d.Set("latest_job", dataSourceShareFlattenLatestJob(*share.LatestJob))
if err != nil {
Expand Down
35 changes: 35 additions & 0 deletions ibm/service/vpc/data_source_ibm_is_shares.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,30 @@ func DataSourceIbmIsShares() *schema.Resource {
Computed: true,
Description: "The maximum input/output operation performance bandwidth per second for the file share.",
},
"latest_sync": &schema.Schema{
Type: schema.TypeList,
Computed: true,
Description: "Information about the latest synchronization for this file share.",
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"completed_at": &schema.Schema{
Type: schema.TypeString,
Computed: true,
Description: "The completed date and time of last synchronization between the replica share and its source.",
},
"data_transferred": &schema.Schema{
Type: schema.TypeInt,
Computed: true,
Description: "The data transferred (in bytes) in the last synchronization between the replica and its source.",
},
"started_at": &schema.Schema{
Type: schema.TypeString,
Computed: true,
Description: "The start date and time of last synchronization between the replica share and its source.",
},
},
},
},
"latest_job": &schema.Schema{
Type: schema.TypeList,
Computed: true,
Expand Down Expand Up @@ -455,6 +479,17 @@ func dataSourceShareCollectionSharesToMap(meta interface{}, sharesItem vpcv1.Sha
if sharesItem.Iops != nil {
sharesMap["iops"] = sharesItem.Iops
}
latest_syncs := []map[string]interface{}{}
if sharesItem.LatestSync != nil {
latest_sync := make(map[string]interface{})
latest_sync["completed_at"] = flex.DateTimeToString(sharesItem.LatestSync.CompletedAt)
if sharesItem.LatestSync.DataTransferred != nil {
latest_sync["data_transferred"] = *sharesItem.LatestSync.DataTransferred
}
latest_sync["started_at"] = flex.DateTimeToString(sharesItem.LatestSync.CompletedAt)
latest_syncs = append(latest_syncs, latest_sync)
}
sharesMap["latest_sync"] = latest_syncs
if sharesItem.LifecycleState != nil {
sharesMap["lifecycle_state"] = sharesItem.LifecycleState
}
Expand Down
89 changes: 69 additions & 20 deletions ibm/service/vpc/resource_ibm_is_share.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,11 @@ func ResourceIbmIsShare() *schema.Resource {

Schema: map[string]*schema.Schema{
"encryption_key": {
Type: schema.TypeString,
Optional: true,
RequiredWith: []string{"size"},
ForceNew: true,
Computed: true,
Description: "The CRN of the key to use for encrypting this file share.If no encryption key is provided, the share will not be encrypted.",
Type: schema.TypeString,
Optional: true,
ForceNew: true,
Computed: true,
Description: "The CRN of the key to use for encrypting this file share.If no encryption key is provided, the share will not be encrypted.",
},
"initial_owner": {
Type: schema.TypeList,
Expand Down Expand Up @@ -105,8 +104,8 @@ func ResourceIbmIsShare() *schema.Resource {
Type: schema.TypeInt,
Optional: true,
Computed: true,
ExactlyOneOf: []string{"size", "source_share"},
ConflictsWith: []string{"replication_cron_spec", "source_share"},
ExactlyOneOf: []string{"size", "source_share", "source_share_crn"},
ConflictsWith: []string{"replication_cron_spec", "source_share", "source_share_crn"},
ValidateFunc: validate.InvokeValidator("ibm_is_share", "size"),
Description: "The size of the file share rounded up to the next gigabyte.",
},
Expand Down Expand Up @@ -511,16 +510,25 @@ func ResourceIbmIsShare() *schema.Resource {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
ConflictsWith: []string{"replica_share", "size"},
Computed: true,
ConflictsWith: []string{"replica_share", "size", "source_share_crn"},
RequiredWith: []string{"replication_cron_spec"},
Description: "The ID of the source file share for this replica file share. The specified file share must not already have a replica, and must not be a replica.",
},
"source_share_crn": &schema.Schema{
Type: schema.TypeString,
Optional: true,
ForceNew: true,
Computed: true,
ConflictsWith: []string{"replica_share", "size", "source_share"},
RequiredWith: []string{"replication_cron_spec"},
Description: "The CRN of the source file share for this replica file share. The specified file share must not already have a replica, and must not be a replica.",
},
"replication_cron_spec": &schema.Schema{
Type: schema.TypeString,
Optional: true,
DiffSuppressFunc: suppressCronSpecDiff,
Computed: true,
RequiredWith: []string{"source_share"},
ConflictsWith: []string{"replica_share", "size"},
Description: "The cron specification for the file share replication schedule.Replication of a share can be scheduled to occur at most once per hour.",
},
Expand Down Expand Up @@ -563,6 +571,30 @@ func ResourceIbmIsShare() *schema.Resource {
Computed: true,
Description: "The date and time that the file share was last synchronized to its replica.This property will be present when the `replication_role` is `source`.",
},
"latest_sync": &schema.Schema{
Type: schema.TypeList,
Computed: true,
Description: "Information about the latest synchronization for this file share.",
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"completed_at": &schema.Schema{
Type: schema.TypeString,
Computed: true,
Description: "The completed date and time of last synchronization between the replica share and its source.",
},
"data_transferred": &schema.Schema{
Type: schema.TypeInt,
Computed: true,
Description: "The data transferred (in bytes) in the last synchronization between the replica and its source.",
},
"started_at": &schema.Schema{
Type: schema.TypeString,
Computed: true,
Description: "The start date and time of last synchronization between the replica share and its source.",
},
},
},
},
"latest_job": &schema.Schema{
Type: schema.TypeList,
Computed: true,
Expand Down Expand Up @@ -727,17 +759,18 @@ func resourceIbmIsShareCreate(context context.Context, d *schema.ResourceData, m
accessControlMode := accessControlModeIntf.(string)
sharePrototype.AccessControlMode = &accessControlMode
}
if encryptionKeyIntf, ok := d.GetOk("encryption_key"); ok {
encryptionKey := encryptionKeyIntf.(string)
encryptionKeyIdentity := &vpcv1.EncryptionKeyIdentity{
CRN: &encryptionKey,
}
sharePrototype.EncryptionKey = encryptionKeyIdentity
}
if sizeIntf, ok := d.GetOk("size"); ok {

size := int64(sizeIntf.(int))
sharePrototype.Size = &size
if encryptionKeyIntf, ok := d.GetOk("encryption_key"); ok {
encryptionKey := encryptionKeyIntf.(string)
encryptionKeyIdentity := &vpcv1.EncryptionKeyIdentity{
CRN: &encryptionKey,
}
sharePrototype.EncryptionKey = encryptionKeyIdentity
}

initial_owner := &vpcv1.ShareInitialOwner{}
if initialOwnerIntf, ok := d.GetOk("initial_owner"); ok {
initialOwnerMap := initialOwnerIntf.([]interface{})[0].(map[string]interface{})
Expand Down Expand Up @@ -823,7 +856,15 @@ func resourceIbmIsShareCreate(context context.Context, d *schema.ResourceData, m
sharePrototype.SourceShare = &vpcv1.ShareIdentity{
ID: &sourceShare,
}
} else {
sourceShareCRN := d.Get("source_share_crn").(string)
if sourceShareCRN != "" {
sharePrototype.SourceShare = &vpcv1.ShareIdentity{
CRN: &sourceShareCRN,
}
}
}

replicationCronSpec := d.Get("replication_cron_spec").(string)
sharePrototype.ReplicationCronSpec = &replicationCronSpec
}
Expand Down Expand Up @@ -1075,9 +1116,17 @@ func resourceIbmIsShareRead(context context.Context, d *schema.ResourceData, met
return diag.FromErr(fmt.Errorf("Error setting resource_type: %s", err))
}

// if share.LastSyncAt != nil {
// d.Set("last_sync_at", share.LastSyncAt.String())
// }
latest_syncs := []map[string]interface{}{}
if share.LatestSync != nil {
latest_sync := make(map[string]interface{})
latest_sync["completed_at"] = flex.DateTimeToString(share.LatestSync.CompletedAt)
if share.LatestSync.DataTransferred != nil {
latest_sync["data_transferred"] = *share.LatestSync.DataTransferred
}
latest_sync["started_at"] = flex.DateTimeToString(share.LatestSync.CompletedAt)
latest_syncs = append(latest_syncs, latest_sync)
}
d.Set("latest_sync", latest_syncs)
latest_jobs := []map[string]interface{}{}
if share.LatestJob != nil {
latest_job := make(map[string]interface{})
Expand Down
35 changes: 34 additions & 1 deletion ibm/service/vpc/resource_ibm_is_share_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,28 @@ func TestAccIbmIsShareBasic(t *testing.T) {
})
}

func TestAccIbmIsShareCrossRegionReplication(t *testing.T) {
var conf vpcv1.Share
name := fmt.Sprintf("tf-fs-name-%d", acctest.RandIntRange(10, 100))
resource.Test(t, resource.TestCase{
PreCheck: func() { acc.TestAccPreCheck(t) },
Providers: acc.TestAccProviders,
CheckDestroy: testAccCheckIbmIsShareDestroy,
Steps: []resource.TestStep{
{
Config: testAccCheckIbmIsShareCrossRegionReplicaConfig(name),
Check: resource.ComposeAggregateTestCheckFunc(
testAccCheckIbmIsShareExists("ibm_is_share.is_share", conf),
resource.TestCheckResourceAttrSet("ibm_is_share.is_share", "source_share_crn"),
resource.TestCheckResourceAttrSet("ibm_is_share.is_share", "encryption_key"),
resource.TestCheckResourceAttr("ibm_is_share.is_share", "name", name),
resource.TestCheckResourceAttr("ibm_is_share.is_share", "encryption", "user_managed"),
),
},
},
})
}

func TestAccIbmIsShareAllArgs(t *testing.T) {
var conf vpcv1.Share

Expand Down Expand Up @@ -157,7 +179,18 @@ func testAccCheckIbmIsShareConfigBasic(name string) string {
}
`, name, acc.ShareProfileName)
}

func testAccCheckIbmIsShareCrossRegionReplicaConfig(name string) string {
return fmt.Sprintf(`
resource "ibm_is_share" "is_share" {
zone = "us-south-2"
encryption_key = "%s"
source_share_crn = "%s"
replication_cron_spec = "0 */5 * * *"
name = "%s"
profile = "%s"
}
`, acc.ShareEncryptionKey, acc.SourceShareCRN, name, acc.ShareProfileName)
}
func testAccCheckIbmIsShareConfig(vpcName, name string, size int, shareTergetName string) string {
return fmt.Sprintf(`
Expand Down
7 changes: 6 additions & 1 deletion website/docs/d/is_share.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,14 @@ The following attributes are exported:
- `created_at` - The date and time that the file share is created.
- `crn` - The CRN for this share.
- `encryption` - The type of encryption used for this file share.
- `encryption_key` - The CRN of the key used to encrypt this file share. Nested `encryption_key` blocks have the following structure:
- `encryption_key` - The CRN of the key used to encrypt this file share.
- `href` - The URL for this share.
- `iops` - The maximum input/output operation performance bandwidth per second for the file share.
- `latest_sync` - (List) Information about the latest synchronization for this file share.
Nested `latest_sync` blocks have the following structure:
- `completed_at` - (String) The completed date and time of last synchronization between the replica share and its source.
- `data_transferred` - (Integer) The data transferred (in bytes) in the last synchronization between the replica and its source.
- `started_at` - (String) The start date and time of last synchronization between the replica share and its source.
- `latest_job` - The latest job associated with this file share.This property will be absent if no jobs have been created for this file share. Nested `latest_job` blocks have the following structure:
- `status` - The status of the file share job
- `status_reasons` - The reasons for the file share job status (if any). Nested `status_reasons` blocks have the following structure:
Expand Down
7 changes: 6 additions & 1 deletion website/docs/d/is_shares.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,15 @@ The following attributes are exported:
- `created_at` - The date and time that the file share is created.
- `crn` - The CRN for this share.
- `encryption` - The type of encryption used for this file share.
- `encryption_key` - The CRN of the key used to encrypt this file share. Nested `encryption_key` blocks have the following structure:
- `encryption_key` - The CRN of the key used to encrypt this file share.
- `href` - The URL for this share.
- `id` - The unique identifier for this file share.
- `iops` - The maximum input/output operation performance bandwidth per second for the file share.
- `latest_sync` - (List) Information about the latest synchronization for this file share.
Nested `latest_sync` blocks have the following structure:
- `completed_at` - (String) The completed date and time of last synchronization between the replica share and its source.
- `data_transferred` - (Integer) The data transferred (in bytes) in the last synchronization between the replica and its source.
- `started_at` - (String) The start date and time of last synchronization between the replica share and its source.
- `latest_job` - The latest job associated with this file share.This property will be absent if no jobs have been created for this file share. Nested `latest_job` blocks have the following structure:
- `status` - The status of the file share job
- `status_reasons` - The reasons for the file share job status (if any). Nested `status_reasons` blocks have the following structure:
Expand Down
Loading

0 comments on commit fc7ba35

Please sign in to comment.