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

enhancement(snapshot): added support for cross region snapshot copy #4678

Merged
merged 2 commits into from
Jul 20, 2023
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
14 changes: 13 additions & 1 deletion examples/ibm-is-ng/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -1273,6 +1273,18 @@ data "ibm_is_share" "is_share" {
data "ibm_is_shares" "is_shares" {
}

// snapshot cross region

provider "ibm" {
alias = "eu-de"
region = "eu-de"
}

resource "ibm_is_snapshot" "b_snapshot_copy" {
provider = ibm.eu-de
name = "my-snapshot-boot-copy"
source_snapshot_crn = ibm_is_snapshot.b_snapshot.crn
}

// image deprecate and obsolete

Expand All @@ -1282,4 +1294,4 @@ resource "ibm_is_image_deprecate" "example" {

resource "ibm_is_image_obsolete" "example" {
image = ibm_is_image.image1.id
}
}
11 changes: 9 additions & 2 deletions ibm/acctest/acctest.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ var VSIUnattachedBootVolumeID string
var VSIDataVolumeID string
var ISRouteDestination string
var ISRouteNextHop string
var ISSnapshotCRN string
var WorkspaceID string
var TemplateID string
var ActionID string
Expand Down Expand Up @@ -594,8 +595,8 @@ func init() {
IsImage = os.Getenv("IS_IMAGE")
if IsImage == "" {
//IsImage = "fc538f61-7dd6-4408-978c-c6b85b69fe76" // for classic infrastructure
IsImage = "r006-13938c0a-89e4-4370-b59b-55cd1402562d" // for next gen infrastructure
fmt.Println("[INFO] Set the environment variable IS_IMAGE for testing ibm_is_instance, ibm_is_floating_ip else it is set to default value 'r006-ed3f775f-ad7e-4e37-ae62-7199b4988b00'")
IsImage = "r006-907911a7-0ffe-467e-8821-3cc9a0d82a39" // for next gen infrastructure ibm-centos-7-9-minimal-amd64-10 image
fmt.Println("[INFO] Set the environment variable IS_IMAGE for testing ibm_is_instance, ibm_is_floating_ip else it is set to default value 'r006-907911a7-0ffe-467e-8821-3cc9a0d82a39'")
}

IsWinImage = os.Getenv("IS_WIN_IMAGE")
Expand Down Expand Up @@ -765,6 +766,12 @@ func init() {
fmt.Println("[INFO] Set the environment variable SL_ROUTE_NEXTHOP else it is set to default value '10.0.0.4'")
}

ISSnapshotCRN = os.Getenv("IS_SNAPSHOT_CRN")
if ISSnapshotCRN == "" {
ISSnapshotCRN = "crn:v1:bluemix:public:is:ca-tor:a/xxxxxxxx::snapshot:xxxx-xxxxc-xxx-xxxx-xxxx-xxxxxxxxxx"
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"
Expand Down
210 changes: 206 additions & 4 deletions ibm/service/vpc/data_source_ibm_is_snapshot.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,74 @@ func DataSourceSnapshot() *schema.Resource {
ValidateFunc: validate.InvokeDataSourceValidator("ibm_is_snapshot", "identifier"),
},

isSnapshotCopies: {
Type: schema.TypeList,
Computed: true,
Description: "The copies of this snapshot in other regions.",
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"crn": &schema.Schema{
Type: schema.TypeString,
Computed: true,
Description: "The CRN for the copied snapshot.",
},
"deleted": &schema.Schema{
Type: schema.TypeList,
Computed: true,
Description: "If present, this property indicates the referenced resource has been deleted, and provides some supplementary information.",
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"more_info": &schema.Schema{
Type: schema.TypeString,
Computed: true,
Description: "Link to documentation about deleted resources.",
},
},
},
},
"href": &schema.Schema{
Type: schema.TypeString,
Computed: true,
Description: "The URL for the copied snapshot.",
},
"id": &schema.Schema{
Type: schema.TypeString,
Computed: true,
Description: "The unique identifier for the copied snapshot.",
},
"name": &schema.Schema{
Type: schema.TypeString,
Computed: true,
Description: "The name for the copied snapshot. The name is unique across all snapshots in the copied snapshot's native region.",
},
"remote": &schema.Schema{
Type: schema.TypeList,
Computed: true,
Description: "If present, this property indicates the referenced resource is remote to this region,and identifies the native region.",
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"href": &schema.Schema{
Type: schema.TypeString,
Computed: true,
Description: "The URL for this region.",
},
"name": &schema.Schema{
Type: schema.TypeString,
Computed: true,
Description: "The globally unique name for this region.",
},
},
},
},
"resource_type": &schema.Schema{
Type: schema.TypeString,
Computed: true,
Description: "The resource type.",
},
},
},
},

isSnapshotName: {
Type: schema.TypeString,
Optional: true,
Expand All @@ -45,6 +113,75 @@ func DataSourceSnapshot() *schema.Resource {
Computed: true,
Description: "Snapshot source volume id",
},
isSnapshotSourceSnapshot: {
Type: schema.TypeList,
Optional: true,
Computed: true,
Description: "If present, the source snapshot this snapshot was created from.",
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"crn": &schema.Schema{
Type: schema.TypeString,
Optional: true,
Computed: true,
Description: "The CRN of the source snapshot.",
},
"deleted": &schema.Schema{
Type: schema.TypeList,
Computed: true,
Description: "If present, this property indicates the referenced resource has been deleted, and providessome supplementary information.",
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"more_info": &schema.Schema{
Type: schema.TypeString,
Computed: true,
Description: "Link to documentation about deleted resources.",
},
},
},
},
"href": &schema.Schema{
Type: schema.TypeString,
Computed: true,
Description: "The URL for the source snapshot.",
},
"id": &schema.Schema{
Type: schema.TypeString,
Computed: true,
Description: "The unique identifier for the source snapshot.",
},
"name": &schema.Schema{
Type: schema.TypeString,
Computed: true,
Description: "The name for the source snapshot. The name is unique across all snapshots in the source snapshot's native region.",
},
"remote": &schema.Schema{
Type: schema.TypeList,
Computed: true,
Description: "If present, this property indicates the referenced resource is remote to this region,and identifies the native region.",
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"href": &schema.Schema{
Type: schema.TypeString,
Computed: true,
Description: "The URL for this region.",
},
"name": &schema.Schema{
Type: schema.TypeString,
Computed: true,
Description: "The globally unique name for this region.",
},
},
},
},
"resource_type": &schema.Schema{
Type: schema.TypeString,
Computed: true,
Description: "The resource type.",
},
},
},
},
isSnapshotSourceImage: {
Type: schema.TypeString,
Computed: true,
Expand Down Expand Up @@ -250,9 +387,41 @@ func snapshotGetByNameOrID(d *schema.ResourceData, meta interface{}, name, id st
d.Set(isSnapshotLCState, *snapshot.LifecycleState)
d.Set(isSnapshotResourceType, *snapshot.ResourceType)
d.Set(isSnapshotBootable, *snapshot.Bootable)

// source snapshot
sourceSnapshotList := []map[string]interface{}{}
if snapshot.SourceSnapshot != nil {
sourceSnapshot := map[string]interface{}{}
sourceSnapshot["href"] = snapshot.SourceSnapshot.Href
if snapshot.SourceSnapshot.Deleted != nil {
snapshotSourceSnapshotDeletedMap := map[string]interface{}{}
snapshotSourceSnapshotDeletedMap["more_info"] = snapshot.SourceSnapshot.Deleted.MoreInfo
sourceSnapshot["deleted"] = []map[string]interface{}{snapshotSourceSnapshotDeletedMap}
}
sourceSnapshot["id"] = snapshot.SourceSnapshot.ID
sourceSnapshot["name"] = snapshot.SourceSnapshot.Name

sourceSnapshot["resource_type"] = snapshot.SourceSnapshot.ResourceType
sourceSnapshotList = append(sourceSnapshotList, sourceSnapshot)
}
d.Set(isSnapshotSourceSnapshot, sourceSnapshotList)

// snapshot copies
snapshotCopies := []map[string]interface{}{}
if snapshot.Copies != nil {
for _, copiesItem := range snapshot.Copies {
copiesMap, err := dataSourceIBMIsSnapshotsSnapshotCopiesItemToMap(&copiesItem)
if err != nil {
return fmt.Errorf("[ERROR] Error fetching snapshot copies: %s", err)
}
snapshotCopies = append(snapshotCopies, copiesMap)
}
}
d.Set(isSnapshotCopies, snapshotCopies)

if snapshot.UserTags != nil {
if err = d.Set(isSnapshotUserTags, snapshot.UserTags); err != nil {
return fmt.Errorf("Error setting user tags: %s", err)
return fmt.Errorf("[ERROR] Error setting user tags: %s", err)
}
}
if snapshot.ResourceGroup != nil && snapshot.ResourceGroup.ID != nil {
Expand Down Expand Up @@ -297,7 +466,7 @@ func snapshotGetByNameOrID(d *schema.ResourceData, meta interface{}, name, id st
accesstags, err := flex.GetGlobalTagsUsingCRN(meta, *snapshot.CRN, "", isAccessTagType)
if err != nil {
log.Printf(
"Error on get of resource snapshot (%s) access tags: %s", d.Id(), err)
"[ERROR] Error on get of resource snapshot (%s) access tags: %s", d.Id(), err)
}
d.Set(isSnapshotAccessTags, accesstags)
return nil
Expand Down Expand Up @@ -325,12 +494,45 @@ func snapshotGetByNameOrID(d *schema.ResourceData, meta interface{}, name, id st
d.Set(isSnapshotLCState, *snapshot.LifecycleState)
d.Set(isSnapshotResourceType, *snapshot.ResourceType)
d.Set(isSnapshotBootable, *snapshot.Bootable)

if snapshot.EncryptionKey != nil && snapshot.EncryptionKey.CRN != nil {
d.Set(isSnapshotEncryptionKey, *snapshot.EncryptionKey.CRN)
}
// source snapshot
sourceSnapshotList := []map[string]interface{}{}
if snapshot.SourceSnapshot != nil {
sourceSnapshot := map[string]interface{}{}
sourceSnapshot["href"] = snapshot.SourceSnapshot.Href
sourceSnapshot["crn"] = snapshot.SourceSnapshot.CRN
if snapshot.SourceSnapshot.Deleted != nil {
snapshotSourceSnapshotDeletedMap := map[string]interface{}{}
snapshotSourceSnapshotDeletedMap["more_info"] = snapshot.SourceSnapshot.Deleted.MoreInfo
sourceSnapshot["deleted"] = []map[string]interface{}{snapshotSourceSnapshotDeletedMap}
}
sourceSnapshot["id"] = snapshot.SourceSnapshot.ID
sourceSnapshot["name"] = snapshot.SourceSnapshot.Name
sourceSnapshot["resource_type"] = snapshot.SourceSnapshot.ResourceType
sourceSnapshotList = append(sourceSnapshotList, sourceSnapshot)
}
// snapshot copies
snapshotCopies := []map[string]interface{}{}
if snapshot.Copies != nil {
for _, copiesItem := range snapshot.Copies {
copiesMap, err := dataSourceIBMIsSnapshotsSnapshotCopiesItemToMap(&copiesItem)
if err != nil {
return fmt.Errorf("[ERROR] Error fetching snapshot copies: %s", err)
}
snapshotCopies = append(snapshotCopies, copiesMap)
}
}
d.Set(isSnapshotCopies, snapshotCopies)

if snapshot.CapturedAt != nil {
d.Set(isSnapshotCapturedAt, (*snapshot.CapturedAt).String())
}
if snapshot.UserTags != nil {
if err = d.Set(isSnapshotUserTags, snapshot.UserTags); err != nil {
return fmt.Errorf("Error setting user tags: %s", err)
return fmt.Errorf("[ERROR] Error setting user tags: %s", err)
}
}
if snapshot.ResourceGroup != nil && snapshot.ResourceGroup.ID != nil {
Expand Down Expand Up @@ -374,7 +576,7 @@ func snapshotGetByNameOrID(d *schema.ResourceData, meta interface{}, name, id st
accesstags, err := flex.GetGlobalTagsUsingCRN(meta, *snapshot.CRN, "", isAccessTagType)
if err != nil {
log.Printf(
"Error on get of resource snapshot (%s) access tags: %s", d.Id(), err)
"[ERROR] Error on get of resource snapshot (%s) access tags: %s", d.Id(), err)
}
d.Set(isSnapshotAccessTags, accesstags)
return nil
Expand Down
Loading