feat(inputs.win_wmi): Add support for remote queries (#14973)
This commit is contained in:
parent
60adc92014
commit
f8905b270a
|
|
@ -19,12 +19,27 @@ See the [CONFIGURATION.md][CONFIGURATION.md] for more details.
|
|||
|
||||
[CONFIGURATION.md]: ../../../docs/CONFIGURATION.md#plugins
|
||||
|
||||
## Secret-store support
|
||||
|
||||
This plugin supports secrets from secret-stores for the `username` and
|
||||
`password` option.
|
||||
See the [secret-store documentation][SECRETSTORE] for more details on how
|
||||
to use them.
|
||||
|
||||
[SECRETSTORE]: ../../../docs/CONFIGURATION.md#secret-store-secrets
|
||||
|
||||
## Configuration
|
||||
|
||||
```toml @sample.conf
|
||||
# Input plugin to query Windows Management Instrumentation
|
||||
# This plugin ONLY supports Windows
|
||||
[[inputs.win_wmi]]
|
||||
## Hostname or IP for remote connections, by default the local machine is queried
|
||||
# host = ""
|
||||
## Credentials for the connection, by default no credentials are used
|
||||
# username = ""
|
||||
# password = ""
|
||||
|
||||
[[inputs.win_wmi.query]]
|
||||
# a string representing the WMI namespace to be queried
|
||||
namespace = "root\\cimv2"
|
||||
|
|
|
|||
|
|
@ -10,7 +10,9 @@ import (
|
|||
|
||||
"github.com/go-ole/go-ole"
|
||||
"github.com/go-ole/go-ole/oleutil"
|
||||
|
||||
"github.com/influxdata/telegraf"
|
||||
"github.com/influxdata/telegraf/config"
|
||||
"github.com/influxdata/telegraf/filter"
|
||||
"github.com/influxdata/telegraf/internal"
|
||||
)
|
||||
|
|
@ -23,11 +25,13 @@ type Query struct {
|
|||
Filter string `toml:"filter"`
|
||||
TagPropertiesInclude []string `toml:"tag_properties"`
|
||||
|
||||
tagFilter filter.Filter
|
||||
query string
|
||||
host string
|
||||
query string
|
||||
connectionParams []interface{}
|
||||
tagFilter filter.Filter
|
||||
}
|
||||
|
||||
func (q *Query) prepare() error {
|
||||
func (q *Query) prepare(host string, username, password config.Secret) error {
|
||||
// Compile the filter
|
||||
f, err := filter.Compile(q.TagPropertiesInclude)
|
||||
if err != nil {
|
||||
|
|
@ -35,6 +39,30 @@ func (q *Query) prepare() error {
|
|||
}
|
||||
q.tagFilter = f
|
||||
|
||||
q.host = host
|
||||
if q.host != "" {
|
||||
q.connectionParams = append(q.connectionParams, q.host)
|
||||
} else {
|
||||
q.connectionParams = append(q.connectionParams, nil)
|
||||
}
|
||||
q.connectionParams = append(q.connectionParams, q.Namespace)
|
||||
if !username.Empty() {
|
||||
u, err := username.Get()
|
||||
if err != nil {
|
||||
return fmt.Errorf("getting username secret failed: %w", err)
|
||||
}
|
||||
q.connectionParams = append(q.connectionParams, u.String())
|
||||
username.Destroy()
|
||||
}
|
||||
if !password.Empty() {
|
||||
p, err := password.Get()
|
||||
if err != nil {
|
||||
return fmt.Errorf("getting password secret failed: %w", err)
|
||||
}
|
||||
q.connectionParams = append(q.connectionParams, p.String())
|
||||
password.Destroy()
|
||||
}
|
||||
|
||||
// Construct the overall query from the given parts
|
||||
wql := fmt.Sprintf("SELECT %s FROM %s", strings.Join(q.Properties, ", "), q.ClassName)
|
||||
if len(q.Filter) > 0 {
|
||||
|
|
@ -78,7 +106,8 @@ func (q *Query) execute(acc telegraf.Accumulator) error {
|
|||
defer wmi.Release()
|
||||
|
||||
// service is a SWbemServices
|
||||
serviceRaw, err := oleutil.CallMethod(wmi, "ConnectServer", nil, q.Namespace)
|
||||
serviceRaw, err := oleutil.CallMethod(wmi, "ConnectServer", q.connectionParams...)
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed calling method ConnectServer: %w", err)
|
||||
}
|
||||
|
|
@ -116,6 +145,10 @@ func (q *Query) execute(acc telegraf.Accumulator) error {
|
|||
func (q *Query) extractProperties(acc telegraf.Accumulator, itemRaw *ole.VARIANT) error {
|
||||
tags, fields := map[string]string{}, map[string]interface{}{}
|
||||
|
||||
if q.host != "" {
|
||||
tags["source"] = q.host
|
||||
}
|
||||
|
||||
item := itemRaw.ToIDispatch()
|
||||
defer item.Release()
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,12 @@
|
|||
# Input plugin to query Windows Management Instrumentation
|
||||
# This plugin ONLY supports Windows
|
||||
[[inputs.win_wmi]]
|
||||
## Hostname or IP for remote connections, by default the local machine is queried
|
||||
# host = ""
|
||||
## Credentials for the connection, by default no credentials are used
|
||||
# username = ""
|
||||
# password = ""
|
||||
|
||||
[[inputs.win_wmi.query]]
|
||||
# a string representing the WMI namespace to be queried
|
||||
namespace = "root\\cimv2"
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import (
|
|||
"sync"
|
||||
|
||||
"github.com/influxdata/telegraf"
|
||||
"github.com/influxdata/telegraf/config"
|
||||
"github.com/influxdata/telegraf/plugins/inputs"
|
||||
)
|
||||
|
||||
|
|
@ -17,8 +18,11 @@ var sampleConfig string
|
|||
|
||||
// Wmi struct
|
||||
type Wmi struct {
|
||||
Queries []Query `toml:"query"`
|
||||
Log telegraf.Logger `toml:"-"`
|
||||
Host string `toml:"host"`
|
||||
Username config.Secret `toml:"username"`
|
||||
Password config.Secret `toml:"password"`
|
||||
Queries []Query `toml:"query"`
|
||||
Log telegraf.Logger `toml:"-"`
|
||||
}
|
||||
|
||||
// S_FALSE is returned by CoInitializeEx if it was already called on this thread.
|
||||
|
|
@ -28,7 +32,7 @@ const sFalse = 0x00000001
|
|||
func (w *Wmi) Init() error {
|
||||
for i := range w.Queries {
|
||||
q := &w.Queries[i]
|
||||
if err := q.prepare(); err != nil {
|
||||
if err := q.prepare(w.Host, w.Username, w.Password); err != nil {
|
||||
return fmt.Errorf("preparing query %q failed: %w", q.ClassName, err)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue