Skip to content

Commit dfb404a

Browse files
committed
Move iSCSI functions to cim package
1 parent 026cd5b commit dfb404a

File tree

2 files changed

+109
-43
lines changed

2 files changed

+109
-43
lines changed

pkg/cim/iscsi.go

Lines changed: 94 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:
@@ -102,6 +106,40 @@ func NewISCSITargetPortal(targetPortalAddress string,
102106
return QueryISCSITargetPortal(targetPortalAddress, targetPortalPortNumber, nil)
103107
}
104108

109+
// ParseISCSITargetPortal retrieves the portal address and port number of an iSCSI target portal.
110+
func ParseISCSITargetPortal(instance *storage.MSFT_iSCSITargetPortal) (string, uint32, error) {
111+
portalAddress, err := instance.GetPropertyTargetPortalAddress()
112+
if err != nil {
113+
return "", 0, fmt.Errorf("failed parsing target portal address %v. err: %w", instance, err)
114+
}
115+
116+
portalPort, err := instance.GetProperty("TargetPortalPortNumber")
117+
if err != nil {
118+
return "", 0, fmt.Errorf("failed parsing target portal port number %v. err: %w", instance, err)
119+
}
120+
121+
return portalAddress, uint32(portalPort.(int32)), nil
122+
}
123+
124+
// RemoveISCSITargetPortal removes an iSCSI target portal.
125+
//
126+
// Refer to https://learn.microsoft.com/en-us/previous-versions/windows/desktop/iscsidisc/msft-iscsitargetportal-remove
127+
// for the WMI method definition.
128+
func RemoveISCSITargetPortal(instance *storage.MSFT_iSCSITargetPortal) (int, error) {
129+
address, port, err := ParseISCSITargetPortal(instance)
130+
if err != nil {
131+
return 0, fmt.Errorf("failed to parse target portal %v. error: %v", instance, err)
132+
}
133+
134+
result, err := instance.InvokeMethodWithReturn("Remove",
135+
nil,
136+
nil,
137+
int(port),
138+
address,
139+
)
140+
return int(result), err
141+
}
142+
105143
// ListISCSITargetsByTargetPortal retrieves all iSCSI targets from the specified iSCSI target portal
106144
// using MSFT_iSCSITargetToiSCSITargetPortal association.
107145
//
@@ -147,7 +185,7 @@ func QueryISCSITarget(address string, port uint32, nodeAddress string) (*storage
147185
}
148186

149187
for _, target := range targets {
150-
targetNodeAddress, err := target.GetProperty("NodeAddress")
188+
targetNodeAddress, err := GetISCSITargetNodeAddress(target)
151189
if err != nil {
152190
return nil, fmt.Errorf("failed to query iSCSI target %v. error: %v", target, err)
153191
}
@@ -160,6 +198,21 @@ func QueryISCSITarget(address string, port uint32, nodeAddress string) (*storage
160198
return nil, nil
161199
}
162200

201+
// GetISCSITargetNodeAddress returns the node address of an iSCSI target.
202+
func GetISCSITargetNodeAddress(target *storage.MSFT_iSCSITarget) (string, error) {
203+
nodeAddress, err := target.GetProperty("NodeAddress")
204+
if err != nil {
205+
return "", err
206+
}
207+
208+
return nodeAddress.(string), err
209+
}
210+
211+
// IsISCSITargetConnected returns whether the iSCSI target is connected.
212+
func IsISCSITargetConnected(target *storage.MSFT_iSCSITarget) (bool, error) {
213+
return target.GetPropertyIsConnected()
214+
}
215+
163216
// QueryISCSISessionByTarget retrieves the iSCSI session from the specified iSCSI target
164217
// using MSFT_iSCSITargetToiSCSISession association.
165218
//
@@ -185,6 +238,34 @@ func QueryISCSISessionByTarget(target *storage.MSFT_iSCSITarget) (*storage.MSFT_
185238
return session, err
186239
}
187240

241+
// UnregisterISCSISession unregisters the iSCSI session so that it is no longer persistent.
242+
//
243+
// Refer https://learn.microsoft.com/en-us/previous-versions/windows/desktop/iscsidisc/msft-iscsisession-unregister
244+
// for the WMI method definition.
245+
func UnregisterISCSISession(session *storage.MSFT_iSCSISession) (int, error) {
246+
result, err := session.InvokeMethodWithReturn("Unregister")
247+
return int(result), err
248+
}
249+
250+
// SetISCSISessionChapSecret sets a CHAP secret key for use with iSCSI initiator connections.
251+
//
252+
// Refer https://learn.microsoft.com/en-us/previous-versions/windows/desktop/iscsidisc/msft-iscsitarget-disconnect
253+
// for the WMI method definition.
254+
func SetISCSISessionChapSecret(mutualChapSecret string) (int, error) {
255+
result, _, err := InvokeCimMethod(WMINamespaceStorage, "MSFT_iSCSISession", "SetCHAPSecret", map[string]interface{}{"ChapSecret": mutualChapSecret})
256+
return result, err
257+
}
258+
259+
// GetISCSISessionIdentifier returns the identifier of an iSCSI session.
260+
func GetISCSISessionIdentifier(session *storage.MSFT_iSCSISession) (string, error) {
261+
return session.GetPropertySessionIdentifier()
262+
}
263+
264+
// IsISCSISessionPersistent returns whether an iSCSI session is persistent.
265+
func IsISCSISessionPersistent(session *storage.MSFT_iSCSISession) (bool, error) {
266+
return session.GetPropertyIsPersistent()
267+
}
268+
188269
// ListDisksByTarget find all disks associated with an iSCSITarget.
189270
// It finds out the iSCSIConnections from MSFT_iSCSITargetToiSCSIConnection association,
190271
// then locate MSFT_Disk objects from MSFT_iSCSIConnectionToDisk association.
@@ -238,7 +319,7 @@ func ListDisksByTarget(target *storage.MSFT_iSCSITarget) ([]*storage.MSFT_Disk,
238319
//
239320
// Refer https://learn.microsoft.com/en-us/previous-versions/windows/desktop/iscsidisc/msft-iscsitarget-connect
240321
// 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) {
322+
func ConnectISCSITarget(portalAddress string, portalPortNumber uint32, nodeAddress string, authType string, chapUsername *string, chapSecret *string) (int, error) {
242323
inParams := map[string]interface{}{
243324
"NodeAddress": nodeAddress,
244325
"TargetPortalAddress": portalAddress,
@@ -256,6 +337,15 @@ func ConnectISCSITarget(portalAddress string, portalPortNumber uint32, nodeAddre
256337
inParams["ChapSecret"] = *chapSecret
257338
}
258339

259-
result, outParams, err := InvokeCimMethod(WMINamespaceStorage, "MSFT_iSCSITarget", "Connect", inParams)
260-
return result, outParams, err
340+
result, _, err := InvokeCimMethod(WMINamespaceStorage, "MSFT_iSCSITarget", "Connect", inParams)
341+
return result, err
342+
}
343+
344+
// DisconnectISCSITarget disconnects the specified session between an iSCSI initiator and an iSCSI target.
345+
//
346+
// Refer https://learn.microsoft.com/en-us/previous-versions/windows/desktop/iscsidisc/msft-iscsitarget-disconnect
347+
// for the WMI method definition.
348+
func DisconnectISCSITarget(target *storage.MSFT_iSCSITarget, sessionIdentifier string) (int, error) {
349+
result, err := target.InvokeMethodWithReturn("Disconnect", sessionIdentifier)
350+
return int(result), err
261351
}

pkg/os/iscsi/api.go

Lines changed: 15 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -21,20 +21,6 @@ func New() APIImplementor {
2121
return APIImplementor{}
2222
}
2323

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-
3824
func (APIImplementor) AddTargetPortal(portal *TargetPortal) error {
3925
existing, err := cim.QueryISCSITargetPortal(portal.Address, portal.Port, nil)
4026
if cim.IgnoreNotFound(err) != nil {
@@ -67,26 +53,26 @@ func (APIImplementor) DiscoverTargetPortal(portal *TargetPortal) ([]string, erro
6753

6854
var iqns []string
6955
for _, target := range targets {
70-
iqn, err := target.GetProperty("NodeAddress")
56+
iqn, err := cim.GetISCSITargetNodeAddress(target)
7157
if err != nil {
7258
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)
7359
}
7460

75-
iqns = append(iqns, iqn.(string))
61+
iqns = append(iqns, iqn)
7662
}
7763

7864
return iqns, nil
7965
}
8066

8167
func (APIImplementor) ListTargetPortals() ([]TargetPortal, error) {
82-
instances, err := cim.ListISCSITargetPortals([]string{"TargetPortalAddress", "TargetPortalPortNumber"})
68+
instances, err := cim.ListISCSITargetPortals(cim.ISCSITargetPortalDefaultSelectorList)
8369
if err != nil {
8470
return nil, err
8571
}
8672

8773
var portals []TargetPortal
8874
for _, instance := range instances {
89-
address, port, err := parseTargetPortal(instance)
75+
address, port, err := cim.ParseISCSITargetPortal(instance)
9076
if err != nil {
9177
return nil, fmt.Errorf("failed parsing target portal %v. err: %w", instance, err)
9278
}
@@ -106,19 +92,9 @@ func (APIImplementor) RemoveTargetPortal(portal *TargetPortal) error {
10692
return err
10793
}
10894

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-
)
95+
result, err := cim.RemoveISCSITargetPortal(instance)
12096
if result != 0 || err != nil {
121-
return fmt.Errorf("error removing target portal at (%s:%d). result: %d, err: %w", address, port, result, err)
97+
return fmt.Errorf("error removing target portal at (%s:%d). result: %d, err: %w", portal.Address, portal.Port, result, err)
12298
}
12399

124100
return nil
@@ -131,7 +107,7 @@ func (APIImplementor) ConnectTarget(portal *TargetPortal, iqn string,
131107
return err
132108
}
133109

134-
connected, err := target.GetPropertyIsConnected()
110+
connected, err := cim.IsISCSITargetConnected(target)
135111
if err != nil {
136112
return err
137113
}
@@ -143,7 +119,7 @@ func (APIImplementor) ConnectTarget(portal *TargetPortal, iqn string,
143119

144120
targetAuthType := strings.ToUpper(strings.ReplaceAll(authType, "_", ""))
145121

146-
result, _, err := cim.ConnectISCSITarget(portal.Address, portal.Port, iqn, targetAuthType, &chapUser, &chapSecret)
122+
result, err := cim.ConnectISCSITarget(portal.Address, portal.Port, iqn, targetAuthType, &chapUser, &chapSecret)
147123
if err != nil {
148124
return fmt.Errorf("error connecting to target portal. result: %d, err: %w", result, err)
149125
}
@@ -157,7 +133,7 @@ func (APIImplementor) DisconnectTarget(portal *TargetPortal, iqn string) error {
157133
return err
158134
}
159135

160-
connected, err := target.GetPropertyIsConnected()
136+
connected, err := cim.IsISCSITargetConnected(target)
161137
if err != nil {
162138
return fmt.Errorf("error query connected of target %s from target portal at (%s:%d). err: %w", iqn, portal.Address, portal.Port, err)
163139
}
@@ -173,24 +149,24 @@ func (APIImplementor) DisconnectTarget(portal *TargetPortal, iqn string) error {
173149
return fmt.Errorf("error query session of target %s from target portal at (%s:%d). err: %w", iqn, portal.Address, portal.Port, err)
174150
}
175151

176-
sessionIdentifier, err := session.GetPropertySessionIdentifier()
152+
sessionIdentifier, err := cim.GetISCSISessionIdentifier(session)
177153
if err != nil {
178154
return fmt.Errorf("error query session identifier of target %s from target portal at (%s:%d). err: %w", iqn, portal.Address, portal.Port, err)
179155
}
180156

181-
persistent, err := session.GetPropertyIsPersistent()
157+
persistent, err := cim.IsISCSISessionPersistent(session)
182158
if err != nil {
183159
return fmt.Errorf("error query session persistency of target %s from target portal at (%s:%d). err: %w", iqn, portal.Address, portal.Port, err)
184160
}
185161

186162
if persistent {
187-
result, err := session.InvokeMethodWithReturn("Unregister")
163+
result, err := cim.UnregisterISCSISession(session)
188164
if err != nil {
189165
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)
190166
}
191167
}
192168

193-
result, err := target.InvokeMethodWithReturn("Disconnect", sessionIdentifier)
169+
result, err := cim.DisconnectISCSITarget(target, sessionIdentifier)
194170
if err != nil {
195171
return fmt.Errorf("error disconnecting target %s from target portal at (%s:%d). result: %d, err: %w", iqn, portal.Address, portal.Port, result, err)
196172
}
@@ -204,7 +180,7 @@ func (APIImplementor) GetTargetDisks(portal *TargetPortal, iqn string) ([]string
204180
return nil, err
205181
}
206182

207-
connected, err := target.GetPropertyIsConnected()
183+
connected, err := cim.IsISCSITargetConnected(target)
208184
if err != nil {
209185
return nil, fmt.Errorf("error query connected of target %s from target portal at (%s:%d). err: %w", iqn, portal.Address, portal.Port, err)
210186
}
@@ -232,7 +208,7 @@ func (APIImplementor) GetTargetDisks(portal *TargetPortal, iqn string) ([]string
232208
}
233209

234210
func (APIImplementor) SetMutualChapSecret(mutualChapSecret string) error {
235-
result, _, err := cim.InvokeCimMethod(cim.WMINamespaceStorage, "MSFT_iSCSISession", "SetCHAPSecret", map[string]interface{}{"ChapSecret": mutualChapSecret})
211+
result, err := cim.SetISCSISessionChapSecret(mutualChapSecret)
236212
if err != nil {
237213
return fmt.Errorf("error setting mutual chap secret. result: %d, err: %v", result, err)
238214
}

0 commit comments

Comments
 (0)