Skip to content

Commit 92cafa9

Browse files
committed
Move iSCSI functions to cim package
1 parent 161c412 commit 92cafa9

File tree

2 files changed

+123
-52
lines changed

2 files changed

+123
-52
lines changed

pkg/cim/iscsi.go

Lines changed: 105 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ import (
1111
"github.com/microsoft/wmi/server2019/root/microsoft/windows/storage"
1212
)
1313

14+
var (
15+
ISCSITargetPortalDefaultSelectorList = []string{"TargetPortalAddress", "TargetPortalPortNumber"}
16+
)
17+
1418
// ListISCSITargetPortals retrieves a list of iSCSI target portals.
1519
//
1620
// The equivalent WMI query is:
@@ -68,6 +72,17 @@ func QueryISCSITargetPortal(address string, port uint32, selectorList []string)
6872
return targetPortal, nil
6973
}
7074

75+
// ListISCSITargetsByTargetPortalAddressAndPort retrieves ISCSI targets by address and port of an iSCSI target portal.
76+
func ListISCSITargetsByTargetPortalAddressAndPort(address string, port uint32, selectorList []string) ([]*storage.MSFT_iSCSITarget, error) {
77+
instance, err := QueryISCSITargetPortal(address, port, selectorList)
78+
if err != nil {
79+
return nil, err
80+
}
81+
82+
targets, err := ListISCSITargetsByTargetPortal([]*storage.MSFT_iSCSITargetPortal{instance})
83+
return targets, err
84+
}
85+
7186
// NewISCSITargetPortal creates a new iSCSI target portal.
7287
//
7388
// Refer to https://learn.microsoft.com/en-us/previous-versions/windows/desktop/iscsidisc/msft-iscsitargetportal-new
@@ -102,6 +117,40 @@ func NewISCSITargetPortal(targetPortalAddress string,
102117
return QueryISCSITargetPortal(targetPortalAddress, targetPortalPortNumber, nil)
103118
}
104119

120+
// ParseISCSITargetPortal retrieves the portal address and port number of an iSCSI target portal.
121+
func ParseISCSITargetPortal(instance *storage.MSFT_iSCSITargetPortal) (string, uint32, error) {
122+
portalAddress, err := instance.GetPropertyTargetPortalAddress()
123+
if err != nil {
124+
return "", 0, fmt.Errorf("failed parsing target portal address %v. err: %w", instance, err)
125+
}
126+
127+
portalPort, err := instance.GetProperty("TargetPortalPortNumber")
128+
if err != nil {
129+
return "", 0, fmt.Errorf("failed parsing target portal port number %v. err: %w", instance, err)
130+
}
131+
132+
return portalAddress, uint32(portalPort.(int32)), nil
133+
}
134+
135+
// RemoveISCSITargetPortal removes an iSCSI target portal.
136+
//
137+
// Refer to https://learn.microsoft.com/en-us/previous-versions/windows/desktop/iscsidisc/msft-iscsitargetportal-remove
138+
// for the WMI method definition.
139+
func RemoveISCSITargetPortal(instance *storage.MSFT_iSCSITargetPortal) (int, error) {
140+
address, port, err := ParseISCSITargetPortal(instance)
141+
if err != nil {
142+
return 0, fmt.Errorf("failed to parse target portal %v. error: %v", instance, err)
143+
}
144+
145+
result, err := instance.InvokeMethodWithReturn("Remove",
146+
nil,
147+
nil,
148+
int(port),
149+
address,
150+
)
151+
return int(result), err
152+
}
153+
105154
// ListISCSITargetsByTargetPortal retrieves all iSCSI targets from the specified iSCSI target portal
106155
// using MSFT_iSCSITargetToiSCSITargetPortal association.
107156
//
@@ -147,7 +196,7 @@ func QueryISCSITarget(address string, port uint32, nodeAddress string) (*storage
147196
}
148197

149198
for _, target := range targets {
150-
targetNodeAddress, err := target.GetProperty("NodeAddress")
199+
targetNodeAddress, err := GetISCSITargetNodeAddress(target)
151200
if err != nil {
152201
return nil, fmt.Errorf("failed to query iSCSI target %v. error: %v", target, err)
153202
}
@@ -160,6 +209,21 @@ func QueryISCSITarget(address string, port uint32, nodeAddress string) (*storage
160209
return nil, nil
161210
}
162211

212+
// GetISCSITargetNodeAddress returns the node address of an iSCSI target.
213+
func GetISCSITargetNodeAddress(target *storage.MSFT_iSCSITarget) (string, error) {
214+
nodeAddress, err := target.GetProperty("NodeAddress")
215+
if err != nil {
216+
return "", err
217+
}
218+
219+
return nodeAddress.(string), err
220+
}
221+
222+
// IsISCSITargetConnected returns whether the iSCSI target is connected.
223+
func IsISCSITargetConnected(target *storage.MSFT_iSCSITarget) (bool, error) {
224+
return target.GetPropertyIsConnected()
225+
}
226+
163227
// QueryISCSISessionByTarget retrieves the iSCSI session from the specified iSCSI target
164228
// using MSFT_iSCSITargetToiSCSISession association.
165229
//
@@ -185,6 +249,34 @@ func QueryISCSISessionByTarget(target *storage.MSFT_iSCSITarget) (*storage.MSFT_
185249
return session, err
186250
}
187251

252+
// UnregisterISCSISession unregisters the iSCSI session so that it is no longer persistent.
253+
//
254+
// Refer https://learn.microsoft.com/en-us/previous-versions/windows/desktop/iscsidisc/msft-iscsisession-unregister
255+
// for the WMI method definition.
256+
func UnregisterISCSISession(session *storage.MSFT_iSCSISession) (int, error) {
257+
result, err := session.InvokeMethodWithReturn("Unregister")
258+
return int(result), err
259+
}
260+
261+
// SetISCSISessionChapSecret sets a CHAP secret key for use with iSCSI initiator connections.
262+
//
263+
// Refer https://learn.microsoft.com/en-us/previous-versions/windows/desktop/iscsidisc/msft-iscsitarget-disconnect
264+
// for the WMI method definition.
265+
func SetISCSISessionChapSecret(mutualChapSecret string) (int, error) {
266+
result, _, err := InvokeCimMethod(WMINamespaceStorage, "MSFT_iSCSISession", "SetCHAPSecret", map[string]interface{}{"ChapSecret": mutualChapSecret})
267+
return result, err
268+
}
269+
270+
// GetISCSISessionIdentifier returns the identifier of an iSCSI session.
271+
func GetISCSISessionIdentifier(session *storage.MSFT_iSCSISession) (string, error) {
272+
return session.GetPropertySessionIdentifier()
273+
}
274+
275+
// IsISCSISessionPersistent returns whether an iSCSI session is persistent.
276+
func IsISCSISessionPersistent(session *storage.MSFT_iSCSISession) (bool, error) {
277+
return session.GetPropertyIsPersistent()
278+
}
279+
188280
// ListDisksByTarget find all disks associated with an iSCSITarget.
189281
// It finds out the iSCSIConnections from MSFT_iSCSITargetToiSCSIConnection association,
190282
// then locate MSFT_Disk objects from MSFT_iSCSIConnectionToDisk association.
@@ -238,7 +330,7 @@ func ListDisksByTarget(target *storage.MSFT_iSCSITarget) ([]*storage.MSFT_Disk,
238330
//
239331
// Refer https://learn.microsoft.com/en-us/previous-versions/windows/desktop/iscsidisc/msft-iscsitarget-connect
240332
// for the WMI method definition.
241-
func ConnectISCSITarget(portalAddress string, portalPortNumber uint32, nodeAddress string, authType string, chapUsername *string, chapSecret *string) (int, map[string]interface{}, error) {
333+
func ConnectISCSITarget(portalAddress string, portalPortNumber uint32, nodeAddress string, authType string, chapUsername *string, chapSecret *string) (int, error) {
242334
inParams := map[string]interface{}{
243335
"NodeAddress": nodeAddress,
244336
"TargetPortalAddress": portalAddress,
@@ -256,6 +348,15 @@ func ConnectISCSITarget(portalAddress string, portalPortNumber uint32, nodeAddre
256348
inParams["ChapSecret"] = *chapSecret
257349
}
258350

259-
result, outParams, err := InvokeCimMethod(WMINamespaceStorage, "MSFT_iSCSITarget", "Connect", inParams)
260-
return result, outParams, err
351+
result, _, err := InvokeCimMethod(WMINamespaceStorage, "MSFT_iSCSITarget", "Connect", inParams)
352+
return result, err
353+
}
354+
355+
// DisconnectISCSITarget disconnects the specified session between an iSCSI initiator and an iSCSI target.
356+
//
357+
// Refer https://learn.microsoft.com/en-us/previous-versions/windows/desktop/iscsidisc/msft-iscsitarget-disconnect
358+
// for the WMI method definition.
359+
func DisconnectISCSITarget(target *storage.MSFT_iSCSITarget, sessionIdentifier string) (int, error) {
360+
result, err := target.InvokeMethodWithReturn("Disconnect", sessionIdentifier)
361+
return int(result), err
261362
}

pkg/os/iscsi/api.go

Lines changed: 18 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import (
66
"strings"
77

88
"github.com/kubernetes-csi/csi-proxy/pkg/cim"
9-
"github.com/microsoft/wmi/server2019/root/microsoft/windows/storage"
109
"k8s.io/klog/v2"
1110
)
1211

@@ -21,20 +20,6 @@ func New() APIImplementor {
2120
return APIImplementor{}
2221
}
2322

24-
func parseTargetPortal(instance *storage.MSFT_iSCSITargetPortal) (string, uint32, error) {
25-
portalAddress, err := instance.GetPropertyTargetPortalAddress()
26-
if err != nil {
27-
return "", 0, fmt.Errorf("failed parsing target portal address %v. err: %w", instance, err)
28-
}
29-
30-
portalPort, err := instance.GetProperty("TargetPortalPortNumber")
31-
if err != nil {
32-
return "", 0, fmt.Errorf("failed parsing target portal port number %v. err: %w", instance, err)
33-
}
34-
35-
return portalAddress, uint32(portalPort.(int32)), nil
36-
}
37-
3823
func (APIImplementor) AddTargetPortal(portal *TargetPortal) error {
3924
existing, err := cim.QueryISCSITargetPortal(portal.Address, portal.Port, nil)
4025
if cim.IgnoreNotFound(err) != nil {
@@ -55,38 +40,33 @@ func (APIImplementor) AddTargetPortal(portal *TargetPortal) error {
5540
}
5641

5742
func (APIImplementor) DiscoverTargetPortal(portal *TargetPortal) ([]string, error) {
58-
instance, err := cim.QueryISCSITargetPortal(portal.Address, portal.Port, nil)
59-
if err != nil {
60-
return nil, err
61-
}
62-
63-
targets, err := cim.ListISCSITargetsByTargetPortal([]*storage.MSFT_iSCSITargetPortal{instance})
43+
targets, err := cim.ListISCSITargetsByTargetPortalAddressAndPort(portal.Address, portal.Port, nil)
6444
if err != nil {
6545
return nil, err
6646
}
6747

6848
var iqns []string
6949
for _, target := range targets {
70-
iqn, err := target.GetProperty("NodeAddress")
50+
iqn, err := cim.GetISCSITargetNodeAddress(target)
7151
if err != nil {
7252
return nil, fmt.Errorf("failed parsing node address of target %v to target portal at (%s:%d). err: %w", target, portal.Address, portal.Port, err)
7353
}
7454

75-
iqns = append(iqns, iqn.(string))
55+
iqns = append(iqns, iqn)
7656
}
7757

7858
return iqns, nil
7959
}
8060

8161
func (APIImplementor) ListTargetPortals() ([]TargetPortal, error) {
82-
instances, err := cim.ListISCSITargetPortals([]string{"TargetPortalAddress", "TargetPortalPortNumber"})
62+
instances, err := cim.ListISCSITargetPortals(cim.ISCSITargetPortalDefaultSelectorList)
8363
if err != nil {
8464
return nil, err
8565
}
8666

8767
var portals []TargetPortal
8868
for _, instance := range instances {
89-
address, port, err := parseTargetPortal(instance)
69+
address, port, err := cim.ParseISCSITargetPortal(instance)
9070
if err != nil {
9171
return nil, fmt.Errorf("failed parsing target portal %v. err: %w", instance, err)
9272
}
@@ -106,19 +86,9 @@ func (APIImplementor) RemoveTargetPortal(portal *TargetPortal) error {
10686
return err
10787
}
10888

109-
address, port, err := parseTargetPortal(instance)
110-
if err != nil {
111-
return fmt.Errorf("failed to parse target portal %v. error: %v", instance, err)
112-
}
113-
114-
result, err := instance.InvokeMethodWithReturn("Remove",
115-
nil,
116-
nil,
117-
int(port),
118-
address,
119-
)
89+
result, err := cim.RemoveISCSITargetPortal(instance)
12090
if result != 0 || err != nil {
121-
return fmt.Errorf("error removing target portal at (%s:%d). result: %d, err: %w", address, port, result, err)
91+
return fmt.Errorf("error removing target portal at (%s:%d). result: %d, err: %w", portal.Address, portal.Port, result, err)
12292
}
12393

12494
return nil
@@ -130,7 +100,7 @@ func (APIImplementor) ConnectTarget(portal *TargetPortal, iqn string, authType s
130100
return err
131101
}
132102

133-
connected, err := target.GetPropertyIsConnected()
103+
connected, err := cim.IsISCSITargetConnected(target)
134104
if err != nil {
135105
return err
136106
}
@@ -142,7 +112,7 @@ func (APIImplementor) ConnectTarget(portal *TargetPortal, iqn string, authType s
142112

143113
targetAuthType := strings.ToUpper(strings.ReplaceAll(authType, "_", ""))
144114

145-
result, _, err := cim.ConnectISCSITarget(portal.Address, portal.Port, iqn, targetAuthType, &chapUser, &chapSecret)
115+
result, err := cim.ConnectISCSITarget(portal.Address, portal.Port, iqn, targetAuthType, &chapUser, &chapSecret)
146116
if err != nil {
147117
return fmt.Errorf("error connecting to target portal. result: %d, err: %w", result, err)
148118
}
@@ -156,7 +126,7 @@ func (APIImplementor) DisconnectTarget(portal *TargetPortal, iqn string) error {
156126
return err
157127
}
158128

159-
connected, err := target.GetPropertyIsConnected()
129+
connected, err := cim.IsISCSITargetConnected(target)
160130
if err != nil {
161131
return fmt.Errorf("error query connected of target %s from target portal at (%s:%d). err: %w", iqn, portal.Address, portal.Port, err)
162132
}
@@ -172,24 +142,24 @@ func (APIImplementor) DisconnectTarget(portal *TargetPortal, iqn string) error {
172142
return fmt.Errorf("error query session of target %s from target portal at (%s:%d). err: %w", iqn, portal.Address, portal.Port, err)
173143
}
174144

175-
sessionIdentifier, err := session.GetPropertySessionIdentifier()
145+
sessionIdentifier, err := cim.GetISCSISessionIdentifier(session)
176146
if err != nil {
177147
return fmt.Errorf("error query session identifier of target %s from target portal at (%s:%d). err: %w", iqn, portal.Address, portal.Port, err)
178148
}
179149

180-
persistent, err := session.GetPropertyIsPersistent()
150+
persistent, err := cim.IsISCSISessionPersistent(session)
181151
if err != nil {
182152
return fmt.Errorf("error query session persistency of target %s from target portal at (%s:%d). err: %w", iqn, portal.Address, portal.Port, err)
183153
}
184154

185155
if persistent {
186-
result, err := session.InvokeMethodWithReturn("Unregister")
156+
result, err := cim.UnregisterISCSISession(session)
187157
if err != nil {
188158
return fmt.Errorf("error unregister session on target %s from target portal at (%s:%d). result: %d, err: %w", iqn, portal.Address, portal.Port, result, err)
189159
}
190160
}
191161

192-
result, err := target.InvokeMethodWithReturn("Disconnect", sessionIdentifier)
162+
result, err := cim.DisconnectISCSITarget(target, sessionIdentifier)
193163
if err != nil {
194164
return fmt.Errorf("error disconnecting target %s from target portal at (%s:%d). result: %d, err: %w", iqn, portal.Address, portal.Port, result, err)
195165
}
@@ -203,7 +173,7 @@ func (APIImplementor) GetTargetDisks(portal *TargetPortal, iqn string) ([]string
203173
return nil, err
204174
}
205175

206-
connected, err := target.GetPropertyIsConnected()
176+
connected, err := cim.IsISCSITargetConnected(target)
207177
if err != nil {
208178
return nil, fmt.Errorf("error query connected of target %s from target portal at (%s:%d). err: %w", iqn, portal.Address, portal.Port, err)
209179
}
@@ -220,18 +190,18 @@ func (APIImplementor) GetTargetDisks(portal *TargetPortal, iqn string) ([]string
220190

221191
var ids []string
222192
for _, disk := range disks {
223-
number, err := disk.GetProperty("Number")
193+
number, err := cim.GetDiskNumber(disk)
224194
if err != nil {
225195
return nil, fmt.Errorf("error getting number of disk %v on target %s from target portal at (%s:%d). err: %w", disk, iqn, portal.Address, portal.Port, err)
226196
}
227197

228-
ids = append(ids, strconv.Itoa(int(number.(int32))))
198+
ids = append(ids, strconv.Itoa(int(number)))
229199
}
230200
return ids, nil
231201
}
232202

233203
func (APIImplementor) SetMutualChapSecret(mutualChapSecret string) error {
234-
result, _, err := cim.InvokeCimMethod(cim.WMINamespaceStorage, "MSFT_iSCSISession", "SetCHAPSecret", map[string]interface{}{"ChapSecret": mutualChapSecret})
204+
result, err := cim.SetISCSISessionChapSecret(mutualChapSecret)
235205
if err != nil {
236206
return fmt.Errorf("error setting mutual chap secret. result: %d, err: %v", result, err)
237207
}

0 commit comments

Comments
 (0)