55package vsphere
66
77import (
8+ "crypto/sha256"
9+ "fmt"
810 "log"
911 "regexp"
1012 "strconv"
@@ -39,31 +41,114 @@ func dataSourceVSphereHostPciDevice() *schema.Resource {
3941 Optional : true ,
4042 Description : "The hexadecimal value of the PCI device's vendor ID." ,
4143 },
42- "name " : {
43- Type : schema .TypeString ,
44+ "pci_devices " : {
45+ Type : schema .TypeList ,
4446 Computed : true ,
45- Description : "The name of the PCI device." ,
47+ Description : "The list of matching PCI Devices available on the host." ,
48+ Elem : & schema.Resource {
49+ Schema : map [string ]* schema.Schema {
50+ "id" : {
51+ Type : schema .TypeString ,
52+ Computed : true ,
53+ Description : "The name ID of this PCI, composed of 'bus:slot.function'" ,
54+ },
55+ "name" : {
56+ Type : schema .TypeString ,
57+ Computed : true ,
58+ Description : "The name of the PCI device." ,
59+ },
60+ "bus" : {
61+ Type : schema .TypeString ,
62+ Computed : true ,
63+ Description : "The bus ID of the PCI device." ,
64+ },
65+ "slot" : {
66+ Type : schema .TypeString ,
67+ Computed : true ,
68+ Description : "The slot ID of the PCI device." ,
69+ },
70+ "function" : {
71+ Type : schema .TypeString ,
72+ Computed : true ,
73+ Description : "The function ID of the PCI device." ,
74+ },
75+ "class_id" : {
76+ Type : schema .TypeString ,
77+ Computed : true ,
78+ Description : "The hexadecimal value of the PCI device's class ID." ,
79+ },
80+ "vendor_id" : {
81+ Type : schema .TypeString ,
82+ Computed : true ,
83+ Description : "The hexadecimal value of the PCI device's vendor ID." ,
84+ },
85+ "sub_vendor_id" : {
86+ Type : schema .TypeString ,
87+ Computed : true ,
88+ Description : "The hexadecimal value of the PCI device's sub vendor ID." ,
89+ },
90+ "vendor_name" : {
91+ Type : schema .TypeString ,
92+ Computed : true ,
93+ Description : "The vendor name of the PCI device." ,
94+ },
95+ "device_id" : {
96+ Type : schema .TypeString ,
97+ Computed : true ,
98+ Description : "The hexadecimal value of the PCI device's device ID." ,
99+ },
100+ "sub_device_id" : {
101+ Type : schema .TypeString ,
102+ Computed : true ,
103+ Description : "The hexadecimal value of the PCI device's sub device ID." ,
104+ },
105+ "parent_bridge" : {
106+ Type : schema .TypeString ,
107+ Computed : true ,
108+ Description : "The parent bridge of the PCI device." ,
109+ },
110+ },
111+ },
46112 },
47113 },
48114 }
49115}
50116
51117func dataSourceVSphereHostPciDeviceRead (d * schema.ResourceData , meta interface {}) error {
52118 log .Printf ("[DEBUG] DataHostPCIDev: Beginning PCI device lookup on %s" , d .Get ("host_id" ).(string ))
119+
53120 client := meta .(* Client ).vimClient
121+
54122 host , err := hostsystem .FromID (client , d .Get ("host_id" ).(string ))
55123 if err != nil {
56124 return err
57125 }
126+
58127 hprops , err := hostsystem .Properties (host )
59128 if err != nil {
60129 return err
61130 }
131+
132+ // Create unique ID based on the host_id
133+ idsum := sha256 .New ()
134+ if _ , err := fmt .Fprintf (idsum , "%#v" , d .Get ("host_id" ).(string )); err != nil {
135+ return err
136+ }
137+
138+ d .SetId (fmt .Sprintf ("%x" , idsum .Sum (nil )))
139+
140+ // Identify PCI devices matching name_regex (if any)
62141 devices , err := matchName (d , hprops .Hardware .PciDevice )
63142 if err != nil {
64143 return err
65144 }
145+
146+ // Output slice
147+ pciDevices := make ([]interface {}, 0 , len (devices ))
148+
66149 log .Printf ("[DEBUG] DataHostPCIDev: Looking for a device with matching class_id and vendor_id" )
150+
151+ // Loop through devices
67152 for _ , device := range devices {
68153 // Match the class_id if it is set.
69154 if class , exists := d .GetOk ("class_id" ); exists {
@@ -75,6 +160,7 @@ func dataSourceVSphereHostPciDeviceRead(d *schema.ResourceData, meta interface{}
75160 continue
76161 }
77162 }
163+
78164 // Now match the vendor_id if it is set.
79165 if vendor , exists := d .GetOk ("vendor_id" ); exists {
80166 vendorInt , err := strconv .ParseInt (vendor .(string ), 16 , 16 )
@@ -85,15 +171,43 @@ func dataSourceVSphereHostPciDeviceRead(d *schema.ResourceData, meta interface{}
85171 continue
86172 }
87173 }
174+
175+ // Convertions
88176 classHex := strconv .FormatInt (int64 (device .ClassId ), 16 )
89177 vendorHex := strconv .FormatInt (int64 (device .VendorId ), 16 )
90- d .SetId (device .Id )
91- _ = d .Set ("name" , device .DeviceName )
92- _ = d .Set ("class_id" , classHex )
93- _ = d .Set ("vendor_id" , vendorHex )
178+ subVendorHex := strconv .FormatInt (int64 (device .SubVendorId ), 16 )
179+ deviceHex := strconv .FormatInt (int64 (device .DeviceId ), 16 )
180+ subDeviceHex := strconv .FormatInt (int64 (device .SubDeviceId ), 16 )
181+ busString := fmt .Sprintf ("%v" , device .Bus )
182+ slotString := fmt .Sprintf ("%v" , device .Slot )
183+ functionString := fmt .Sprintf ("%v" , device .Function )
184+
185+ dev := map [string ]interface {}{
186+ "id" : device .Id ,
187+ "name" : device .DeviceName ,
188+ "class_id" : classHex ,
189+ "vendor_id" : vendorHex ,
190+ "sub_vendor_id" : subVendorHex ,
191+ "device_id" : deviceHex ,
192+ "sub_device_id" : subDeviceHex ,
193+ "bus" : busString ,
194+ "slot" : slotString ,
195+ "function" : functionString ,
196+ "parent_bridge" : device .ParentBridge ,
197+ "vendor_name" : device .VendorName ,
198+ }
199+
200+ // Add PCI device to output slice
201+ pciDevices = append (pciDevices , dev )
202+
94203 log .Printf ("[DEBUG] DataHostPCIDev: Matching PCI device found: %s" , device .DeviceName )
95- return nil
96204 }
205+
206+ // Set the `pci_devices` output to all PCI devices
207+ if err := d .Set ("pci_devices" , pciDevices ); err != nil {
208+ return err
209+ }
210+
97211 return nil
98212}
99213
0 commit comments