diff --git a/go.mod b/go.mod index dc00e70f275..d1c00c2a819 100644 --- a/go.mod +++ b/go.mod @@ -40,7 +40,7 @@ require ( github.com/IBM/secrets-manager-go-sdk/v2 v2.0.7 github.com/IBM/vmware-go-sdk v0.1.2 github.com/IBM/vpc-beta-go-sdk v0.8.0 - github.com/IBM/vpc-go-sdk v0.62.0 + github.com/IBM/vpc-go-sdk v0.63.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 3429de702a6..bfef280bc50 100644 --- a/go.sum +++ b/go.sum @@ -196,6 +196,10 @@ github.com/IBM/vpc-beta-go-sdk v0.8.0 h1:cEPpv4iw3Ba5W2d0AWg3TIbKeJ8y1nPuUuibR5J github.com/IBM/vpc-beta-go-sdk v0.8.0/go.mod h1:hORgIyTFRzXrZIK9IohaWmCRBBlYiDRagsufi7M6akE= github.com/IBM/vpc-go-sdk v0.62.0 h1:Xga74D70ziD7nzm51ue3othHz1epMLVkGP/L6/Be+/0= github.com/IBM/vpc-go-sdk v0.62.0/go.mod h1:VBR6bAznHsNCFA89Ue4JFQpqCcFp8F5neqbCFCyks4Q= +github.com/IBM/vpc-go-sdk v0.63.0 h1:0eSG/8WLK4fW7AvPHlhCmPEe819pgWLF1OIxF0vR43A= +github.com/IBM/vpc-go-sdk v0.63.0/go.mod h1:VBR6bAznHsNCFA89Ue4JFQpqCcFp8F5neqbCFCyks4Q= +github.com/IBM/vpc-go-sdk v0.63.1 h1:HqQeq2wGI2pF4y0/m18EaPsOEEXFjyml+xwlLC9AiXE= +github.com/IBM/vpc-go-sdk v0.63.1/go.mod h1:VBR6bAznHsNCFA89Ue4JFQpqCcFp8F5neqbCFCyks4Q= 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= diff --git a/ibm/service/vpc/data_source_ibm_is_bare_metal_server.go b/ibm/service/vpc/data_source_ibm_is_bare_metal_server.go index 529ff295df3..0481d4e619f 100644 --- a/ibm/service/vpc/data_source_ibm_is_bare_metal_server.go +++ b/ibm/service/vpc/data_source_ibm_is_bare_metal_server.go @@ -756,6 +756,144 @@ func DataSourceIBMIsBareMetalServer() *schema.Resource { Set: flex.ResourceIBMVPCHash, Description: "List of access tags", }, + "health_reasons": { + Type: schema.TypeList, + Computed: true, + Description: "The reasons for the current health_state (if any).", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "code": { + Type: schema.TypeString, + Computed: true, + Description: "A snake case string succinctly identifying the reason for this health state.", + }, + "message": { + Type: schema.TypeString, + Computed: true, + Description: "An explanation of the reason for this health state.", + }, + "more_info": { + Type: schema.TypeString, + Computed: true, + Description: "Link to documentation about the reason for this health state.", + }, + }, + }, + }, + "health_state": &schema.Schema{ + Type: schema.TypeString, + Computed: true, + Description: "The health of this resource", + }, + isReservation: { + Type: schema.TypeList, + Computed: true, + Description: "The reservation used by this bare metal server", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + isReservationId: { + Type: schema.TypeString, + Computed: true, + Description: "The unique identifier for this reservation.", + }, + isReservationCrn: { + Type: schema.TypeString, + Computed: true, + Description: "The CRN for this reservation.", + }, + isReservationName: { + Type: schema.TypeString, + Computed: true, + Description: "The name for this reservation. The name is unique across all reservations in the region.", + }, + isReservationHref: { + Type: schema.TypeString, + Computed: true, + Description: "The URL for this reservation.", + }, + isReservationResourceType: { + Type: schema.TypeString, + Computed: true, + Description: "The resource type.", + }, + isReservationDeleted: &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{ + isReservationDeletedMoreInfo: &schema.Schema{ + Type: schema.TypeString, + Computed: true, + Description: "Link to documentation about deleted resources.", + }, + }, + }, + }, + }, + }, + }, + isReservationAffinity: { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + isReservationAffinityPolicyResp: { + Type: schema.TypeString, + Computed: true, + Description: "The reservation affinity policy to use for this bare metal server.", + }, + isReservationAffinityPool: &schema.Schema{ + Type: schema.TypeList, + Computed: true, + Description: "The pool of reservations available for use by this bare metal server.", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + isReservationId: { + Type: schema.TypeString, + Computed: true, + Description: "The unique identifier for this reservation.", + }, + isReservationCrn: { + Type: schema.TypeString, + Computed: true, + Description: "The CRN for this reservation.", + }, + isReservationName: { + Type: schema.TypeString, + Computed: true, + Description: "The name for this reservation. The name is unique across all reservations in the region.", + }, + isReservationHref: { + Type: schema.TypeString, + Computed: true, + Description: "The URL for this reservation.", + }, + isReservationResourceType: { + Type: schema.TypeString, + Computed: true, + Description: "The resource type.", + }, + isReservationDeleted: &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{ + isReservationDeletedMoreInfo: &schema.Schema{ + Type: schema.TypeString, + Computed: true, + Description: "Link to documentation about deleted resources.", + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, }, } } @@ -1161,6 +1299,71 @@ func dataSourceIBMISBareMetalServerRead(context context.Context, d *schema.Resou } d.Set(isBareMetalServerAccessTags, accesstags) + if bms.HealthReasons != nil { + healthReasonsList := make([]map[string]interface{}, 0) + for _, sr := range bms.HealthReasons { + currentSR := map[string]interface{}{} + if sr.Code != nil && sr.Message != nil { + currentSR["code"] = *sr.Code + currentSR["message"] = *sr.Message + if sr.MoreInfo != nil { + currentSR["more_info"] = *sr.Message + } + healthReasonsList = append(healthReasonsList, currentSR) + } + } + d.Set("health_reasons", healthReasonsList) + } + if err = d.Set("health_state", bms.HealthState); err != nil { + return diag.FromErr(fmt.Errorf("[ERROR] Error setting health_state: %s", err)) + } + if bms.ReservationAffinity != nil { + reservationAffinity := []map[string]interface{}{} + reservationAffinityMap := map[string]interface{}{} + + reservationAffinityMap[isReservationAffinityPolicyResp] = bms.ReservationAffinity.Policy + if bms.ReservationAffinity.Pool != nil { + poolList := make([]map[string]interface{}, 0) + for _, pool := range bms.ReservationAffinity.Pool { + res := map[string]interface{}{} + + res[isReservationId] = *pool.ID + res[isReservationHref] = *pool.Href + res[isReservationName] = *pool.Name + res[isReservationCrn] = *pool.CRN + res[isReservationResourceType] = *pool.ResourceType + if pool.Deleted != nil { + deletedList := []map[string]interface{}{} + deletedMap := dataSourceReservationDeletedToMap(*pool.Deleted) + deletedList = append(deletedList, deletedMap) + res[isReservationDeleted] = deletedList + } + poolList = append(poolList, res) + } + reservationAffinityMap[isReservationAffinityPool] = poolList + } + reservationAffinity = append(reservationAffinity, reservationAffinityMap) + d.Set(isReservationAffinity, reservationAffinity) + } + if bms.Reservation != nil { + resList := make([]map[string]interface{}, 0) + res := map[string]interface{}{} + + res[isReservationId] = *bms.Reservation.ID + res[isReservationHref] = *bms.Reservation.Href + res[isReservationName] = *bms.Reservation.Name + res[isReservationCrn] = *bms.Reservation.CRN + res[isReservationResourceType] = *bms.Reservation.ResourceType + if bms.Reservation.Deleted != nil { + deletedList := []map[string]interface{}{} + deletedMap := dataSourceReservationDeletedToMap(*bms.Reservation.Deleted) + deletedList = append(deletedList, deletedMap) + res[isReservationDeleted] = deletedList + } + resList = append(resList, res) + d.Set(isReservation, resList) + } + return nil } diff --git a/ibm/service/vpc/data_source_ibm_is_bare_metal_server_profile.go b/ibm/service/vpc/data_source_ibm_is_bare_metal_server_profile.go index 6247adeb2d6..82a7bbb0396 100644 --- a/ibm/service/vpc/data_source_ibm_is_bare_metal_server_profile.go +++ b/ibm/service/vpc/data_source_ibm_is_bare_metal_server_profile.go @@ -408,6 +408,28 @@ func DataSourceIBMIsBareMetalServerProfile() *schema.Resource { }, }, }, + "reservation_terms": { + Type: schema.TypeList, + Computed: true, + Description: "The type for this profile field", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "type": { + Type: schema.TypeString, + Computed: true, + Description: "The type for this profile field.", + }, + "values": { + Type: schema.TypeList, + Computed: true, + Description: "The supported committed use terms for a reservation using this profile", + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + }, + }, + }, }, } } @@ -611,10 +633,37 @@ func dataSourceIBMISBMSProfileRead(context context.Context, d *schema.ResourceDa return diag.FromErr(fmt.Errorf("Error setting network_attachment_count %s", err)) } } + if bmsProfile.ReservationTerms != nil { + err = d.Set("reservation_terms", dataSourceBaremetalServerProfileFlattenReservationTerms(*bmsProfile.ReservationTerms)) + if err != nil { + return diag.FromErr(fmt.Errorf("Error setting reservation_terms %s", err)) + } + } return nil } +func dataSourceBaremetalServerProfileFlattenReservationTerms(result vpcv1.BareMetalServerProfileReservationTerms) (finalList []map[string]interface{}) { + finalList = []map[string]interface{}{} + finalMap := dataSourceBaremetalServerProfileReservationTermsToMap(result) + finalList = append(finalList, finalMap) + + return finalList +} + +func dataSourceBaremetalServerProfileReservationTermsToMap(resTermItem vpcv1.BareMetalServerProfileReservationTerms) map[string]interface{} { + resTermMap := map[string]interface{}{} + + if resTermItem.Type != nil { + resTermMap["type"] = resTermItem.Type + } + if resTermItem.Values != nil { + resTermMap["values"] = resTermItem.Values + } + + return resTermMap +} + func dataSourceIBMIsBareMetalServerProfileBareMetalServerProfileConsoleTypesToMap(model *vpcv1.BareMetalServerProfileConsoleTypes) (map[string]interface{}, error) { modelMap := make(map[string]interface{}) modelMap["type"] = model.Type diff --git a/ibm/service/vpc/data_source_ibm_is_bare_metal_server_profile_test.go b/ibm/service/vpc/data_source_ibm_is_bare_metal_server_profile_test.go index d3265274caf..70f3030a3c8 100644 --- a/ibm/service/vpc/data_source_ibm_is_bare_metal_server_profile_test.go +++ b/ibm/service/vpc/data_source_ibm_is_bare_metal_server_profile_test.go @@ -42,6 +42,9 @@ func TestAccIBMISBMSProfileDataSource_basic(t *testing.T) { resource.TestCheckResourceAttrSet(resName, "os_architecture.#"), resource.TestCheckResourceAttrSet(resName, "resource_type"), resource.TestCheckResourceAttrSet(resName, "supported_trusted_platform_module_modes.#"), + resource.TestCheckResourceAttrSet(resName, "reservation_terms.#"), + resource.TestCheckResourceAttrSet(resName, "reservation_terms.0.type"), + resource.TestCheckResourceAttrSet(resName, "reservation_terms.0.values"), ), }, }, diff --git a/ibm/service/vpc/data_source_ibm_is_bare_metal_servers.go b/ibm/service/vpc/data_source_ibm_is_bare_metal_servers.go index f639006c021..cbb4aa77537 100644 --- a/ibm/service/vpc/data_source_ibm_is_bare_metal_servers.go +++ b/ibm/service/vpc/data_source_ibm_is_bare_metal_servers.go @@ -799,6 +799,144 @@ func DataSourceIBMIsBareMetalServers() *schema.Resource { Set: flex.ResourceIBMVPCHash, Description: "List of access tags", }, + "health_reasons": { + Type: schema.TypeList, + Computed: true, + Description: "The reasons for the current health_state (if any).", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "code": { + Type: schema.TypeString, + Computed: true, + Description: "A snake case string succinctly identifying the reason for this health state.", + }, + "message": { + Type: schema.TypeString, + Computed: true, + Description: "An explanation of the reason for this health state.", + }, + "more_info": { + Type: schema.TypeString, + Computed: true, + Description: "Link to documentation about the reason for this health state.", + }, + }, + }, + }, + "health_state": &schema.Schema{ + Type: schema.TypeString, + Computed: true, + Description: "The health of this resource", + }, + isReservation: { + Type: schema.TypeList, + Computed: true, + Description: "The reservation used by this bare metal server", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + isReservationId: { + Type: schema.TypeString, + Computed: true, + Description: "The unique identifier for this reservation.", + }, + isReservationCrn: { + Type: schema.TypeString, + Computed: true, + Description: "The CRN for this reservation.", + }, + isReservationName: { + Type: schema.TypeString, + Computed: true, + Description: "The name for this reservation. The name is unique across all reservations in the region.", + }, + isReservationHref: { + Type: schema.TypeString, + Computed: true, + Description: "The URL for this reservation.", + }, + isReservationResourceType: { + Type: schema.TypeString, + Computed: true, + Description: "The resource type.", + }, + isReservationDeleted: &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{ + isReservationDeletedMoreInfo: &schema.Schema{ + Type: schema.TypeString, + Computed: true, + Description: "Link to documentation about deleted resources.", + }, + }, + }, + }, + }, + }, + }, + isReservationAffinity: { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + isReservationAffinityPolicyResp: { + Type: schema.TypeString, + Computed: true, + Description: "The reservation affinity policy to use for this bare metal server.", + }, + isReservationAffinityPool: &schema.Schema{ + Type: schema.TypeList, + Computed: true, + Description: "The pool of reservations available for use by this bare metal server.", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + isReservationId: { + Type: schema.TypeString, + Computed: true, + Description: "The unique identifier for this reservation.", + }, + isReservationCrn: { + Type: schema.TypeString, + Computed: true, + Description: "The CRN for this reservation.", + }, + isReservationName: { + Type: schema.TypeString, + Computed: true, + Description: "The name for this reservation. The name is unique across all reservations in the region.", + }, + isReservationHref: { + Type: schema.TypeString, + Computed: true, + Description: "The URL for this reservation.", + }, + isReservationResourceType: { + Type: schema.TypeString, + Computed: true, + Description: "The resource type.", + }, + isReservationDeleted: &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{ + isReservationDeletedMoreInfo: &schema.Schema{ + Type: schema.TypeString, + Computed: true, + Description: "Link to documentation about deleted resources.", + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, }, }, }, @@ -1180,6 +1318,62 @@ func dataSourceIBMISBareMetalServersRead(context context.Context, d *schema.Reso if bms.ResourceGroup != nil { l[isBareMetalServerResourceGroup] = *bms.ResourceGroup.ID } + if bms.HealthReasons != nil { + healthReasonsList := []map[string]interface{}{} + for _, healthReasonsItem := range bms.HealthReasons { + healthReasonsList = append(healthReasonsList, dataSourceBaremetalServersCollectionHealthReasonsToMap(healthReasonsItem)) + } + l["health_reasons"] = healthReasonsList + } + if bms.HealthState != nil { + l["health_state"] = bms.HealthState + } + if bms.ReservationAffinity != nil { + reservationAffinity := []map[string]interface{}{} + reservationAffinityMap := map[string]interface{}{} + + reservationAffinityMap[isReservationAffinityPolicyResp] = bms.ReservationAffinity.Policy + if bms.ReservationAffinity.Pool != nil { + poolList := make([]map[string]interface{}, 0) + for _, pool := range bms.ReservationAffinity.Pool { + res := map[string]interface{}{} + + res[isReservationId] = *pool.ID + res[isReservationHref] = *pool.Href + res[isReservationName] = *pool.Name + res[isReservationCrn] = *pool.CRN + res[isReservationResourceType] = *pool.ResourceType + if pool.Deleted != nil { + deletedList := []map[string]interface{}{} + deletedMap := dataSourceReservationDeletedToMap(*pool.Deleted) + deletedList = append(deletedList, deletedMap) + res[isReservationDeleted] = deletedList + } + poolList = append(poolList, res) + } + reservationAffinityMap[isReservationAffinityPool] = poolList + } + reservationAffinity = append(reservationAffinity, reservationAffinityMap) + l[isReservationAffinity] = reservationAffinity + } + if bms.Reservation != nil { + resList := make([]map[string]interface{}, 0) + res := map[string]interface{}{} + + res[isReservationId] = *bms.Reservation.ID + res[isReservationHref] = *bms.Reservation.Href + res[isReservationName] = *bms.Reservation.Name + res[isReservationCrn] = *bms.Reservation.CRN + res[isReservationResourceType] = *bms.Reservation.ResourceType + if bms.Reservation.Deleted != nil { + deletedList := []map[string]interface{}{} + deletedMap := dataSourceReservationDeletedToMap(*bms.Reservation.Deleted) + deletedList = append(deletedList, deletedMap) + res[isReservationDeleted] = deletedList + } + resList = append(resList, res) + l[isReservation] = resList + } serversInfo = append(serversInfo, l) } d.SetId(dataSourceIBMISBareMetalServersID(d)) @@ -1187,6 +1381,22 @@ func dataSourceIBMISBareMetalServersRead(context context.Context, d *schema.Reso return nil } +func dataSourceBaremetalServersCollectionHealthReasonsToMap(statusReasonsItem vpcv1.BareMetalServerHealthReason) (healthReasonsMap map[string]interface{}) { + healthReasonsMap = map[string]interface{}{} + + if statusReasonsItem.Code != nil { + healthReasonsMap["code"] = statusReasonsItem.Code + } + if statusReasonsItem.Message != nil { + healthReasonsMap["message"] = statusReasonsItem.Message + } + if statusReasonsItem.MoreInfo != nil { + healthReasonsMap["more_info"] = statusReasonsItem.MoreInfo + } + + return healthReasonsMap +} + // dataSourceIBMISBareMetalServersID returns a reasonable ID for a Bare Metal Servers list. func dataSourceIBMISBareMetalServersID(d *schema.ResourceData) string { return time.Now().UTC().String() diff --git a/ibm/service/vpc/data_source_ibm_is_instance.go b/ibm/service/vpc/data_source_ibm_is_instance.go index 0e1aed9a503..cbae0937a41 100644 --- a/ibm/service/vpc/data_source_ibm_is_instance.go +++ b/ibm/service/vpc/data_source_ibm_is_instance.go @@ -1080,6 +1080,35 @@ func DataSourceIBMISInstance() *schema.Resource { }, }, }, + "health_reasons": { + Type: schema.TypeList, + Computed: true, + Description: "The reasons for the current health_state (if any).", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "code": { + Type: schema.TypeString, + Computed: true, + Description: "A snake case string succinctly identifying the reason for this health state.", + }, + "message": { + Type: schema.TypeString, + Computed: true, + Description: "An explanation of the reason for this health state.", + }, + "more_info": { + Type: schema.TypeString, + Computed: true, + Description: "Link to documentation about the reason for this health state.", + }, + }, + }, + }, + "health_state": &schema.Schema{ + Type: schema.TypeString, + Computed: true, + Description: "The health of this resource", + }, isInstanceReservation: { Type: schema.TypeList, Computed: true, @@ -1651,6 +1680,24 @@ func instanceGetByName(d *schema.ResourceData, meta interface{}, name string) er d.Set(isInstanceResourceGroup, instance.ResourceGroup.ID) d.Set(flex.ResourceGroupName, instance.ResourceGroup.Name) } + if instance.HealthReasons != nil { + healthReasonsList := make([]map[string]interface{}, 0) + for _, sr := range instance.HealthReasons { + currentSR := map[string]interface{}{} + if sr.Code != nil && sr.Message != nil { + currentSR["code"] = *sr.Code + currentSR["message"] = *sr.Message + if sr.MoreInfo != nil { + currentSR["more_info"] = *sr.Message + } + healthReasonsList = append(healthReasonsList, currentSR) + } + } + d.Set("health_reasons", healthReasonsList) + } + if err = d.Set("health_state", instance.HealthState); err != nil { + return err + } if instance.ReservationAffinity != nil { reservationAffinity := []map[string]interface{}{} reservationAffinityMap := map[string]interface{}{} @@ -1668,7 +1715,7 @@ func instanceGetByName(d *schema.ResourceData, meta interface{}, name string) er res[isReservationResourceType] = *pool.ResourceType if pool.Deleted != nil { deletedList := []map[string]interface{}{} - deletedMap := dataSourceInstanceReservationDeletedToMap(*pool.Deleted) + deletedMap := dataSourceReservationDeletedToMap(*pool.Deleted) deletedList = append(deletedList, deletedMap) res[isReservationDeleted] = deletedList } @@ -1690,7 +1737,7 @@ func instanceGetByName(d *schema.ResourceData, meta interface{}, name string) er res[isReservationResourceType] = *instance.Reservation.ResourceType if instance.Reservation.Deleted != nil { deletedList := []map[string]interface{}{} - deletedMap := dataSourceInstanceReservationDeletedToMap(*instance.Reservation.Deleted) + deletedMap := dataSourceReservationDeletedToMap(*instance.Reservation.Deleted) deletedList = append(deletedList, deletedMap) res[isReservationDeleted] = deletedList } @@ -1701,7 +1748,7 @@ func instanceGetByName(d *schema.ResourceData, meta interface{}, name string) er } -func dataSourceInstanceReservationDeletedToMap(deletedItem vpcv1.Deleted) (deletedMap map[string]interface{}) { +func dataSourceReservationDeletedToMap(deletedItem vpcv1.Deleted) (deletedMap map[string]interface{}) { deletedMap = map[string]interface{}{} if deletedItem.MoreInfo != nil { diff --git a/ibm/service/vpc/data_source_ibm_is_instances.go b/ibm/service/vpc/data_source_ibm_is_instances.go index 7a26fcf1962..455b597aa33 100644 --- a/ibm/service/vpc/data_source_ibm_is_instances.go +++ b/ibm/service/vpc/data_source_ibm_is_instances.go @@ -1033,6 +1033,35 @@ func DataSourceIBMISInstances() *schema.Resource { }, }, }, + "health_reasons": { + Type: schema.TypeList, + Computed: true, + Description: "The reasons for the current health_state (if any).", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "code": { + Type: schema.TypeString, + Computed: true, + Description: "A snake case string succinctly identifying the reason for this health state.", + }, + "message": { + Type: schema.TypeString, + Computed: true, + Description: "An explanation of the reason for this health state.", + }, + "more_info": { + Type: schema.TypeString, + Computed: true, + Description: "Link to documentation about the reason for this health state.", + }, + }, + }, + }, + "health_state": &schema.Schema{ + Type: schema.TypeString, + Computed: true, + Description: "The health of this resource", + }, isInstanceReservation: { Type: schema.TypeList, Computed: true, @@ -1613,6 +1642,16 @@ func instancesList(d *schema.ResourceData, meta interface{}) error { if instance.Disks != nil { l[isInstanceDisks] = dataSourceInstanceFlattenDisks(instance.Disks) } + if instance.HealthReasons != nil { + healthReasonsList := []map[string]interface{}{} + for _, healthReasonsItem := range instance.HealthReasons { + healthReasonsList = append(healthReasonsList, dataSourceInstancesCollectionHealthReasonsToMap(healthReasonsItem)) + } + l["health_reasons"] = healthReasonsList + } + if instance.HealthState != nil { + l["health_state"] = instance.HealthState + } if instance.ReservationAffinity != nil { reservationAffinity := []map[string]interface{}{} reservationAffinityMap := map[string]interface{}{} @@ -1630,7 +1669,7 @@ func instancesList(d *schema.ResourceData, meta interface{}) error { res[isReservationResourceType] = *pool.ResourceType if pool.Deleted != nil { deletedList := []map[string]interface{}{} - deletedMap := dataSourceInstanceReservationDeletedToMap(*pool.Deleted) + deletedMap := dataSourceReservationDeletedToMap(*pool.Deleted) deletedList = append(deletedList, deletedMap) res[isReservationDeleted] = deletedList } @@ -1652,7 +1691,7 @@ func instancesList(d *schema.ResourceData, meta interface{}) error { res[isReservationResourceType] = *instance.Reservation.ResourceType if instance.Reservation.Deleted != nil { deletedList := []map[string]interface{}{} - deletedMap := dataSourceInstanceReservationDeletedToMap(*instance.Reservation.Deleted) + deletedMap := dataSourceReservationDeletedToMap(*instance.Reservation.Deleted) deletedList = append(deletedList, deletedMap) res[isReservationDeleted] = deletedList } @@ -1671,3 +1710,19 @@ func instancesList(d *schema.ResourceData, meta interface{}) error { func dataSourceIBMISInstancesID(d *schema.ResourceData) string { return time.Now().UTC().String() } + +func dataSourceInstancesCollectionHealthReasonsToMap(statusReasonsItem vpcv1.InstanceHealthReason) (healthReasonsMap map[string]interface{}) { + healthReasonsMap = map[string]interface{}{} + + if statusReasonsItem.Code != nil { + healthReasonsMap["code"] = statusReasonsItem.Code + } + if statusReasonsItem.Message != nil { + healthReasonsMap["message"] = statusReasonsItem.Message + } + if statusReasonsItem.MoreInfo != nil { + healthReasonsMap["more_info"] = statusReasonsItem.MoreInfo + } + + return healthReasonsMap +} diff --git a/ibm/service/vpc/data_source_ibm_is_reservation.go b/ibm/service/vpc/data_source_ibm_is_reservation.go index 66b6d820bb5..8c0999028ba 100644 --- a/ibm/service/vpc/data_source_ibm_is_reservation.go +++ b/ibm/service/vpc/data_source_ibm_is_reservation.go @@ -310,7 +310,7 @@ func dataSourceIBMIsReservationRead(context context.Context, d *schema.ResourceD if reservation.Profile != nil { profileList := []map[string]interface{}{} profile := reservation.Profile - profileMap := dataSourceReservationProfileToMap(*profile) + profileMap := dataSourceReservationProfileToMap(profile) profileList = append(profileList, profileMap) if err = d.Set("profile", profileList); err != nil { return diag.FromErr(fmt.Errorf("[ERROR] Error setting profile: %s", err)) @@ -349,17 +349,23 @@ func dataSourceIBMIsReservationRead(context context.Context, d *schema.ResourceD return nil } -func dataSourceReservationProfileToMap(profileItem vpcv1.ReservationProfile) (profileMap map[string]interface{}) { - profileMap = map[string]interface{}{} +func dataSourceReservationProfileToMap(profileItem vpcv1.ReservationProfileIntf) (profileMap map[string]interface{}) { + var profile *vpcv1.ReservationProfile + if profileItem == nil { + return + } + if profile = profileItem.(*vpcv1.ReservationProfile); profile == nil { + return + } - if profileItem.Href != nil { - profileMap["href"] = profileItem.Href + if profile.Href != nil { + profileMap["href"] = profile.Href } - if profileItem.Name != nil { - profileMap["name"] = profileItem.Name + if profile.Name != nil { + profileMap["name"] = profile.Name } - if profileItem.ResourceType != nil { - profileMap["resource_type"] = profileItem.ResourceType + if profile.ResourceType != nil { + profileMap["resource_type"] = profile.ResourceType } return profileMap } diff --git a/ibm/service/vpc/data_source_ibm_is_reservations.go b/ibm/service/vpc/data_source_ibm_is_reservations.go index 313d7625dd9..c773d65e01a 100644 --- a/ibm/service/vpc/data_source_ibm_is_reservations.go +++ b/ibm/service/vpc/data_source_ibm_is_reservations.go @@ -341,7 +341,7 @@ func dataSourceReservationCollectionReservationsToMap(reservationsItem vpcv1.Res if reservationsItem.Profile != nil { profileList := []map[string]interface{}{} profile := reservationsItem.Profile - profileMap := dataSourceReservationCollectionReservationsProfileToMap(*profile) + profileMap := dataSourceReservationCollectionReservationsProfileToMap(profile) profileList = append(profileList, profileMap) reservationsMap["profile"] = profileList } @@ -370,17 +370,22 @@ func dataSourceReservationCollectionReservationsToMap(reservationsItem vpcv1.Res return reservationsMap } -func dataSourceReservationCollectionReservationsProfileToMap(profileItem vpcv1.ReservationProfile) (profileMap map[string]interface{}) { - profileMap = map[string]interface{}{} - - if profileItem.Href != nil { - profileMap["href"] = profileItem.Href +func dataSourceReservationCollectionReservationsProfileToMap(profileItem vpcv1.ReservationProfileIntf) (profileMap map[string]interface{}) { + if profileItem == nil { + return + } + var profile *vpcv1.ReservationProfile + if profile = profileItem.(*vpcv1.ReservationProfile); profile == nil { + return + } + if profile.Href != nil { + profileMap["href"] = profile.Href } - if profileItem.Name != nil { - profileMap["name"] = profileItem.Name + if profile.Name != nil { + profileMap["name"] = profile.Name } - if profileItem.ResourceType != nil { - profileMap["resource_type"] = profileItem.ResourceType + if profile.ResourceType != nil { + profileMap["resource_type"] = profile.ResourceType } return profileMap } diff --git a/ibm/service/vpc/resource_ibm_is_bare_metal_server.go b/ibm/service/vpc/resource_ibm_is_bare_metal_server.go index 766496bdf0d..11f794bbbc5 100644 --- a/ibm/service/vpc/resource_ibm_is_bare_metal_server.go +++ b/ibm/service/vpc/resource_ibm_is_bare_metal_server.go @@ -1167,6 +1167,148 @@ func ResourceIBMIsBareMetalServer() *schema.Resource { Set: flex.ResourceIBMVPCHash, Description: "List of access management tags", }, + "health_reasons": { + Type: schema.TypeList, + Computed: true, + Description: "The reasons for the current health_state (if any).", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "code": { + Type: schema.TypeString, + Computed: true, + Description: "A snake case string succinctly identifying the reason for this health state.", + }, + "message": { + Type: schema.TypeString, + Computed: true, + Description: "An explanation of the reason for this health state.", + }, + "more_info": { + Type: schema.TypeString, + Computed: true, + Description: "Link to documentation about the reason for this health state.", + }, + }, + }, + }, + "health_state": &schema.Schema{ + Type: schema.TypeString, + Computed: true, + Description: "The health of this resource", + }, + isReservation: { + Type: schema.TypeList, + Computed: true, + Description: "The reservation used by this bare metal server", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + isReservationId: { + Type: schema.TypeString, + Computed: true, + Description: "The unique identifier for this reservation.", + }, + isReservationCrn: { + Type: schema.TypeString, + Computed: true, + Description: "The CRN for this reservation.", + }, + isReservationName: { + Type: schema.TypeString, + Computed: true, + Description: "The name for this reservation. The name is unique across all reservations in the region.", + }, + isReservationHref: { + Type: schema.TypeString, + Computed: true, + Description: "The URL for this reservation.", + }, + isReservationResourceType: { + Type: schema.TypeString, + Computed: true, + Description: "The resource type.", + }, + isReservationDeleted: &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{ + isReservationDeletedMoreInfo: &schema.Schema{ + Type: schema.TypeString, + Computed: true, + Description: "Link to documentation about deleted resources.", + }, + }, + }, + }, + }, + }, + }, + isReservationAffinity: { + Type: schema.TypeList, + Optional: true, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "policy": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "The reservation affinity policy to use for this bare metal server.", + }, + isReservationAffinityPool: &schema.Schema{ + Type: schema.TypeList, + Optional: true, + Computed: true, + Description: "The pool of reservations available for use by this bare metal server.", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + isReservationId: { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "The unique identifier for this reservation.", + }, + isReservationCrn: { + Type: schema.TypeString, + Computed: true, + Description: "The CRN for this reservation.", + }, + isReservationHref: { + Type: schema.TypeString, + Computed: true, + Description: "The URL for this reservation.", + }, + isReservationName: { + Type: schema.TypeString, + Computed: true, + Description: "The name for this reservation. The name is unique across all reservations in the region.", + }, + isReservationResourceType: { + Type: schema.TypeString, + Computed: true, + Description: "The resource type.", + }, + isReservationDeleted: &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{ + isReservationDeletedMoreInfo: &schema.Schema{ + Type: schema.TypeString, + Computed: true, + Description: "Link to documentation about deleted resources.", + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, }, } } @@ -1292,6 +1434,32 @@ func resourceIBMISBareMetalServerCreate(context context.Context, d *schema.Resou options.Name = &nameStr } + if resAffinity, ok := d.GetOk(isReservationAffinity); ok { + resAff := resAffinity.([]interface{})[0].(map[string]interface{}) + var resAffinity = &vpcv1.BareMetalServerReservationAffinityPrototype{} + policy, ok := resAff["policy"] + policyStr := policy.(string) + if policyStr != "" && ok { + resAffinity.Policy = &policyStr + } + poolIntf, okPool := resAff[isReservationAffinityPool] + if okPool && poolIntf != nil && poolIntf.([]interface{}) != nil && len(poolIntf.([]interface{})) > 0 { + pool := poolIntf.([]interface{})[0].(map[string]interface{}) + id, okId := pool["id"] + if okId { + idStr, ok := id.(string) + if idStr != "" && ok { + var resAffPool = make([]vpcv1.ReservationIdentityIntf, 1) + resAffPool[0] = &vpcv1.ReservationIdentity{ + ID: &idStr, + } + resAffinity.Pool = resAffPool + } + } + } + options.ReservationAffinity = resAffinity + } + if primnicintf, ok := d.GetOk(isBareMetalServerPrimaryNetworkInterface); ok && len(primnicintf.([]interface{})) > 0 { primnic := primnicintf.([]interface{})[0].(map[string]interface{}) subnetintf, _ := primnic[isBareMetalServerNicSubnet] @@ -2130,6 +2298,71 @@ func bareMetalServerGet(context context.Context, d *schema.ResourceData, meta in d.Set(isBareMetalServerPrimaryNetworkInterface, primaryNicList) } + if bms.HealthReasons != nil { + healthReasonsList := make([]map[string]interface{}, 0) + for _, sr := range bms.HealthReasons { + currentSR := map[string]interface{}{} + if sr.Code != nil && sr.Message != nil { + currentSR["code"] = *sr.Code + currentSR["message"] = *sr.Message + if sr.MoreInfo != nil { + currentSR["more_info"] = *sr.Message + } + healthReasonsList = append(healthReasonsList, currentSR) + } + } + d.Set("health_reasons", healthReasonsList) + } + if err = d.Set("health_state", bms.HealthState); err != nil { + return err + } + if bms.ReservationAffinity != nil { + reservationAffinity := []map[string]interface{}{} + reservationAffinityMap := map[string]interface{}{} + + reservationAffinityMap[isReservationAffinityPolicyResp] = bms.ReservationAffinity.Policy + if bms.ReservationAffinity.Pool != nil && len(bms.ReservationAffinity.Pool) > 0 { + poolList := make([]map[string]interface{}, 0) + for _, pool := range bms.ReservationAffinity.Pool { + res := map[string]interface{}{} + + res[isReservationId] = *pool.ID + res[isReservationHref] = *pool.Href + res[isReservationName] = *pool.Name + res[isReservationCrn] = *pool.CRN + res[isReservationResourceType] = *pool.ResourceType + if pool.Deleted != nil { + deletedList := []map[string]interface{}{} + deletedMap := dataSourceReservationDeletedToMap(*pool.Deleted) + deletedList = append(deletedList, deletedMap) + res[isReservationDeleted] = deletedList + } + poolList = append(poolList, res) + } + reservationAffinityMap[isReservationAffinityPool] = poolList + } + reservationAffinity = append(reservationAffinity, reservationAffinityMap) + d.Set(isReservationAffinity, reservationAffinity) + } + resList := make([]map[string]interface{}, 0) + if bms.Reservation != nil { + res := map[string]interface{}{} + + res[isReservationId] = *bms.Reservation.ID + res[isReservationHref] = *bms.Reservation.Href + res[isReservationName] = *bms.Reservation.Name + res[isReservationCrn] = *bms.Reservation.CRN + res[isReservationResourceType] = *bms.Reservation.ResourceType + if bms.Reservation.Deleted != nil { + deletedList := []map[string]interface{}{} + deletedMap := dataSourceReservationDeletedToMap(*bms.Reservation.Deleted) + deletedList = append(deletedList, deletedMap) + res[isReservationDeleted] = deletedList + } + resList = append(resList, res) + } + d.Set(isReservation, resList) + if !core.IsNil(bms.PrimaryNetworkAttachment) { pnaId := *bms.PrimaryNetworkAttachment.ID getBareMetalServerNetworkAttachment := &vpcv1.GetBareMetalServerNetworkAttachmentOptions{ @@ -3648,8 +3881,49 @@ func bareMetalServerUpdate(context context.Context, d *schema.ResourceData, meta } bmsPatchModel.Name = &nameStr } + resPol := "reservation_affinity.0.policy" + resPool := "reservation_affinity.0.pool" + policyStr := "" + idStr := "" + + if (d.HasChange(resPol) || d.HasChange(resPool)) && !d.IsNewResource() { + flag = true + if resAffinity, ok := d.GetOk(isReservationAffinity); ok { + resAff := resAffinity.([]interface{})[0].(map[string]interface{}) + var resAffinityPatch = &vpcv1.BareMetalServerReservationAffinityPatch{} + policy, ok := resAff["policy"] + policyStr = policy.(string) + if policyStr != "" && ok { + resAffinityPatch.Policy = &policyStr + } + if d.HasChange(resPool) { + poolIntf, okPool := resAff[isReservationAffinityPool] + if okPool && poolIntf != nil && poolIntf.([]interface{}) != nil && len(poolIntf.([]interface{})) > 0 { + pool := poolIntf.([]interface{})[0].(map[string]interface{}) + id, okId := pool["id"] + if okId { + idStr, ok = id.(string) + if idStr != "" && ok { + var resAffPool = make([]vpcv1.ReservationIdentityIntf, 1) + resAffPool[0] = &vpcv1.ReservationIdentity{ + ID: &idStr, + } + resAffinityPatch.Pool = resAffPool + } + } + + } + } + } + } if flag { bmsPatch, err := bmsPatchModel.AsPatch() + //Detaching the reservation from the reserved bare metal server + if policyStr == "disabled" && idStr == "" { + resAffMap := bmsPatch["reservation_affinity"].(map[string]interface{}) + resAffMap["pool"] = nil + bmsPatch["reservation_affinity"] = resAffMap + } if err != nil { return fmt.Errorf("[ERROR] Error calling asPatch for BareMetalServerPatch: %s", err) } @@ -3675,7 +3949,7 @@ func bareMetalServerUpdate(context context.Context, d *schema.ResourceData, meta } if flag || isServerStopped { - isServerStopped, err = resourceStartServerIfStopped(id, "hard", d, context, sess, isServerStopped) + _, err = resourceStartServerIfStopped(id, "hard", d, context, sess, isServerStopped) if err != nil { return err } diff --git a/ibm/service/vpc/resource_ibm_is_bare_metal_server_test.go b/ibm/service/vpc/resource_ibm_is_bare_metal_server_test.go index 3a96f58756b..3a5fbadad1e 100644 --- a/ibm/service/vpc/resource_ibm_is_bare_metal_server_test.go +++ b/ibm/service/vpc/resource_ibm_is_bare_metal_server_test.go @@ -482,6 +482,77 @@ ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCKVmnMOlHKcZK8tpt3MP1lqOLAcqcJzhsvJcjscgVE }) } +func TestAccIBMISBareMetalServer_reservation(t *testing.T) { + var server string + vpcname := fmt.Sprintf("tf-vpc-%d", acctest.RandIntRange(10, 100)) + name := fmt.Sprintf("tf-server-%d", acctest.RandIntRange(10, 100)) + subnetname := fmt.Sprintf("tfip-subnet-%d", acctest.RandIntRange(10, 100)) + publicKey := strings.TrimSpace(` +ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCKVmnMOlHKcZK8tpt3MP1lqOLAcqcJzhsvJcjscgVERRN7/9484SOBJ3HSKxxNG5JN8owAjy5f9yYwcUg+JaUVuytn5Pv3aeYROHGGg+5G346xaq3DAwX6Y5ykr2fvjObgncQBnuU5KHWCECO/4h8uWuwh/kfniXPVjFToc+gnkqA+3RKpAecZhFXwfalQ9mMuYGFxn+fwn8cYEApsJbsEmb0iJwPiZ5hjFC8wREuiTlhPHDgkBLOiycd20op2nXzDbHfCHInquEe/gYxEitALONxm0swBOwJZwlTDOB7C6y2dzlrtxr1L59m7pCkWI4EtTRLvleehBoj3u7jB4usR +`) + sshname := fmt.Sprintf("tf-sshname-%d", acctest.RandIntRange(10, 100)) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { acc.TestAccPreCheck(t) }, + Providers: acc.TestAccProviders, + CheckDestroy: testAccCheckIBMISBareMetalServerDestroy, + Steps: []resource.TestStep{ + { + Config: testAccCheckIBMISBareMetalServerReservationConfig(vpcname, subnetname, sshname, publicKey, name), + Check: resource.ComposeTestCheckFunc( + testAccCheckIBMISBareMetalServerExists("ibm_is_bare_metal_server.testacc_bms", server), + resource.TestCheckResourceAttr( + "ibm_is_bare_metal_server.testacc_bms", "name", name), + resource.TestCheckResourceAttr( + "ibm_is_bare_metal_server.testacc_bms", "zone", acc.ISZoneName), + resource.TestCheckResourceAttr( + "ibm_is_bare_metal_server.testacc_bms", "reservation_affinity.0.policy", "manual"), + resource.TestCheckResourceAttrSet( + "ibm_is_bare_metal_server.testacc_bms", "reservation_affinity.0.pool"), + ), + }, + }, + }) +} + +func testAccCheckIBMISBareMetalServerReservationConfig(vpcname, subnetname, sshname, publicKey, name string) string { + return fmt.Sprintf(` + resource "ibm_is_vpc" "testacc_vpc" { + name = "%s" + } + + resource "ibm_is_subnet" "testacc_subnet" { + name = "%s" + vpc = ibm_is_vpc.testacc_vpc.id + zone = "%s" + total_ipv4_address_count = 16 + } + + resource "ibm_is_ssh_key" "testacc_sshkey" { + name = "%s" + public_key = "%s" + } + + resource "ibm_is_bare_metal_server" "testacc_bms" { + profile = "%s" + name = "%s" + image = "%s" + zone = "%s" + keys = [ibm_is_ssh_key.testacc_sshkey.id] + primary_network_interface { + subnet = ibm_is_subnet.testacc_subnet.id + } + vpc = ibm_is_vpc.testacc_vpc.id + reservation_affinity { + policy = "manual" + pool { + id = "0735-b4a78f50-33bd-44f9-a3ff-4c33f444459d" + } + } + } +`, vpcname, subnetname, acc.ISZoneName, sshname, publicKey, acc.IsBareMetalServerProfileName, name, acc.IsBareMetalServerImage, acc.ISZoneName) +} + func testAccCheckIBMISBareMetalServerDestroy(s *terraform.State) error { sess, _ := acc.TestAccProvider.Meta().(conns.ClientSession).VpcV1API() diff --git a/ibm/service/vpc/resource_ibm_is_instance.go b/ibm/service/vpc/resource_ibm_is_instance.go index cb2e000aa37..1f1d6bb628b 100644 --- a/ibm/service/vpc/resource_ibm_is_instance.go +++ b/ibm/service/vpc/resource_ibm_is_instance.go @@ -1546,6 +1546,35 @@ func ResourceIBMISInstance() *schema.Resource { }, }, }, + "health_reasons": { + Type: schema.TypeList, + Computed: true, + Description: "The reasons for the current health_state (if any).", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "code": { + Type: schema.TypeString, + Computed: true, + Description: "A snake case string succinctly identifying the reason for this health state.", + }, + "message": { + Type: schema.TypeString, + Computed: true, + Description: "An explanation of the reason for this health state.", + }, + "more_info": { + Type: schema.TypeString, + Computed: true, + Description: "Link to documentation about the reason for this health state.", + }, + }, + }, + }, + "health_state": &schema.Schema{ + Type: schema.TypeString, + Computed: true, + Description: "The health of this resource", + }, isInstanceReservation: { Type: schema.TypeList, Computed: true, @@ -1933,7 +1962,7 @@ func instanceCreateByImage(d *schema.ResourceData, meta interface{}, profile, na resAffinity.Policy = &policyStr } poolIntf, okPool := resAff[isReservationAffinityPool] - if okPool { + if okPool && poolIntf != nil && poolIntf.([]interface{}) != nil && len(poolIntf.([]interface{})) > 0 { pool := poolIntf.([]interface{})[0].(map[string]interface{}) id, okId := pool["id"] if okId { @@ -2388,7 +2417,7 @@ func instanceCreateByCatalogOffering(d *schema.ResourceData, meta interface{}, p resAffinity.Policy = &policyStr } poolIntf, okPool := resAff[isReservationAffinityPool] - if okPool { + if okPool && poolIntf != nil && poolIntf.([]interface{}) != nil && len(poolIntf.([]interface{})) > 0 { pool := poolIntf.([]interface{})[0].(map[string]interface{}) id, okId := pool["id"] if okId { @@ -2823,7 +2852,7 @@ func instanceCreateByTemplate(d *schema.ResourceData, meta interface{}, profile, resAffinity.Policy = &policyStr } poolIntf, okPool := resAff[isReservationAffinityPool] - if okPool { + if okPool && poolIntf != nil && poolIntf.([]interface{}) != nil && len(poolIntf.([]interface{})) > 0 { pool := poolIntf.([]interface{})[0].(map[string]interface{}) id, okId := pool["id"] if okId { @@ -3233,7 +3262,7 @@ func instanceCreateBySnapshot(d *schema.ResourceData, meta interface{}, profile, resAffinity.Policy = &policyStr } poolIntf, okPool := resAff[isReservationAffinityPool] - if okPool { + if okPool && poolIntf != nil && poolIntf.([]interface{}) != nil && len(poolIntf.([]interface{})) > 0 { pool := poolIntf.([]interface{})[0].(map[string]interface{}) id, okId := pool["id"] if okId { @@ -3632,7 +3661,7 @@ func instanceCreateByVolume(d *schema.ResourceData, meta interface{}, profile, n resAffinity.Policy = &policyStr } poolIntf, okPool := resAff[isReservationAffinityPool] - if okPool { + if okPool && poolIntf != nil && poolIntf.([]interface{}) != nil && len(poolIntf.([]interface{})) > 0 { pool := poolIntf.([]interface{})[0].(map[string]interface{}) id, okId := pool["id"] if okId { @@ -4277,6 +4306,24 @@ func instanceGet(d *schema.ResourceData, meta interface{}, id string) error { primaryNicList = append(primaryNicList, currentPrimNic) d.Set(isInstancePrimaryNetworkInterface, primaryNicList) } + if instance.HealthReasons != nil { + healthReasonsList := make([]map[string]interface{}, 0) + for _, sr := range instance.HealthReasons { + currentSR := map[string]interface{}{} + if sr.Code != nil && sr.Message != nil { + currentSR["code"] = *sr.Code + currentSR["message"] = *sr.Message + if sr.MoreInfo != nil { + currentSR["more_info"] = *sr.Message + } + healthReasonsList = append(healthReasonsList, currentSR) + } + } + d.Set("health_reasons", healthReasonsList) + } + if err = d.Set("health_state", instance.HealthState); err != nil { + return err + } if instance.ReservationAffinity != nil { reservationAffinity := []map[string]interface{}{} reservationAffinityMap := map[string]interface{}{} @@ -4294,7 +4341,7 @@ func instanceGet(d *schema.ResourceData, meta interface{}, id string) error { res[isReservationResourceType] = *pool.ResourceType if pool.Deleted != nil { deletedList := []map[string]interface{}{} - deletedMap := dataSourceInstanceReservationDeletedToMap(*pool.Deleted) + deletedMap := dataSourceReservationDeletedToMap(*pool.Deleted) deletedList = append(deletedList, deletedMap) res[isReservationDeleted] = deletedList } @@ -4316,7 +4363,7 @@ func instanceGet(d *schema.ResourceData, meta interface{}, id string) error { res[isReservationResourceType] = *instance.Reservation.ResourceType if instance.Reservation.Deleted != nil { deletedList := []map[string]interface{}{} - deletedMap := dataSourceInstanceReservationDeletedToMap(*instance.Reservation.Deleted) + deletedMap := dataSourceReservationDeletedToMap(*instance.Reservation.Deleted) deletedList = append(deletedList, deletedMap) res[isReservationDeleted] = deletedList } @@ -5101,7 +5148,7 @@ func instanceUpdate(d *schema.ResourceData, meta interface{}) error { } if d.HasChange(resPool) { poolIntf, okPool := resAff[isReservationAffinityPool] - if okPool { + if okPool && poolIntf != nil && poolIntf.([]interface{}) != nil && len(poolIntf.([]interface{})) > 0 { pool := poolIntf.([]interface{})[0].(map[string]interface{}) id, okId := pool["id"] if okId { @@ -6375,15 +6422,6 @@ func resourceIbmIsInstanceInstancePlacementToMap(instancePlacement vpcv1.Instanc return instancePlacementMap } -func resourceIbmIsInstanceReservationAffinityPoolToMap(reservationPool vpcv1.ReservationReference) map[string]interface{} { - resAffPoolMap := map[string]interface{}{} - - resAffPoolMap["crn"] = reservationPool.CRN - resAffPoolMap["href"] = reservationPool.Href - resAffPoolMap["id"] = reservationPool.ID - return resAffPoolMap -} - func resourceIbmIsInstanceDedicatedHostGroupReferenceDeletedToMap(dedicatedHostGroupReferenceDeleted vpcv1.Deleted) map[string]interface{} { dedicatedHostGroupReferenceDeletedMap := map[string]interface{}{} diff --git a/ibm/service/vpc/resource_ibm_is_instance_template.go b/ibm/service/vpc/resource_ibm_is_instance_template.go index 7a0b0ac2de3..4fd13aab33c 100644 --- a/ibm/service/vpc/resource_ibm_is_instance_template.go +++ b/ibm/service/vpc/resource_ibm_is_instance_template.go @@ -1860,7 +1860,7 @@ func instanceTemplateCreate(d *schema.ResourceData, meta interface{}, profile, n resAffinity.Policy = &policyStr } poolIntf, okPool := resAff[isReservationAffinityPool] - if okPool { + if okPool && poolIntf != nil && poolIntf.([]interface{}) != nil && len(poolIntf.([]interface{})) > 0 { pool := poolIntf.([]interface{})[0].(map[string]interface{}) id, okId := pool["id"] if okId { diff --git a/ibm/service/vpc/resource_ibm_is_reservation.go b/ibm/service/vpc/resource_ibm_is_reservation.go index 0d98ac3520f..d9835590e55 100644 --- a/ibm/service/vpc/resource_ibm_is_reservation.go +++ b/ibm/service/vpc/resource_ibm_is_reservation.go @@ -264,9 +264,9 @@ func ResourceIBMISReservation() *schema.Resource { func ResourceIBMISReservationValidator() *validate.ResourceValidator { validateSchema := make([]validate.ValidateSchema, 0) - affinityPolicy := "restricted" - term := "one_year,three_year" - resourceType := "instance_profile" + affinityPolicy := "automatic, restricted" + term := "one_year, three_year" + resourceType := "bare_metal_server_profile, instance_profile" validateSchema = append(validateSchema, validate.ValidateSchema{ @@ -504,7 +504,7 @@ func resourceIBMISReservationRead(d *schema.ResourceData, meta interface{}) erro profileMap := []map[string]interface{}{} finalList := map[string]interface{}{} - profileItem := reservation.Profile + profileItem := reservation.Profile.(*vpcv1.ReservationProfile) if profileItem.Href != nil { finalList[isReservationProfileHref] = profileItem.Href @@ -576,6 +576,7 @@ func resourceIBMISReservationUpdate(d *schema.ResourceData, meta interface{}) er } hasChanged := false name := "" + affPol := "" reservationPatchModel := &vpcv1.ReservationPatch{} if d.HasChange(isReservationName) { @@ -585,6 +586,13 @@ func resourceIBMISReservationUpdate(d *schema.ResourceData, meta interface{}) er hasChanged = true } } + if d.HasChange(isReservationAffinityPolicy) { + affPol = d.Get(isReservationAffinityPolicy).(string) + if affPol != "" { + reservationPatchModel.AffinityPolicy = &affPol + hasChanged = true + } + } if d.HasChange(isReservationCapacity) { capacityIntf := d.Get(isReservationCapacity) capacityMap := capacityIntf.([]interface{})[0].(map[string]interface{}) @@ -593,6 +601,7 @@ func resourceIBMISReservationUpdate(d *schema.ResourceData, meta interface{}) er reservationPatchModel.Capacity = &vpcv1.ReservationCapacityPatch{ Total: core.Int64Ptr(int64(totalIntf.(int))), } + hasChanged = true } } } @@ -605,12 +614,14 @@ func resourceIBMISReservationUpdate(d *schema.ResourceData, meta interface{}) er if expPolIntf.(string) != "" { cuPatch.ExpirationPolicy = core.StringPtr(string(expPolIntf.(string))) } + hasChanged = true } } if d.HasChange(isReservationCommittedUse + ".0." + isReservationComittedUseTerm) { if termIntf, ok := committedUseMap[isReservationComittedUseTerm]; ok { cuPatch.Term = core.StringPtr(string(termIntf.(string))) } + hasChanged = true } reservationPatchModel.CommittedUse = cuPatch } @@ -623,6 +634,7 @@ func resourceIBMISReservationUpdate(d *schema.ResourceData, meta interface{}) er if profNameIntf.(string) != "" { profPatch.Name = core.StringPtr(string(profNameIntf.(string))) } + hasChanged = true } } if d.HasChange(isReservationProfile + ".0." + isReservationProfileResourceType) { @@ -630,6 +642,7 @@ func resourceIBMISReservationUpdate(d *schema.ResourceData, meta interface{}) er if resTypeIntf.(string) != "" { profPatch.ResourceType = core.StringPtr(string(resTypeIntf.(string))) } + hasChanged = true } } reservationPatchModel.Profile = profPatch diff --git a/ibm/service/vpc/resource_ibm_is_reservation_activate.go b/ibm/service/vpc/resource_ibm_is_reservation_activate.go index 96ac3c47538..8379f63eb8c 100644 --- a/ibm/service/vpc/resource_ibm_is_reservation_activate.go +++ b/ibm/service/vpc/resource_ibm_is_reservation_activate.go @@ -350,7 +350,7 @@ func resourceIBMISReservationActivateRead(d *schema.ResourceData, meta interface profileMap := []map[string]interface{}{} finalList := map[string]interface{}{} - profileItem := reservation.Profile + profileItem := reservation.Profile.(*vpcv1.ReservationProfile) if profileItem.Href != nil { finalList[isReservationProfileHref] = profileItem.Href diff --git a/website/docs/d/is_bare_metal_server.markdown b/website/docs/d/is_bare_metal_server.markdown index b0a118b2a03..1612f89eb04 100644 --- a/website/docs/d/is_bare_metal_server.markdown +++ b/website/docs/d/is_bare_metal_server.markdown @@ -6,7 +6,7 @@ description: |- Manages IBM Cloud Bare Metal Server. --- -# ibm\_is_bare_metal_server +# ibm_is_bare_metal_server Import the details of an existing IBM Cloud Bare Metal Server as a read-only data source. You can then reference the fields of the data source in other resources within the same configuration using interpolation syntax. For more information, about bare metal servers, see [About Bare Metal Servers for VPC](https://cloud.ibm.com/docs/vpc?topic=vpc-about-bare-metal-servers). @@ -70,6 +70,13 @@ In addition to all argument reference list, you can access the following attribu - `resource_type` - (String) The resource type - `size` - (Integer) The size of the disk in GB (gigabytes) - `enable_secure_boot` - (Boolean) Indicates whether secure boot is enabled. If enabled, the image must support secure boot or the server will fail to boot. +- `health_reasons` - (List) The reasons for the current health_state (if any). + + Nested scheme for `health_reasons`: + - `code` - (String) A snake case string succinctly identifying the reason for this health state. + - `message` - (String) An explanation of the reason for this health state. + - `more_info` - (String) Link to documentation about the reason for this health state. +- `health_state` - (String) The health of this resource. - `href` - (String) The URL for this bare metal server - `id` - (String) The unique identifier for this bare metal server - `image` - (String) Image used in the bare metal server. @@ -95,8 +102,35 @@ In addition to all argument reference list, you can access the following attribu - `name` - (String) The name for this reserved IP. The name is unique across all reserved IPs in a subnet. - `resource_type` - (String) The resource type. + - `reservation`- (List) The reservation used by this bare metal server. + Nested scheme for `reservation`: + - `crn` - (String) The CRN for this reservation. + - `deleted` - (List) If present, this property indicates the referenced resource has been deleted, and provides some supplementary information. + + Nested `deleted` blocks have the following structure: + - `more_info` - (String) Link to documentation about deleted resources. + - `href` - (String) The URL for this reservation. + - `id` - (String) The unique identifier for this reservation. + - `name` - (string) The name for this reservation. The name is unique across all reservations in the region. + - `resource_type` - (string) The resource type. + - `reservation_affinity`- (List) The bare metal server reservation affinity. + + Nested scheme for `reservation_affinity`: + - `policy` - (String) The reservation affinity policy to use for this bare metal server. + - `pool` - (List) The pool of reservations available for use by this bare metal server. + + Nested `pool` blocks have the following structure: + - `crn` - (String) The CRN for this reservation. + - `deleted` - (List) If present, this property indicates the referenced resource has been deleted, and provides some supplementary information. + + Nested `deleted` blocks have the following structure: + - `more_info` - (String) Link to documentation about deleted resources. + - `href` - (String) The URL for this reservation. + - `id` - (String) The unique identifier for this reservation. + - `name` - (string) The name for this reservation. The name is unique across all reservations in the region. + - `resource_type` - (string) The resource type. - `resource_type` - (String) The resource type. - - `subnet` - (List) The subnet of the virtual network interface for the network attachment. + - `subnet` - (List) The subnet of the virtual network interface for the network attachment. Nested schema for **subnet**: - `crn` - (String) The CRN for this subnet. - `deleted` - (List) If present, this property indicates the referenced resource has been deleted, and providessome supplementary information. diff --git a/website/docs/d/is_bare_metal_servers.markdown b/website/docs/d/is_bare_metal_servers.markdown index 037c5fd49a3..6b73c612b3b 100644 --- a/website/docs/d/is_bare_metal_servers.markdown +++ b/website/docs/d/is_bare_metal_servers.markdown @@ -6,7 +6,7 @@ description: |- Manages IBM Cloud Bare Metal Servers. --- -# ibm\_is_bare_metal_servers +# ibm_is_bare_metal_servers Import the details of an existing IBM Cloud vBare Metal Server collection as a read-only data source. You can then reference the fields of the data source in other resources within the same configuration using interpolation syntax. For more information, about bare metal servers, see [About Bare Metal Servers for VPC](https://cloud.ibm.com/docs/vpc?topic=vpc-about-bare-metal-servers). @@ -62,6 +62,13 @@ Review the attribute references that you can access after you retrieve your data - `resource_type` - (String) The resource type - `size` - (Integer) The size of the disk in GB (gigabytes) - `enable_secure_boot` - (Boolean) Indicates whether secure boot is enabled. If enabled, the image must support secure boot or the server will fail to boot. + - `health_reasons` - (List) The reasons for the current health_state (if any). + + Nested scheme for `health_reasons`: + - `code` - (String) A snake case string succinctly identifying the reason for this health state. + - `message` - (String) An explanation of the reason for this health state. + - `more_info` - (String) Link to documentation about the reason for this health state. + - `health_state` - (String) The health of this resource. - `href` - (String) The URL for this bare metal server - `id` - (String) The unique identifier for this bare metal server - `image` - (String) Image used in the bare metal server. @@ -180,6 +187,33 @@ Review the attribute references that you can access after you retrieve your data - `security_groups` - (Array) List of security groups. - `subnet` - (String) ID of the subnet. - `profile` - (String) The name for this bare metal server profile + - `reservation`- (List) The reservation used by this bare metal server. + Nested scheme for `reservation`: + - `crn` - (String) The CRN for this reservation. + - `deleted` - (List) If present, this property indicates the referenced resource has been deleted, and provides some supplementary information. + + Nested `deleted` blocks have the following structure: + - `more_info` - (String) Link to documentation about deleted resources. + - `href` - (String) The URL for this reservation. + - `id` - (String) The unique identifier for this reservation. + - `name` - (string) The name for this reservation. The name is unique across all reservations in the region. + - `resource_type` - (string) The resource type. + - `reservation_affinity`- (List) The bare metal server reservation affinity. + + Nested scheme for `reservation_affinity`: + - `policy` - (String) The reservation affinity policy to use for this bare metal server. + - `pool` - (List) The pool of reservations available for use by this bare metal server. + + Nested `pool` blocks have the following structure: + - `crn` - (String) The CRN for this reservation. + - `deleted` - (List) If present, this property indicates the referenced resource has been deleted, and provides some supplementary information. + + Nested `deleted` blocks have the following structure: + - `more_info` - (String) Link to documentation about deleted resources. + - `href` - (String) The URL for this reservation. + - `id` - (String) The unique identifier for this reservation. + - `name` - (string) The name for this reservation. The name is unique across all reservations in the region. + - `resource_type` - (string) The resource type. - `resource_group` - (String) resource group id of the bare metal server. - `resource_type` - (String) The type of resource referenced - `firmware_update_type_available` - (String) The firmware update type available for the bare metal server. diff --git a/website/docs/d/is_instance.html.markdown b/website/docs/d/is_instance.html.markdown index 952a3cfe236..8cacbc87cb0 100644 --- a/website/docs/d/is_instance.html.markdown +++ b/website/docs/d/is_instance.html.markdown @@ -148,6 +148,13 @@ In addition to all argument reference list, you can access the following attribu - `manufacture` - (String) The manufacturer of the GPU. - `memory`- (Integer) The amount of memory that was allocated to the GPU. - `model` - (String) The model of the GPU. +- `health_reasons` - (List) The reasons for the current health_state (if any). + + Nested scheme for `health_reasons`: + - `code` - (String) A snake case string succinctly identifying the reason for this health state. + - `message` - (String) An explanation of the reason for this health state. + - `more_info` - (String) Link to documentation about the reason for this health state. +- `health_state` - (String) The health of this resource. - `id` - (String) The ID that was assigned to the Virtual Servers for VPC instance. - `image` - (String) The ID of the virtual server image that is used in the instance. - `keys`- (List) A list of SSH keys that were added to the instance during creation. diff --git a/website/docs/d/is_instances.html.markdown b/website/docs/d/is_instances.html.markdown index effd99dcc07..7c3ca0f75ff 100644 --- a/website/docs/d/is_instances.html.markdown +++ b/website/docs/d/is_instances.html.markdown @@ -97,6 +97,13 @@ In addition to all argument reference list, you can access the following attribu - `manufacture` - Manufacture of the gpu. - `memory` - Memory of the gpu. - `model` - Model of the gpu. + - `health_reasons` - (List) The reasons for the current health_state (if any). + + Nested scheme for `health_reasons`: + - `code` - (String) A snake case string succinctly identifying the reason for this health state. + - `message` - (String) An explanation of the reason for this health state. + - `more_info` - (String) Link to documentation about the reason for this health state. + - `health_state` - (String) The health of this resource. - `id` - (String) The ID that was assigned to the Virtual Servers for VPC instance. - `image` - (String) The ID of the virtual server image that is used in the instance. - `lifecycle_reasons`- (List) The reasons for the current lifecycle_state (if any). diff --git a/website/docs/r/is_bare_metal_server.markdown b/website/docs/r/is_bare_metal_server.markdown index 0d5ae468d12..e999bf4e9d8 100644 --- a/website/docs/r/is_bare_metal_server.markdown +++ b/website/docs/r/is_bare_metal_server.markdown @@ -56,6 +56,53 @@ resource "ibm_is_bare_metal_server" "example" { } vpc = ibm_is_vpc.example.id } +``` +### Reservation Example +```terraform +resource "ibm_is_reservation" "example" { + capacity { + total = 5 + } + committed_use { + term = "one_year" + } + profile { + name = "mx2d-metal-32x192" + resource_type = "bare_metal_server_profile" + } + zone = "us-east-3" + name = "reservation-name" +} +resource "ibm_is_vpc" "example" { + name = "example-vpc" +} +resource "ibm_is_subnet" "example" { + name = "example-subnet" + vpc = ibm_is_vpc.vpc.id + zone = "us-south-3" + ipv4_cidr_block = "10.240.129.0/24" +} +resource "ibm_is_ssh_key" "example" { + name = "example-ssh" + public_key = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCKVmnMOlHKcZK8tpt3MP1lqOLAcqcJzhsvJcjscgVERRN7/9484SOBJ3HSKxxNG5JN8owAjy5f9yYwcUg+JaUVuytn5Pv3aeYROHGGg+5G346xaq3DAwX6Y5ykr2fvjObgncQBnuU5KHWCECO/4h8uWuwh/kfniXPVjFToc+gnkqA+3RKpAecZhFXwfalQ9mMuYGFxn+fwn8cYEApsJbsEmb0iJwPiZ5hjFC8wREuiTlhPHDgkBLOiycd20op2nXzDbHfCHInquEe/gYxEitALONxm0swBOwJZwlTDOB7C6y2dzlrtxr1L59m7pCkWI4EtTRLvleehBoj3u7jB4usR" +} +resource "ibm_is_bare_metal_server" "example" { + profile = "mx2d-metal-32x192" + name = "example-bms" + image = "r134-31c8ca90-2623-48d7-8cf7-737be6fc4c3e" + zone = "us-south-3" + keys = [ibm_is_ssh_key.example.id] + primary_network_interface { + subnet = ibm_is_subnet.example.id + } + reservation_affinity { + policy = "manual" + pool { + id = ibm_is_reservation.example.id + } + } + vpc = ibm_is_vpc.example.id +} ``` ### Reserved ip example @@ -141,6 +188,13 @@ Review the argument references that you can specify for your resource. - `bandwidth` - (Integer) The total bandwidth (in megabits per second) shared across the bare metal server's network interfaces. The specified value must match one of the bandwidth values in the bare metal server's profile. - `delete_type` - (Optional, String) Type of deletion on destroy. **soft** signals running operating system to quiesce and shutdown cleanly, **hard** immediately stop the server. By default its `hard`. - `enable_secure_boot` - (Optional, Boolean) Indicates whether secure boot is enabled. If enabled, the image must support secure boot or the server will fail to boot. Updating `enable_secure_boot` requires the server to be stopped and then it would be started. +- `health_reasons` - (List) The reasons for the current health_state (if any). + + Nested scheme for `health_reasons`: + - `code` - (String) A snake case string succinctly identifying the reason for this health state. + - `message` - (String) An explanation of the reason for this health state. + - `more_info` - (String) Link to documentation about the reason for this health state. +- `health_state` - (String) The health of this resource. - `image` - (Required, String) ID of the image. ( On update of `image`, server will be [reinitialized](https://cloud.ibm.com/apidocs/vpc/latest#replace-bare-metal-server-initialization) if server is in stopped state, else server will be stopped and restarted during update ) -> **NOTE:** @@ -288,6 +342,31 @@ Review the argument references that you can specify for your resource. - `subnet` - (Required, String) ID of the subnet to associate with. - `profile` - (Required, Forces new resource, String) The name the profile to use for this bare metal server. +- `reservation`- (List) The reservation used by this bare metal server. + Nested scheme for `reservation`: + - `crn` - (String) The CRN for this reservation. + - `deleted` - (List) If present, this property indicates the referenced resource has been deleted, and provides some supplementary information. + + Nested `deleted` blocks have the following structure: + - `more_info` - (String) Link to documentation about deleted resources. + - `href` - (String) The URL for this reservation. + - `id` - (String) The unique identifier for this reservation. + - `name` - (string) The name for this reservation. The name is unique across all reservations in the region. + - `resource_type` - (string) The resource type. +- `reservation_affinity`- (List) The bare metal server reservation affinity. + + Nested scheme for `reservation_affinity`: + - `policy` - (String) The reservation affinity policy to use for this bare metal server. + - `pool` - (List) The pool of reservations available for use by this bare metal server. + Nested `pool` blocks have the following structure: + - `crn` - (String) The CRN for this reservation. + - `deleted` - (List) If present, this property indicates the referenced resource has been deleted, and provides some supplementary information. + Nested `deleted` blocks have the following structure: + - `more_info` - (String) Link to documentation about deleted resources. + - `href` - (String) The URL for this reservation. + - `id` - (String) The unique identifier for this reservation. + - `name` - (string) The name for this reservation. The name is unique across all reservations in the region. + - `resource_type` - (string) The resource type. - `resource_group` - (Optional, Forces new resource, String) The resource group ID for this bare metal server. - `trusted_platform_module` - (Optional, List) trusted platform module (TPM) configuration for the bare metals server @@ -339,6 +418,16 @@ In addition to all argument reference list, you can access the following attribu - `subnet` - (String) ID of the subnet to associate with. - `vlan` - (Integer) Indicates the 802.1Q VLAN ID tag that must be used for all traffic on this interface. [ conflicts with `allowed_vlans`] +- `reservation_affinity` - (Optional, List) The reservation affinity for the bare metal server + Nested scheme for `reservation_affinity`: + - `policy` - (Optional, String) The reservation affinity policy to use for this bare metal server. + + ->**policy** + • disabled: Reservations will not be used +
• manual: Reservations in pool will be available for use + - `pool` - (Optional, String) The pool of reservations available for use by this bare metal server. Specified reservations must have a status of active, and have the same profile and zone as this bare metal server. The pool must be empty if policy is disabled, and must not be empty if policy is manual. + Nested scheme for `pool`: + - `id` - The unique identifier for this reservation - `resource_type` - (String) The type of resource. - `firmware_update_type_available` - (String) The firmware update type available for the bare metal server. -> **Supported firmware update types**
• none
• optional
• required diff --git a/website/docs/r/is_instance.html.markdown b/website/docs/r/is_instance.html.markdown index 4293929715b..eee5980d059 100644 --- a/website/docs/r/is_instance.html.markdown +++ b/website/docs/r/is_instance.html.markdown @@ -778,6 +778,13 @@ In addition to all argument reference list, you can access the following attribu - `manufacture` - (String) The manufacturer of the GPU. - `memory`- (Integer) The amount of memory of the GPU in gigabytes. - `model` - (String) The model of the GPU. +- `health_reasons` - (List) The reasons for the current health_state (if any). + + Nested scheme for `health_reasons`: + - `code` - (String) A snake case string succinctly identifying the reason for this health state. + - `message` - (String) An explanation of the reason for this health state. + - `more_info` - (String) Link to documentation about the reason for this health state. +- `health_state` - (String) The health of this resource. - `placement_target` - The placement restrictions for the virtual server instance. - `crn` - The CRN of the placement target - `deleted` - If present, this property indicates the referenced resource has been deleted and providessome supplementary information.