Skip to content

Commit

Permalink
Openldap module support (#2117)
Browse files Browse the repository at this point in the history
* Initial work on the openldap module

* chore: run make lint

* chore: run mod tidy

* Adding LoadLdif

* chore: run mod tidy

* Running go mod tidy

* Adding WithInitialLdif

---------

Co-authored-by: Manuel de la Peña <mdelapenya@gmail.com>
  • Loading branch information
jespino and mdelapenya authored Jan 26, 2024
1 parent 35d28e3 commit 8438da6
Show file tree
Hide file tree
Showing 12 changed files with 850 additions and 2 deletions.
7 changes: 7 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,13 @@ updates:
day: sunday
open-pull-requests-limit: 3
rebase-strategy: disabled
- package-ecosystem: gomod
directory: /modules/openldap
schedule:
interval: monthly
day: sunday
open-pull-requests-limit: 3
rebase-strategy: disabled
- package-ecosystem: gomod
directory: /modules/postgres
schedule:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ jobs:
matrix:
go-version: [1.20.x, 1.x]
platform: [ubuntu-latest, macos-latest]
module: [artemis, cassandra, clickhouse, compose, couchbase, elasticsearch, gcloud, inbucket, k3s, k6, kafka, localstack, mariadb, minio, mockserver, mongodb, mssql, mysql, nats, neo4j, postgres, pulsar, rabbitmq, redis, redpanda, vault]
module: [artemis, cassandra, clickhouse, compose, couchbase, elasticsearch, gcloud, inbucket, k3s, k6, kafka, localstack, mariadb, minio, mockserver, mongodb, mssql, mysql, nats, neo4j, openldap, postgres, pulsar, rabbitmq, redis, redpanda, vault]
exclude:
- go-version: 1.20.x
module: compose
Expand Down
4 changes: 4 additions & 0 deletions .vscode/.testcontainers-go.code-workspace
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,10 @@
"name": "module / neo4j",
"path": "../modules/neo4j"
},
{
"name": "module / openldap",
"path": "../modules/openldap"
},
{
"name": "module / postgres",
"path": "../modules/postgres"
Expand Down
69 changes: 69 additions & 0 deletions docs/modules/openldap.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# OpenLDAP

Not available until the next release of testcontainers-go <a href="https://github.com/testcontainers/testcontainers-go"><span class="tc-version">:material-tag: main</span></a>

## Introduction

The Testcontainers module for OpenLDAP.

## Adding this module to your project dependencies

Please run the following command to add the OpenLDAP module to your Go dependencies:

```
go get github.com/testcontainers/testcontainers-go/modules/openldap
```

## Usage example

<!--codeinclude-->
[Creating a OpenLDAP container](../../modules/openldap/examples_test.go) inside_block:runOpenLDAPContainer
<!--/codeinclude-->

## Module reference

The OpenLDAP module exposes one entrypoint function to create the OpenLDAP container, and this function receives two parameters:

```golang
func RunContainer(ctx context.Context, opts ...testcontainers.ContainerCustomizer) (*OpenLDAPContainer, error)
```

- `context.Context`, the Go context.
- `testcontainers.ContainerCustomizer`, a variadic argument for passing options.

### Container Options

When starting the OpenLDAP container, you can pass options in a variadic way to configure it.

#### Image

If you need to set a different OpenLDAP Docker image, you can use `testcontainers.WithImage` with a valid Docker image
for OpenLDAP. E.g. `testcontainers.WithImage("bitnami/openldap:2.6.6")`.

{% include "../features/common_functional_options.md" %}

### Container Methods

The OpenLDAP container exposes the following methods:

#### ConnectionString

This method returns the connection string to connect to the OpenLDAP container, using the `1389` port.

<!--codeinclude-->
[Get connection string](../../modules/openldap/openldap_test.go) inside_block:connectionString
<!--/codeinclude-->

#### LoadLdif

This method loads an ldif file in the OpenLDAP server.
It returns and error if there is any problem with the ldif file loading process.

<!--codeinclude-->
[Load ldif](../../modules/openldap/openldap_test.go) inside_block:loadLdif
<!--/codeinclude-->

#### Initial Ldif

If you would like to load an ldif at the initialization of the openldap container, you can use `WithInititialLdif` function.
The file will be copied after the container is started and loaded in openldap.
1 change: 1 addition & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ nav:
- modules/mysql.md
- modules/nats.md
- modules/neo4j.md
- modules/openldap.md
- modules/postgres.md
- modules/pulsar.md
- modules/rabbitmq.md
Expand Down
5 changes: 5 additions & 0 deletions modules/openldap/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
include ../../commons-test.mk

.PHONY: test
test:
$(MAKE) test-openldap
96 changes: 96 additions & 0 deletions modules/openldap/examples_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
package openldap_test

import (
"context"
"fmt"

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

"github.com/testcontainers/testcontainers-go"
"github.com/testcontainers/testcontainers-go/modules/openldap"
)

func ExampleRunContainer() {
// runOpenLDAPContainer {
ctx := context.Background()

openldapContainer, err := openldap.RunContainer(ctx, testcontainers.WithImage("bitnami/openldap:2.6.6"))
if err != nil {
panic(err)
}

// Clean up the container
defer func() {
if err := openldapContainer.Terminate(ctx); err != nil {
panic(err)
}
}()
// }

state, err := openldapContainer.State(ctx)
if err != nil {
panic(err)
}

fmt.Println(state.Running)

// Output:
// true
}

func ExampleRunContainer_connect() {
// connectToOpenLdap {
ctx := context.Background()

openldapContainer, err := openldap.RunContainer(ctx, testcontainers.WithImage("bitnami/openldap:2.6.6"))
if err != nil {
panic(err)
}

// Clean up the container
defer func() {
if err := openldapContainer.Terminate(ctx); err != nil {
panic(err)
}
}()

connectionString, err := openldapContainer.ConnectionString(ctx)
if err != nil {
panic(err)
}

client, err := ldap.DialURL(connectionString)
if err != nil {
panic(err)
}
defer client.Close()

// First bind with a read only user
err = client.Bind("cn=admin,dc=example,dc=org", "adminpassword")
if err != nil {
panic(err)
}

// Search for the given username
searchRequest := ldap.NewSearchRequest(
"dc=example,dc=org",
ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false,
"(&(objectClass=organizationalPerson)(uid=user01))",
[]string{"dn"},
nil,
)

sr, err := client.Search(searchRequest)
if err != nil {
panic(err)
}

if len(sr.Entries) != 1 {
panic("User does not exist or too many entries returned")
}

fmt.Println(sr.Entries[0].DN)

// Output:
// cn=user01,ou=users,dc=example,dc=org
}
64 changes: 64 additions & 0 deletions modules/openldap/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
module github.com/testcontainers/testcontainers-go/modules/openldap

go 1.20

require (
github.com/go-ldap/ldap/v3 v3.4.6
github.com/testcontainers/testcontainers-go v0.27.0
)

require (
dario.cat/mergo v1.0.0 // indirect
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 // indirect
github.com/Microsoft/go-winio v0.6.1 // indirect
github.com/Microsoft/hcsshim v0.11.4 // indirect
github.com/cenkalti/backoff/v4 v4.2.1 // indirect
github.com/containerd/containerd v1.7.12 // indirect
github.com/containerd/log v0.1.0 // indirect
github.com/cpuguy83/dockercfg v0.3.1 // indirect
github.com/distribution/reference v0.5.0 // indirect
github.com/docker/docker v25.0.1+incompatible // indirect
github.com/docker/go-connections v0.5.0 // indirect
github.com/docker/go-units v0.5.0 // indirect
github.com/felixge/httpsnoop v1.0.3 // indirect
github.com/go-asn1-ber/asn1-ber v1.5.5 // indirect
github.com/go-logr/logr v1.2.4 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-ole/go-ole v1.2.6 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/google/uuid v1.5.0 // indirect
github.com/klauspost/compress v1.16.0 // indirect
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect
github.com/magiconair/properties v1.8.7 // indirect
github.com/moby/patternmatcher v0.6.0 // indirect
github.com/moby/sys/sequential v0.5.0 // indirect
github.com/moby/sys/user v0.1.0 // indirect
github.com/moby/term v0.5.0 // indirect
github.com/morikuni/aec v1.0.0 // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/opencontainers/image-spec v1.1.0-rc5 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
github.com/shirou/gopsutil/v3 v3.23.12 // indirect
github.com/shoenig/go-m1cpu v0.1.6 // indirect
github.com/sirupsen/logrus v1.9.3 // indirect
github.com/tklauser/go-sysconf v0.3.12 // indirect
github.com/tklauser/numcpus v0.6.1 // indirect
github.com/yusufpapurcu/wmi v1.2.3 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.45.0 // indirect
go.opentelemetry.io/otel v1.19.0 // indirect
go.opentelemetry.io/otel/metric v1.19.0 // indirect
go.opentelemetry.io/otel/trace v1.19.0 // indirect
golang.org/x/crypto v0.14.0 // indirect
golang.org/x/exp v0.0.0-20230510235704-dd950f8aeaea // indirect
golang.org/x/mod v0.11.0 // indirect
golang.org/x/sys v0.16.0 // indirect
golang.org/x/tools v0.10.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 // indirect
google.golang.org/grpc v1.58.3 // indirect
google.golang.org/protobuf v1.31.0 // indirect
)

replace github.com/testcontainers/testcontainers-go => ../..
Loading

0 comments on commit 8438da6

Please sign in to comment.