|
8 | 8 | "strconv" |
9 | 9 |
|
10 | 10 | "github.com/microsoft/wmi/pkg/base/query" |
11 | | - cim "github.com/microsoft/wmi/pkg/wmiinstance" |
12 | 11 | "github.com/microsoft/wmi/server2019/root/microsoft/windows/storage" |
13 | 12 | ) |
14 | 13 |
|
@@ -103,242 +102,136 @@ func NewISCSITargetPortal(targetPortalAddress string, |
103 | 102 | return QueryISCSITargetPortal(targetPortalAddress, targetPortalPortNumber, nil) |
104 | 103 | } |
105 | 104 |
|
106 | | -var ( |
107 | | - // Indexes iSCSI targets by their Object ID specified in node address |
108 | | - mappingISCSITargetIndexer = mappingObjectRefIndexer("iSCSITarget", "MSFT_iSCSITarget", "NodeAddress") |
109 | | - // Indexes iSCSI target portals by their Object ID specified in portal address |
110 | | - mappingISCSITargetPortalIndexer = mappingObjectRefIndexer("iSCSITargetPortal", "MSFT_iSCSITargetPortal", "TargetPortalAddress") |
111 | | - // Indexes iSCSI connections by their Object ID specified in connection identifier |
112 | | - mappingISCSIConnectionIndexer = mappingObjectRefIndexer("iSCSIConnection", "MSFT_iSCSIConnection", "ConnectionIdentifier") |
113 | | - // Indexes iSCSI sessions by their Object ID specified in session identifier |
114 | | - mappingISCSISessionIndexer = mappingObjectRefIndexer("iSCSISession", "MSFT_iSCSISession", "SessionIdentifier") |
115 | | - |
116 | | - // Indexes iSCSI targets by their node address |
117 | | - iscsiTargetIndexer = stringPropertyIndexer("NodeAddress") |
118 | | - // Indexes iSCSI targets by their target portal address |
119 | | - iscsiTargetPortalIndexer = stringPropertyIndexer("TargetPortalAddress") |
120 | | - // Indexes iSCSI connections by their connection identifier |
121 | | - iscsiConnectionIndexer = stringPropertyIndexer("ConnectionIdentifier") |
122 | | - // Indexes iSCSI sessions by their session identifier |
123 | | - iscsiSessionIndexer = stringPropertyIndexer("SessionIdentifier") |
124 | | -) |
125 | | - |
126 | | -// ListISCSITargetToISCSITargetPortalMapping builds a mapping between iSCSI target and iSCSI target portal with iSCSI target as the key. |
127 | | -// |
128 | | -// The equivalent WMI query is: |
129 | | -// |
130 | | -// SELECT [selectors] FROM MSFT_iSCSITargetToiSCSITargetPortal |
131 | | -// |
132 | | -// iSCSITarget | iSCSITargetPortal |
133 | | -// ----------- | ----------------- |
134 | | -// MSFT_iSCSITarget (NodeAddress = "iqn.1991-05.com.microsoft:win-8e2evaq9q...) | MSFT_iSCSITargetPortal (TargetPortalAdd... |
135 | | -// |
136 | | -// Refer to https://learn.microsoft.com/en-us/previous-versions/windows/desktop/iscsidisc/msft-iscsitargettoiscsitargetportal |
137 | | -// for the WMI class definition. |
138 | | -func ListISCSITargetToISCSITargetPortalMapping() (map[string]string, error) { |
139 | | - return ListWMIInstanceMappings(WMINamespaceStorage, "MSFT_iSCSITargetToiSCSITargetPortal", nil, mappingISCSITargetIndexer, mappingISCSITargetPortalIndexer) |
140 | | -} |
141 | | - |
142 | | -// ListISCSIConnectionToISCSITargetMapping builds a mapping between iSCSI connection and iSCSI target with iSCSI connection as the key. |
143 | | -// |
144 | | -// The equivalent WMI query is: |
145 | | -// |
146 | | -// SELECT [selectors] FROM MSFT_iSCSITargetToiSCSIConnection |
147 | | -// |
148 | | -// iSCSIConnection | iSCSITarget |
149 | | -// --------------- | ----------- |
150 | | -// MSFT_iSCSIConnection (ConnectionIdentifier = "ffffac0cacbff010-15") | MSFT_iSCSITarget (NodeAddress = "iqn.1991-05.com... |
151 | | -// |
152 | | -// Refer to https://learn.microsoft.com/en-us/previous-versions/windows/desktop/iscsidisc/msft-iscsitargettoiscsitargetportal |
153 | | -// for the WMI class definition. |
154 | | -func ListISCSIConnectionToISCSITargetMapping() (map[string]string, error) { |
155 | | - return ListWMIInstanceMappings(WMINamespaceStorage, "MSFT_iSCSITargetToiSCSIConnection", nil, mappingISCSIConnectionIndexer, mappingISCSITargetIndexer) |
156 | | -} |
157 | | - |
158 | | -// ListISCSISessionToISCSITargetMapping builds a mapping between iSCSI session and iSCSI target with iSCSI session as the key. |
159 | | -// |
160 | | -// The equivalent WMI query is: |
161 | | -// |
162 | | -// SELECT [selectors] FROM MSFT_iSCSITargetToiSCSISession |
163 | | -// |
164 | | -// iSCSISession | iSCSITarget |
165 | | -// ------------ | ----------- |
166 | | -// MSFT_iSCSISession (SessionIdentifier = "ffffac0cacbff010-4000013700000016") | MSFT_iSCSITarget (NodeAddress = "iqn.199... |
167 | | -// |
168 | | -// Refer to https://learn.microsoft.com/en-us/previous-versions/windows/desktop/iscsidisc/msft-iscsitargettoiscsisession |
169 | | -// for the WMI class definition. |
170 | | -func ListISCSISessionToISCSITargetMapping() (map[string]string, error) { |
171 | | - return ListWMIInstanceMappings(WMINamespaceStorage, "MSFT_iSCSITargetToiSCSISession", nil, mappingISCSISessionIndexer, mappingISCSITargetIndexer) |
172 | | -} |
173 | | - |
174 | | -// ListDiskToISCSIConnectionMapping builds a mapping between disk and iSCSI connection with disk Object ID as the key. |
175 | | -// |
176 | | -// The equivalent WMI query is: |
177 | | -// |
178 | | -// SELECT [selectors] FROM MSFT_iSCSIConnectionToDisk |
179 | | -// |
180 | | -// Disk | iSCSIConnection |
181 | | -// ---- | --------------- |
182 | | -// MSFT_Disk (ObjectId = "{1}\\WIN-8E2EVAQ9QSB\root/Microsoft/Win...) | MSFT_iSCSIConnection (ConnectionIdentifier = "fff... |
183 | | -// |
184 | | -// Refer to https://learn.microsoft.com/en-us/previous-versions/windows/desktop/iscsidisc/msft-iscsiconnectiontodisk |
185 | | -// for the WMI class definition. |
186 | | -func ListDiskToISCSIConnectionMapping() (map[string]string, error) { |
187 | | - return ListWMIInstanceMappings(WMINamespaceStorage, "MSFT_iSCSIConnectionToDisk", nil, mappingObjectRefIndexer("Disk", "MSFT_Disk", "ObjectId"), mappingISCSIConnectionIndexer) |
188 | | -} |
189 | | - |
190 | | -// ListISCSITargetsByTargetPortalWithFilters retrieves all iSCSI targets from the specified iSCSI target portal and conditions by query filters. |
191 | | -// |
192 | | -// It lists all the iSCSI targets via the following WMI query |
| 105 | +// ListISCSITargetsByTargetPortal retrieves all iSCSI targets from the specified iSCSI target portal |
| 106 | +// using MSFT_iSCSITargetToiSCSITargetPortal association. |
193 | 107 | // |
194 | | -// SELECT [selectors] FROM MSFT_iSCSITarget |
| 108 | +// WMI association MSFT_iSCSITargetToiSCSITargetPortal: |
195 | 109 | // |
196 | | -// Then find all iSCSITarget objects from MSFT_iSCSITargetToiSCSITargetPortal mapping. |
| 110 | +// iSCSITarget | iSCSITargetPortal |
| 111 | +// ----------- | ----------------- |
| 112 | +// MSFT_iSCSITarget (NodeAddress = "iqn.1991-05.com.microsoft:win-8e2evaq9q...) | MSFT_iSCSITargetPortal (TargetPortalAdd... |
197 | 113 | // |
198 | 114 | // Refer to https://learn.microsoft.com/en-us/previous-versions/windows/desktop/iscsidisc/msft-iscsitarget |
199 | 115 | // for the WMI class definition. |
200 | | -func ListISCSITargetsByTargetPortalWithFilters(targetSelectorList []string, portals []*storage.MSFT_iSCSITargetPortal, filters ...*query.WmiQueryFilter) ([]*storage.MSFT_iSCSITarget, error) { |
201 | | - targetQuery := query.NewWmiQueryWithSelectList("MSFT_iSCSITarget", targetSelectorList) |
202 | | - targetQuery.Filters = append(targetQuery.Filters, filters...) |
203 | | - instances, err := QueryInstances(WMINamespaceStorage, targetQuery) |
204 | | - if err != nil { |
205 | | - return nil, err |
206 | | - } |
207 | | - |
208 | | - var portalInstances []*cim.WmiInstance |
209 | | - for _, portal := range portals { |
210 | | - portalInstances = append(portalInstances, portal.WmiInstance) |
211 | | - } |
212 | | - |
213 | | - targetToTargetPortalMapping, err := ListISCSITargetToISCSITargetPortalMapping() |
214 | | - if err != nil { |
215 | | - return nil, err |
216 | | - } |
217 | | - |
218 | | - targetInstances, err := FindInstancesByMapping(instances, iscsiTargetIndexer, portalInstances, iscsiTargetPortalIndexer, targetToTargetPortalMapping) |
219 | | - if err != nil { |
220 | | - return nil, err |
221 | | - } |
222 | | - |
| 116 | +func ListISCSITargetsByTargetPortal(portals []*storage.MSFT_iSCSITargetPortal) ([]*storage.MSFT_iSCSITarget, error) { |
223 | 117 | var targets []*storage.MSFT_iSCSITarget |
224 | | - for _, instance := range targetInstances { |
225 | | - target, err := storage.NewMSFT_iSCSITargetEx1(instance) |
| 118 | + for _, portal := range portals { |
| 119 | + collection, err := portal.GetAssociated("MSFT_iSCSITargetToiSCSITargetPortal", "MSFT_iSCSITarget", "iSCSITarget", "iSCSITargetPortal") |
226 | 120 | if err != nil { |
227 | | - return nil, fmt.Errorf("failed to query iSCSI target %v. %v", instance, err) |
| 121 | + return nil, fmt.Errorf("failed to query associated iSCSITarget for %v. error: %v", portal, err) |
228 | 122 | } |
229 | 123 |
|
230 | | - targets = append(targets, target) |
| 124 | + for _, instance := range collection { |
| 125 | + target, err := storage.NewMSFT_iSCSITargetEx1(instance) |
| 126 | + if err != nil { |
| 127 | + return nil, fmt.Errorf("failed to query iSCSI target %v. error: %v", instance, err) |
| 128 | + } |
| 129 | + |
| 130 | + targets = append(targets, target) |
| 131 | + } |
231 | 132 | } |
232 | 133 |
|
233 | 134 | return targets, nil |
234 | 135 | } |
235 | 136 |
|
236 | 137 | // QueryISCSITarget retrieves the iSCSI target from the specified portal address, portal and node address. |
237 | | -func QueryISCSITarget(address string, port uint32, nodeAddress string, selectorList []string) (*storage.MSFT_iSCSITarget, error) { |
| 138 | +func QueryISCSITarget(address string, port uint32, nodeAddress string) (*storage.MSFT_iSCSITarget, error) { |
238 | 139 | portal, err := QueryISCSITargetPortal(address, port, nil) |
239 | 140 | if err != nil { |
240 | 141 | return nil, err |
241 | 142 | } |
242 | 143 |
|
243 | | - targets, err := ListISCSITargetsByTargetPortalWithFilters(selectorList, []*storage.MSFT_iSCSITargetPortal{portal}, |
244 | | - query.NewWmiQueryFilter("NodeAddress", nodeAddress, query.Equals)) |
| 144 | + targets, err := ListISCSITargetsByTargetPortal([]*storage.MSFT_iSCSITargetPortal{portal}) |
245 | 145 | if err != nil { |
246 | 146 | return nil, err |
247 | 147 | } |
248 | 148 |
|
249 | | - return targets[0], nil |
| 149 | + for _, target := range targets { |
| 150 | + targetNodeAddress, err := target.GetProperty("NodeAddress") |
| 151 | + if err != nil { |
| 152 | + return nil, fmt.Errorf("failed to query iSCSI target %v. error: %v", target, err) |
| 153 | + } |
| 154 | + |
| 155 | + if targetNodeAddress == nodeAddress { |
| 156 | + return target, nil |
| 157 | + } |
| 158 | + } |
| 159 | + |
| 160 | + return nil, nil |
250 | 161 | } |
251 | 162 |
|
252 | | -// QueryISCSISessionByTarget retrieves the iSCSI session from the specified iSCSI target. |
253 | | -// |
254 | | -// It lists all the iSCSI sessions via the following WMI query |
| 163 | +// QueryISCSISessionByTarget retrieves the iSCSI session from the specified iSCSI target |
| 164 | +// using MSFT_iSCSITargetToiSCSISession association. |
255 | 165 | // |
256 | | -// SELECT [selectors] FROM MSFT_iSCSISession |
| 166 | +// WMI association MSFT_iSCSITargetToiSCSISession: |
257 | 167 | // |
258 | | -// Then find all MSFT_iSCSISession objects from MSFT_iSCSITargetToiSCSISession mapping. |
| 168 | +// iSCSISession | iSCSITarget |
| 169 | +// ------------ | ----------- |
| 170 | +// MSFT_iSCSISession (SessionIdentifier = "ffffac0cacbff010-4000013700000016") | MSFT_iSCSITarget (NodeAddress = "iqn.199... |
259 | 171 | // |
260 | 172 | // Refer to https://learn.microsoft.com/en-us/previous-versions/windows/desktop/iscsidisc/msft-iscsisession |
261 | 173 | // for the WMI class definition. |
262 | | -func QueryISCSISessionByTarget(target *storage.MSFT_iSCSITarget, selectorList []string) (*storage.MSFT_iSCSISession, error) { |
263 | | - sessionQuery := query.NewWmiQueryWithSelectList("MSFT_iSCSISession", selectorList) |
264 | | - sessionInstances, err := QueryInstances(WMINamespaceStorage, sessionQuery) |
| 174 | +func QueryISCSISessionByTarget(target *storage.MSFT_iSCSITarget) (*storage.MSFT_iSCSISession, error) { |
| 175 | + collection, err := target.GetAssociated("MSFT_iSCSITargetToiSCSISession", "MSFT_iSCSISession", "iSCSISession", "iSCSITarget") |
265 | 176 | if err != nil { |
266 | | - return nil, err |
| 177 | + return nil, fmt.Errorf("failed to query associated iSCSISession for %v. error: %v", target, err) |
267 | 178 | } |
268 | 179 |
|
269 | | - targetToTargetSessionMapping, err := ListISCSISessionToISCSITargetMapping() |
270 | | - if err != nil { |
271 | | - return nil, err |
| 180 | + if len(collection) == 0 { |
| 181 | + return nil, nil |
272 | 182 | } |
273 | 183 |
|
274 | | - filtered, err := FindInstancesByMapping(sessionInstances, iscsiSessionIndexer, []*cim.WmiInstance{target.WmiInstance}, iscsiTargetIndexer, targetToTargetSessionMapping) |
275 | | - if err != nil { |
276 | | - return nil, err |
277 | | - } |
278 | | - |
279 | | - session, err := storage.NewMSFT_iSCSISessionEx1(filtered[0]) |
| 184 | + session, err := storage.NewMSFT_iSCSISessionEx1(collection[0]) |
280 | 185 | return session, err |
281 | 186 | } |
282 | 187 |
|
283 | | -// ListDisksByTarget lists all the disks on the specified iSCSI target. |
| 188 | +// ListDisksByTarget find all disks associated with an iSCSITarget. |
| 189 | +// It finds out the iSCSIConnections from MSFT_iSCSITargetToiSCSIConnection association, |
| 190 | +// then locate MSFT_Disk objects from MSFT_iSCSIConnectionToDisk association. |
284 | 191 | // |
285 | | -// It lists all the iSCSI connections via the following WMI query |
| 192 | +// WMI association MSFT_iSCSITargetToiSCSIConnection: |
286 | 193 | // |
287 | | -// SELECT [selectors] FROM MSFT_iSCSIConnection |
| 194 | +// iSCSIConnection | iSCSITarget |
| 195 | +// --------------- | ----------- |
| 196 | +// MSFT_iSCSIConnection (ConnectionIdentifier = "ffffac0cacbff010-15") | MSFT_iSCSITarget (NodeAddress = "iqn.1991-05.com... |
288 | 197 | // |
289 | | -// Then find all MSFT_iSCSIConnection objects from MSFT_iSCSITargetToiSCSIConnection mapping, |
290 | | -// locate the MSFT_Disk objects using MSFT_iSCSIConnectionToDisk mapping. |
| 198 | +// WMI association MSFT_iSCSIConnectionToDisk: |
| 199 | +// |
| 200 | +// Disk | iSCSIConnection |
| 201 | +// ---- | --------------- |
| 202 | +// MSFT_Disk (ObjectId = "{1}\\WIN-8E2EVAQ9QSB\root/Microsoft/Win...) | MSFT_iSCSIConnection (ConnectionIdentifier = "fff... |
291 | 203 | // |
292 | 204 | // Refer to https://learn.microsoft.com/en-us/previous-versions/windows/desktop/iscsidisc/msft-iscsiconnection |
293 | 205 | // for the WMI class definition. |
294 | | -func ListDisksByTarget(target *storage.MSFT_iSCSITarget, selectorList []string) ([]*storage.MSFT_Disk, error) { |
| 206 | +func ListDisksByTarget(target *storage.MSFT_iSCSITarget) ([]*storage.MSFT_Disk, error) { |
295 | 207 | // list connections to the given iSCSI target |
296 | | - connectionQuery := query.NewWmiQueryWithSelectList("MSFT_iSCSIConnection", selectorList) |
297 | | - connectionInstances, err := QueryInstances(WMINamespaceStorage, connectionQuery) |
298 | | - if err != nil { |
299 | | - return nil, err |
300 | | - } |
301 | | - |
302 | | - connectionToTargetMapping, err := ListISCSIConnectionToISCSITargetMapping() |
303 | | - if err != nil { |
304 | | - return nil, err |
305 | | - } |
306 | | - |
307 | | - connectionsToTarget, err := FindInstancesByMapping(connectionInstances, iscsiConnectionIndexer, []*cim.WmiInstance{target.WmiInstance}, iscsiTargetIndexer, connectionToTargetMapping) |
308 | | - if err != nil { |
309 | | - return nil, err |
310 | | - } |
311 | | - |
312 | | - disks, err := ListDisks(selectorList) |
| 208 | + collection, err := target.GetAssociated("MSFT_iSCSITargetToiSCSIConnection", "MSFT_iSCSIConnection", "iSCSIConnection", "iSCSITarget") |
313 | 209 | if err != nil { |
314 | | - return nil, err |
| 210 | + return nil, fmt.Errorf("failed to query associated iSCSISession for %v. error: %v", target, err) |
315 | 211 | } |
316 | 212 |
|
317 | | - var diskInstances []*cim.WmiInstance |
318 | | - for _, disk := range disks { |
319 | | - diskInstances = append(diskInstances, disk.WmiInstance) |
| 213 | + if len(collection) == 0 { |
| 214 | + return nil, nil |
320 | 215 | } |
321 | 216 |
|
322 | | - diskToConnectionMapping, err := ListDiskToISCSIConnectionMapping() |
323 | | - if err != nil { |
324 | | - return nil, err |
325 | | - } |
326 | | - |
327 | | - filtered, err := FindInstancesByMapping(diskInstances, objectIDPropertyIndexer, connectionsToTarget, iscsiConnectionIndexer, diskToConnectionMapping) |
328 | | - if err != nil { |
329 | | - return nil, err |
330 | | - } |
331 | | - |
332 | | - var filteredDisks []*storage.MSFT_Disk |
333 | | - for _, instance := range filtered { |
334 | | - disk, err := storage.NewMSFT_DiskEx1(instance) |
| 217 | + var result []*storage.MSFT_Disk |
| 218 | + for _, conn := range collection { |
| 219 | + instances, err := conn.GetAssociated("MSFT_iSCSIConnectionToDisk", "MSFT_Disk", "Disk", "iSCSIConnection") |
335 | 220 | if err != nil { |
336 | | - return nil, fmt.Errorf("failed to query disk %v. error: %v", disk, err) |
| 221 | + return nil, fmt.Errorf("failed to query associated disk for %v. error: %v", target, err) |
337 | 222 | } |
338 | 223 |
|
339 | | - filteredDisks = append(filteredDisks, disk) |
| 224 | + for _, instance := range instances { |
| 225 | + disk, err := storage.NewMSFT_DiskEx1(instance) |
| 226 | + if err != nil { |
| 227 | + return nil, fmt.Errorf("failed to query associated disk %v. error: %v", instance, err) |
| 228 | + } |
| 229 | + |
| 230 | + result = append(result, disk) |
| 231 | + } |
340 | 232 | } |
341 | | - return filteredDisks, err |
| 233 | + |
| 234 | + return result, err |
342 | 235 | } |
343 | 236 |
|
344 | 237 | // ConnectISCSITarget establishes a connection to an iSCSI target with optional CHAP authentication credential. |
|
0 commit comments