Skip to content

Commit 40de367

Browse files
committed
Use WMI instead of PowerShell for OS operations
1 parent 07be14d commit 40de367

File tree

12 files changed

+1398
-384
lines changed

12 files changed

+1398
-384
lines changed

Diff for: go.mod

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
module github.com/kubernetes-csi/csi-proxy
22

3-
go 1.20
3+
go 1.22
4+
5+
toolchain go1.22.3
46

57
require (
68
github.com/Microsoft/go-winio v0.6.1
9+
github.com/go-ole/go-ole v1.3.0
710
github.com/google/go-cmp v0.6.0
811
github.com/iancoleman/strcase v0.3.0
912
github.com/kubernetes-csi/csi-proxy/client v0.0.0-00010101000000-000000000000
13+
github.com/microsoft/wmi v0.23.0
1014
github.com/pkg/errors v0.9.1
1115
github.com/sergi/go-diff v1.3.1
1216
github.com/spf13/pflag v1.0.5

Diff for: go.sum

+6
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7
1616
github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
1717
github.com/go-logr/logr v1.2.0 h1:QK40JKJyMdUDz+h+xvCsru/bJhvG0UxvePV0ufL/AcE=
1818
github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
19+
github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE=
20+
github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78=
1921
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
2022
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
2123
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
@@ -50,6 +52,8 @@ github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
5052
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
5153
github.com/mauriciopoppe/gengo v0.0.0-20210525224835-9c78f58f3486 h1:+l047vEi0SyAzdVToIaAcfoY5DwwGW+OyqTdH/P3TTg=
5254
github.com/mauriciopoppe/gengo v0.0.0-20210525224835-9c78f58f3486/go.mod h1:xXv3T4UXTLta31wMhVezwVkc26OLei4hMbLeBJbPmxc=
55+
github.com/microsoft/wmi v0.23.0 h1:EbgjakKBOfb4QaTJNiGkfKrb2RWv7wpyicI2g3DHWkw=
56+
github.com/microsoft/wmi v0.23.0/go.mod h1:PNc5VFG7cpB7VOb3ILZNuWMWsqFfYLPyzpoiFkA6fAQ=
5357
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
5458
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
5559
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
@@ -85,10 +89,12 @@ golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJ
8589
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
8690
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
8791
golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E=
92+
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
8893
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
8994
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
9095
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
9196
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
97+
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
9298
golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
9399
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
94100
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=

Diff for: pkg/cim/disk.go

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
package cim
2+
3+
import (
4+
"fmt"
5+
"strconv"
6+
7+
"github.com/microsoft/wmi/pkg/base/query"
8+
"github.com/microsoft/wmi/server2019/root/microsoft/windows/storage"
9+
)
10+
11+
const (
12+
PartitionStyleUnknown = 0
13+
PartitionStyleGPT = 2
14+
15+
GPTPartitionTypeBasicData = "{ebd0a0a2-b9e5-4433-87c0-68b6b72699c7}"
16+
GPTPartitionTypeMicrosoftReserved = "{e3c9e316-0b5c-4db8-817d-f92df00215ae}"
17+
)
18+
19+
func QueryDiskByNumber(diskNumber uint32, selectorList []string) (*storage.MSFT_Disk, error) {
20+
diskQuery := query.NewWmiQueryWithSelectList("MSFT_Disk", selectorList, "Number", strconv.Itoa(int(diskNumber)))
21+
instances, err := QueryInstances(WMINamespaceStorage, diskQuery)
22+
if err != nil {
23+
return nil, err
24+
}
25+
26+
disk, err := storage.NewMSFT_DiskEx1(instances[0])
27+
if err != nil {
28+
return nil, fmt.Errorf("failed to query disk %d. error: %v", diskNumber, err)
29+
}
30+
31+
return disk, nil
32+
}
33+
34+
func ListDisks(selectorList []string) ([]*storage.MSFT_Disk, error) {
35+
diskQuery := query.NewWmiQueryWithSelectList("MSFT_Disk", selectorList)
36+
instances, err := QueryInstances(WMINamespaceStorage, diskQuery)
37+
if IgnoreNotFound(err) != nil {
38+
return nil, err
39+
}
40+
41+
var disks []*storage.MSFT_Disk
42+
for _, instance := range instances {
43+
disk, err := storage.NewMSFT_DiskEx1(instance)
44+
if err != nil {
45+
return nil, fmt.Errorf("failed to query disk %v. error: %v", instance, err)
46+
}
47+
48+
disks = append(disks, disk)
49+
}
50+
51+
return disks, nil
52+
}

Diff for: pkg/cim/iscsi.go

+249
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,249 @@
1+
package cim
2+
3+
import (
4+
"fmt"
5+
"github.com/microsoft/wmi/pkg/base/query"
6+
cim "github.com/microsoft/wmi/pkg/wmiinstance"
7+
"github.com/microsoft/wmi/server2019/root/microsoft/windows/storage"
8+
"strconv"
9+
)
10+
11+
func ListISCSITargetPortals(selectorList []string) ([]*storage.MSFT_iSCSITargetPortal, error) {
12+
q := query.NewWmiQueryWithSelectList("MSFT_IscsiTargetPortal", selectorList)
13+
instances, err := QueryInstances(WMINamespaceStorage, q)
14+
if IgnoreNotFound(err) != nil {
15+
return nil, err
16+
}
17+
18+
var targetPortals []*storage.MSFT_iSCSITargetPortal
19+
for _, instance := range instances {
20+
portal, err := storage.NewMSFT_iSCSITargetPortalEx1(instance)
21+
if err != nil {
22+
return nil, fmt.Errorf("failed to query iSCSI target portal %v. error: %v", instance, err)
23+
}
24+
25+
targetPortals = append(targetPortals, portal)
26+
}
27+
28+
return targetPortals, nil
29+
}
30+
31+
func QueryISCSITargetPortal(address string, port uint32, selectorList []string) (*storage.MSFT_iSCSITargetPortal, error) {
32+
portalQuery := query.NewWmiQueryWithSelectList(
33+
"MSFT_iSCSITargetPortal", selectorList,
34+
"TargetPortalAddress", address,
35+
"TargetPortalPortNumber", strconv.Itoa(int(port)))
36+
instances, err := QueryInstances(WMINamespaceStorage, portalQuery)
37+
if err != nil {
38+
return nil, err
39+
}
40+
41+
targetPortal, err := storage.NewMSFT_iSCSITargetPortalEx1(instances[0])
42+
if err != nil {
43+
return nil, fmt.Errorf("failed to query iSCSI target portal at (%s:%d). error: %v", address, port, err)
44+
}
45+
46+
return targetPortal, nil
47+
}
48+
49+
func NewISCSITargetPortal(targetPortalAddress string,
50+
targetPortalPortNumber uint32,
51+
initiatorInstanceName *string,
52+
initiatorPortalAddress *string,
53+
isHeaderDigest *bool,
54+
isDataDigest *bool) (*storage.MSFT_iSCSITargetPortal, error) {
55+
params := map[string]interface{}{
56+
"TargetPortalAddress": targetPortalAddress,
57+
"TargetPortalPortNumber": targetPortalPortNumber,
58+
}
59+
if initiatorInstanceName != nil {
60+
params["InitiatorInstanceName"] = *initiatorInstanceName
61+
}
62+
if initiatorPortalAddress != nil {
63+
params["InitiatorPortalAddress"] = *initiatorPortalAddress
64+
}
65+
if isHeaderDigest != nil {
66+
params["IsHeaderDigest"] = *isHeaderDigest
67+
}
68+
if isDataDigest != nil {
69+
params["IsDataDigest"] = *isDataDigest
70+
}
71+
result, _, err := InvokeCimMethod(WMINamespaceStorage, "MSFT_iSCSITargetPortal", "New", params)
72+
if err != nil {
73+
return nil, fmt.Errorf("failed to create iSCSI target portal with %v. result: %d, error: %v", params, result, err)
74+
}
75+
76+
return QueryISCSITargetPortal(targetPortalAddress, targetPortalPortNumber, nil)
77+
}
78+
79+
var (
80+
mappingISCSIiTargetIndexer = mappingObjectRefIndexer("iSCSITarget", "MSFT_iSCSITarget", "NodeAddress")
81+
mappingISCSITargetPortalIndexer = mappingObjectRefIndexer("iSCSITargetPortal", "MSFT_iSCSITargetPortal", "TargetPortalAddress")
82+
mappingISCSIConnectionIndexer = mappingObjectRefIndexer("iSCSIConnection", "MSFT_iSCSIConnection", "ConnectionIdentifier")
83+
mappingISCSISessionIndexer = mappingObjectRefIndexer("iSCSISession", "MSFT_iSCSISession", "SessionIdentifier")
84+
85+
iscsiTargetIndexer = stringPropertyIndexer("NodeAddress")
86+
iscsiTargetPortalIndexer = stringPropertyIndexer("TargetPortalAddress")
87+
iscsiConnectionIndexer = stringPropertyIndexer("ConnectionIdentifier")
88+
iscsiSessionIndexer = stringPropertyIndexer("SessionIdentifier")
89+
)
90+
91+
func ListISCSITargetToISCSITargetPortalMapping() (map[string]string, error) {
92+
return ListWMIInstanceMappings(WMINamespaceStorage, "MSFT_iSCSITargetToiSCSITargetPortal", nil, mappingISCSIiTargetIndexer, mappingISCSITargetPortalIndexer)
93+
}
94+
95+
func ListISCSIConnectionToISCSITargetMapping() (map[string]string, error) {
96+
return ListWMIInstanceMappings(WMINamespaceStorage, "MSFT_iSCSITargetToiSCSIConnection", nil, mappingISCSIConnectionIndexer, mappingISCSIiTargetIndexer)
97+
}
98+
99+
func ListISCSISessionToISCSITargetMapping() (map[string]string, error) {
100+
return ListWMIInstanceMappings(WMINamespaceStorage, "MSFT_iSCSITargetToiSCSISession", nil, mappingISCSISessionIndexer, mappingISCSIiTargetIndexer)
101+
}
102+
103+
func ListDiskToISCSIConnectionMapping() (map[string]string, error) {
104+
return ListWMIInstanceMappings(WMINamespaceStorage, "MSFT_iSCSIConnectionToDisk", nil, mappingObjectRefIndexer("Disk", "MSFT_Disk", "ObjectId"), mappingISCSIConnectionIndexer)
105+
}
106+
107+
func ListISCSITargetByTargetPortalWithFilters(targetSelectorList []string, portals []*storage.MSFT_iSCSITargetPortal, filters ...*query.WmiQueryFilter) ([]*storage.MSFT_iSCSITarget, error) {
108+
targetQuery := query.NewWmiQueryWithSelectList("MSFT_iSCSITarget", targetSelectorList)
109+
targetQuery.Filters = append(targetQuery.Filters, filters...)
110+
instances, err := QueryInstances(WMINamespaceStorage, targetQuery)
111+
if err != nil {
112+
return nil, err
113+
}
114+
115+
var portalInstances []*cim.WmiInstance
116+
for _, portal := range portals {
117+
portalInstances = append(portalInstances, portal.WmiInstance)
118+
}
119+
120+
targetToTargetPortalMapping, err := ListISCSITargetToISCSITargetPortalMapping()
121+
if err != nil {
122+
return nil, err
123+
}
124+
125+
targetInstances, err := FindInstancesByMapping(instances, iscsiTargetIndexer, portalInstances, iscsiTargetPortalIndexer, targetToTargetPortalMapping)
126+
if err != nil {
127+
return nil, err
128+
}
129+
130+
var targets []*storage.MSFT_iSCSITarget
131+
for _, instance := range targetInstances {
132+
target, err := storage.NewMSFT_iSCSITargetEx1(instance)
133+
if err != nil {
134+
return nil, fmt.Errorf("failed to query iSCSI target %v. %v", instance, err)
135+
}
136+
137+
targets = append(targets, target)
138+
}
139+
140+
return targets, nil
141+
}
142+
143+
func QueryISCSITarget(address string, port uint32, nodeAddress string, selectorList []string) (*storage.MSFT_iSCSITarget, error) {
144+
portal, err := QueryISCSITargetPortal(address, port, nil)
145+
if err != nil {
146+
return nil, err
147+
}
148+
149+
targets, err := ListISCSITargetByTargetPortalWithFilters(selectorList, []*storage.MSFT_iSCSITargetPortal{portal},
150+
query.NewWmiQueryFilter("NodeAddress", nodeAddress, query.Equals))
151+
if err != nil {
152+
return nil, err
153+
}
154+
155+
return targets[0], nil
156+
}
157+
158+
func QueryISCSISessionByTarget(target *storage.MSFT_iSCSITarget, selectorList []string) (*storage.MSFT_iSCSISession, error) {
159+
sessionQuery := query.NewWmiQueryWithSelectList("MSFT_iSCSISession", selectorList)
160+
sessionInstances, err := QueryInstances(WMINamespaceStorage, sessionQuery)
161+
if err != nil {
162+
return nil, err
163+
}
164+
165+
targetToTargetSessionMapping, err := ListISCSISessionToISCSITargetMapping()
166+
if err != nil {
167+
return nil, err
168+
}
169+
170+
filtered, err := FindInstancesByMapping(sessionInstances, iscsiSessionIndexer, []*cim.WmiInstance{target.WmiInstance}, iscsiTargetIndexer, targetToTargetSessionMapping)
171+
if err != nil {
172+
return nil, err
173+
}
174+
175+
session, err := storage.NewMSFT_iSCSISessionEx1(filtered[0])
176+
return session, err
177+
}
178+
179+
func ListDisksByTarget(target *storage.MSFT_iSCSITarget, selectorList []string) ([]*storage.MSFT_Disk, error) {
180+
// list connections to the given iSCSI target
181+
connectionQuery := query.NewWmiQueryWithSelectList("MSFT_iSCSIConnection", selectorList)
182+
connectionInstances, err := QueryInstances(WMINamespaceStorage, connectionQuery)
183+
if err != nil {
184+
return nil, err
185+
}
186+
187+
connectionToTargetMapping, err := ListISCSIConnectionToISCSITargetMapping()
188+
if err != nil {
189+
return nil, err
190+
}
191+
192+
connectionsToTarget, err := FindInstancesByMapping(connectionInstances, iscsiConnectionIndexer, []*cim.WmiInstance{target.WmiInstance}, iscsiTargetIndexer, connectionToTargetMapping)
193+
if err != nil {
194+
return nil, err
195+
}
196+
197+
disks, err := ListDisks(selectorList)
198+
if err != nil {
199+
return nil, err
200+
}
201+
202+
var diskInstances []*cim.WmiInstance
203+
for _, disk := range disks {
204+
diskInstances = append(diskInstances, disk.WmiInstance)
205+
}
206+
207+
diskToConnectionMapping, err := ListDiskToISCSIConnectionMapping()
208+
if err != nil {
209+
return nil, err
210+
}
211+
212+
filtered, err := FindInstancesByMapping(diskInstances, objectIDPropertyIndexer, connectionsToTarget, iscsiConnectionIndexer, diskToConnectionMapping)
213+
if err != nil {
214+
return nil, err
215+
}
216+
217+
var filteredDisks []*storage.MSFT_Disk
218+
for _, instance := range filtered {
219+
disk, err := storage.NewMSFT_DiskEx1(instance)
220+
if err != nil {
221+
return nil, fmt.Errorf("failed to query disk %v. error: %v", disk, err)
222+
}
223+
224+
filteredDisks = append(filteredDisks, disk)
225+
}
226+
return filteredDisks, err
227+
}
228+
229+
func ConnectISCSITarget(portalAddress string, portalPortNumber uint32, nodeAddress string, authType string, chapUsername *string, chapSecret *string) (int, map[string]interface{}, error) {
230+
inParams := map[string]interface{}{
231+
"NodeAddress": nodeAddress,
232+
"TargetPortalAddress": portalAddress,
233+
"TargetPortalPortNumber": int(portalPortNumber),
234+
"AuthenticationType": authType,
235+
}
236+
// InitiatorPortalAddress
237+
// IsDataDigest
238+
// IsHeaderDigest
239+
// ReportToPnP
240+
if chapUsername != nil {
241+
inParams["ChapUsername"] = *chapUsername
242+
}
243+
if chapSecret != nil {
244+
inParams["ChapSecret"] = *chapSecret
245+
}
246+
247+
result, outParams, err := InvokeCimMethod(WMINamespaceStorage, "MSFT_iSCSITarget", "Connect", inParams)
248+
return result, outParams, err
249+
}

0 commit comments

Comments
 (0)