Skip to content

Commit

Permalink
Merge pull request #772 from c88888/ldap
Browse files Browse the repository at this point in the history
Add LDAP input plugin supporting OpenLDAP and 389ds
  • Loading branch information
kongfei605 committed Jan 26, 2024
2 parents ff41972 + b8936fd commit 9ab360a
Show file tree
Hide file tree
Showing 6 changed files with 566 additions and 0 deletions.
1 change: 1 addition & 0 deletions agent/metrics_agent.go
Expand Up @@ -43,6 +43,7 @@ import (
_ "flashcat.cloud/categraf/inputs/kernel"
_ "flashcat.cloud/categraf/inputs/kernel_vmstat"
_ "flashcat.cloud/categraf/inputs/kubernetes"
_ "flashcat.cloud/categraf/inputs/ldap"
_ "flashcat.cloud/categraf/inputs/linux_sysctl_fs"
_ "flashcat.cloud/categraf/inputs/logstash"
_ "flashcat.cloud/categraf/inputs/mem"
Expand Down
37 changes: 37 additions & 0 deletions conf/input.ldap/ldap.toml
@@ -0,0 +1,37 @@
# # collect interval
# interval = 15

[[instances]]
# # append some labels for series
# labels = { region="cloud", product="n9e" }

# # interval = global.interval * interval_times
# interval_times = 1

## Server to monitor
## The scheme determines the mode to use for connection with
## ldap://... -- unencrypted (non-TLS) connection
## ldaps://... -- TLS connection
## starttls://... -- StartTLS connection
## If no port is given, the default ports, 389 for ldap and starttls and
## 636 for ldaps, are used.
#server = "ldap://localhost"

## Server dialect, can be "openldap" or "389ds"
# dialect = "openldap"

# DN and password to bind with
## If bind_dn is empty an anonymous bind is performed.
bind_dn = ""
bind_password = ""

## Reverse the field names constructed from the monitoring DN
# reverse_field_names = false

## Optional TLS Config
# use_tls = false
# tls_ca = "/etc/categraf/ca.pem"
# tls_cert = "/etc/categraf/cert.pem"
# tls_key = "/etc/categraf/key.pem"
## Use TLS but skip chain & host verification
# insecure_skip_verify = false
115 changes: 115 additions & 0 deletions inputs/ldap/389ds.go
@@ -0,0 +1,115 @@
package ldap

import (
"strconv"
"strings"
"time"

"github.com/go-ldap/ldap/v3"

"flashcat.cloud/categraf/types"
"flashcat.cloud/categraf/types/metric"
)

// Empty mappings are identity mappings
var attrMap389ds = map[string]string{
"addentryops": "add_operations",
"anonymousbinds": "anonymous_binds",
"bindsecurityerrors": "bind_security_errors",
"bytesrecv": "bytes_received",
"bytessent": "bytes_sent",
"cacheentries": "cache_entries",
"cachehits": "cache_hits",
"chainings": "",
"compareops": "compare_operations",
"connections": "",
"connectionsinmaxthreads": "connections_in_max_threads",
"connectionsmaxthreadscount": "connections_max_threads",
"copyentries": "copy_entries",
"currentconnections": "current_connections",
"currentconnectionsatmaxthreads": "current_connections_at_max_threads",
"dtablesize": "",
"entriesreturned": "entries_returned",
"entriessent": "entries_sent",
"errors": "",
"inops": "in_operations",
"listops": "list_operations",
"removeentryops": "delete_operations",
"masterentries": "master_entries",
"maxthreadsperconnhits": "maxthreads_per_conn_hits",
"modifyentryops": "modify_operations",
"modifyrdnops": "modrdn_operations",
"nbackends": "backends",
"onelevelsearchops": "onelevel_search_operations",
"opscompleted": "operations_completed",
"opsinitiated": "operations_initiated",
"readops": "read_operations",
"readwaiters": "read_waiters",
"referrals": "referrals",
"referralsreturned": "referrals_returned",
"searchops": "search_operations",
"securityerrors": "security_errors",
"simpleauthbinds": "simpleauth_binds",
"slavehits": "slave_hits",
"strongauthbinds": "strongauth_binds",
"threads": "",
"totalconnections": "total_connections",
"unauthbinds": "unauth_binds",
"wholesubtreesearchops": "wholesubtree_search_operations",
}

func (ins *Instance) new389dsConfig() []request {
attributes := make([]string, 0, len(attrMap389ds))
for k := range attrMap389ds {
attributes = append(attributes, k)
}

req := ldap.NewSearchRequest(
"cn=Monitor",
ldap.ScopeWholeSubtree,
ldap.NeverDerefAliases,
0,
0,
false,
"(objectClass=*)",
attributes,
nil,
)
return []request{{req, ins.convert389ds}}
}

func (ins *Instance) convert389ds(result *ldap.SearchResult, ts time.Time) []types.Metric {
tags := map[string]string{
"server": ins.host,
"port": ins.port,
}
fields := make(map[string]interface{})
for _, entry := range result.Entries {
for _, attr := range entry.Attributes {
if len(attr.Values[0]) == 0 {
continue
}
// Map the attribute-name to the field-name
name := attrMap389ds[attr.Name]
if name == "" {
name = attr.Name
}
// Reverse the name if requested
if ins.ReverseFieldNames {
parts := strings.Split(name, "_")
for i, j := 0, len(parts)-1; i < j; i, j = i+1, j-1 {
parts[i], parts[j] = parts[j], parts[i]
}
name = strings.Join(parts, "_")
}

// Convert the number
if v, err := strconv.ParseInt(attr.Values[0], 10, 64); err == nil {
fields[name] = v
}
}
}

m := metric.New("389ds", tags, fields, ts)
return []types.Metric{m}
}
114 changes: 114 additions & 0 deletions inputs/ldap/README.md
@@ -0,0 +1,114 @@
# LDAP Input Plugin

This plugin gathers metrics from LDAP servers' monitoring (`cn=Monitor`)
backend. Currently this plugin supports [OpenLDAP](https://www.openldap.org/)
and [389ds](https://www.port389.org/) servers.

To use this plugin you must enable the monitoring backend/plugin of your LDAP
server. See
[OpenLDAP](https://www.openldap.org/devel/admin/monitoringslapd.html) or 389ds
documentation for details.

## Metrics

Depending on the server dialect, different metrics are produced. The metrics
are usually named according to the selected dialect.

### Tags

- server -- Server name or IP
- port -- Port used for connecting

## Example Output

Using the `openldap` dialect

```text
openldap_modify_operations_completed agent_hostname=zy-fat port=389 server=localhost 0
openldap_referrals_statistics agent_hostname=zy-fat port=389 server=localhost 0
openldap_unbind_operations_initiated agent_hostname=zy-fat port=389 server=localhost 0
openldap_delete_operations_completed agent_hostname=zy-fat port=389 server=localhost 0
openldap_extended_operations_completed agent_hostname=zy-fat port=389 server=localhost 0
openldap_pdu_statistics agent_hostname=zy-fat port=389 server=localhost 42
openldap_starting_threads agent_hostname=zy-fat port=389 server=localhost 0
openldap_active_threads agent_hostname=zy-fat port=389 server=localhost 1
openldap_uptime_time agent_hostname=zy-fat port=389 server=localhost 102
openldap_bytes_statistics agent_hostname=zy-fat port=389 server=localhost 3176
openldap_compare_operations_completed agent_hostname=zy-fat port=389 server=localhost 0
openldap_bind_operations_completed agent_hostname=zy-fat port=389 server=localhost 1
openldap_total_connections agent_hostname=zy-fat port=389 server=localhost 1002
openldap_search_operations_completed agent_hostname=zy-fat port=389 server=localhost 1
openldap_abandon_operations_initiated agent_hostname=zy-fat port=389 server=localhost 0
openldap_add_operations_initiated agent_hostname=zy-fat port=389 server=localhost 0
openldap_open_threads agent_hostname=zy-fat port=389 server=localhost 1
openldap_add_operations_completed agent_hostname=zy-fat port=389 server=localhost 0
openldap_operations_initiated agent_hostname=zy-fat port=389 server=localhost 3
openldap_write_waiters agent_hostname=zy-fat port=389 server=localhost 0
openldap_entries_statistics agent_hostname=zy-fat port=389 server=localhost 41
openldap_modrdn_operations_completed agent_hostname=zy-fat port=389 server=localhost 0
openldap_pending_threads agent_hostname=zy-fat port=389 server=localhost 0
openldap_max_pending_threads agent_hostname=zy-fat port=389 server=localhost 0
openldap_bind_operations_initiated agent_hostname=zy-fat port=389 server=localhost 1
openldap_max_file_descriptors_connections agent_hostname=zy-fat port=389 server=localhost 1024
openldap_compare_operations_initiated agent_hostname=zy-fat port=389 server=localhost 0
openldap_search_operations_initiated agent_hostname=zy-fat port=389 server=localhost 2
openldap_modrdn_operations_initiated agent_hostname=zy-fat port=389 server=localhost 0
openldap_read_waiters agent_hostname=zy-fat port=389 server=localhost 1
openldap_backload_threads agent_hostname=zy-fat port=389 server=localhost 1
openldap_current_connections agent_hostname=zy-fat port=389 server=localhost 1
openldap_unbind_operations_completed agent_hostname=zy-fat port=389 server=localhost 0
openldap_delete_operations_initiated agent_hostname=zy-fat port=389 server=localhost 0
openldap_extended_operations_initiated agent_hostname=zy-fat port=389 server=localhost 0
openldap_modify_operations_initiated agent_hostname=zy-fat port=389 server=localhost 0
openldap_max_threads agent_hostname=zy-fat port=389 server=localhost 16
openldap_abandon_operations_completed agent_hostname=zy-fat port=389 server=localhost 0
openldap_operations_completed agent_hostname=zy-fat port=389 server=localhost 2
openldap_database_2_databases agent_hostname=zy-fat port=389 server=localhost 0
```

Using the `389ds` dialect

```text
389ds_current_connections_at_max_threads agent_hostname=zy-fat port=389 server=localhost 0
389ds_connections_max_threads agent_hostname=zy-fat port=389 server=localhost 0
389ds_add_operations agent_hostname=zy-fat port=389 server=localhost 0
389ds_dtablesize agent_hostname=zy-fat port=389 server=localhost 63936
389ds_strongauth_binds agent_hostname=zy-fat port=389 server=localhost 13
389ds_modrdn_operations agent_hostname=zy-fat port=389 server=localhost 0
389ds_maxthreads_per_conn_hits agent_hostname=zy-fat port=389 server=localhost 0
389ds_current_connections agent_hostname=zy-fat port=389 server=localhost 2
389ds_security_errors agent_hostname=zy-fat port=389 server=localhost 0
389ds_entries_sent agent_hostname=zy-fat port=389 server=localhost 13
389ds_cache_entries agent_hostname=zy-fat port=389 server=localhost 0
389ds_backends agent_hostname=zy-fat port=389 server=localhost 0
389ds_threads agent_hostname=zy-fat port=389 server=localhost 17
389ds_connections agent_hostname=zy-fat port=389 server=localhost 2
389ds_read_operations agent_hostname=zy-fat port=389 server=localhost 0
389ds_entries_returned agent_hostname=zy-fat port=389 server=localhost 13
389ds_unauth_binds agent_hostname=zy-fat port=389 server=localhost 0
389ds_search_operations agent_hostname=zy-fat port=389 server=localhost 14
389ds_simpleauth_binds agent_hostname=zy-fat port=389 server=localhost 0
389ds_operations_completed agent_hostname=zy-fat port=389 server=localhost 51
389ds_connections_in_max_threads agent_hostname=zy-fat port=389 server=localhost 0
389ds_modify_operations agent_hostname=zy-fat port=389 server=localhost 0
389ds_wholesubtree_search_operations agent_hostname=zy-fat port=389 server=localhost 1
389ds_read_waiters agent_hostname=zy-fat port=389 server=localhost 0
389ds_compare_operations agent_hostname=zy-fat port=389 server=localhost 0
389ds_errors agent_hostname=zy-fat port=389 server=localhost 13
389ds_in_operations agent_hostname=zy-fat port=389 server=localhost 52
389ds_total_connections agent_hostname=zy-fat port=389 server=localhost 15
389ds_cache_hits agent_hostname=zy-fat port=389 server=localhost 0
389ds_list_operations agent_hostname=zy-fat port=389 server=localhost 0
389ds_referrals_returned agent_hostname=zy-fat port=389 server=localhost 0
389ds_copy_entries agent_hostname=zy-fat port=389 server=localhost 0
389ds_operations_initiated agent_hostname=zy-fat port=389 server=localhost 52
389ds_chainings agent_hostname=zy-fat port=389 server=localhost 0
389ds_bind_security_errors agent_hostname=zy-fat port=389 server=localhost 0
389ds_onelevel_search_operations agent_hostname=zy-fat port=389 server=localhost 0
389ds_bytes_sent agent_hostname=zy-fat port=389 server=localhost 1702
389ds_bytes_received agent_hostname=zy-fat port=389 server=localhost 0
389ds_referrals agent_hostname=zy-fat port=389 server=localhost 0
389ds_delete_operations agent_hostname=zy-fat port=389 server=localhost 0
389ds_anonymous_binds agent_hostname=zy-fat port=389 server=localhost 0
```

0 comments on commit 9ab360a

Please sign in to comment.