From 343f9332e665fa351845d032b879d4d80a38fbf3 Mon Sep 17 00:00:00 2001 From: Deepak Selvakumar <77007253+deepaksibm@users.noreply.github.com> Date: Wed, 13 Dec 2023 14:10:36 +0530 Subject: [PATCH 1/3] Enhancement: Added operating system attributes to is images data sources --- ibm/service/vpc/data_source_ibm_is_image.go | 49 ++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/ibm/service/vpc/data_source_ibm_is_image.go b/ibm/service/vpc/data_source_ibm_is_image.go index 760014aff7..4f32c32394 100644 --- a/ibm/service/vpc/data_source_ibm_is_image.go +++ b/ibm/service/vpc/data_source_ibm_is_image.go @@ -54,7 +54,54 @@ func DataSourceIBMISImage() *schema.Resource { Computed: true, Description: "The status of this image", }, - + "operating_system": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "architecture": { + Type: schema.TypeString, + Computed: true, + Description: "The operating system architecture", + }, + "dedicated_host_only": { + Type: schema.TypeString, + Computed: true, + Description: "Images with this operating system can only be used on dedicated hosts or dedicated host groups", + }, + "display_name": { + Type: schema.TypeString, + Computed: true, + Description: "A unique, display-friendly name for the operating system", + }, + "family": { + Type: schema.TypeString, + Computed: true, + Description: "The software family for this operating system", + }, + "href": { + Type: schema.TypeString, + Computed: true, + Description: "The URL for this operating system", + }, + "name": { + Type: schema.TypeString, + Computed: true, + Description: "The globally unique name for this operating system", + }, + "vendor": { + Type: schema.TypeString, + Computed: true, + Description: "The vendor of the operating system", + }, + "version": { + Type: schema.TypeString, + Computed: true, + Description: "The major release version of this operating system", + }, + }, + }, + }, "os": { Type: schema.TypeString, Computed: true, From 5de0b0be11d4e76ad9f8cc0ad75104444362753a Mon Sep 17 00:00:00 2001 From: Deepak Selvakumar <77007253+deepaksibm@users.noreply.github.com> Date: Mon, 18 Dec 2023 12:33:52 +0530 Subject: [PATCH 2/3] set the values --- ibm/service/vpc/data_source_ibm_is_image.go | 40 ++++++++++++++- ibm/service/vpc/data_source_ibm_is_images.go | 54 ++++++++++++++++++++ 2 files changed, 93 insertions(+), 1 deletion(-) diff --git a/ibm/service/vpc/data_source_ibm_is_image.go b/ibm/service/vpc/data_source_ibm_is_image.go index 4f32c32394..9e100f9cad 100644 --- a/ibm/service/vpc/data_source_ibm_is_image.go +++ b/ibm/service/vpc/data_source_ibm_is_image.go @@ -65,7 +65,7 @@ func DataSourceIBMISImage() *schema.Resource { Description: "The operating system architecture", }, "dedicated_host_only": { - Type: schema.TypeString, + Type: schema.TypeBool, Computed: true, Description: "Images with this operating system can only be used on dedicated hosts or dedicated host groups", }, @@ -262,6 +262,14 @@ func imageGetByName(d *schema.ResourceData, meta interface{}, name, visibility s } d.Set(isImageAccessTags, accesstags) d.Set("visibility", *image.Visibility) + + if image.OperatingSystem != nil { + operatingSystemList := []map[string]interface{}{} + operatingSystemMap := dataSourceIBMISImageOperatingSystemToMap(*image.OperatingSystem) + operatingSystemList = append(operatingSystemList, operatingSystemMap) + d.Set("operating_system", operatingSystemList) + } + d.Set("os", *image.OperatingSystem.Name) d.Set("architecture", *image.OperatingSystem.Architecture) d.Set("crn", *image.CRN) @@ -344,6 +352,36 @@ func imageGetById(d *schema.ResourceData, meta interface{}, identifier string) e return nil } +func dataSourceIBMISImageOperatingSystemToMap(operatingSystemItem vpcv1.OperatingSystem) (operatingSystemMap map[string]interface{}) { + operatingSystemMap = map[string]interface{}{} + + if operatingSystemItem.Architecture != nil { + operatingSystemMap["architecture"] = operatingSystemItem.Architecture + } + if operatingSystemItem.DedicatedHostOnly != nil { + operatingSystemMap["dedicated_host_only"] = operatingSystemItem.DedicatedHostOnly + } + if operatingSystemItem.DisplayName != nil { + operatingSystemMap["display_name"] = operatingSystemItem.DisplayName + } + if operatingSystemItem.Family != nil { + operatingSystemMap["family"] = operatingSystemItem.Family + } + if operatingSystemItem.Href != nil { + operatingSystemMap["href"] = operatingSystemItem.Href + } + if operatingSystemItem.Name != nil { + operatingSystemMap["name"] = operatingSystemItem.Name + } + if operatingSystemItem.Vendor != nil { + operatingSystemMap["vendor"] = operatingSystemItem.Vendor + } + if operatingSystemItem.Version != nil { + operatingSystemMap["version"] = operatingSystemItem.Version + } + return operatingSystemMap +} + func dataSourceImageCollectionCatalogOfferingToMap(imageCatalogOfferingItem vpcv1.ImageCatalogOffering) (imageCatalogOfferingMap map[string]interface{}) { imageCatalogOfferingMap = map[string]interface{}{} if imageCatalogOfferingItem.Managed != nil { diff --git a/ibm/service/vpc/data_source_ibm_is_images.go b/ibm/service/vpc/data_source_ibm_is_images.go index e1d22caf44..8ac7a59ed4 100644 --- a/ibm/service/vpc/data_source_ibm_is_images.go +++ b/ibm/service/vpc/data_source_ibm_is_images.go @@ -79,6 +79,54 @@ func DataSourceIBMISImages() *schema.Resource { Computed: true, Description: "Whether the image is publicly visible or private to the account", }, + "operating_system": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "architecture": { + Type: schema.TypeString, + Computed: true, + Description: "The operating system architecture", + }, + "dedicated_host_only": { + Type: schema.TypeBool, + Computed: true, + Description: "Images with this operating system can only be used on dedicated hosts or dedicated host groups", + }, + "display_name": { + Type: schema.TypeString, + Computed: true, + Description: "A unique, display-friendly name for the operating system", + }, + "family": { + Type: schema.TypeString, + Computed: true, + Description: "The software family for this operating system", + }, + "href": { + Type: schema.TypeString, + Computed: true, + Description: "The URL for this operating system", + }, + "name": { + Type: schema.TypeString, + Computed: true, + Description: "The globally unique name for this operating system", + }, + "vendor": { + Type: schema.TypeString, + Computed: true, + Description: "The vendor of the operating system", + }, + "version": { + Type: schema.TypeString, + Computed: true, + Description: "The major release version of this operating system", + }, + }, + }, + }, "os": { Type: schema.TypeString, Computed: true, @@ -283,6 +331,12 @@ func imageList(d *schema.ResourceData, meta interface{}) error { "os": *image.OperatingSystem.Name, "architecture": *image.OperatingSystem.Architecture, } + if image.OperatingSystem != nil { + operatingSystemList := []map[string]interface{}{} + operatingSystemMap := dataSourceIBMISImageOperatingSystemToMap(*image.OperatingSystem) + operatingSystemList = append(operatingSystemList, operatingSystemMap) + l["operating_system"] = operatingSystemList + } if image.File != nil && image.File.Checksums != nil { l[isImageCheckSum] = *image.File.Checksums.Sha256 } From 03e79f3ea20129cbd2753dc4d2e2ddb173206759 Mon Sep 17 00:00:00 2001 From: Deepak Selvakumar <77007253+deepaksibm@users.noreply.github.com> Date: Mon, 18 Dec 2023 16:53:03 +0530 Subject: [PATCH 3/3] test and doc changes --- ibm/service/vpc/data_source_ibm_is_image.go | 111 +++++++++++++++++- .../vpc/data_source_ibm_is_image_test.go | 37 ++++++ ibm/service/vpc/data_source_ibm_is_images.go | 57 +++++++++ .../vpc/data_source_ibm_is_images_test.go | 34 ++++++ website/docs/d/is_image.html.markdown | 24 ++++ website/docs/d/is_images.html.markdown | 22 ++++ 6 files changed, 283 insertions(+), 2 deletions(-) diff --git a/ibm/service/vpc/data_source_ibm_is_image.go b/ibm/service/vpc/data_source_ibm_is_image.go index 9e100f9cad..61248d9c81 100644 --- a/ibm/service/vpc/data_source_ibm_is_image.go +++ b/ibm/service/vpc/data_source_ibm_is_image.go @@ -48,12 +48,59 @@ func DataSourceIBMISImage() *schema.Resource { ValidateFunc: validate.ValidateAllowedStringValues([]string{"public", "private"}), Description: "Whether the image is publicly visible or private to the account", }, - + "resource_group": { + Type: schema.TypeList, + Computed: true, + Description: "The resource group for this IPsec policy.", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "href": { + Type: schema.TypeString, + Computed: true, + Description: "The URL for this resource group.", + }, + "id": { + Type: schema.TypeString, + Computed: true, + Description: "The unique identifier for this resource group.", + }, + "name": { + Type: schema.TypeString, + Computed: true, + Description: "The user-defined name for this resource group.", + }, + }, + }, + }, "status": { Type: schema.TypeString, Computed: true, Description: "The status of this image", }, + "status_reasons": &schema.Schema{ + Type: schema.TypeList, + Computed: true, + Description: "The reasons for the current status (if any).", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "code": &schema.Schema{ + Type: schema.TypeString, + Computed: true, + Description: "A snake case string succinctly identifying the status reason.", + }, + "message": &schema.Schema{ + Type: schema.TypeString, + Computed: true, + Description: "An explanation of the status reason.", + }, + "more_info": &schema.Schema{ + Type: schema.TypeString, + Computed: true, + Description: "Link to documentation about this status reason.", + }, + }, + }, + }, "operating_system": { Type: schema.TypeList, Computed: true, @@ -254,6 +301,9 @@ func imageGetByName(d *schema.ResourceData, meta interface{}, name, visibility s if *image.Status == "deprecated" { fmt.Printf("[WARN] Given image %s is deprecated and soon will be obsolete.", name) } + if len(image.StatusReasons) > 0 { + d.Set("status_reasons", dataSourceIBMIsImageFlattenStatusReasons(image.StatusReasons)) + } d.Set("name", *image.Name) accesstags, err := flex.GetGlobalTagsUsingCRN(meta, *image.CRN, "", isImageAccessTagType) if err != nil { @@ -269,7 +319,12 @@ func imageGetByName(d *schema.ResourceData, meta interface{}, name, visibility s operatingSystemList = append(operatingSystemList, operatingSystemMap) d.Set("operating_system", operatingSystemList) } - + if image.ResourceGroup != nil { + resourceGroupList := []map[string]interface{}{} + resourceGroupMap := dataSourceImageResourceGroupToMap(*image.ResourceGroup) + resourceGroupList = append(resourceGroupList, resourceGroupMap) + d.Set("resource_group", resourceGroupList) + } d.Set("os", *image.OperatingSystem.Name) d.Set("architecture", *image.OperatingSystem.Architecture) d.Set("crn", *image.CRN) @@ -326,8 +381,23 @@ func imageGetById(d *schema.ResourceData, meta interface{}, identifier string) e if *image.Status == "deprecated" { fmt.Printf("[WARN] Given image %s is deprecated and soon will be obsolete.", name) } + if len(image.StatusReasons) > 0 { + d.Set("status_reasons", dataSourceIBMIsImageFlattenStatusReasons(image.StatusReasons)) + } d.Set("name", *image.Name) d.Set("visibility", *image.Visibility) + if image.OperatingSystem != nil { + operatingSystemList := []map[string]interface{}{} + operatingSystemMap := dataSourceIBMISImageOperatingSystemToMap(*image.OperatingSystem) + operatingSystemList = append(operatingSystemList, operatingSystemMap) + d.Set("operating_system", operatingSystemList) + } + if image.ResourceGroup != nil { + resourceGroupList := []map[string]interface{}{} + resourceGroupMap := dataSourceImageResourceGroupToMap(*image.ResourceGroup) + resourceGroupList = append(resourceGroupList, resourceGroupMap) + d.Set("resource_group", resourceGroupList) + } d.Set("os", *image.OperatingSystem.Name) d.Set("architecture", *image.OperatingSystem.Architecture) d.Set("crn", *image.CRN) @@ -405,3 +475,40 @@ func dataSourceImageCollectionCatalogOfferingToMap(imageCatalogOfferingItem vpcv return imageCatalogOfferingMap } + +func dataSourceIBMIsImageFlattenStatusReasons(result []vpcv1.ImageStatusReason) (statusReasons []map[string]interface{}) { + for _, statusReasonsItem := range result { + statusReasons = append(statusReasons, dataSourceIBMIsImageStatusReasonToMap(&statusReasonsItem)) + } + + return statusReasons +} + +func dataSourceIBMIsImageStatusReasonToMap(model *vpcv1.ImageStatusReason) map[string]interface{} { + modelMap := make(map[string]interface{}) + if model.Code != nil { + modelMap["code"] = *model.Code + } + if model.Message != nil { + modelMap["message"] = *model.Message + } + if model.MoreInfo != nil { + modelMap["more_info"] = *model.MoreInfo + } + return modelMap +} +func dataSourceImageResourceGroupToMap(resourceGroupItem vpcv1.ResourceGroupReference) (resourceGroupMap map[string]interface{}) { + resourceGroupMap = map[string]interface{}{} + + if resourceGroupItem.Href != nil { + resourceGroupMap["href"] = resourceGroupItem.Href + } + if resourceGroupItem.ID != nil { + resourceGroupMap["id"] = resourceGroupItem.ID + } + if resourceGroupItem.Name != nil { + resourceGroupMap["name"] = resourceGroupItem.Name + } + + return resourceGroupMap +} 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 9c7c126b5e..425a160dc5 100644 --- a/ibm/service/vpc/data_source_ibm_is_image_test.go +++ b/ibm/service/vpc/data_source_ibm_is_image_test.go @@ -34,6 +34,33 @@ func TestAccIBMISImageDataSource_basic(t *testing.T) { }, }) } +func TestAccIBMISImageDataSource_All(t *testing.T) { + resName := "data.ibm_is_image.test1" + imageName := fmt.Sprintf("tfimage-name-%d", acctest.RandIntRange(10, 100)) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { acc.TestAccPreCheck(t) }, + Providers: acc.TestAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccCheckIBMISImageDataSourceAllConfig(imageName), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrSet(resName, "operating_system.0.name"), + resource.TestCheckResourceAttrSet(resName, "operating_system.0.dedicated_host_only"), + resource.TestCheckResourceAttrSet(resName, "operating_system.0.display_name"), + resource.TestCheckResourceAttrSet(resName, "operating_system.0.family"), + resource.TestCheckResourceAttrSet(resName, "operating_system.0.href"), + resource.TestCheckResourceAttrSet(resName, "operating_system.0.vendor"), + resource.TestCheckResourceAttrSet(resName, "operating_system.0.version"), + resource.TestCheckResourceAttrSet(resName, "operating_system.0.architecture"), + resource.TestCheckResourceAttrSet(resName, "status"), + resource.TestCheckResourceAttrSet(resName, "resource_group.0.id"), + resource.TestCheckResourceAttrSet(resName, "resource_group.0.name"), + ), + }, + }, + }) +} func TestAccIBMISImageDataSource_ilc(t *testing.T) { resName := "data.ibm_is_image.test1" imageName := fmt.Sprintf("tfimage-name-%d", acctest.RandIntRange(10, 100)) @@ -144,6 +171,16 @@ func testAccCheckIBMISImageDataSourceConfig(imageName string) string { }`, acc.Image_cos_url, imageName, acc.Image_operating_system) } +func testAccCheckIBMISImageDataSourceAllConfig(imageName string) string { + return fmt.Sprintf(` + data "ibm_is_images" "test1" { + status = "available" + } + data "ibm_is_image" "test1" { + name = data.ibm_is_images.test1.images.0.name + }`) +} + func testAccCheckIBMISImageDataSourceConfigIlc(imageName string) string { return fmt.Sprintf(` resource "ibm_is_image" "isExampleImage" { diff --git a/ibm/service/vpc/data_source_ibm_is_images.go b/ibm/service/vpc/data_source_ibm_is_images.go index 8ac7a59ed4..bd9c059110 100644 --- a/ibm/service/vpc/data_source_ibm_is_images.go +++ b/ibm/service/vpc/data_source_ibm_is_images.go @@ -74,6 +74,30 @@ func DataSourceIBMISImages() *schema.Resource { Computed: true, Description: "The status of this image", }, + "status_reasons": &schema.Schema{ + Type: schema.TypeList, + Computed: true, + Description: "The reasons for the current status (if any).", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "code": &schema.Schema{ + Type: schema.TypeString, + Computed: true, + Description: "A snake case string succinctly identifying the status reason.", + }, + "message": &schema.Schema{ + Type: schema.TypeString, + Computed: true, + Description: "An explanation of the status reason.", + }, + "more_info": &schema.Schema{ + Type: schema.TypeString, + Computed: true, + Description: "Link to documentation about this status reason.", + }, + }, + }, + }, "visibility": { Type: schema.TypeString, Computed: true, @@ -137,6 +161,30 @@ func DataSourceIBMISImages() *schema.Resource { Computed: true, Description: "The operating system architecture", }, + "resource_group": { + Type: schema.TypeList, + Computed: true, + Description: "The resource group for this IPsec policy.", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "href": { + Type: schema.TypeString, + Computed: true, + Description: "The URL for this resource group.", + }, + "id": { + Type: schema.TypeString, + Computed: true, + Description: "The unique identifier for this resource group.", + }, + "name": { + Type: schema.TypeString, + Computed: true, + Description: "The user-defined name for this resource group.", + }, + }, + }, + }, "crn": { Type: schema.TypeString, Computed: true, @@ -331,6 +379,15 @@ func imageList(d *schema.ResourceData, meta interface{}) error { "os": *image.OperatingSystem.Name, "architecture": *image.OperatingSystem.Architecture, } + if len(image.StatusReasons) > 0 { + l["status_reasons"] = dataSourceIBMIsImageFlattenStatusReasons(image.StatusReasons) + } + if image.ResourceGroup != nil { + resourceGroupList := []map[string]interface{}{} + resourceGroupMap := dataSourceImageResourceGroupToMap(*image.ResourceGroup) + resourceGroupList = append(resourceGroupList, resourceGroupMap) + l["resource_group"] = resourceGroupList + } if image.OperatingSystem != nil { operatingSystemList := []map[string]interface{}{} operatingSystemMap := dataSourceIBMISImageOperatingSystemToMap(*image.OperatingSystem) 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 2bbbbda009..08c30998de 100644 --- a/ibm/service/vpc/data_source_ibm_is_images_test.go +++ b/ibm/service/vpc/data_source_ibm_is_images_test.go @@ -9,6 +9,7 @@ import ( acc "github.com/IBM-Cloud/terraform-provider-ibm/ibm/acctest" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" ) @@ -30,6 +31,33 @@ func TestAccIBMISImagesDataSource_basic(t *testing.T) { }, }) } +func TestAccIBMISImagesDataSource_All(t *testing.T) { + resName := "data.ibm_is_images.test1" + imageName := fmt.Sprintf("tfimage-name-%d", acctest.RandIntRange(10, 100)) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { acc.TestAccPreCheck(t) }, + Providers: acc.TestAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccCheckIBMISImagesDataSourceAllConfig(imageName), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrSet(resName, "images.0.operating_system.0.name"), + resource.TestCheckResourceAttrSet(resName, "images.0.operating_system.0.dedicated_host_only"), + resource.TestCheckResourceAttrSet(resName, "images.0.operating_system.0.display_name"), + resource.TestCheckResourceAttrSet(resName, "images.0.operating_system.0.family"), + resource.TestCheckResourceAttrSet(resName, "images.0.operating_system.0.href"), + resource.TestCheckResourceAttrSet(resName, "images.0.operating_system.0.vendor"), + resource.TestCheckResourceAttrSet(resName, "images.0.operating_system.0.version"), + resource.TestCheckResourceAttrSet(resName, "images.0.operating_system.0.architecture"), + resource.TestCheckResourceAttrSet(resName, "images.0.status"), + resource.TestCheckResourceAttrSet(resName, "images.0.resource_group.0.id"), + resource.TestCheckResourceAttrSet(resName, "images.0.resource_group.0.name"), + ), + }, + }, + }) +} func TestAccIBMISImagesDataSource_catalog(t *testing.T) { resName := "data.ibm_is_images.test1" @@ -92,6 +120,12 @@ func testAccCheckIBMISImagesDataSourceConfig() string { data "ibm_is_images" "test1" { }`) } +func testAccCheckIBMISImagesDataSourceAllConfig(imageName string) string { + return fmt.Sprintf(` + data "ibm_is_images" "test1" { + status = "available" + }`) +} func testAccCheckIBMISCatalogImagesDataSourceConfig() string { // status filter defaults to empty return fmt.Sprintf(` diff --git a/website/docs/d/is_image.html.markdown b/website/docs/d/is_image.html.markdown index 4b7f19ebd2..994d2f510e 100644 --- a/website/docs/d/is_image.html.markdown +++ b/website/docs/d/is_image.html.markdown @@ -69,5 +69,29 @@ In addition to all argument reference list, you can access the following attribu - `id` - (String) The unique identifier of the image. - `obsolescence_at` - (String) The obsolescence date and time (UTC) for this image. If absent, no obsolescence date and time has been set. - `os` - (String) The name of the operating system. +- `operating_system` - (List) The operating system details. + + Nested scheme for `operating_system`: + - `architecture` - (String) The operating system architecture. + - `dedicated_host_only` - (Bool) Images with this operating system can only be used on dedicated hosts or dedicated host groups. + - `display_name` - (String) A unique, display-friendly name for the operating system. + - `family` - (String) The software family for this operating system. + - `href` - (String) The URL for this operating system. + - `name` - (String) The globally unique name for this operating system. + - `vendor` - (String) The vendor of the operating system. + - `version` - (String) The major release version of this operating system. +- `resource_group` - (List) The resource group object, for this image. + + Nested scheme for `resource_group`: + - `href` - (String) The URL for this resource group. + - `id` - (String) The unique identifier for this resource group. + - `name` - (String) The user-defined name for this resource group. - `status` - (String) The status of this image. +- `status_reasons` - (List) The reasons for the current status (if any). + + Nested scheme for `status_reasons`: + - `code` - (String) The status reason code + - `message` - (String) An explanation of the status reason + - `more_info` - (String) Link to documentation about this status reason + - `source_volume` - The source volume id of the image. diff --git a/website/docs/d/is_images.html.markdown b/website/docs/d/is_images.html.markdown index d5a63840af..012e1beb74 100644 --- a/website/docs/d/is_images.html.markdown +++ b/website/docs/d/is_images.html.markdown @@ -65,7 +65,29 @@ You can access the following attribute references after your data source is crea - `id` - (String) The unique identifier for this image. - `name` - (String) The name for this image. - `os` - (String) The name of the Operating System. + - `operating_system` - (List) The operating system details. + + Nested scheme for `operating_system`: + - `architecture` - (String) The operating system architecture. + - `dedicated_host_only` - (Bool) Images with this operating system can only be used on dedicated hosts or dedicated host groups. + - `display_name` - (String) A unique, display-friendly name for the operating system. + - `family` - (String) The software family for this operating system. + - `href` - (String) The URL for this operating system. + - `name` - (String) The globally unique name for this operating system. + - `vendor` - (String) The vendor of the operating system. + - `version` - (String) The major release version of this operating system. + - `resource_group` - (List) The resource group object, for this image. + Nested scheme for `resource_group`: + - `href` - (String) The URL for this resource group. + - `id` - (String) The unique identifier for this resource group. + - `name` - (String) The user-defined name for this resource group. - `status` - (String) The status of this image. + - `status_reasons` - (List) The reasons for the current status (if any). + + Nested scheme for `status_reasons`: + - `code` - (String) The status reason code + - `message` - (String) An explanation of the status reason + - `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.