Skip to content

Commit b78ee11

Browse files
committed
Use WMI to implement SMB API to reduce PowerShell overhead
1 parent ddd12ba commit b78ee11

File tree

3 files changed

+67
-11
lines changed

3 files changed

+67
-11
lines changed

pkg/cim/smb.go

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
//go:build windows
2+
// +build windows
3+
4+
package cim
5+
6+
import (
7+
"github.com/microsoft/wmi/pkg/base/query"
8+
cim "github.com/microsoft/wmi/pkg/wmiinstance"
9+
)
10+
11+
// QuerySmbGlobalMappingByRemotePath retrieves the SMB global mapping from its remote path.
12+
//
13+
// The equivalent WMI query is:
14+
//
15+
// SELECT [selectors] FROM MSFT_SmbGlobalMapping
16+
//
17+
// Refer to https://pkg.go.dev/github.com/microsoft/wmi/server2019/root/microsoft/windows/smb#MSFT_SmbGlobalMapping
18+
// for the WMI class definition.
19+
func QuerySmbGlobalMappingByRemotePath(remotePath string) (*cim.WmiInstance, error) {
20+
smbQuery := query.NewWmiQuery("MSFT_SmbGlobalMapping", "RemotePath", remotePath)
21+
instances, err := QueryInstances(WMINamespaceSmb, smbQuery)
22+
if err != nil {
23+
return nil, IgnoreNotFound(err)
24+
}
25+
26+
return instances[0], err
27+
}
28+
29+
// RemoveSmbGlobalMappingByRemotePath removes a SMB global mapping matching to the remote path.
30+
//
31+
// Refer to https://pkg.go.dev/github.com/microsoft/wmi/server2019/root/microsoft/windows/smb#MSFT_SmbGlobalMapping
32+
// for the WMI class definition.
33+
func RemoveSmbGlobalMappingByRemotePath(remotePath string) error {
34+
smbQuery := query.NewWmiQuery("MSFT_SmbGlobalMapping", "RemotePath", remotePath)
35+
instances, err := QueryInstances(WMINamespaceSmb, smbQuery)
36+
if err != nil {
37+
return err
38+
}
39+
40+
_, err = instances[0].InvokeMethod("Remove", true)
41+
return err
42+
}

pkg/cim/wmi.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import (
1818
const (
1919
WMINamespaceRoot = "Root\\CimV2"
2020
WMINamespaceStorage = "Root\\Microsoft\\Windows\\Storage"
21+
WMINamespaceSmb = "Root\\Microsoft\\Windows\\Smb"
2122
)
2223

2324
type InstanceHandler func(instance *cim.WmiInstance) (bool, error)

pkg/os/smb/api.go

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"fmt"
55
"strings"
66

7+
"github.com/kubernetes-csi/csi-proxy/pkg/cim"
78
"github.com/kubernetes-csi/csi-proxy/pkg/utils"
89
)
910

@@ -26,17 +27,16 @@ func New(requirePrivacy bool) *SmbAPI {
2627
}
2728
}
2829

30+
func remotePathForQuery(remotePath string) string {
31+
return strings.ReplaceAll(remotePath, "\\", "\\\\")
32+
}
33+
2934
func (*SmbAPI) IsSmbMapped(remotePath string) (bool, error) {
30-
cmdLine := `$(Get-SmbGlobalMapping -RemotePath $Env:smbremotepath -ErrorAction Stop).Status `
31-
cmdEnv := fmt.Sprintf("smbremotepath=%s", remotePath)
32-
out, err := utils.RunPowershellCmd(cmdLine, cmdEnv)
35+
_, err := cim.QuerySmbGlobalMappingByRemotePath(remotePathForQuery(remotePath))
3336
if err != nil {
34-
return false, fmt.Errorf("error checking smb mapping. cmd %s, output: %s, err: %v", remotePath, string(out), err)
37+
return false, err
3538
}
3639

37-
if len(out) == 0 || !strings.EqualFold(strings.TrimSpace(string(out)), "OK") {
38-
return false, nil
39-
}
4040
return true, nil
4141
}
4242

@@ -48,7 +48,6 @@ func (*SmbAPI) IsSmbMapped(remotePath string) (bool, error) {
4848
// alpha to merge the paths.
4949
// TODO (for beta release): Merge the link paths - os.Symlink and Powershell link path.
5050
func (*SmbAPI) NewSmbLink(remotePath, localPath string) error {
51-
5251
if !strings.HasSuffix(remotePath, "\\") {
5352
// Golang has issues resolving paths mapped to file shares if they do not end in a trailing \
5453
// so add one if needed.
@@ -78,12 +77,26 @@ func (api *SmbAPI) NewSmbGlobalMapping(remotePath, username, password string) er
7877
return fmt.Errorf("NewSmbGlobalMapping failed. output: %q, err: %v", string(output), err)
7978
}
8079
return nil
80+
//TODO: move to use WMI when the credentials could be correctly handled
81+
//params := map[string]interface{}{
82+
// "RemotePath": remotePath,
83+
// "RequirePrivacy": api.RequirePrivacy,
84+
//}
85+
//if username != "" {
86+
// params["Credential"] = fmt.Sprintf("%s:%s", username, password)
87+
//}
88+
//result, _, err := cim.InvokeCimMethod(cim.WMINamespaceSmb, "MSFT_SmbGlobalMapping", "Create", params)
89+
//if err != nil {
90+
// return fmt.Errorf("NewSmbGlobalMapping failed. result: %d, err: %v", result, err)
91+
//}
92+
//return nil
8193
}
8294

8395
func (*SmbAPI) RemoveSmbGlobalMapping(remotePath string) error {
84-
cmd := `Remove-SmbGlobalMapping -RemotePath $Env:smbremotepath -Force`
85-
if output, err := utils.RunPowershellCmd(cmd, fmt.Sprintf("smbremotepath=%s", remotePath)); err != nil {
86-
return fmt.Errorf("UnmountSmbShare failed. output: %q, err: %v", string(output), err)
96+
err := cim.RemoveSmbGlobalMappingByRemotePath(remotePathForQuery(remotePath))
97+
if err != nil {
98+
return fmt.Errorf("error remove smb mapping '%s'. err: %v", remotePath, err)
8799
}
100+
88101
return nil
89102
}

0 commit comments

Comments
 (0)