diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 18f6c605..ee1cf39b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -16,7 +16,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v5 with: - go-version: 1.20.x + go-version: 1.22.x - name: Import GPG key id: import_gpg uses: crazy-max/ghaction-import-gpg@v5 diff --git a/.github/workflows/snapshot.yml b/.github/workflows/snapshot.yml index 0fcda867..e31e94ed 100644 --- a/.github/workflows/snapshot.yml +++ b/.github/workflows/snapshot.yml @@ -18,7 +18,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v5 with: - go-version: 1.20.x + go-version: 1.22.x - name: Import GPG key id: import_gpg uses: crazy-max/ghaction-import-gpg@v5 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index d47831ca..888ad25c 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -16,7 +16,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v5 with: - go-version: 1.20.x + go-version: 1.22.x - run: make test #lint: @@ -33,7 +33,7 @@ jobs: steps: - uses: actions/setup-go@v5 with: - go-version: 1.20.x + go-version: 1.22.x - uses: actions/checkout@v4 - name: golangci-lint uses: golangci/golangci-lint-action@v3 @@ -50,7 +50,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v5 with: - go-version: 1.20.x + go-version: 1.22.x - uses: actions/cache@v3 with: path: ~/go/pkg/mod diff --git a/README.md b/README.md index 280578ef..adc4423c 100644 --- a/README.md +++ b/README.md @@ -113,11 +113,12 @@ provider "kafka" { | `skip_tls_verify` | Skip TLS verification. | `false` | | `sasl_username` | Username for SASL authentication. | `""` | | `sasl_password` | Password for SASL authentication. | `""` | -| `sasl_mechanism` | Mechanism for SASL authentication. Allowed values are plain, aws-iam, scram-sha512 and scram-sha256 | `plain` | +| `sasl_mechanism` | Mechanism for SASL authentication. Allowed values are `plain`, `aws-iam`, `scram-sha256`, `scram-sha512` or `oauthbearer` | `plain` | | `sasl_aws_region` | AWS region for IAM authentication. | `""` | | `sasl_aws_role_arn` | Arn of AWS IAM role to assume for IAM authentication. | `""` | | `sasl_aws_profile` | AWS profile to use for IAM authentication. | `""` | | `sasl_aws_creds_debug` | Enable debug logging for AWS authentication. | `false` | +| `sasl_token_url` | The url to retrieve oauth2 tokens from, when using sasl mechanism `oauthbearer` | `""` | ## Resources diff --git a/go.mod b/go.mod index f6c046e8..026a0148 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,8 @@ module github.com/Mongey/terraform-provider-kafka -go 1.19 +go 1.21 + +toolchain go1.21.6 require ( github.com/IBM/sarama v1.43.0 @@ -11,6 +13,7 @@ require ( github.com/hashicorp/terraform-plugin-sdk/v2 v2.32.0 github.com/xdg/scram v1.0.5 golang.org/x/net v0.22.0 + golang.org/x/oauth2 v0.16.0 ) require ( @@ -41,6 +44,7 @@ require ( github.com/eapache/go-xerial-snappy v0.0.0-20230731223053-c322873962e3 // indirect github.com/eapache/queue v1.1.0 // indirect github.com/fatih/color v1.16.0 // indirect + github.com/frankban/quicktest v1.14.5 // indirect github.com/golang/protobuf v1.5.3 // indirect github.com/golang/snappy v0.0.4 // indirect github.com/google/go-cmp v0.6.0 // indirect @@ -71,9 +75,10 @@ require ( github.com/jcmturner/gokrb5/v8 v8.4.4 // indirect github.com/jcmturner/rpc/v2 v2.0.3 // indirect github.com/klauspost/compress v1.17.7 // indirect + github.com/kr/pretty v0.3.1 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect - github.com/mattn/go-runewidth v0.0.9 // indirect + github.com/mattn/go-runewidth v0.0.15 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/go-testing-interface v1.14.1 // indirect github.com/mitchellh/go-wordwrap v1.0.0 // indirect @@ -83,6 +88,7 @@ require ( github.com/pierrec/lz4/v4 v4.1.21 // indirect github.com/posener/complete v1.2.3 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect + github.com/rivo/uniseg v0.4.6 // indirect github.com/russross/blackfriday v1.6.0 // indirect github.com/shopspring/decimal v1.3.1 // indirect github.com/spf13/cast v1.5.0 // indirect @@ -98,11 +104,12 @@ require ( golang.org/x/mod v0.14.0 // indirect golang.org/x/sys v0.18.0 // indirect golang.org/x/text v0.14.0 // indirect + golang.org/x/tools v0.14.0 // indirect google.golang.org/appengine v1.6.8 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20231106174013-bbf56f31fb17 // indirect google.golang.org/grpc v1.61.0 // indirect google.golang.org/protobuf v1.32.0 // indirect - gopkg.in/yaml.v2 v2.3.0 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect ) replace git.apache.org/thrift.git => github.com/apache/thrift v0.0.0-20180902110319-2566ecd5d999 diff --git a/go.sum b/go.sum index bc813d83..3e8cb06f 100644 --- a/go.sum +++ b/go.sum @@ -1,4 +1,5 @@ dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= +dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= github.com/IBM/sarama v1.43.0 h1:YFFDn8mMI2QL0wOrG0J2sFoVIAFl7hS9JQi2YZsXtJc= github.com/IBM/sarama v1.43.0/go.mod h1:zlE6HEbC/SMQ9mhEYaF7nNLYOUyrs0obySKCckWP9BM= github.com/Kunde21/markdownfmt/v3 v3.1.0 h1:KiZu9LKs+wFFBQKhrZJrFZwtLnCCWJahL+S+E/3VnM0= @@ -10,6 +11,7 @@ github.com/Masterminds/semver/v3 v3.2.0/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYr github.com/Masterminds/sprig/v3 v3.2.3 h1:eL2fZNezLomi0uOLqjQoN6BfsDD+fyLtgbJMAj9n6YA= github.com/Masterminds/sprig/v3 v3.2.3/go.mod h1:rXcFaZ2zZbLRJv/xSysmlgIM1u11eBaRMhvYXJNkGuM= github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= +github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 h1:kkhsdkhsCvIsutKu5zLMgWtgh9YxGCNAw8Ad8hjwfYg= github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0= github.com/agext/levenshtein v1.2.2 h1:0S/Yg6LYmFJ5stwQeRp6EeOcCbj7xiqQSdNelsXvaqE= @@ -48,11 +50,14 @@ github.com/aws/smithy-go v1.13.5/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQkY= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZlaQsNA= +github.com/bufbuild/protocompile v0.4.0/go.mod h1:3v93+mbWn/v3xzN+31nwkJfrEpAUwp+BagBSZWx+TP8= github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA= github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU= github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg= +github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -63,16 +68,24 @@ github.com/eapache/go-xerial-snappy v0.0.0-20230731223053-c322873962e3/go.mod h1 github.com/eapache/queue v1.1.0 h1:YOEu7KNc61ntiQlcEeUIoDTJ2o8mQznoNvUhiigpIqc= github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= +github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= -github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE= +github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= +github.com/frankban/quicktest v1.14.5 h1:dfYrrRyLtiqT9GyKXgdh+k4inNeTvmGbuSgZ3lx3GhA= +github.com/frankban/quicktest v1.14.5/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI= +github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic= github.com/go-git/go-billy/v5 v5.5.0 h1:yEY4yhzCDuMGSv83oGxiBotRzhwhNr8VZyphhiu+mTU= +github.com/go-git/go-billy/v5 v5.5.0/go.mod h1:hmexnoNsr2SJU1Ju67OaNz5ASJY3+sHgFRpCtpDCKow= github.com/go-git/go-git/v5 v5.10.1 h1:tu8/D8i+TWxgKpzQ3Vc43e+kkhXqtsZCKI/egajKnxk= +github.com/go-git/go-git/v5 v5.10.1/go.mod h1:uEuHjxkHap8kAl//V5F/nNWwqIYtP/402ddd05mp0wg= github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68= +github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/protobuf v1.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= @@ -83,6 +96,7 @@ github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEW github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -145,6 +159,7 @@ github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH github.com/imdario/mergo v0.3.15 h1:M8XP7IuFNsqUx6VPK2P9OSmsYsI/YFaGil0uD21V3dM= github.com/imdario/mergo v0.3.15/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= +github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= github.com/jcmturner/aescts/v2 v2.0.0 h1:9YKLH6ey7H4eDBXW8khjYslgyqG2xZikXP0EQFKrle8= github.com/jcmturner/aescts/v2 v2.0.0/go.mod h1:AiaICIRyfYg35RUkr8yESTqvSy7csK90qZ5xfvvsoNs= github.com/jcmturner/dnsutils/v2 v2.0.0 h1:lltnkeZGL0wILNvrNiVCR6Ro5PGU/SeBvVO/8c/iPbo= @@ -158,17 +173,22 @@ github.com/jcmturner/gokrb5/v8 v8.4.4/go.mod h1:1btQEpgT6k+unzCwX1KdWMEwPPkkgBtP github.com/jcmturner/rpc/v2 v2.0.3 h1:7FXXj8Ti1IaVFpSAziCZWNzbNuZmnvw/i6CqLNdWfZY= github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc= github.com/jhump/protoreflect v1.15.1 h1:HUMERORf3I3ZdX05WaQ6MIpd/NJ434hTp5YiKgfCL6c= +github.com/jhump/protoreflect v1.15.1/go.mod h1:jD/2GMKKE6OqX8qTjhADU1e6DShO+gavG9e0Q693nKo= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4= +github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= github.com/klauspost/compress v1.17.7 h1:ehO88t2UGzQK66LMdE8tibEd1ErmzZjNEqWkjLAKQQg= github.com/klauspost/compress v1.17.7/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= @@ -178,8 +198,8 @@ github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27k github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= -github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= +github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= +github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= @@ -197,20 +217,29 @@ github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQ github.com/pierrec/lz4/v4 v4.1.21 h1:yOVMLb6qSIDP67pl/5F7RepeKYu/VmTyEXvuMI5d9mQ= github.com/pierrec/lz4/v4 v4.1.21/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4= +github.com/pjbgf/sha1cd v0.3.0/go.mod h1:nZ1rrWOcGJ5uZgEEVL1VUM9iRQiZvWdbZjkKyFzPPsI= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.2.3 h1:NP0eAhjcjImqslEwo/1hq7gpajME0fTLTezBKDqfXqo= github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rivo/uniseg v0.4.6 h1:Sovz9sDSwbOz9tgUy8JpT+KgCkPYJEN/oYzlJiYTNLg= +github.com/rivo/uniseg v0.4.6/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= +github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= github.com/russross/blackfriday v1.6.0 h1:KqfZb0pUVN2lYqZUYRddxF4OR8ZMURnJIG5Y3VRLtww= github.com/russross/blackfriday v1.6.0/go.mod h1:ti0ldHuxg49ri4ksnFxlkCfN+hvslNlmVHqNRXXJNAY= github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= +github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8= github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= github.com/skeema/knownhosts v1.2.1 h1:SHWdIUa82uGZz+F+47k8SY4QhhI291cXCpopT1lK2AQ= +github.com/skeema/knownhosts v1.2.1/go.mod h1:xYbVRSPxqBZFrdmDyMmsOs+uX1UZC3nTN3ThzgDxUwo= github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w= github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU= @@ -225,6 +254,7 @@ github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1F github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= github.com/vmihailenco/msgpack v4.0.4+incompatible h1:dSLoQfGFAo3F6OoNhwUmLwVgaUXK79GlxNBwueZn0xI= github.com/vmihailenco/msgpack v4.0.4+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= @@ -233,6 +263,7 @@ github.com/vmihailenco/msgpack/v5 v5.4.1/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21 github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM= +github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw= github.com/xdg/scram v1.0.5 h1:TuS0RFmt5Is5qm9Tm2SoD89OPqe4IRiFtyFY4iwWXsw= github.com/xdg/scram v1.0.5/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I= github.com/xdg/stringprep v1.0.3 h1:cmL5Enob4W83ti/ZHuZLuKD/xqJfus4fVPwE+/BDm+4= @@ -269,11 +300,14 @@ golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc= golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= +golang.org/x/oauth2 v0.16.0 h1:aDkGMBSYxElaoP81NpoUoz2oo2R2wHdZpGToUxfyQrQ= +golang.org/x/oauth2 v0.16.0/go.mod h1:hqZ+0LWXsiVoZpeld6jVt06P3adbS2Uu911W1SsJv2o= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= +golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -310,7 +344,8 @@ golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ= +golang.org/x/tools v0.14.0 h1:jvNa2pY0M4r62jkRQ6RwEZZyPcymeL9XZMLBbV7U2nc= +golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= @@ -327,11 +362,14 @@ google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHh gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= +gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/kafka/client.go b/kafka/client.go index a7affbdf..47ef6cb7 100644 --- a/kafka/client.go +++ b/kafka/client.go @@ -235,7 +235,6 @@ func (c *Client) UpdateTopic(topic Topic) error { } res, err := broker.AlterConfigs(r) - if err != nil { return err } @@ -350,7 +349,6 @@ func (c *Client) buildAssignment(t Topic) (*[][]int32, error) { allReplicas := c.allReplicas() newRF := t.ReplicationFactor - rand.Seed(time.Now().UnixNano()) assignment := make([][]int32, len(partitions)) for _, p := range partitions { @@ -587,6 +585,7 @@ func (c *Client) topicConfig(topic string) (map[string]*string, error) { func (c *Client) getDescribeAclsRequestAPIVersion() int16 { return int16(c.versionForKey(29, 1)) } + func (c *Client) getCreateAclsRequestAPIVersion() int16 { return int16(c.versionForKey(30, 1)) } diff --git a/kafka/config.go b/kafka/config.go index a8ed35c5..5f67e2a3 100644 --- a/kafka/config.go +++ b/kafka/config.go @@ -13,6 +13,8 @@ import ( "github.com/IBM/sarama" "github.com/aws/aws-msk-iam-sasl-signer-go/signer" "golang.org/x/net/proxy" + "golang.org/x/oauth2" + "golang.org/x/oauth2/clientcredentials" ) type Config struct { @@ -31,6 +33,47 @@ type Config struct { SASLAWSRoleArn string SASLAWSProfile string SASLAWSCredsDebug bool + SASLTokenUrl string +} + +type OAuth2Config interface { + Token(ctx context.Context) (*oauth2.Token, error) +} + +type oauthbearerTokenProvider struct { + tokenExpiration time.Time + token string + oauth2Config OAuth2Config +} + +func newOauthbearerTokenProvider(oauth2Config OAuth2Config) *oauthbearerTokenProvider { + return &oauthbearerTokenProvider{ + tokenExpiration: time.Time{}, + token: "", + oauth2Config: oauth2Config, + } +} + +func (o *oauthbearerTokenProvider) Token() (*sarama.AccessToken, error) { + var accessToken string + var err error + currentTime := time.Now() + ctx := context.Background() + + if o.token != "" && currentTime.Before(o.tokenExpiration.Add(time.Duration(-2)*time.Second)) { + accessToken = o.token + err = nil + } else { + token, _err := o.oauth2Config.Token(ctx) + err = _err + if err == nil { + accessToken = token.AccessToken + o.token = token.AccessToken + o.tokenExpiration = token.Expiry + } + } + + return &sarama.AccessToken{Token: accessToken}, err } func (c *Config) Token() (*sarama.AccessToken, error) { @@ -79,6 +122,21 @@ func (c *Config) newKafkaConfig() (*sarama.Config, error) { log.Fatalf("[ERROR] aws region must be configured or AWS_REGION environment variable must be set to use aws-iam sasl mechanism") } kafkaConfig.Net.SASL.TokenProvider = c + case "oauthbearer": + kafkaConfig.Net.SASL.Mechanism = sarama.SASLMechanism(sarama.SASLTypeOAuth) + tokenUrl := c.SASLTokenUrl + if tokenUrl == "" { + tokenUrl = os.Getenv("TOKEN_URL") + } + if tokenUrl == "" { + log.Fatalf("[ERROR] token url must be configured or TOKEN_URL environment variable must be set to use oauthbearer sasl mechanism") + } + oauth2Config := clientcredentials.Config{ + TokenURL: tokenUrl, + ClientID: c.SASLUsername, + ClientSecret: c.SASLPassword, + } + kafkaConfig.Net.SASL.TokenProvider = newOauthbearerTokenProvider(&oauth2Config) case "plain": default: log.Fatalf("[ERROR] Invalid sasl mechanism \"%s\": can only be \"scram-sha256\", \"scram-sha512\", \"aws-iam\" or \"plain\"", c.SASLMechanism) @@ -104,7 +162,6 @@ func (c *Config) newKafkaConfig() (*sarama.Config, error) { c.CACert, c.ClientCertKeyPassphrase, ) - if err != nil { return kafkaConfig, err } @@ -127,11 +184,11 @@ func NewTLSConfig(clientCert, clientKey, caCert, clientKeyPassphrase string) (*t func parsePemOrLoadFromFile(input string) (*pem.Block, []byte, error) { // attempt to parse - var inputBytes = []byte(input) + inputBytes := []byte(input) inputBlock, _ := pem.Decode(inputBytes) if inputBlock == nil { - //attempt to load from file + // attempt to load from file log.Printf("[INFO] Attempting to load from file '%s'", input) var err error inputBytes, err = os.ReadFile(input) @@ -220,13 +277,14 @@ func (config *Config) copyWithMaskedSensitiveValues() Config { "*****", config.TLSEnabled, config.SkipTLSVerify, - config.SASLAWSRegion, config.SASLUsername, "*****", config.SASLMechanism, + config.SASLAWSRegion, config.SASLAWSProfile, config.SASLAWSRoleArn, config.SASLAWSCredsDebug, + config.SASLTokenUrl, } return copy } diff --git a/kafka/config_test.go b/kafka/config_test.go index 944f7582..e0b4f0d8 100644 --- a/kafka/config_test.go +++ b/kafka/config_test.go @@ -1,10 +1,165 @@ package kafka import ( + "context" + "errors" "os" "testing" + "time" + + "github.com/IBM/sarama" + "golang.org/x/oauth2" + "golang.org/x/oauth2/clientcredentials" ) +func assertEquals(t *testing.T, expected any, actual any) { + if expected != actual { + t.Errorf("Expected %s, got %s", expected, actual) + } +} + +func assertNil(t *testing.T, actual any) { + assertEquals(t, nil, actual) +} + +func assertNotNil(t *testing.T, actual any) { + if actual == nil { + t.Error("Actual was nil") + } +} + +func Test_newOauthbearerTokenProvider(t *testing.T) { + tokenUrl := "https://fake-url.com/token" + clientId := "clientId" + clientSecret := "clientSecret" + oauth2Config := clientcredentials.Config{ + TokenURL: tokenUrl, + ClientID: clientId, + ClientSecret: clientSecret, + } + tokenProvider := newOauthbearerTokenProvider(&oauth2Config) + //assertEquals(t, tokenUrl, tokenProvider.oauth2Config.TokenURL) + //assertEquals(t, clientId, tokenProvider.oauth2Config.ClientID) + //assertEquals(t, clientSecret, tokenProvider.oauth2Config.ClientSecret) + assertEquals(t, "", tokenProvider.token) + assertEquals(t, time.Time{}, tokenProvider.tokenExpiration) +} + +type MockConfig_NoError struct { + AccessToken string + Expiry time.Time +} + +type MockConfig_Error struct { + err error +} + +func (m *MockConfig_NoError) Token(ctx context.Context) (*oauth2.Token, error) { + // You can customize the mock behavior for testing here. + return &oauth2.Token{ + AccessToken: m.AccessToken, + Expiry: m.Expiry, + }, nil +} + +func (m *MockConfig_Error) Token(ctx context.Context) (*oauth2.Token, error) { + return nil, m.err +} + +func TestOauthbearerTokenProvider_Token_WhenNoPreviousTokenExists(t *testing.T) { + now := time.Now() + mockConfig := MockConfig_NoError{ + AccessToken: "tokenNew", + Expiry: now, + } + tokenProvider := newOauthbearerTokenProvider(&mockConfig) + + token, err := tokenProvider.Token() + + assertNil(t, err) + + assertEquals(t, mockConfig.AccessToken, token.Token) + assertEquals(t, mockConfig.AccessToken, tokenProvider.token) + assertEquals(t, mockConfig.Expiry, tokenProvider.tokenExpiration) + +} + +func TestOauthbearerTokenProvider_Token_WhenPreviousTokenExistsButExpired(t *testing.T) { + now := time.Now() + mockConfig := MockConfig_NoError{ + AccessToken: "tokenNew", + Expiry: now.Add(time.Duration(24) * time.Hour), + } + tokenProvider := newOauthbearerTokenProvider(&mockConfig) + tokenProvider.token = "tokenOld" + tokenProvider.tokenExpiration = now.Add(time.Duration(-10) * time.Second) + + token, err := tokenProvider.Token() + + assertNil(t, err) + + assertEquals(t, mockConfig.AccessToken, token.Token) + assertEquals(t, mockConfig.AccessToken, tokenProvider.token) + assertEquals(t, mockConfig.Expiry, tokenProvider.tokenExpiration) + +} + +func TestOauthbearerTokenProvider_Token_WhenPreviousTokenExists(t *testing.T) { + mockConfig := MockConfig_NoError{ + AccessToken: "tokenNew", + Expiry: time.Now(), + } + oldToken := "tokenOld" + expiry := time.Now().Add(time.Duration(100) * time.Second) + tokenProvider := newOauthbearerTokenProvider(&mockConfig) + tokenProvider.token = oldToken + tokenProvider.tokenExpiration = expiry + + token, err := tokenProvider.Token() + + assertNil(t, err) + + assertEquals(t, oldToken, token.Token) + assertEquals(t, oldToken, tokenProvider.token) + assertEquals(t, expiry, tokenProvider.tokenExpiration) + +} + +func TestOauthbearerTokenProvider_Token_WhenError(t *testing.T) { + mockConfig := MockConfig_Error{ + err: errors.New("TestError"), + } + tokenProvider := newOauthbearerTokenProvider(&mockConfig) + + token, err := tokenProvider.Token() + + assertEquals(t, "", token.Token) + + assertEquals(t, mockConfig.err, err) +} + +func TestConfig_NewKafkaConfig_WithOauthBearerMechanism(t *testing.T) { + user := "user" + pass := "pass" + url := "url" + mechanism := "oauthbearer" + config := Config{ + SASLUsername: user, + SASLPassword: pass, + SASLTokenUrl: url, + SASLMechanism: mechanism, + } + + sConfig, err := config.newKafkaConfig() + + assertNil(t, err) + + assertEquals(t, user, sConfig.Net.SASL.User) + assertEquals(t, pass, sConfig.Net.SASL.Password) + assertNotNil(t, sConfig.Net.SASL.TokenProvider) + assertEquals(t, sarama.SASLMechanism(sarama.SASLTypeOAuth), sConfig.Net.SASL.Mechanism) +} + func loadFile(t *testing.T, file string) string { fb, err := os.ReadFile(file) if err != nil { diff --git a/kafka/provider.go b/kafka/provider.go index c82f4174..ee0a2035 100644 --- a/kafka/provider.go +++ b/kafka/provider.go @@ -16,40 +16,40 @@ func Provider() *schema.Provider { Required: true, Description: "A list of kafka brokers", }, - "ca_cert_file": &schema.Schema{ + "ca_cert_file": { Type: schema.TypeString, Optional: true, DefaultFunc: schema.EnvDefaultFunc("KAFKA_CA_CERT", nil), Description: "Path to a CA certificate file to validate the server's certificate.", Deprecated: "This parameter is now deprecated and will be removed in a later release, please use `ca_cert` instead.", }, - "client_cert_file": &schema.Schema{ + "client_cert_file": { Type: schema.TypeString, Optional: true, DefaultFunc: schema.EnvDefaultFunc("KAFKA_CLIENT_CERT", nil), Description: "Path to a file containing the client certificate.", Deprecated: "This parameter is now deprecated and will be removed in a later release, please use `client_cert` instead.", }, - "client_key_file": &schema.Schema{ + "client_key_file": { Type: schema.TypeString, Optional: true, DefaultFunc: schema.EnvDefaultFunc("KAFKA_CLIENT_KEY", nil), Description: "Path to a file containing the private key that the certificate was issued for.", Deprecated: "This parameter is now deprecated and will be removed in a later release, please use `client_key` instead.", }, - "ca_cert": &schema.Schema{ + "ca_cert": { Type: schema.TypeString, Optional: true, DefaultFunc: schema.EnvDefaultFunc("KAFKA_CA_CERT", nil), Description: "CA certificate file to validate the server's certificate.", }, - "client_cert": &schema.Schema{ + "client_cert": { Type: schema.TypeString, Optional: true, DefaultFunc: schema.EnvDefaultFunc("KAFKA_CLIENT_CERT", nil), Description: "The client certificate.", }, - "client_key": &schema.Schema{ + "client_key": { Type: schema.TypeString, Optional: true, DefaultFunc: schema.EnvDefaultFunc("KAFKA_CLIENT_KEY", nil), @@ -61,55 +61,61 @@ func Provider() *schema.Provider { DefaultFunc: schema.EnvDefaultFunc("KAFKA_CLIENT_KEY_PASSPHRASE", nil), Description: "The passphrase for the private key that the certificate was issued for.", }, - "sasl_aws_region": &schema.Schema{ + "sasl_aws_region": { Type: schema.TypeString, Optional: true, DefaultFunc: schema.EnvDefaultFunc("KAFKA_SASL_IAM_AWS_REGION", nil), Description: "AWS region where MSK is deployed.", }, - "sasl_aws_role_arn": &schema.Schema{ + "sasl_aws_role_arn": { Type: schema.TypeString, Optional: true, DefaultFunc: schema.EnvDefaultFunc("AWS_ROLE_ARN", nil), Description: "Arn of an AWS IAM role to assume", }, - "sasl_aws_profile": &schema.Schema{ + "sasl_aws_profile": { Type: schema.TypeString, Optional: true, DefaultFunc: schema.EnvDefaultFunc("AWS_PROFILE", nil), Description: "AWS profile name to use", }, - "sasl_aws_creds_debug": &schema.Schema{ + "sasl_aws_creds_debug": { Type: schema.TypeBool, Optional: true, DefaultFunc: schema.EnvDefaultFunc("AWS_CREDS_DEBUG", "false"), Description: "Set this to true to turn AWS credentials debug.", }, - "sasl_username": &schema.Schema{ + "sasl_username": { Type: schema.TypeString, Optional: true, DefaultFunc: schema.EnvDefaultFunc("KAFKA_SASL_USERNAME", nil), Description: "Username for SASL authentication.", }, - "sasl_password": &schema.Schema{ + "sasl_password": { Type: schema.TypeString, Optional: true, DefaultFunc: schema.EnvDefaultFunc("KAFKA_SASL_PASSWORD", nil), Description: "Password for SASL authentication.", }, - "sasl_mechanism": &schema.Schema{ + "sasl_token_url": { + Type: schema.TypeString, + Optional: true, + DefaultFunc: schema.EnvDefaultFunc("KAFKA_SASL_TOKEN_URL", nil), + Description: "The url to retrieve oauth2 tokens from, when using sasl mechanism oauthbearer", + }, + "sasl_mechanism": { Type: schema.TypeString, Optional: true, DefaultFunc: schema.EnvDefaultFunc("KAFKA_SASL_MECHANISM", "plain"), Description: "SASL mechanism, can be plain, scram-sha512, scram-sha256, aws-iam", }, - "skip_tls_verify": &schema.Schema{ + "skip_tls_verify": { Type: schema.TypeBool, Optional: true, DefaultFunc: schema.EnvDefaultFunc("KAFKA_SKIP_VERIFY", "false"), Description: "Set this to true only if the target Kafka server is an insecure development instance.", }, - "tls_enabled": &schema.Schema{ + "tls_enabled": { Type: schema.TypeBool, Optional: true, DefaultFunc: schema.EnvDefaultFunc("KAFKA_ENABLE_TLS", "true"), @@ -143,9 +149,9 @@ func providerConfigure(d *schema.ResourceData) (interface{}, error) { saslMechanism := d.Get("sasl_mechanism").(string) switch saslMechanism { - case "scram-sha512", "scram-sha256", "aws-iam", "plain": + case "scram-sha512", "scram-sha256", "aws-iam", "oauthbearer", "plain": default: - return nil, fmt.Errorf("[ERROR] Invalid sasl mechanism \"%s\": can only be \"scram-sha256\", \"scram-sha512\", \"aws-iam\" or \"plain\"", saslMechanism) + return nil, fmt.Errorf("[ERROR] Invalid sasl mechanism \"%s\": can only be \"scram-sha256\", \"scram-sha512\", \"aws-iam\", \"oauthbearer\" or \"plain\"", saslMechanism) } config := &Config{ @@ -158,6 +164,7 @@ func providerConfigure(d *schema.ResourceData) (interface{}, error) { SASLAWSRegion: d.Get("sasl_aws_region").(string), SASLUsername: d.Get("sasl_username").(string), SASLPassword: d.Get("sasl_password").(string), + SASLTokenUrl: d.Get("sasl_token_url").(string), SASLAWSRoleArn: d.Get("sasl_aws_role_arn").(string), SASLAWSProfile: d.Get("sasl_aws_profile").(string), SASLAWSCredsDebug: d.Get("sasl_aws_creds_debug").(bool), diff --git a/website/docs/index.html.markdown b/website/docs/index.html.markdown index 663d8441..0b786142 100644 --- a/website/docs/index.html.markdown +++ b/website/docs/index.html.markdown @@ -96,8 +96,9 @@ In addition to [generic `provider` arguments](https://www.terraform.io/docs/conf * `sasl_password` - (Optional) Password for SASL authentication. Can be set through the `KAFKA_SASL_PASSWORD` environment variable. -* `sasl_mechanism` - (Optional) Mechanism for SASL authentication. Allowed values - are `plain`, `scram-sha512`, `scram-sha256` and `aws-iam`. Default `plain`. Can be set through the `KAFKA_SASL_MECHANISM` environment variable. +* `sasl_token_url` - (Optional) The url to retrieve oauth2 tokens from, when using sasl mechanism oauthbearer. Can be set through the `KAFKA_SASL_TOKEN_URL` environment variable. + +* `sasl_mechanism` - (Optional) Mechanism for SASL authentication. Allowed values are `plain`, `scram-sha512`, `scram-sha256`, `aws-iam` or `oauthbearer`. Default `plain`. Can be set through the `KAFKA_SASL_MECHANISM` environment variable. * `sasl_aws_region` - (Optional) AWS region where MSK is deployed. Required when sasl_mechanism is aws-iam. @@ -105,4 +106,4 @@ In addition to [generic `provider` arguments](https://www.terraform.io/docs/conf * `sasl_aws_profile` - (Optional) AWS profile name to use. -* `sasl_aws_creds_debug` - (Optional) Set this to true to turn AWS credentials debug. \ No newline at end of file +* `sasl_aws_creds_debug` - (Optional) Set this to true to turn AWS credentials debug.