diff --git a/ibm/acctest/acctest.go b/ibm/acctest/acctest.go index 211e496f85..87efdc973f 100644 --- a/ibm/acctest/acctest.go +++ b/ibm/acctest/acctest.go @@ -262,6 +262,7 @@ var ( Pi_capture_storage_image_path string Pi_capture_cloud_storage_access_key string Pi_capture_cloud_storage_secret_key string + Pi_capture_cloud_storage_region string ) var ISDelegegatedVPC string @@ -1322,6 +1323,12 @@ func init() { fmt.Println("[INFO] Set the environment variable PI_CAPTURE_CLOUD_STORAGE_SECRET_KEY for testing Pi_capture_cloud_storage_secret_key resource else it is set to default value 'terraform-test-power'") } + Pi_capture_cloud_storage_region = os.Getenv("PI_CAPTURE_CLOUD_STORAGE_REGION") + if Pi_capture_cloud_storage_region == "" { + Pi_capture_cloud_storage_region = "us-south" + fmt.Println("[INFO] Set the environment variable PI_CAPTURE_CLOUD_STORAGE_REGION for testing Pi_capture_cloud_storage_region resource else it is set to default value 'us-south'") + } + Pi_shared_processor_pool_id = os.Getenv("PI_SHARED_PROCESSOR_POOL_ID") if Pi_shared_processor_pool_id == "" { Pi_shared_processor_pool_id = "tf-pi-shared-processor-pool" diff --git a/ibm/service/power/ibm_pi_constants.go b/ibm/service/power/ibm_pi_constants.go index f587aa1c9a..f6e90283e2 100644 --- a/ibm/service/power/ibm_pi_constants.go +++ b/ibm/service/power/ibm_pi_constants.go @@ -11,6 +11,13 @@ const ( Arg_AntiAffinityInstances = "pi_anti_affinity_instances" Arg_AntiAffinityVolumes = "pi_anti_affinity_volumes" Arg_BootVolumeReplicationEnabled = "pi_boot_volume_replication_enabled" + Arg_CaptureCloudStorageAccessKey = "pi_capture_cloud_storage_access_key" + Arg_CaptureCloudStorageRegion = "pi_capture_cloud_storage_region" + Arg_CaptureCloudStorageSecretKey = "pi_capture_cloud_storage_secret_key" + Arg_CaptureDestination = "pi_capture_destination" + Arg_CaptureName = "pi_capture_name" + Arg_CaptureStorageImagePath = "pi_capture_storage_image_path" + Arg_CaptureVolumeIDs = "pi_capture_volume_ids" Arg_Cidr = "pi_cidr" Arg_CloudConnectionID = "pi_cloud_connection_id" Arg_CloudConnectionName = "pi_cloud_connection_name" @@ -509,8 +516,10 @@ const ( Bidirectional_BGP = "bidirectional-bgp" Bidirectional_L2Out = "bidirectional-l2out" Bidirectional_Static_Route = "bidirectional-static-route" + Both = "both" BYOL = "byol" Capped = "capped" + CloudStorage = "cloud-storage" Critical = "CRITICAL" CUSTOM_VIRTUAL_CORES = "custom-virtualcores" Dedicated = "dedicated" @@ -530,6 +539,7 @@ const ( Host = "host" HostGroup = "hostGroup" ICMP = "icmp" + ImageCatalog = "image-catalog" Internal_Only = "internal-only" IPV4_Address = "ipv4-address" L2 = "L2" diff --git a/ibm/service/power/resource_ibm_pi_capture.go b/ibm/service/power/resource_ibm_pi_capture.go index 5c35be92cc..bc22efddde 100644 --- a/ibm/service/power/resource_ibm_pi_capture.go +++ b/ibm/service/power/resource_ibm_pi_capture.go @@ -11,8 +11,8 @@ import ( "strings" "time" + "github.com/IBM-Cloud/power-go-client/clients/instance" st "github.com/IBM-Cloud/power-go-client/clients/instance" - "github.com/IBM-Cloud/power-go-client/helpers" "github.com/IBM-Cloud/power-go-client/power/client/p_cloud_images" "github.com/IBM-Cloud/power-go-client/power/models" "github.com/IBM-Cloud/terraform-provider-ibm/ibm/conns" @@ -21,11 +21,9 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/customdiff" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" ) -const cloudStorageDestination string = "cloud-storage" -const imageCatalogDestination string = "image-catalog" - func ResourceIBMPICapture() *schema.Resource { return &schema.Resource{ CreateContext: resourceIBMPICaptureCreate, @@ -46,72 +44,69 @@ func ResourceIBMPICapture() *schema.Resource { ), Schema: map[string]*schema.Schema{ - - helpers.PICloudInstanceId: { - Type: schema.TypeString, - Required: true, + // Arguments + Arg_CaptureCloudStorageAccessKey: { + Description: "Name of Cloud Storage Access Key", ForceNew: true, - Description: " Cloud Instance ID - This is the service_instance_id.", - }, - - helpers.PIInstanceName: { + Optional: true, + Sensitive: true, Type: schema.TypeString, - Required: true, - ForceNew: true, - Description: "Instance Name of the Power VM", }, - - helpers.PIInstanceCaptureName: { + Arg_CaptureCloudStorageRegion: { + Description: "List of Regions to use", + ForceNew: true, + Optional: true, Type: schema.TypeString, - Required: true, + }, + Arg_CaptureCloudStorageSecretKey: { + Description: "Name of the Cloud Storage Secret Key", ForceNew: true, - Description: "Name of the capture to create. Note : this must be unique", + Optional: true, + Sensitive: true, + Type: schema.TypeString, }, - - helpers.PIInstanceCaptureDestination: { - Type: schema.TypeString, - Required: true, - ForceNew: true, + Arg_CaptureDestination: { Description: "Destination for the deployable image", - ValidateFunc: validate.ValidateAllowedStringValues([]string{"image-catalog", "cloud-storage", "both"}), + ForceNew: true, + Required: true, + Type: schema.TypeString, + ValidateFunc: validate.ValidateAllowedStringValues([]string{ImageCatalog, CloudStorage, Both}), }, - - helpers.PIInstanceCaptureVolumeIds: { - Type: schema.TypeSet, - Optional: true, - Elem: &schema.Schema{Type: schema.TypeString}, - Set: schema.HashString, - ForceNew: true, - DiffSuppressFunc: flex.ApplyOnce, - Description: "List of Data volume IDs", + Arg_CaptureName: { + Description: "Name of the capture to create. Note : this must be unique", + ForceNew: true, + Required: true, + Type: schema.TypeString, + ValidateFunc: validation.NoZeroValues, }, - - helpers.PIInstanceCaptureCloudStorageRegion: { - Type: schema.TypeString, - Optional: true, + Arg_CaptureStorageImagePath: { + Description: "Cloud Storage Image Path (bucket-name [/folder/../..])", ForceNew: true, - Description: "List of Regions to use", - }, - - helpers.PIInstanceCaptureCloudStorageAccessKey: { - Type: schema.TypeString, Optional: true, - ForceNew: true, - Sensitive: true, - Description: "Name of Cloud Storage Access Key", - }, - helpers.PIInstanceCaptureCloudStorageSecretKey: { Type: schema.TypeString, - Optional: true, - ForceNew: true, - Sensitive: true, - Description: "Name of the Cloud Storage Secret Key", }, - helpers.PIInstanceCaptureCloudStorageImagePath: { - Type: schema.TypeString, - Optional: true, - ForceNew: true, - Description: "Cloud Storage Image Path (bucket-name [/folder/../..])", + Arg_CaptureVolumeIDs: { + Description: "List of Data volume IDs", + DiffSuppressFunc: flex.ApplyOnce, + Elem: &schema.Schema{Type: schema.TypeString}, + ForceNew: true, + Optional: true, + Set: schema.HashString, + Type: schema.TypeSet, + }, + Arg_CloudInstanceID: { + Description: "The GUID of the service instance associated with an account.", + ForceNew: true, + Required: true, + Type: schema.TypeString, + ValidateFunc: validation.NoZeroValues, + }, + Arg_InstanceName: { + Description: "Instance Name of the Power VM", + ForceNew: true, + Required: true, + Type: schema.TypeString, + ValidateFunc: validation.NoZeroValues, }, Arg_UserTags: { Computed: true, @@ -127,10 +122,10 @@ func ResourceIBMPICapture() *schema.Resource { Description: "The CRN of the resource.", Type: schema.TypeString, }, - "image_id": { - Type: schema.TypeString, + Attr_ImageID: { Computed: true, - Description: "Image ID of Capture Instance", + Description: "The image id of the capture instance.", + Type: schema.TypeString, }, }, } @@ -142,41 +137,41 @@ func resourceIBMPICaptureCreate(ctx context.Context, d *schema.ResourceData, met return diag.FromErr(err) } - name := d.Get(helpers.PIInstanceName).(string) - capturename := d.Get(helpers.PIInstanceCaptureName).(string) - capturedestination := d.Get(helpers.PIInstanceCaptureDestination).(string) - cloudInstanceID := d.Get(helpers.PICloudInstanceId).(string) + name := d.Get(Arg_InstanceName).(string) + capturename := d.Get(Arg_CaptureName).(string) + capturedestination := d.Get(Arg_CaptureDestination).(string) + cloudInstanceID := d.Get(Arg_CloudInstanceID).(string) - client := st.NewIBMPIInstanceClient(context.Background(), sess, cloudInstanceID) + client := instance.NewIBMPIInstanceClient(context.Background(), sess, cloudInstanceID) captureBody := &models.PVMInstanceCapture{ CaptureDestination: &capturedestination, CaptureName: &capturename, } - if capturedestination != imageCatalogDestination { - if v, ok := d.GetOk(helpers.PIInstanceCaptureCloudStorageRegion); ok { + if capturedestination != ImageCatalog { + if v, ok := d.GetOk(Arg_CaptureCloudStorageRegion); ok { captureBody.CloudStorageRegion = v.(string) } else { - return diag.Errorf("%s is required when capture destination is %s", helpers.PIInstanceCaptureCloudStorageRegion, capturedestination) + return diag.Errorf("%s is required when capture destination is %s", Arg_CaptureCloudStorageRegion, capturedestination) } - if v, ok := d.GetOk(helpers.PIInstanceCaptureCloudStorageAccessKey); ok { + if v, ok := d.GetOk(Arg_CaptureCloudStorageAccessKey); ok { captureBody.CloudStorageAccessKey = v.(string) } else { - return diag.Errorf("%s is required when capture destination is %s ", helpers.PIInstanceCaptureCloudStorageAccessKey, capturedestination) + return diag.Errorf("%s is required when capture destination is %s ", Arg_CaptureCloudStorageAccessKey, capturedestination) } - if v, ok := d.GetOk(helpers.PIInstanceCaptureCloudStorageImagePath); ok { + if v, ok := d.GetOk(Arg_CaptureStorageImagePath); ok { captureBody.CloudStorageImagePath = v.(string) } else { - return diag.Errorf("%s is required when capture destination is %s ", helpers.PIInstanceCaptureCloudStorageImagePath, capturedestination) + return diag.Errorf("%s is required when capture destination is %s ", Arg_CaptureStorageImagePath, capturedestination) } - if v, ok := d.GetOk(helpers.PIInstanceCaptureCloudStorageSecretKey); ok { + if v, ok := d.GetOk(Arg_CaptureCloudStorageSecretKey); ok { captureBody.CloudStorageSecretKey = v.(string) } else { - return diag.Errorf("%s is required when capture destination is %s ", helpers.PIInstanceCaptureCloudStorageSecretKey, capturedestination) + return diag.Errorf("%s is required when capture destination is %s ", Arg_CaptureCloudStorageSecretKey, capturedestination) } } - if v, ok := d.GetOk(helpers.PIInstanceCaptureVolumeIds); ok { + if v, ok := d.GetOk(Arg_CaptureVolumeIDs); ok { volids := flex.ExpandStringList((v.(*schema.Set)).List()) if len(volids) > 0 { captureBody.CaptureVolumeIDs = volids @@ -194,13 +189,13 @@ func resourceIBMPICaptureCreate(ctx context.Context, d *schema.ResourceData, met } d.SetId(fmt.Sprintf("%s/%s/%s", cloudInstanceID, capturename, capturedestination)) - jobClient := st.NewIBMPIJobClient(ctx, sess, cloudInstanceID) + jobClient := instance.NewIBMPIJobClient(ctx, sess, cloudInstanceID) _, err = waitForIBMPIJobCompleted(ctx, jobClient, *captureResponse.ID, d.Timeout(schema.TimeoutCreate)) if err != nil { return diag.FromErr(err) } - if _, ok := d.GetOk(Arg_UserTags); ok && capturedestination != cloudStorageDestination { + if _, ok := d.GetOk(Arg_UserTags); ok && capturedestination != CloudStorage { imageClient := st.NewIBMPIImageClient(ctx, sess, cloudInstanceID) imagedata, err := imageClient.Get(capturename) if err != nil { @@ -233,8 +228,8 @@ func resourceIBMPICaptureRead(ctx context.Context, d *schema.ResourceData, meta cloudInstanceID := parts[0] captureID := parts[1] capturedestination := parts[2] - if capturedestination != cloudStorageDestination { - imageClient := st.NewIBMPIImageClient(ctx, sess, cloudInstanceID) + if capturedestination != CloudStorage { + imageClient := instance.NewIBMPIImageClient(ctx, sess, cloudInstanceID) imagedata, err := imageClient.Get(captureID) if err != nil { uErr := errors.Unwrap(err) @@ -248,6 +243,7 @@ func resourceIBMPICaptureRead(ctx context.Context, d *schema.ResourceData, meta return diag.FromErr(err) } imageid := *imagedata.ImageID + d.Set(Attr_ImageID, imageid) if imagedata.Crn != "" { d.Set(Attr_CRN, imagedata.Crn) tags, err := flex.GetGlobalTagsUsingCRN(meta, string(imagedata.Crn), "", UserTagType) @@ -256,9 +252,8 @@ func resourceIBMPICaptureRead(ctx context.Context, d *schema.ResourceData, meta } d.Set(Arg_UserTags, tags) } - d.Set("image_id", imageid) } - d.Set(helpers.PICloudInstanceId, cloudInstanceID) + d.Set(Arg_CloudInstanceID, cloudInstanceID) return nil } @@ -274,8 +269,8 @@ func resourceIBMPICaptureDelete(ctx context.Context, d *schema.ResourceData, met cloudInstanceID := parts[0] captureID := parts[1] capturedestination := parts[2] - if capturedestination != cloudStorageDestination { - imageClient := st.NewIBMPIImageClient(ctx, sess, cloudInstanceID) + if capturedestination != CloudStorage { + imageClient := instance.NewIBMPIImageClient(ctx, sess, cloudInstanceID) err = imageClient.Delete(captureID) if err != nil { uErr := errors.Unwrap(err) @@ -301,7 +296,7 @@ func resourceIBMPICaptureUpdate(ctx context.Context, d *schema.ResourceData, met captureID := parts[1] capturedestination := parts[2] - if capturedestination != cloudStorageDestination && d.HasChange(Arg_UserTags) { + if capturedestination != CloudStorage && d.HasChange(Arg_UserTags) { if crn, ok := d.GetOk(Attr_CRN); ok { oldList, newList := d.GetChange(Arg_UserTags) err := flex.UpdateGlobalTagsUsingCRN(oldList, newList, meta, crn.(string), "", UserTagType) diff --git a/ibm/service/power/resource_ibm_pi_capture_test.go b/ibm/service/power/resource_ibm_pi_capture_test.go index e66401efa6..6a3a3081f9 100644 --- a/ibm/service/power/resource_ibm_pi_capture_test.go +++ b/ibm/service/power/resource_ibm_pi_capture_test.go @@ -9,11 +9,11 @@ import ( "fmt" "testing" - st "github.com/IBM-Cloud/power-go-client/clients/instance" - "github.com/IBM-Cloud/power-go-client/helpers" + "github.com/IBM-Cloud/power-go-client/clients/instance" acc "github.com/IBM-Cloud/terraform-provider-ibm/ibm/acctest" "github.com/IBM-Cloud/terraform-provider-ibm/ibm/conns" "github.com/IBM-Cloud/terraform-provider-ibm/ibm/flex" + "github.com/IBM-Cloud/terraform-provider-ibm/ibm/service/power" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" @@ -47,7 +47,7 @@ func TestAccIBMPICaptureWithVolume(t *testing.T) { CheckDestroy: testAccCheckIBMPICaptureDestroy, Steps: []resource.TestStep{ { - Config: testAccCheckIBMPICaptureWithVolumeConfig(name, helpers.PIInstanceHealthOk), + Config: testAccCheckIBMPICaptureWithVolumeConfig(name, power.OK), Check: resource.ComposeTestCheckFunc( testAccCheckIBMPICaptureExists(captureRes), resource.TestCheckResourceAttr(captureRes, "pi_capture_name", name), @@ -153,7 +153,7 @@ func testAccCheckIBMPICaptureExists(n string) resource.TestCheckFunc { if err != nil { return err } - client := st.NewIBMPIImageClient(context.Background(), sess, cloudInstanceID) + client := instance.NewIBMPIImageClient(context.Background(), sess, cloudInstanceID) _, err = client.Get(captureID) if err != nil { @@ -179,7 +179,7 @@ func testAccCheckIBMPICaptureDestroy(s *terraform.State) error { if err != nil { return err } - imageClient := st.NewIBMPIImageClient(context.Background(), sess, cloudInstanceID) + imageClient := instance.NewIBMPIImageClient(context.Background(), sess, cloudInstanceID) _, err = imageClient.Get(captureID) if err == nil { return fmt.Errorf("PI Image still exists: %s", rs.Primary.ID) @@ -228,29 +228,29 @@ func testAccCheckIBMPICaptureUserTagsConfig(name string, userTagsString string) func testAccCheckIBMPICaptureCloudStorageConfig(name string) string { return fmt.Sprintf(` resource "ibm_pi_capture" "capture_instance" { - pi_cloud_instance_id="%[1]s" + pi_cloud_instance_id="%s" pi_capture_name = "%s" pi_instance_name = "%s" pi_capture_destination = "cloud-storage" - pi_capture_cloud_storage_region = "us-east" + pi_capture_cloud_storage_region = "%s" pi_capture_cloud_storage_access_key = "%s" pi_capture_cloud_storage_secret_key = "%s" pi_capture_storage_image_path = "%s" } - `, acc.Pi_cloud_instance_id, name, acc.Pi_instance_name, acc.Pi_capture_cloud_storage_access_key, acc.Pi_capture_cloud_storage_secret_key, acc.Pi_capture_storage_image_path) + `, acc.Pi_cloud_instance_id, name, acc.Pi_instance_name, acc.Pi_capture_cloud_storage_region, acc.Pi_capture_cloud_storage_access_key, acc.Pi_capture_cloud_storage_secret_key, acc.Pi_capture_storage_image_path) } func testAccCheckIBMPICaptureBothConfig(name string) string { return fmt.Sprintf(` resource "ibm_pi_capture" "capture_instance" { - pi_cloud_instance_id="%[1]s" + pi_cloud_instance_id="%s" pi_capture_name = "%s" pi_instance_name = "%s" pi_capture_destination = "both" - pi_capture_cloud_storage_region = "us-east" + pi_capture_cloud_storage_region = "%s" pi_capture_cloud_storage_access_key = "%s" pi_capture_cloud_storage_secret_key = "%s" pi_capture_storage_image_path = "%s" } - `, acc.Pi_cloud_instance_id, name, acc.Pi_instance_name, acc.Pi_capture_cloud_storage_access_key, acc.Pi_capture_cloud_storage_secret_key, acc.Pi_capture_storage_image_path) + `, acc.Pi_cloud_instance_id, name, acc.Pi_instance_name, acc.Pi_capture_cloud_storage_region, acc.Pi_capture_cloud_storage_access_key, acc.Pi_capture_cloud_storage_secret_key, acc.Pi_capture_storage_image_path) } diff --git a/website/docs/r/pi_capture.html.markdown b/website/docs/r/pi_capture.html.markdown index 7d61848b5f..5ab6466faa 100644 --- a/website/docs/r/pi_capture.html.markdown +++ b/website/docs/r/pi_capture.html.markdown @@ -68,16 +68,15 @@ ibm_pi_capture provides the following [timeouts](https://www.terraform.io/docs/l Review the argument references that you can specify for your resource. -- `pi_cloud_instance_id` - (Required, String) The GUID of the service instance associated with an account. -- `pi_capture_name` - (Required, String) Name of the deployable image created for the captured PVMInstance. -- `pi_instance_name` - (Required, String) The name of the instance. -- `pi_capture_destination`- (Required, String) Destination for the deployable image. -`[image-catalog,cloud-storage,both]` -- `pi_capture_volume_ids`- (Optional, List of String) List of Data volume IDs to include in the captured PVMInstance. -- `pi_capture_cloud_storage_region`- (Optional,String) The Cloud Object Storage region. Supported COS regions are: `au-syd`, `br-sao`, `ca-tor`, `che01`, `eu-de`, `eu-es`, `eu-gb`, `jp-osa`, `jp-tok`, `us-east`, `us-south`. - `pi_capture_cloud_storage_access_key`- (Optional,String) Cloud Storage Access key +- `pi_capture_cloud_storage_region`- (Optional,String) The Cloud Object Storage region. Supported COS regions are: `au-syd`, `br-sao`, `ca-tor`, `eu-de`, `eu-es`, `eu-gb`, `jp-osa`, `jp-tok`, `us-east`, `us-south`. - `pi_capture_cloud_storage_secret_key`- (Optional,String) Cloud Storage Secret key +- `pi_capture_destination`- (Required, String) Destination for the deployable image.`[image-catalog,cloud-storage,both]` +- `pi_capture_name` - (Required, String) Name of the deployable image created for the captured PVMInstance. - `pi_capture_storage_image_path` - (Optional,String) Cloud Storage Image Path (bucket-name [/folder/../..]) +- `pi_capture_volume_ids`- (Optional, List of String) List of Data volume IDs to include in the captured PVMInstance. +- `pi_cloud_instance_id` - (Required, String) The GUID of the service instance associated with an account. +- `pi_instance_name` - (Required, String) The name of the instance. - `pi_user_tags` - (Optional, List) List of user tags attached to the resource. ## Attribute reference