Skip to content

Commit 908df98

Browse files
authored
Merge pull request #2 from bushelpowered/add-data-object
Add data object
2 parents 3f06fb4 + 3e2b30c commit 908df98

File tree

6 files changed

+372
-52
lines changed

6 files changed

+372
-52
lines changed

Makefile

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
TEST?=$$(go list ./... | grep -v 'vendor')
2-
HOSTNAME=github.com
3-
NAMESPACE=trevex
4-
NAME=ldap
5-
BINARY=terraform-provider-${NAME}
6-
VERSION=0.2
7-
OS_ARCH=darwin_amd64
2+
HOSTNAME ?= github.com
3+
NAMESPACE ?= trevex
4+
NAME ?= ldap
5+
BINARY = terraform-provider-${NAME}
6+
VERSION ?= 0.2
7+
OS_ARCH ?= darwin_amd64
88

99
default: install
1010

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ go 1.15
55
require (
66
github.com/go-ldap/ldap/v3 v3.2.4
77
github.com/hashicorp/terraform-plugin-sdk/v2 v2.0.4
8+
github.com/pkg/errors v0.8.1
89
golang.org/x/text v0.3.3
910
)
1011

go.sum

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/g
4242
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
4343
github.com/apparentlymart/go-cidr v1.0.1/go.mod h1:EBcsNrHc3zQeuaeCeCtQruQm+n9/YjEn/vI25Lg7Gwc=
4444
github.com/apparentlymart/go-dump v0.0.0-20180507223929-23540a00eaa3/go.mod h1:oL81AME2rN47vu18xqj1S1jPIPuN7afo62yKTNn3XMM=
45+
github.com/apparentlymart/go-dump v0.0.0-20190214190832-042adf3cf4a0 h1:MzVXffFUye+ZcSR6opIgz9Co7WcDx6ZcY+RjfFHoA0I=
4546
github.com/apparentlymart/go-dump v0.0.0-20190214190832-042adf3cf4a0/go.mod h1:oL81AME2rN47vu18xqj1S1jPIPuN7afo62yKTNn3XMM=
4647
github.com/apparentlymart/go-textseg v1.0.0 h1:rRmlIsPEEhUTIKQb7T++Nz/A5Q6C9IuX2wFoYVvnCs0=
4748
github.com/apparentlymart/go-textseg v1.0.0/go.mod h1:z96Txxhf3xSFMPmb5X/1W05FF/Nj9VFpLOpjS5yuumk=
@@ -61,6 +62,7 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk
6162
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
6263
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
6364
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
65+
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
6466
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
6567
github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o=
6668
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
@@ -79,9 +81,9 @@ github.com/go-git/go-git/v5 v5.1.0/go.mod h1:ZKfuPUoY1ZqIG4QG9BDBh3G4gLM5zvPuSJA
7981
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
8082
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
8183
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
82-
github.com/go-ldap/ldap v3.0.3+incompatible h1:HTeSZO8hWMS1Rgb2Ziku6b8a7qRIZZMHjsvuZyatzwk=
8384
github.com/go-ldap/ldap/v3 v3.2.4 h1:PFavAq2xTgzo/loE8qNXcQaofAaqIpI4WgaLdv+1l3E=
8485
github.com/go-ldap/ldap/v3 v3.2.4/go.mod h1:iYS1MdmrmceOJ1QOTnRXrIs7i3kloqtmGQjRvjKpyMg=
86+
github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68=
8587
github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
8688
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
8789
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
@@ -116,6 +118,7 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw
116118
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
117119
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
118120
github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
121+
github.com/google/go-cmp v0.5.0 h1:/QaMHBdZ26BB3SSst0Iwl10Epc+xhTquomWX0oZEB6w=
119122
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
120123
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
121124
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
@@ -169,6 +172,7 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:
169172
github.com/imdario/mergo v0.3.9/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
170173
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
171174
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
175+
github.com/jhump/protoreflect v1.6.0 h1:h5jfMVslIg6l29nsMs0D8Wj17RDVdNYti0vDN/PZZoE=
172176
github.com/jhump/protoreflect v1.6.0/go.mod h1:eaTn3RZAmMBcV0fifFvlm6VHNz3wSkYyXYWUh7ymB74=
173177
github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
174178
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
@@ -177,11 +181,14 @@ github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/X
177181
github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
178182
github.com/keybase/go-crypto v0.0.0-20161004153544-93f5b35093ba/go.mod h1:ghbZscTyKdM07+Fw3KSi0hcJm+AlEUWj8QLlPtijN/M=
179183
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
184+
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
180185
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
181186
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
182187
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
188+
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
183189
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
184190
github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k=
191+
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
185192
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
186193
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
187194
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
@@ -204,11 +211,14 @@ github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh
204211
github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
205212
github.com/mitchellh/reflectwalk v1.0.1 h1:FVzMWA5RllMAKIdUSC8mdWo3XtwoecrH79BY70sEEpE=
206213
github.com/mitchellh/reflectwalk v1.0.1/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
214+
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
207215
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
208216
github.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw=
209217
github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
210218
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
219+
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
211220
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
221+
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
212222
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
213223
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
214224
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
@@ -219,6 +229,7 @@ github.com/spf13/pflag v1.0.2/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnIn
219229
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
220230
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
221231
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
232+
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
222233
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
223234
github.com/ulikunitz/xz v0.5.5/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8=
224235
github.com/ulikunitz/xz v0.5.8/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
@@ -394,6 +405,7 @@ golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roY
394405
golang.org/x/tools v0.0.0-20200713011307-fd294ab11aed/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
395406
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
396407
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
408+
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
397409
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
398410
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
399411
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
@@ -414,6 +426,7 @@ google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7
414426
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
415427
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
416428
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
429+
google.golang.org/appengine v1.6.6 h1:lMO5rYAqUxkmaj76jAkRUvt5JZgFymx/+Q5Mzfivuhc=
417430
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
418431
google.golang.org/genproto v0.0.0-20170818010345-ee236bd376b0/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
419432
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
@@ -471,11 +484,13 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba
471484
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
472485
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
473486
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
487+
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
474488
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
475489
gopkg.in/cheggaaa/pb.v1 v1.0.27/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
476490
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
477491
gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
478492
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
493+
gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I=
479494
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
480495
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
481496
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=

provider/data_ldap_object.go

Lines changed: 239 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,239 @@
1+
// Heavily based on https://github.com/Pryz/terraform-provider-ldap, see LICENSE
2+
3+
package provider
4+
5+
import (
6+
"encoding/json"
7+
"fmt"
8+
"strings"
9+
10+
"github.com/go-ldap/ldap/v3"
11+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
12+
"github.com/pkg/errors"
13+
)
14+
15+
var SEARCH_DEPTHS = map[int][]string{
16+
ldap.ScopeWholeSubtree: {
17+
"sub",
18+
"subtree",
19+
"wholeSubtree",
20+
},
21+
ldap.ScopeBaseObject: {
22+
"base",
23+
"baseObject",
24+
},
25+
ldap.ScopeSingleLevel: {
26+
"one",
27+
"singleLevel",
28+
},
29+
}
30+
31+
// searchDepthLookup normalizes the name of a search depth
32+
func normalizeSearchDepth(search string) int {
33+
lowerSearch := strings.ToLower(search)
34+
for val, alternates := range SEARCH_DEPTHS {
35+
for _, a := range alternates {
36+
if strings.ToLower(a) == lowerSearch {
37+
return val
38+
}
39+
}
40+
}
41+
return -1
42+
}
43+
44+
func depthHelpString() string {
45+
out := []string{}
46+
for _, alternates := range SEARCH_DEPTHS {
47+
out = append(out, fmt.Sprintf("%s (or %s)", alternates[0], strings.Join(alternates[1:], ", ")))
48+
}
49+
50+
return strings.Join(out, ", ")
51+
}
52+
53+
func dataLDAPObject() *schema.Resource {
54+
return &schema.Resource{
55+
Read: dataLDAPObjectRead,
56+
// Importer: &schema.ResourceImporter{
57+
// State: resourceLDAPObjectImport,
58+
// },
59+
60+
Schema: map[string]*schema.Schema{
61+
"base_dn": {
62+
Type: schema.TypeString,
63+
Description: "Base DN to search from",
64+
Required: true,
65+
},
66+
"depth": {
67+
Type: schema.TypeString,
68+
// Search depth can be any of the keys or values in SEARCH_DEPTHS
69+
Description: "Search depth kind: " + depthHelpString(),
70+
Default: "subtree",
71+
Optional: true,
72+
},
73+
"search_values": {
74+
Type: schema.TypeMap,
75+
Description: "A dict of values to search by, will be AND'd together",
76+
Required: true,
77+
Elem: &schema.Schema{
78+
Type: schema.TypeString,
79+
Description: "The value to search for on this attribute",
80+
},
81+
},
82+
"dn": {
83+
Type: schema.TypeString,
84+
Description: "DN Of the object",
85+
Computed: true,
86+
},
87+
"attributes": {
88+
Type: schema.TypeSet,
89+
Description: "The map of attributes of this object; each attribute can be multi-valued.",
90+
Set: attributeHash,
91+
MinItems: 0,
92+
Computed: true,
93+
94+
Elem: &schema.Schema{
95+
Type: schema.TypeMap,
96+
Description: "The list of values for a given attribute.",
97+
MinItems: 1,
98+
MaxItems: 1,
99+
Elem: &schema.Schema{
100+
Type: schema.TypeString,
101+
Description: "The individual value for the given attribute.",
102+
},
103+
},
104+
},
105+
"attributes_json": {
106+
Computed: true,
107+
Type: schema.TypeMap,
108+
Description: "A map of json encoded attribute values. Each entry is a JSON encoded string list",
109+
Elem: &schema.Schema{
110+
Type: schema.TypeString,
111+
Description: "A json-encoded array of strings",
112+
},
113+
},
114+
},
115+
}
116+
}
117+
118+
func dataLDAPObjectRead(d *schema.ResourceData, meta interface{}) error {
119+
return searchLDAPObject(d, meta)
120+
}
121+
122+
func searchLDAPObject(d *schema.ResourceData, meta interface{}) error {
123+
client := meta.(*ldap.Conn)
124+
baseDN := d.Get("base_dn").(string)
125+
searchDepthInput := d.Get("depth").(string)
126+
searchDepth := normalizeSearchDepth(searchDepthInput)
127+
128+
if searchDepth < 0 {
129+
return fmt.Errorf("Search depth of '%s' not a valid option", searchDepthInput)
130+
}
131+
132+
searchFilters := []string{}
133+
if requestedSearch, ok := d.GetOk("search_values"); ok {
134+
for key, val := range requestedSearch.(map[string]interface{}) {
135+
searchFilters = append(searchFilters, fmt.Sprintf("(%s=%s)", key, val.(string)))
136+
}
137+
}
138+
searchFilter := fmt.Sprintf("(&%s)", strings.Join(searchFilters, ""))
139+
140+
debugLog("ldap_object::read - looking in %q for %q", baseDN, searchFilter)
141+
// when searching by DN, you don't need t specify the base DN a search
142+
// filter a "subtree" scope: just put the DN (i.e. the primary key) as the
143+
// base DN with a "base object" scope, and the returned object will be the
144+
// entry, if it exists
145+
request := ldap.NewSearchRequest(
146+
baseDN,
147+
searchDepth,
148+
ldap.NeverDerefAliases, // deref Aliases
149+
0, // sizeLimit
150+
0, // timeLimit
151+
false, // typesOnly
152+
searchFilter, // filter
153+
[]string{"*"}, // attributes
154+
nil, // controls
155+
)
156+
157+
searchResult, err := client.Search(request)
158+
if err != nil {
159+
if err, ok := err.(*ldap.Error); ok {
160+
if err.ResultCode == 32 { // no such object
161+
warnLog("ldap_object::read - object not found with filter: %s", searchFilter)
162+
return fmt.Errorf("Object not found with filter: %s", searchFilter)
163+
}
164+
}
165+
debugLog("ldap_object::read - search %q returned an error %v", searchFilter, err)
166+
return err
167+
}
168+
169+
if len(searchResult.Entries) > 1 {
170+
err := fmt.Errorf("There were more than one objects foudn with search %q", searchFilter)
171+
errorLog(err.Error())
172+
return err
173+
} else if len(searchResult.Entries) < 1 {
174+
err := fmt.Errorf("There were no objects found against %q", searchFilter)
175+
errorLog(err.Error())
176+
return err
177+
}
178+
179+
foundObject := searchResult.Entries[0]
180+
181+
var dn string
182+
for _, key := range []string{"dn", "DN", "distinguished_name", "distinguishedName"} {
183+
dn = foundObject.GetAttributeValue(key)
184+
if dn != "" {
185+
traceLog("Found Distinguished Name for object: %s = %q", key, dn)
186+
break
187+
}
188+
}
189+
190+
if dn == "" {
191+
err := fmt.Errorf("Failed to find DN for object %+v", foundObject)
192+
errorLog(err.Error())
193+
return err
194+
}
195+
196+
traceLog("ldap_object::read - found %q : %+v", dn, foundObject)
197+
d.Set("dn", dn)
198+
d.SetId("-")
199+
200+
// now deal with attributes
201+
set := &schema.Set{
202+
F: attributeHash,
203+
}
204+
205+
jsonAttributes := make(map[string]string)
206+
207+
for _, attribute := range searchResult.Entries[0].Attributes {
208+
debugLog("ldap_object::read - adding attribute %q to %q (%d values)", attribute.Name, dn, len(attribute.Values))
209+
// now add each value as an individual entry into the object, because
210+
// we do not handle name => []values, and we have a set of maps each
211+
// holding a single entry name => value; multiple maps may share the
212+
// same key.
213+
for _, value := range attribute.Values {
214+
traceLog("ldap_object::read - for %q, setting %q => %q", dn, attribute.Name, value)
215+
set.Add(map[string]interface{}{
216+
attribute.Name: value,
217+
})
218+
}
219+
jsonBytes, err := json.Marshal(attribute.Values)
220+
if err != nil {
221+
err = errors.Wrapf(err, "Marshalling attribute %s values", attribute.Name)
222+
errorLog(err.Error())
223+
return err
224+
}
225+
jsonAttributes[attribute.Name] = string(jsonBytes)
226+
}
227+
228+
if err := d.Set("attributes", set); err != nil {
229+
warnLog("ldap_object::read - error setting attributes for %q : %v", dn, err)
230+
return err
231+
}
232+
233+
if err := d.Set("attributes_json", jsonAttributes); err != nil {
234+
warnLog("ldap_object::read - error setting attributes_json for %q : %v", dn, err)
235+
return err
236+
}
237+
238+
return nil
239+
}

0 commit comments

Comments
 (0)