Skip to content

Commit fd53815

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

File tree

2 files changed

+108
-43
lines changed

2 files changed

+108
-43
lines changed

pkg/cim/iscsi.go

Lines changed: 93 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,39 @@ func NewISCSITargetPortal(targetPortalAddress string,
102106
return QueryISCSITargetPortal(targetPortalAddress, targetPortalPortNumber, nil)
103107
}
104108

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

149186
for _, target := range targets {
150-
targetNodeAddress, err := target.GetProperty("NodeAddress")
187+
targetNodeAddress, err := GetISCSITargetNodeAddress(target)
151188
if err != nil {
152189
return nil, fmt.Errorf("failed to query iSCSI target %v. error: %v", target, err)
153190
}
@@ -160,6 +197,21 @@ func QueryISCSITarget(address string, port uint32, nodeAddress string) (*storage
160197
return nil, nil
161198
}
162199

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

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

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

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)