Skip to content

feat(inputs.ldap): Support ldapi protocol - #17478

Merged
skartikey merged 1 commit into
influxdata:masterfrom
mistotebe:ldapi
Nov 13, 2025
Merged

feat(inputs.ldap): Support ldapi protocol#17478
skartikey merged 1 commit into
influxdata:masterfrom
mistotebe:ldapi

Conversation

@mistotebe

@mistotebe mistotebe commented Aug 14, 2025

Copy link
Copy Markdown
Contributor

Summary

Implements #17477 (enabling Unix socket support and EXTERNAL SASL binds)

Checklist

  • No AI generated code was used in this PR

Related issues

based on #17989
resolves #17477

@telegraf-tiger telegraf-tiger Bot added feat Improvement on an existing feature such as adding a new setting/mode to an existing plugin plugin/input 1. Request for new input plugins 2. Issues/PRs that are related to input plugins labels Aug 14, 2025
@mistotebe
mistotebe force-pushed the ldapi branch 5 times, most recently from 0b91794 to fb3f465 Compare August 19, 2025 15:45

@srebhan srebhan left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @mistotebe for your contribution. I think we can simplify the handling of LDAPI and avoid touching the code that much. Furthermore, I think the new bind_mechanism feature should be in its own PR as we want only one feature in a PR...

Comment thread plugins/inputs/ldap/README.md
Comment thread plugins/inputs/ldap/ldap.go
Comment thread plugins/inputs/ldap/ldap.go Outdated
Comment thread plugins/inputs/ldap/ldap.go
Comment thread plugins/inputs/ldap/ldap.go Outdated
Comment thread plugins/inputs/ldap/openldap.go Outdated
@srebhan srebhan self-assigned this Aug 28, 2025
@srebhan srebhan added the waiting for response waiting for response from contributor label Sep 1, 2025
@telegraf-tiger

Copy link
Copy Markdown
Contributor

Hello! I am closing this issue due to inactivity. I hope you were able to resolve your problem, if not please try posting this question in our Community Slack or Community Forums or provide additional details in this issue and reqeust that it be re-opened. Thank you!

@telegraf-tiger telegraf-tiger Bot closed this Sep 15, 2025
@srebhan srebhan reopened this Oct 8, 2025
@srebhan

srebhan commented Oct 8, 2025

Copy link
Copy Markdown
Member

Sorry @mistotebe for closing the PR due to inactivity. I added a comment above. However, this PR does many different things and IMO changes the code structure without an actual need. Please try to be as less intrusive as possible. If you need to change the code structure, please do this in a first PR so that each PR only does one thing!

@telegraf-tiger telegraf-tiger Bot removed the waiting for response waiting for response from contributor label Oct 8, 2025
@srebhan

srebhan commented Oct 23, 2025

Copy link
Copy Markdown
Member

So my approach would be

diff --git a/plugins/inputs/ldap/ldap.go b/plugins/inputs/ldap/ldap.go
index 7a69871ca..164ac98b7 100644
--- a/plugins/inputs/ldap/ldap.go
+++ b/plugins/inputs/ldap/ldap.go
@@ -7,6 +7,7 @@ import (
        _ "embed"
        "fmt"
        "net/url"
+       "strings"
        "time"
 
        "github.com/go-ldap/ldap/v3"
@@ -49,6 +50,20 @@ func (l *LDAP) Init() error {
                l.Server = "ldap://localhost:389"
        }
 
+       // Handle LDAPI which contains the unix sockets in percent encoded form, so we need to
+       // unescape the path to allow the LDAP library to handle the server using the url package
+       if addr, isLdapi := strings.CutPrefix(l.Server, "ldapi://"); isLdapi {
+               path, rest, found := strings.Cut(addr, "/")
+               if found {
+                       return fmt.Errorf("additional elements %q are not supported by this plugin", rest)
+               }
+               path, err := url.PathUnescape(path)
+               if err != nil {
+                       return fmt.Errorf("parsing escaped path %q failed: %w", path, err)
+               }
+               l.Server = "ldapi://" + path
+       }
+
        u, err := url.Parse(l.Server)
        if err != nil {
                return fmt.Errorf("parsing server failed: %w", err)
@@ -72,6 +87,8 @@ func (l *LDAP) Init() error {
                        u.Host = u.Host + ":636"
                }
                tlsEnable = true
+       case "ldapi":
+               u.Host = u.Path
        default:
                return fmt.Errorf("invalid scheme: %q", u.Scheme)
        }
@@ -131,9 +148,9 @@ func (l *LDAP) Gather(acc telegraf.Accumulator) error {
 func (l *LDAP) connect() (*ldap.Conn, error) {
        var conn *ldap.Conn
        switch l.mode {
-       case "ldap":
+       case "ldap", "ldapi":
                var err error
-               conn, err = ldap.DialURL("ldap://" + l.Server)
+               conn, err = ldap.DialURL(l.mode + "://" + l.Server)
                if err != nil {
                        return nil, err
                }

with the unit-test

func TestLdapiURLHandling(t *testing.T) {
	// Setup the plugin
	plugin := &LDAP{
		Server: "ldapi://%2ftmp%2fsocket",
	}
	require.NoError(t, plugin.Init())

	// Test the resulting setting
	require.Equal(t, "/tmp/socket", plugin.Server)
	require.Equal(t, "/tmp/socket", plugin.host)
	require.Empty(t, plugin.port)
}

As you can see this is much less-intrusive...

@srebhan srebhan added the waiting for response waiting for response from contributor label Nov 3, 2025
@mistotebe
mistotebe force-pushed the ldapi branch 3 times, most recently from f7caa34 to 14e61a9 Compare November 10, 2025 17:55
@mistotebe mistotebe changed the title feat(inputs.ldap): Allow ldapi:// URI scheme, EXTERNAL SASL Bind (#17477) Nov 10, 2025

@srebhan srebhan left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just two small comments left @mistotebe...

Comment thread plugins/inputs/ldap/ldap.go Outdated
}
tlsEnable = false
case "ldapi":
tlsEnable = false

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't need to be set to false as this is the default in Golang.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I kept the structure identical with the original switch (e.g. "ldap" case also sets tlsEnable = false) is that not desired?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm OK with keeping it as it is also done for ldap but we really shouldn't. Anyway, that's probably for another PR to remove both.

Comment thread plugins/inputs/ldap/README.md Outdated
Comment on lines +89 to +96
- uri -- configured server URI
- server -- Server name or IP
- port -- Port used for connecting

Or with the ldapi scheme:

- uri -- configured server URI
- path -- Path used to connect

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about

Suggested change
- uri -- configured server URI
- server -- Server name or IP
- port -- Port used for connecting
Or with the ldapi scheme:
- uri -- configured server URI
- path -- Path used to connect
- uri -- configured server URI
- server -- Server name or IP (for non Unix socket)
- port -- Port used for connecting (for non Unix socket)
- path -- Path used to connect (for Unix socket)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How do we get hold of the host name if I wanted to put it in (unless I just put "localhost" in?). Also there is still no port in UNIX sockets, I could make it an empty string if that's what you prefer to it being absent.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But if you prefer it has a value, then shouldn't "path" now have a value in the TCP case? Don't have any strong feelings either way, just trying to gauge what to put where.

@srebhan srebhan Nov 11, 2025

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you read what's in the brackets after the text? ;-)

I'm just putting the "condition" in brackets after the tag instead of splitting everything into sections as you did.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did but the reds and greens confused me and so I misread the intent, sorry, I'll update the doc.

@srebhan srebhan removed the waiting for response waiting for response from contributor label Nov 10, 2025
@mistotebe
mistotebe force-pushed the ldapi branch 2 times, most recently from 29e8c65 to 26afe3c Compare November 11, 2025 10:39
@srebhan

srebhan commented Nov 11, 2025

Copy link
Copy Markdown
Member

@mistotebe please revert 448d556 as this again is intrusive and has nothing to do with the PR title. If you want to cleanup the stuff, do it in a separate PR!

ONE PR ONE THING!

@mistotebe

Copy link
Copy Markdown
Contributor Author

@mistotebe please revert 448d556 as this again is intrusive and has nothing to do with the PR title. If you want to cleanup the stuff, do it in a separate PR!

The current structure is spaghetti and adding LDAPI support without addressing that would make the code even harder to understand, I tried and you can too if you don't believe me. If it really is project policy not to include required cleanup in feature PRs, let me know and I will submit it as a separate one.

@mistotebe

mistotebe commented Nov 11, 2025

Copy link
Copy Markdown
Contributor Author

There are 3 patches currently:

  • exposing the connection URI, if you believe it is unrelated/doesn't add value, we can probably synthesize it back from the other tags so I can drop it altogether or submit as a separate PR
  • the patch I marked 'chore' (now that I double checked your docs it has been retagged to 'refactor') is cleanup that the last:
  • LDAPI support patch cannot reasonably live without, at least as far as I've tried

The alternative is to squash the last two commits together but that goes against every practice of drafting patch series for review/inclusion I've seen so far. Again you're the maintainer, so your rules, however since I'm starting to feel I'm not following them at all yet we seem to agree on the rough shape of the final code(?), please outline a path for me to where you're willing to accept a patch(set) that gets there and I'll follow it or state that no such path exists.

@srebhan

srebhan commented Nov 11, 2025

Copy link
Copy Markdown
Member

@mistotebe don't get me wrong I'm not saying you cannot change the code, but you cannot modify code in a PR that is unrelated to that PR. If you need to cleanup code before adding a new feature then this should go to a separate PR!
Furthermore, you cannot change existing metrics!

Let me reply in detail

  • exposing the connection URI, if you believe it is unrelated/doesn't add value, we can probably synthesize it back from the other tags so I can drop it altogether or submit as a separate PR

This modifies existing metrics and is a no-go.

  • the patch I marked 'chore' (now that I double checked your docs it has been retagged to 'refactor') is cleanup that the last:

Exactly, you should add a chore PR to refactor the code. But I don't think this is necessary. You could directly store the tags related to the connection in the LDAP structure and avoid any iffery in the dialects and keep the rest of the code as-is!

Furthermore, your current patch is very intrusive, e.g. by changing the starttls protocol handling! There must be a clear reason why this is done and this should go to an own PR to be able to find this change and to be able to revert this change if necessary.

  • LDAPI support patch cannot reasonably live without, at least as far as I've tried

I really don't see this! At #17478 (review) we were in a state where you only would need to change the documentation and remove the uri tag to get an approval from my side but then decided to re-introduce bigger code changes...

The alternative is to squash the last two commits together but that goes against every practice of drafting patch series for review/inclusion I've seen so far. Again you're the maintainer, so your rules, however since I'm starting to feel I'm not following them at all yet we seem to agree on the rough shape of the final code(?), please outline a path for me to where you're willing to accept a patch(set) that gets there and I'll follow it or state that no such path exists.

My suggestion for a path forward is to revert to commit 14e61a9, remove the uri tag and apply my documentation suggestion.
If you want to, but that's not a must, you can store the tags with the host/port or path in the LDAP struct instead of constructing them in the dialects to get rid of the special ldapi handling there. But that's not a must.

@mistotebe

Copy link
Copy Markdown
Contributor Author

I really don't see this! At #17478 (review) we were in a state where you only would need to change the documentation and remove the uri tag to get an approval from my side but then decided to re-introduce bigger code changes...

Now I'm confused, so let me talk about one thing at a time, starting with the one that really does it for me:

To the best of my understanding, the above state you're referencing is the PR at commit 14e61a9 (2 hours before your review) which contains all the changes you also say are unacceptable? Am I missing something or are you referring to another message but put the wrong link?

@mistotebe

Copy link
Copy Markdown
Contributor Author

Part two:

@mistotebe don't get me wrong I'm not saying you cannot change the code, but you cannot modify code in a PR that is unrelated to that PR. If you need to cleanup code before adding a new feature then this should go to a separate PR! Furthermore, you cannot change existing metrics!

Ok, that no metrics can even have new tags added to them is new to me and not clear from the documentation at all. I guess I'm OK to drop this completely, we are able to synthesise this tag in our own deployments from the data already exposed (except the actual protocol but that's a decision that can be baked into the processing at deployment time).

  • the patch I marked 'chore' (now that I double checked your docs it has been retagged to 'refactor') is cleanup that the last:

Exactly, you should add a chore PR to refactor the code. But I don't think this is necessary. You could directly store the tags related to the connection in the LDAP structure and avoid any iffery in the dialects and keep the rest of the code as-is!

Hmm, you previously rejected me doing the very same thing in this conversation... I mean it makes more sense to set them up in Init(), but that's a refactor/chore commit now?

Furthermore, your current patch is very intrusive, e.g. by changing the starttls protocol handling! There must be a clear reason why this is done and this should go to an own PR to be able to find this change and to be able to revert this change if necessary.

The point is it does nothing of the sort. It makes the intention clear (first connect over the right protocol, then set up TLS if requested and not already a layer that's set up as part of the protocol) without undue duplication and escaping things properly where needed (i.e. not just doing text manipulation to get a URL)?

Since adding a new 'URI' tag is a no-go, I'm preparing a minimal patch that never has to deal with an actual URI, so it touch as little of the existing code as possible. Once go-ldap/ldap#564 is resolved and the module accepts the correct form, to finally support all possible ldapi:// URLs (relative paths are not connectable at the moment) you will probably do exactly as I did until now.

mistotebe added a commit to mistotebe/telegraf that referenced this pull request Nov 11, 2025
@mistotebe
mistotebe marked this pull request as draft November 11, 2025 15:48
@mistotebe

Copy link
Copy Markdown
Contributor Author

I've done the minimal possible implementation now, removing everything else that I could, aiming for the smallest (textual) diff.

Since it depends on (and includes a commit from) #17989, switching state to Draft to avoid conflicts/accidental merges.

@srebhan srebhan left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mistotebe this looks very good to me. I maybe would have set the l.tags in the switch statement but I'm fine doing it this way.

Can you please move the PR out of draft so I can approve it!?

And sorry for the confusion around the tags! It came from my impression to use the server tag also for the ldapi part but having this in an extra tag makes a lot of sense!

@mistotebe

Copy link
Copy Markdown
Contributor Author

@mistotebe this looks very good to me. I maybe would have set the l.tags in the switch statement but I'm fine doing it this way.

Can you please move the PR out of draft so I can approve it!?

This one is draft because #17989 needs to happen first right?

@srebhan

srebhan commented Nov 12, 2025

Copy link
Copy Markdown
Member

Yes we should get #17989 in first...

@telegraf-tiger

Copy link
Copy Markdown
Contributor
@mistotebe
mistotebe marked this pull request as ready for review November 13, 2025 10:46
@srebhan srebhan changed the title feat(inputs.ldap): Allow ldapi:// URI scheme (#17477) Nov 13, 2025

@srebhan srebhan left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you very much @mistotebe for keeping this going!

@srebhan srebhan added the ready for final review This pull request has been reviewed and/or tested by multiple users and is ready for a final review. label Nov 13, 2025
@srebhan srebhan assigned skartikey and mstrandboge and unassigned srebhan Nov 13, 2025

@skartikey skartikey left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice work on this PR, @mistotebe!
This is a clean and well-thought-out implementation.

@skartikey
skartikey merged commit 33cfc34 into influxdata:master Nov 13, 2025
31 checks passed
@github-actions github-actions Bot added this to the v1.37.0 milestone Nov 13, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feat Improvement on an existing feature such as adding a new setting/mode to an existing plugin plugin/input 1. Request for new input plugins 2. Issues/PRs that are related to input plugins ready for final review This pull request has been reviewed and/or tested by multiple users and is ready for a final review.

4 participants