diff --git a/go.mod b/go.mod index 0a4435d223..2c0669175f 100644 --- a/go.mod +++ b/go.mod @@ -38,7 +38,7 @@ require ( github.com/IBM/secrets-manager-go-sdk/v2 v2.0.11 github.com/IBM/vmware-go-sdk v0.1.3 github.com/IBM/vpc-beta-go-sdk v0.8.0 - github.com/IBM/vpc-go-sdk v0.67.1 + github.com/IBM/vpc-go-sdk v0.70.1 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 diff --git a/go.sum b/go.sum index 2200d5e95e..1520e1550c 100644 --- a/go.sum +++ b/go.sum @@ -167,8 +167,8 @@ github.com/IBM/vmware-go-sdk v0.1.3 h1:uJL3kwzM0jAKsT6Gj9tE5xT9SZBVXVaJvZdxrSMx8 github.com/IBM/vmware-go-sdk v0.1.3/go.mod h1:OyQKRInGGsBaOyE5LIZCqH7b1DZ01BvIYa8BgGy+wWo= github.com/IBM/vpc-beta-go-sdk v0.8.0 h1:cEPpv4iw3Ba5W2d0AWg3TIbKeJ8y1nPuUuibR5Jt9eE= github.com/IBM/vpc-beta-go-sdk v0.8.0/go.mod h1:hORgIyTFRzXrZIK9IohaWmCRBBlYiDRagsufi7M6akE= -github.com/IBM/vpc-go-sdk v0.67.1 h1:z0q1af1iItV4kHgreM21vzZtw6XQ13og2GBkX7WCJ8c= -github.com/IBM/vpc-go-sdk v0.67.1/go.mod h1:VL7sy61ybg6tvA60SepoQx7TFe20m7JyNUt+se2tHP4= +github.com/IBM/vpc-go-sdk v0.70.1 h1:6NsbRkiA5gDNxe7cjNx8Pi1j9s0PlhwNQj29wsKZxAo= +github.com/IBM/vpc-go-sdk v0.70.1/go.mod h1:K3vVlje72PYE3ZRt1iouE+jSIq+vCyYzT1HiFC06hUA= github.com/Logicalis/asn1 v0.0.0-20190312173541-d60463189a56 h1:vuquMR410psHNax14XKNWa0Ae/kYgWJcXi0IFuX60N0= github.com/Logicalis/asn1 v0.0.0-20190312173541-d60463189a56/go.mod h1:Zb3OT4l0mf7P/GOs2w2Ilj5sdm5Whoq3pa24dAEBHFc= github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= diff --git a/ibm/service/vpc/data_source_ibm_is_image.go b/ibm/service/vpc/data_source_ibm_is_image.go index f2debfaa36..ec0a5f4c7f 100644 --- a/ibm/service/vpc/data_source_ibm_is_image.go +++ b/ibm/service/vpc/data_source_ibm_is_image.go @@ -197,6 +197,34 @@ func DataSourceIBMISImage() *schema.Resource { Computed: true, Description: "The type of encryption used on the image", }, + "remote": { + Type: schema.TypeList, + Computed: true, + Description: "If present, this property indicates that the resource associated with this reference is remote and therefore may not be directly retrievable.", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "account": { + Type: schema.TypeList, + Computed: true, + Description: "If present, this property indicates that the referenced resource is remote to this account, and identifies the owning account.", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeString, + Computed: true, + Description: "The unique identifier for this resource group.", + }, + "resource_type": { + Type: schema.TypeString, + Computed: true, + Description: "The resource type.", + }, + }, + }, + }, + }, + }, + }, "source_volume": { Type: schema.TypeString, Computed: true, @@ -366,6 +394,22 @@ func imageGetByName(context context.Context, d *schema.ResourceData, meta interf return flex.DiscriminatedTerraformErrorf(err, fmt.Sprintf("Error setting resource_group: %s", err), "(Data) ibm_is_image", "read", "set-resource_group").GetDiag() } } + if image.Remote != nil { + imageRemoteList := []map[string]interface{}{} + imageRemoteMap, err := dataSourceImageRemote(image) + if err != nil { + if err != nil { + tfErr := flex.DiscriminatedTerraformErrorf(err, err.Error(), "(Data) ibm_is_image", "read", "initialize-client") + log.Printf("[DEBUG]\n%s", tfErr.GetDebugMessage()) + return tfErr.GetDiag() + } + } + imageRemoteList = append(imageRemoteList, imageRemoteMap) + if err = d.Set(isImageRemote, imageRemoteList); err != nil { + return flex.DiscriminatedTerraformErrorf(err, fmt.Sprintf("Error setting remote: %s", err), "(Data) ibm_is_image", "read", "set-remote").GetDiag() + } + } + if err = d.Set("os", image.OperatingSystem.Name); err != nil { return flex.DiscriminatedTerraformErrorf(err, fmt.Sprintf("Error setting os: %s", err), "(Data) ibm_is_image", "read", "set-os").GetDiag() } @@ -443,6 +487,21 @@ func imageGetById(context context.Context, d *schema.ResourceData, meta interfac if *image.Status == "deprecated" { fmt.Printf("[WARN] Given image %s is deprecated and soon will be obsolete.", name) } + + if image.Remote != nil { + imageRemoteList := []map[string]interface{}{} + imageRemoteMap, err := dataSourceImageRemote(*image) + if err != nil { + tfErr := flex.DiscriminatedTerraformErrorf(err, err.Error(), "(Data) ibm_legacy_vendor_images", "read", "initialize-client") + log.Printf("[DEBUG]\n%s", tfErr.GetDebugMessage()) + return tfErr.GetDiag() + } + imageRemoteList = append(imageRemoteList, imageRemoteMap) + if err = d.Set(isImageRemote, imageRemoteList); err != nil { + return flex.DiscriminatedTerraformErrorf(err, fmt.Sprintf("Error setting remote: %s", err), "(Data) ibm_is_image", "read", "set-remote").GetDiag() + } + } + if len(image.StatusReasons) > 0 { if err = d.Set("status_reasons", dataSourceIBMIsImageFlattenStatusReasons(image.StatusReasons)); err != nil { return flex.DiscriminatedTerraformErrorf(err, fmt.Sprintf("Error setting status_reasons: %s", err), "(Data) ibm_is_image", "read", "set-status_reasons").GetDiag() @@ -571,6 +630,27 @@ func dataSourceImageCollectionCatalogOfferingToMap(imageCatalogOfferingItem vpcv return imageCatalogOfferingMap } +func dataSourceImageRemote(imageRemote vpcv1.Image) (map[string]interface{}, error) { + if imageRemote.Remote == nil || imageRemote.Remote.Account == nil { + return nil, nil + } + + accountMap := map[string]interface{}{} + + if imageRemote.Remote.Account.ID != nil { + accountMap["id"] = *imageRemote.Remote.Account.ID + } + if imageRemote.Remote.Account.ResourceType != nil { + accountMap["resource_type"] = *imageRemote.Remote.Account.ResourceType + } + + remoteMap := map[string]interface{}{ + "account": []interface{}{accountMap}, + } + + return remoteMap, nil +} + func dataSourceIBMIsImageFlattenStatusReasons(result []vpcv1.ImageStatusReason) (statusReasons []map[string]interface{}) { for _, statusReasonsItem := range result { statusReasons = append(statusReasons, dataSourceIBMIsImageStatusReasonToMap(&statusReasonsItem)) diff --git a/ibm/service/vpc/data_source_ibm_is_image_test.go b/ibm/service/vpc/data_source_ibm_is_image_test.go index 552d7f0e81..ac90a59164 100644 --- a/ibm/service/vpc/data_source_ibm_is_image_test.go +++ b/ibm/service/vpc/data_source_ibm_is_image_test.go @@ -174,6 +174,26 @@ func TestAccIBMISImageDataSource_With_VisibiltyPrivate(t *testing.T) { }) } +func TestAccIBMISImageDataSourceRemoteAccountId(t *testing.T) { + resName := "data.ibm_is_image.example" + + resource.Test(t, resource.TestCase{ + PreCheck: func() { acc.TestAccPreCheck(t) }, + Providers: acc.TestAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccCheckIBMISImageDataSourceWithRemoteAccountId(), + Check: resource.ComposeTestCheckFunc( + // resource.TestCheckResourceAttrSet(resName, "image.0.remote.#"), + // resource.TestCheckResourceAttrSet(resName, "image.0.remote.0.account.#"), + resource.TestCheckResourceAttrSet(resName, "remote.0.account.0.id"), + resource.TestCheckResourceAttrSet(resName, "remote.0.account.0.resource_type"), + ), + }, + }, + }) +} + func testAccCheckIBMISImageDataSourceConfig(imageName string) string { return fmt.Sprintf(` resource "ibm_is_image" "isExampleImage" { @@ -248,3 +268,17 @@ func testAccCheckIBMISImageDataSourceWithVisibilityPrivate(imageName, visibility visibility = "%s" }`, acc.Image_cos_url, imageName, acc.Image_operating_system, visibility) } + +func testAccCheckIBMISCatalogImageDataSourceRemoteAccountId() string { + return fmt.Sprintf(` + data "ibm_is_images" "test1" { + catalog_managed = true + }`) +} + +func testAccCheckIBMISImageDataSourceWithRemoteAccountId() string { + return fmt.Sprintf(` + data "ibm_is_image" "example" { + name = "ibm-ubuntu-18-04-1-minimal-amd64-1" + }`) +} diff --git a/ibm/service/vpc/data_source_ibm_is_images.go b/ibm/service/vpc/data_source_ibm_is_images.go index 0f22416a1b..e8e5d7b6c1 100644 --- a/ibm/service/vpc/data_source_ibm_is_images.go +++ b/ibm/service/vpc/data_source_ibm_is_images.go @@ -20,6 +20,7 @@ const ( isImages = "images" isImagesResourceGroupID = "resource_group" isImageCatalogManaged = "catalog_managed" + isImageRemoteAccountId = "remote_account_id" ) func DataSourceIBMISImages() *schema.Resource { @@ -54,6 +55,11 @@ func DataSourceIBMISImages() *schema.Resource { Optional: true, Description: "Whether the image is publicly visible or private to the account", }, + isImageRemoteAccountId: { + Type: schema.TypeString, + Optional: true, + Description: "Filters the collection to images with a remote.account.id property matching the specified account identifier.", + }, isImageUserDataFormat: { Type: schema.TypeSet, Elem: &schema.Schema{Type: schema.TypeString}, @@ -180,6 +186,34 @@ func DataSourceIBMISImages() *schema.Resource { Computed: true, Description: "The operating system architecture", }, + "remote": { + Type: schema.TypeList, + Computed: true, + Description: "If present, this property indicates that the resource associated with this reference is remote and therefore may not be directly retrievable.", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "account": { + Type: schema.TypeList, + Computed: true, + Description: "If present, this property indicates that the referenced resource is remote to this account, and identifies the owning account.", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeString, + Computed: true, + Description: "The unique identifier for this resource group.", + }, + "resource_type": { + Type: schema.TypeString, + Computed: true, + Description: "The resource type.", + }, + }, + }, + }, + }, + }, + }, "resource_group": { Type: schema.TypeList, Computed: true, @@ -338,6 +372,10 @@ func imageList(context context.Context, d *schema.ResourceData, meta interface{} visibility = v.(string) } + var remoteAccountId string + if v, ok := d.GetOk(isImageRemoteAccountId); ok { + remoteAccountId = v.(string) + } var status string if v, ok := d.GetOk(isImageStatus); ok { status = v.(string) @@ -354,6 +392,19 @@ func imageList(context context.Context, d *schema.ResourceData, meta interface{} if imageName != "" { listImagesOptions.SetName(imageName) } + + if remoteAccountId != "" { + if remoteAccountId == "user" { + remoteAccountId = "null" + listImagesOptions.SetRemoteAccountID(remoteAccountId) + } else if remoteAccountId == "provider" { + remoteAccountId = "not:null" + listImagesOptions.SetRemoteAccountID(remoteAccountId) + } else { + listImagesOptions.SetRemoteAccountID(remoteAccountId) + } + } + if visibility != "" { listImagesOptions.SetVisibility(visibility) } @@ -454,6 +505,21 @@ func imageList(context context.Context, d *schema.ResourceData, meta interface{} catalogOfferingList = append(catalogOfferingList, catalogOfferingMap) l[isImageCatalogOffering] = catalogOfferingList } + + if image.Remote != nil { + imageRemoteMap, err := dataSourceImageRemote(image) + if err != nil { + if err != nil { + tfErr := flex.DiscriminatedTerraformErrorf(err, err.Error(), "(Data) ibm_is_image", "read", "initialize-client") + log.Printf("[DEBUG]\n%s", tfErr.GetDebugMessage()) + return tfErr.GetDiag() + } + } + if len(imageRemoteMap) > 0 { + l["remote"] = []interface{}{imageRemoteMap} + } + } + accesstags, err := flex.GetGlobalTagsUsingCRN(meta, *image.CRN, "", isImageAccessTagType) if err != nil { log.Printf( diff --git a/ibm/service/vpc/data_source_ibm_is_images_test.go b/ibm/service/vpc/data_source_ibm_is_images_test.go index 08c30998de..6a058ef8fb 100644 --- a/ibm/service/vpc/data_source_ibm_is_images_test.go +++ b/ibm/service/vpc/data_source_ibm_is_images_test.go @@ -96,6 +96,25 @@ func TestAccIBMISImageDataSource_With_FilterVisibilty(t *testing.T) { }) } +func TestAccIBMISImageDataSource_With_FilterRemoteAccountId(t *testing.T) { + resName := "data.ibm_is_images.example" + resource.Test(t, resource.TestCase{ + PreCheck: func() { acc.TestAccPreCheck(t) }, + Providers: acc.TestAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccCheckIBMISImagesDataSourceWithRemoteAccountId("provider"), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrSet(resName, "images.0.remote.#"), + resource.TestCheckResourceAttrSet(resName, "images.0.remote.0.account.#"), + resource.TestCheckResourceAttrSet(resName, "images.0.remote.0.account.0.id"), + resource.TestCheckResourceAttrSet(resName, "images.0.remote.0.account.0.resource_type"), + ), + }, + }, + }) +} + func TestAccIBMISImageDataSource_With_FilterStatus(t *testing.T) { resName := "data.ibm_is_images.test1" resource.Test(t, resource.TestCase{ @@ -149,3 +168,12 @@ func testAccCheckIBMISImagesDataSourceWithStatusPublic(status string) string { } `, status) } + +func testAccCheckIBMISImagesDataSourceWithRemoteAccountId(remoteAccountId string) string { + return fmt.Sprintf(` + data "ibm_is_images" "example" { + remote_account_id = "%s" + status = "available" + } + `, remoteAccountId) +} diff --git a/ibm/service/vpc/data_source_ibm_is_instance_profile.go b/ibm/service/vpc/data_source_ibm_is_instance_profile.go index c8a5b66c90..b1c045ccc9 100644 --- a/ibm/service/vpc/data_source_ibm_is_instance_profile.go +++ b/ibm/service/vpc/data_source_ibm_is_instance_profile.go @@ -980,7 +980,7 @@ func instanceProfileGet(context context.Context, d *schema.ResourceData, meta in // Manufacturer details added. if profile.VcpuManufacturer != nil { - err = d.Set(isInstanceVCPUManufacturer, dataSourceInstanceProfileFlattenVcpuManufacture(*profile.VcpuManufacturer)) + err = d.Set(isInstanceVCPUManufacturer, dataSourceInstanceProfileFlattenVcpuManufacture(*profile.VcpuManufacturer.(*vpcv1.InstanceProfileVcpuManufacturer))) if err != nil { return flex.DiscriminatedTerraformErrorf(err, fmt.Sprintf("Error setting vcpu_manufacturer: %s", err), "(Data) ibm_is_instance_profile", "read", "set-vcpu_manufacturer").GetDiag() } diff --git a/ibm/service/vpc/data_source_ibm_is_instance_profiles.go b/ibm/service/vpc/data_source_ibm_is_instance_profiles.go index 3f14eba2b3..d7b96a7478 100644 --- a/ibm/service/vpc/data_source_ibm_is_instance_profiles.go +++ b/ibm/service/vpc/data_source_ibm_is_instance_profiles.go @@ -952,7 +952,7 @@ func instanceProfilesList(context context.Context, d *schema.ResourceData, meta // reduce the line of code here. - sumit's suggestions if profile.VcpuManufacturer != nil { vcpuManufacturerList := []map[string]interface{}{} - vcpuManufacturerMap := dataSourceInstanceProfileVcpuManufacturerToMap(*profile.VcpuManufacturer) + vcpuManufacturerMap := dataSourceInstanceProfileVcpuManufacturerToMap(*profile.VcpuManufacturer.(*vpcv1.InstanceProfileVcpuManufacturer)) vcpuManufacturerList = append(vcpuManufacturerList, vcpuManufacturerMap) l["vcpu_manufacturer"] = vcpuManufacturerList } diff --git a/ibm/service/vpc/resource_ibm_is_image.go b/ibm/service/vpc/resource_ibm_is_image.go index dc6257d3d8..e5f35b970f 100644 --- a/ibm/service/vpc/resource_ibm_is_image.go +++ b/ibm/service/vpc/resource_ibm_is_image.go @@ -51,6 +51,8 @@ const ( isImageDeprecate = "deprecate" isImageObsolete = "obsolete" isImageUserDataFormat = "user_data_format" + + isImageRemote = "remote" ) func ResourceIBMISImage() *schema.Resource { diff --git a/website/docs/d/is_image.html.markdown b/website/docs/d/is_image.html.markdown index 0f338c240c..118032a03d 100644 --- a/website/docs/d/is_image.html.markdown +++ b/website/docs/d/is_image.html.markdown @@ -47,6 +47,7 @@ Review the argument references that you can specify for your data source. - `visibility` - (Optional, String) The visibility of the image. Accepted values are `public` or `private`. + ## Attribute reference In addition to all argument reference list, you can access the following attribute references after your data source is created. @@ -103,6 +104,15 @@ In addition to all argument reference list, you can access the following attribu - `source_volume` - The source volume id of the image. - `user_data_format` - (String) The user data format for this image. +- `remote` - (Optional, List) If present, this property indicates that the resource associated with this reference is remote and therefore may not be directly retrievable. + + **Nested schema for `remote`:** + - `account` - (Optional, List) Indicates that the referenced resource is remote to this account, and identifies the owning account. + + **Nested schema for `account`:** + - `id` – (Computed, String) The unique identifier for this account. + - `resource_type` – (Computed, String) The resource type. + ~> **Note:**
Supported values are :
**•** `cloud_init`: user_data will be interpreted according to the cloud-init standard.
diff --git a/website/docs/d/is_images.html.markdown b/website/docs/d/is_images.html.markdown index da545dd2ce..f306a79013 100644 --- a/website/docs/d/is_images.html.markdown +++ b/website/docs/d/is_images.html.markdown @@ -31,6 +31,12 @@ data "ibm_is_images" "ds_images" { visibility = "public" } +```terraform +data "ibm_is_image" "example" { + remote_account_id = "provider" +} +``` + ``` ## Argument reference @@ -41,7 +47,9 @@ Review the argument references that you can specify for your data source. - `name` - (Optional, string) The name of the image. - `visibility` - (Optional, string) Visibility of the image. Accepted values : **private**, **public** - `status` - (Optional, string) Status of the image. Accepted value : **available**, **deleting**, **deprecated**, **failed**, **obsolete**, **pending**, **unusable** -- `user_data_format` - (String) The user data format for this image. +- `user_data_format` - (String) The user data format for this image. +- `remote-account-id` - (Optional, String) Accepted values are `provider` or `user` or valid account_id. + ~> **Note:**
Allowed values are :
**•** `cloud_init`: user_data will be interpreted according to the cloud-init standard.
@@ -103,4 +111,15 @@ You can access the following attribute references after your data source is crea - `more_info` - (String) Link to documentation about this status reason - `visibility` - (String) The visibility of the image public or private. - `source_volume` - The source volume id of the image. + - `remote` - (Optional, List) If present, this property indicates that the resource associated with this reference is remote and therefore may not be directly retrievable. + + **Nested schema for `remote`:** + - `account` - (Optional, List) Indicates that the referenced resource is remote to this account, and identifies the owning account. + + **Nested schema for `account`:** + - `id` – (Computed, String) The unique identifier for this account. + - `resource_type` – (Computed, String) The resource type. + + +