diff --git a/docs/data-sources/host.md b/docs/data-sources/host.md
new file mode 100644
index 0000000..8d05693
--- /dev/null
+++ b/docs/data-sources/host.md
@@ -0,0 +1,113 @@
+---
+# generated by https://github.com/hashicorp/terraform-plugin-docs
+page_title: "vcf_host Data Source - terraform-provider-vcf"
+subcategory: ""
+description: |-
+
+---
+
+# Data Source: vcf_host
+
+The `vcf_host` data source provides information about an ESXi host in a VMware Cloud Foundation environment.
+
+## Schema
+
+### Required
+
+- `fqdn` (String) - The fully qualified domain name of the ESXi host.
+
+### Read-Only
+
+- `id` (String) - The unique identifier of the ESXi host.
+- `status` (String) - The status of the ESXi host.
+- `version` (String) - The version of the ESXi running on the host.
+- `compatible_storage_type` (String) - The compatible storage type of the ESXi host.
+
+### Nested Schema for `hardware`
+
+Read-Only:
+
+- `vendor` (String) - The hardware vendor of the ESXi host.
+- `model` (String) - The hardware model of the ESXi host.
+- `hybrid` (Boolean) - The hybrid status of the hardware.
+
+### Nested Schema for `network_pool`
+
+Read-Only:
+
+- `name` (String) - The name of the network pool.
+- `id` (String) - The ID of the network pool.
+
+### Nested Schema for `domain`
+
+Read-Only:
+
+- `id` (String) - The unique identifier of the domain.
+- `name` (String) - The name of the domain.
+
+### Nested Schema for `cluster`
+
+Read-Only:
+
+- `id` (String) - The unique identifier of the cluster.
+
+### Nested Schema for `ip_addresses`
+
+Read-Only:
+
+- `ip_address` (String) - The IP address of the ESXi host.
+- `type` (String) - The service type of the IP address.
+
+### Nested Schema for `cpu`
+
+Read-Only:
+
+- `cores` (Number) - Number of CPU cores.
+- `frequency_mhz` (Number) - Total CPU frequency in MHz.
+- `used_frequency_mhz` (Number) - Used CPU frequency in MHz.
+- `cpu_cores` (List of Object) - Information about each of the [CPU cores](#nestedobjatt--cpu--cpu_cores).
+
+
+
+#### Nested Schema for `cpu.cpu_cores`
+
+Read-Only:
+
+- `frequency` (Number) - The frequency of the CPU core in MHz.
+- `manufacturer` (String) - The manufacturer of the CPU.
+- `model` (String) - The model of the CPU.
+
+### Nested Schema for `memory`
+
+Read-Only:
+
+- `total_capacity_mb` (Number) - The total memory capacity in MB.
+- `used_capacity_mb` (Number) - The used memory capacity in MB.
+
+### Nested Schema for `storage`
+
+Read-Only:
+
+- `total_capacity_mb` (Number) - The total storage capacity in MB.
+- `used_capacity_mb` (Number) - The used storage capacity in MB.
+- `disks` (List of Object) - The disks information of the ESXi host (see [below for nested schema](#nestedobjatt--storage--disks)).
+
+
+
+### Nested Schema for `storage.disks`
+
+Read-Only:
+
+- `capacity_mb` (Number) - The capacity of the disk in MB.
+- `disk_type` (String) - The type of the disk.
+- `manufacturer` (String) - The manufacturer of the disk.
+- `model` (String) - The model of the disk.
+
+### Nested Schema for `physical_nics`
+
+Read-Only:
+
+- `device_name` (String) - The device name of the physical NIC.
+- `mac_address` (String) - The MAC address of the physical NIC.
+- `speed` (Number) - The speed of the physical NIC.
+- `unit` (String) - The unit of the physical NIC speed.
diff --git a/examples/data-sources/host/variables.tf b/examples/data-sources/host/variables.tf
new file mode 100644
index 0000000..9e69411
--- /dev/null
+++ b/examples/data-sources/host/variables.tf
@@ -0,0 +1,22 @@
+variable "sddc_manager_host" {
+ type = string
+ description = "The fully qualified domain name of the SDDC Manager instance."
+}
+
+variable "sddc_manager_username" {
+ type = string
+ description = "The username to authenticate to the SDDC Manager instance."
+ sensitive = true
+}
+
+variable "sddc_manager_password" {
+ type = string
+ description = "The password to authenticate to the SDDC Manager instance."
+ sensitive = true
+}
+
+variable "host_fqdn" {
+ type = string
+ description = "The fully qualified domain name of the ESXi host."
+ default = "sfo-w01-esx01.sfo.rainpole.io"
+}
diff --git a/examples/data-sources/host/vcf_host.tf b/examples/data-sources/host/vcf_host.tf
new file mode 100644
index 0000000..f635ace
--- /dev/null
+++ b/examples/data-sources/host/vcf_host.tf
@@ -0,0 +1,21 @@
+terraform {
+ required_providers {
+ vcf = {
+ source = "vmware/vcf"
+ }
+ }
+}
+
+provider "vcf" {
+ sddc_manager_username = var.sddc_manager_username
+ sddc_manager_password = var.sddc_manager_password
+ sddc_manager_host = var.sddc_manager_host
+}
+
+data "vcf_host" "example" {
+ fqdn = var.host_fqdn
+}
+
+output "host_id" {
+ value = data.vcf_host.example.id
+}
diff --git a/internal/provider/data_host.go b/internal/provider/data_host.go
new file mode 100644
index 0000000..df69904
--- /dev/null
+++ b/internal/provider/data_host.go
@@ -0,0 +1,434 @@
+// © Broadcom. All Rights Reserved.
+// The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries.
+// SPDX-License-Identifier: MPL-2.0
+
+package provider
+
+import (
+ "context"
+
+ "github.com/hashicorp/terraform-plugin-framework/datasource"
+ "github.com/hashicorp/terraform-plugin-framework/datasource/schema"
+ "github.com/hashicorp/terraform-plugin-framework/diag"
+ "github.com/hashicorp/terraform-plugin-framework/types"
+ "github.com/hashicorp/terraform-plugin-log/tflog"
+ "github.com/vmware/vcf-sdk-go/client"
+ "github.com/vmware/vcf-sdk-go/client/hosts"
+ "github.com/vmware/vcf-sdk-go/models"
+
+ "github.com/vmware/terraform-provider-vcf/internal/api_client"
+ "github.com/vmware/terraform-provider-vcf/internal/constants"
+)
+
+type HostModel struct {
+ Fqdn types.String `tfsdk:"fqdn"`
+ Id types.String `tfsdk:"id"`
+ Status types.String `tfsdk:"status"`
+ CompatibleStorageType types.String `tfsdk:"compatible_storage_type"`
+ Domain []DomainModel `tfsdk:"domain"`
+ Cluster []ClusterModel `tfsdk:"cluster"`
+ NetworkPool []NetworkPoolModel `tfsdk:"network_pool"`
+ Version types.String `tfsdk:"version"`
+ Hardware []HardwareModel `tfsdk:"hardware"`
+ IpAddresses []IpAddressModel `tfsdk:"ip_addresses"`
+ Cpu CpuModel `tfsdk:"cpu"`
+ Memory MemoryModel `tfsdk:"memory"`
+ Storage []StorageModel `tfsdk:"storage"`
+ PhysicalNics []PhysicalNicModel `tfsdk:"physical_nics"`
+}
+
+type DomainModel struct {
+ Id types.String `tfsdk:"id"`
+ Name types.String `tfsdk:"name"`
+}
+
+type ClusterModel struct {
+ Id types.String `tfsdk:"id"`
+}
+
+type NetworkPoolModel struct {
+ Id types.String `tfsdk:"id"`
+ Name types.String `tfsdk:"name"`
+}
+
+type HardwareModel struct {
+ Model types.String `tfsdk:"model"`
+ Vendor types.String `tfsdk:"vendor"`
+ Hybrid types.Bool `tfsdk:"hybrid"`
+}
+
+type IpAddressModel struct {
+ IpAddress types.String `tfsdk:"ip_address"`
+ Type types.String `tfsdk:"type"`
+}
+
+type CpuModel struct {
+ Cores types.Int64 `tfsdk:"cores"`
+ CpuCoreDetails []CpuCoreModel `tfsdk:"cpu_core_details"`
+ FrequencyMHz types.Float64 `tfsdk:"frequency_mhz"`
+ UsedFrequencyMHz types.Float64 `tfsdk:"used_frequency_mhz"`
+}
+
+type CpuCoreModel struct {
+ FrequencyMHz types.Float64 `tfsdk:"frequency_mhz"`
+ Manufacturer types.String `tfsdk:"manufacturer"`
+ Model types.String `tfsdk:"model"`
+}
+
+type MemoryModel struct {
+ TotalCapacityMB types.Float64 `tfsdk:"total_capacity_mb"`
+ UsedCapacityMB types.Float64 `tfsdk:"used_capacity_mb"`
+}
+
+type StorageModel struct {
+ TotalCapacityMB types.Float64 `tfsdk:"total_capacity_mb"`
+ UsedCapacityMB types.Float64 `tfsdk:"used_capacity_mb"`
+ Disks []DiskModel `tfsdk:"disks"`
+}
+
+type DiskModel struct {
+ CapacityMB types.Float64 `tfsdk:"capacity_mb"`
+ DiskType types.String `tfsdk:"disk_type"`
+ Manufacturer types.String `tfsdk:"manufacturer"`
+ Model types.String `tfsdk:"model"`
+}
+
+type PhysicalNicModel struct {
+ DeviceName types.String `tfsdk:"device_name"`
+ MacAddress types.String `tfsdk:"mac_address"`
+ Speed types.Int64 `tfsdk:"speed"`
+ Unit types.String `tfsdk:"unit"`
+}
+
+type DataSourceHost struct {
+ client *client.VcfClient
+}
+
+func (d *DataSourceHost) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
+ resp.TypeName = "vcf_host"
+}
+
+func (d *DataSourceHost) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {
+ if req.ProviderData == nil {
+ return
+ }
+
+ d.client = req.ProviderData.(*api_client.SddcManagerClient).ApiClient
+}
+
+func (d *DataSourceHost) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) {
+ resp.Schema = schema.Schema{
+ Attributes: map[string]schema.Attribute{
+ "fqdn": schema.StringAttribute{
+ Required: true,
+ Description: "The fully qualified domain name of the ESXi host.",
+ },
+ "id": schema.StringAttribute{
+ Computed: true,
+ Description: "The unique identifier of the ESXi host.",
+ },
+ "status": schema.StringAttribute{
+ Computed: true,
+ Description: "The status of the ESXi host.",
+ },
+ "domain": schema.ListNestedAttribute{
+ Computed: true,
+ Description: "The domain details of the ESXi host.",
+ NestedObject: schema.NestedAttributeObject{
+ Attributes: map[string]schema.Attribute{
+ "id": schema.StringAttribute{
+ Computed: true,
+ },
+ "name": schema.StringAttribute{
+ Computed: true,
+ },
+ },
+ },
+ },
+ "cluster": schema.ListNestedAttribute{
+ Computed: true,
+ Description: "The clusters of the ESXi host.",
+ NestedObject: schema.NestedAttributeObject{
+ Attributes: map[string]schema.Attribute{
+ "id": schema.StringAttribute{
+ Computed: true,
+ },
+ },
+ },
+ },
+ "network_pool": schema.ListNestedAttribute{
+ Computed: true,
+ Description: "The network pool of the ESXi host.",
+ NestedObject: schema.NestedAttributeObject{
+ Attributes: map[string]schema.Attribute{
+ "id": schema.StringAttribute{
+ Computed: true,
+ },
+ "name": schema.StringAttribute{
+ Computed: true,
+ },
+ },
+ },
+ },
+ "version": schema.StringAttribute{
+ Computed: true,
+ Description: "The version of the ESXi host.",
+ },
+ "compatible_storage_type": schema.StringAttribute{
+ Computed: true,
+ Description: "The compatible storage type of the ESXi host.",
+ },
+ "hardware": schema.ListNestedAttribute{
+ Computed: true,
+ Description: "The hardware details of the ESXi host.",
+ NestedObject: schema.NestedAttributeObject{
+ Attributes: map[string]schema.Attribute{
+ "model": schema.StringAttribute{
+ Computed: true,
+ },
+ "vendor": schema.StringAttribute{
+ Computed: true,
+ },
+ "hybrid": schema.BoolAttribute{
+ Computed: true,
+ },
+ },
+ },
+ },
+ "ip_addresses": schema.ListNestedAttribute{
+ Computed: true,
+ Description: "The IP addresses of the ESXi host.",
+ NestedObject: schema.NestedAttributeObject{
+ Attributes: map[string]schema.Attribute{
+ "ip_address": schema.StringAttribute{
+ Computed: true,
+ },
+ "type": schema.StringAttribute{
+ Computed: true,
+ },
+ },
+ },
+ },
+ "cpu": schema.SingleNestedAttribute{
+ Computed: true,
+ Description: "The CPU details of the ESXi host.",
+ Attributes: map[string]schema.Attribute{
+ "cores": schema.Int64Attribute{
+ Computed: true,
+ },
+ "cpu_cores": schema.ListNestedAttribute{
+ Computed: true,
+ Description: "The CPU core details of the ESXi host.",
+ NestedObject: schema.NestedAttributeObject{
+ Attributes: map[string]schema.Attribute{
+ "frequency_mhz": schema.Float64Attribute{
+ Computed: true,
+ },
+ "manufacturer": schema.StringAttribute{
+ Computed: true,
+ },
+ "model": schema.StringAttribute{
+ Computed: true,
+ },
+ },
+ },
+ },
+ "frequency_mhz": schema.Float64Attribute{
+ Computed: true,
+ },
+ "used_frequency_mhz": schema.Float64Attribute{
+ Computed: true,
+ },
+ },
+ },
+ "memory": schema.SingleNestedAttribute{
+ Computed: true,
+ Description: "The memory details of the ESXi host.",
+ Attributes: map[string]schema.Attribute{
+ "total_capacity_mb": schema.Float64Attribute{
+ Computed: true,
+ },
+ "used_capacity_mb": schema.Float64Attribute{
+ Computed: true,
+ },
+ },
+ },
+ "storage": schema.ListNestedAttribute{
+ Computed: true,
+ Description: "The storage details of the ESXi host.",
+ NestedObject: schema.NestedAttributeObject{
+ Attributes: map[string]schema.Attribute{
+ "total_capacity_mb": schema.Float64Attribute{
+ Computed: true,
+ },
+ "used_capacity_mb": schema.Float64Attribute{
+ Computed: true,
+ },
+ "disks": schema.ListNestedAttribute{
+ Computed: true,
+ Description: "The disks of the ESXi host.",
+ NestedObject: schema.NestedAttributeObject{
+ Attributes: map[string]schema.Attribute{
+ "capacity_mb": schema.Float64Attribute{
+ Computed: true,
+ },
+ "disk_type": schema.StringAttribute{
+ Computed: true,
+ },
+ "manufacturer": schema.StringAttribute{
+ Computed: true,
+ },
+ "model": schema.StringAttribute{
+ Computed: true,
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ "physical_nics": schema.ListNestedAttribute{
+ Computed: true,
+ Description: "The physical NICs of the ESXi host.",
+ NestedObject: schema.NestedAttributeObject{
+ Attributes: map[string]schema.Attribute{
+ "device_name": schema.StringAttribute{
+ Computed: true,
+ },
+ "mac_address": schema.StringAttribute{
+ Computed: true,
+ },
+ "speed": schema.Int64Attribute{
+ Computed: true,
+ },
+ "unit": schema.StringAttribute{
+ Computed: true,
+ },
+ },
+ },
+ },
+ },
+ }
+}
+
+func (d *DataSourceHost) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
+ var data []HostModel
+
+ params := hosts.NewGetHostsParamsWithContext(ctx).
+ WithTimeout(constants.DefaultVcfApiCallTimeout)
+
+ hostPayload, err := d.client.Hosts.GetHosts(params)
+ if err != nil {
+ resp.Diagnostics.Append(diag.NewErrorDiagnostic("Failed to retrieve hosts", err.Error()))
+ return
+ }
+
+ for _, element := range hostPayload.Payload.Elements {
+ // Debugging logs to print the values of id and status
+ tflog.Debug(ctx, "Mapping host", map[string]interface{}{
+ "fqdn": element.Fqdn,
+ "id": element.ID,
+ "status": element.Status,
+ })
+
+ host := mapHostElementToModel(element)
+ data = append(data, host)
+ }
+
+ // Debugging log to trace the mapped data
+ tflog.Debug(ctx, "Mapped data", map[string]interface{}{
+ "hosts": data,
+ })
+
+ resp.State.Set(ctx, &data)
+}
+
+func mapHostElementToModel(element *models.Host) HostModel {
+ // Inline dereferencing logic
+ domainID := derefString(element.Domain.ID)
+ clusterID := derefString(element.Cluster.ID)
+ networkPoolID := derefString(element.Networkpool.ID)
+
+ return HostModel{
+ Fqdn: types.StringValue(element.Fqdn),
+ Id: types.StringValue(element.ID),
+ Status: types.StringValue(element.Status),
+ Domain: []DomainModel{
+ {
+ Id: types.StringValue(domainID),
+ Name: types.StringValue(element.Domain.Name),
+ },
+ },
+ Cluster: []ClusterModel{
+ {
+ Id: types.StringValue(clusterID),
+ },
+ },
+ NetworkPool: []NetworkPoolModel{
+ {
+ Id: types.StringValue(networkPoolID),
+ Name: types.StringValue(element.Networkpool.Name),
+ },
+ },
+ Version: types.StringValue(element.EsxiVersion),
+ CompatibleStorageType: types.StringValue(element.CompatibleStorageType),
+ Hardware: []HardwareModel{
+ {
+ Model: types.StringValue(element.HardwareModel),
+ Vendor: types.StringValue(element.HardwareVendor),
+ Hybrid: types.BoolValue(element.Hybrid),
+ },
+ },
+ IpAddresses: []IpAddressModel{
+ {
+ IpAddress: types.StringValue(element.IPAddresses[0].IPAddress),
+ Type: types.StringValue(element.IPAddresses[0].Type),
+ },
+ },
+ Cpu: CpuModel{
+ Cores: types.Int64Value(int64(element.CPU.Cores)),
+ CpuCoreDetails: []CpuCoreModel{
+ {
+ FrequencyMHz: types.Float64Value(element.CPU.CPUCores[0].FrequencyMHz),
+ Manufacturer: types.StringValue(element.CPU.CPUCores[0].Manufacturer),
+ Model: types.StringValue(element.CPU.CPUCores[0].Model),
+ },
+ },
+ FrequencyMHz: types.Float64Value(element.CPU.FrequencyMHz),
+ UsedFrequencyMHz: types.Float64Value(element.CPU.UsedFrequencyMHz),
+ },
+ Memory: MemoryModel{
+ TotalCapacityMB: types.Float64Value(element.Memory.TotalCapacityMB),
+ UsedCapacityMB: types.Float64Value(element.Memory.UsedCapacityMB),
+ },
+ Storage: []StorageModel{
+ {
+ TotalCapacityMB: types.Float64Value(element.Storage.TotalCapacityMB),
+ UsedCapacityMB: types.Float64Value(element.Storage.UsedCapacityMB),
+ Disks: []DiskModel{
+ {
+ CapacityMB: types.Float64Value(element.Storage.Disks[0].CapacityMB),
+ DiskType: types.StringValue(element.Storage.Disks[0].DiskType),
+ Manufacturer: types.StringValue(element.Storage.Disks[0].Manufacturer),
+ Model: types.StringValue(element.Storage.Disks[0].Model),
+ },
+ },
+ },
+ },
+ PhysicalNics: []PhysicalNicModel{
+ {
+ DeviceName: types.StringValue(element.PhysicalNics[0].DeviceName),
+ MacAddress: types.StringValue(element.PhysicalNics[0].MacAddress),
+ Speed: types.Int64Value(element.PhysicalNics[0].Speed),
+ Unit: types.StringValue(element.PhysicalNics[0].Unit),
+ },
+ },
+ }
+}
+
+func derefString(s *string) string {
+ if s == nil {
+ return ""
+ }
+ return *s
+}
diff --git a/internal/provider/data_host_test.go b/internal/provider/data_host_test.go
new file mode 100644
index 0000000..97bf334
--- /dev/null
+++ b/internal/provider/data_host_test.go
@@ -0,0 +1,56 @@
+// © Broadcom. All Rights Reserved.
+// The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries.
+// SPDX-License-Identifier: MPL-2.0
+
+package provider
+
+import (
+ "fmt"
+ "testing"
+
+ "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
+
+ "github.com/vmware/terraform-provider-vcf/internal/constants"
+)
+
+func TestAccDataSourceVcfHost(t *testing.T) {
+ hosts := []string{
+ constants.VcfTestHost1Fqdn,
+ constants.VcfTestHost2Fqdn,
+ constants.VcfTestHost3Fqdn,
+ constants.VcfTestHost4Fqdn,
+ }
+
+ var steps []resource.TestStep
+ for _, fqdn := range hosts {
+ steps = append(steps, resource.TestStep{
+ Config: testAccDataSourceVcfHostConfig(fqdn),
+ Check: resource.ComposeTestCheckFunc(
+ resource.TestCheckResourceAttrSet("data.vcf_host.test_host", "id"),
+ resource.TestCheckResourceAttr("data.vcf_host.test_host", "fqdn", fqdn),
+ ),
+ })
+ }
+
+ resource.ParallelTest(t, resource.TestCase{
+ PreCheck: func() { testAccPreCheck(t) },
+ ProtoV6ProviderFactories: muxedFactories(),
+ Steps: steps,
+ })
+}
+
+func testAccDataSourceVcfHostConfig(hostFqdn string) string {
+ return fmt.Sprintf(`
+ resource "vcf_host" "test_host" {
+ fqdn = %q
+ username = "root"
+ password = "password"
+ network_pool_id = "test_network_pool_id"
+ storage_type = "VSAN"
+ }
+
+ data "vcf_host" "test_host" {
+ fqdn = vcf_host.test_host.fqdn
+ }
+ `, hostFqdn)
+}
diff --git a/internal/provider/framework_provider.go b/internal/provider/framework_provider.go
index a96800e..4367728 100644
--- a/internal/provider/framework_provider.go
+++ b/internal/provider/framework_provider.go
@@ -143,7 +143,11 @@ func (frameworkProvider *FrameworkProvider) Resources(ctx context.Context) []fun
}
func (frameworkProvider *FrameworkProvider) DataSources(ctx context.Context) []func() datasource.DataSource {
- return []func() datasource.DataSource{}
+ return []func() datasource.DataSource{
+ func() datasource.DataSource {
+ return &DataSourceHost{}
+ },
+ }
}
func (frameworkProvider *FrameworkProvider) Configure(ctx context.Context, req provider.ConfigureRequest, res *provider.ConfigureResponse) {
@@ -168,6 +172,7 @@ func (frameworkProvider *FrameworkProvider) Configure(ctx context.Context, req p
frameworkProvider.SddcManagerClient = client
res.ResourceData = client
+ res.DataSourceData = client
} else {
// Connect to Cloud Builder
client := api_client.NewCloudBuilderClient(
@@ -179,6 +184,7 @@ func (frameworkProvider *FrameworkProvider) Configure(ctx context.Context, req p
frameworkProvider.CloudBuilderClient = client
res.ResourceData = client
+ res.DataSourceData = client
}
}