Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add reverse proxy resource #13

Merged
merged 8 commits into from
Dec 14, 2023
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Add new resource 'platform_reverse_proxy'
alexhung committed Dec 13, 2023
commit 728f4aa6b280a5381b12907985c0b695ec9fd88c
49 changes: 49 additions & 0 deletions docs/resources/reverse_proxy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "platform_reverse_proxy Resource - terraform-provider-platform"
subcategory: ""
description: |-
Provides a JFrog Reverse Proxy https://jfrog.com/help/r/jfrog-artifactory-documentation/reverse-proxy-settings resource.
~>Only available for self-hosted instances.
---

# platform_reverse_proxy (Resource)

Provides a JFrog [Reverse Proxy](https://jfrog.com/help/r/jfrog-artifactory-documentation/reverse-proxy-settings) resource.

~>Only available for self-hosted instances.

## Example Usage

```terraform
resource "platform_reverse_proxy" "my-reverse-proxy" {
docker_reverse_proxy_method = "SUBDOMAIN"
server_name_expression = "*.jfrog.com"
server_provider = "NGINX"
public_server_name = "jfrog.com"
internal_hostname = "localhost"
use_https = true
http_port = 80
https_port = 443
ssl_key_path = "/etc/ssl/private/myserver.key"
ssl_certificate_path = "/etc/ssl/certs/myserver.crt"
}
```

<!-- schema generated by tfplugindocs -->
## Schema

### Required

- `server_provider` (String) Set the server provider type. Supported values: DIRECT, NGINX, APACHE.

### Optional

- `docker_reverse_proxy_method` (String) Docker access method. The default value is SUBDOMAIN. Supported values: SUBDOMAIN, REPOPATHPREFIX, PORTPERREPO.
- `http_port` (Number) The port for access via HTTP. The default value is 80. Only settable when `server_provider` is set to `NIGNIX` or `APACHE`
- `https_port` (Number) The port for access via HTTPS. The default value is 443. Only settable when `use_https` is set to `true`
- `internal_hostname` (String) The internal server name for Artifactory which will be used by the web server to access the Artifactory machine. If the web server is installed on the same machine as Artifactory you can use localhost, otherwise use the IP or hostname. Must be set when `server_provider` is set to `NIGNIX` or `APACHE`
- `public_server_name` (String) The server name that will be used to access Artifactory. Should be correlated with the base URL value. Must be set when `server_provider` is set to `NIGNIX` or `APACHE`
- `ssl_certificate_path` (String) The full path of the certificate file on the web server, e.g. `/etc/ssl/certs/myserver.crt`. Must be set when `use_https` is set to `true`
- `ssl_key_path` (String) The full path of the key file on the web server, e.g. `/etc/ssl/private/myserver.key`. Must be set when `use_https` is set to `true`
- `use_https` (Boolean) When set, Artifactory will be accessible via HTTPS at the corresponding port that is set. Only settable when `server_provider` is set to `NIGNIX` or `APACHE`
12 changes: 12 additions & 0 deletions examples/resources/platform_reverse_proxy/resource.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
resource "platform_reverse_proxy" "my-reverse-proxy" {
docker_reverse_proxy_method = "SUBDOMAIN"
server_name_expression = "*.jfrog.com"
server_provider = "NGINX"
public_server_name = "jfrog.com"
internal_hostname = "localhost"
use_https = true
http_port = 80
https_port = 443
ssl_key_path = "/etc/ssl/private/myserver.key"
ssl_certificate_path = "/etc/ssl/certs/myserver.crt"
}
6 changes: 3 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
@@ -3,14 +3,16 @@ module github.com/jfrog/terraform-provider-platform
// if you need to do local dev, literally just uncomment the line below
// replace github.com/jfrog/terraform-provider-shared => ../terraform-provider-shared

go 1.19
go 1.21

require (
github.com/go-resty/resty/v2 v2.10.0
github.com/hashicorp/terraform-json v0.18.0
github.com/hashicorp/terraform-plugin-docs v0.16.0
github.com/hashicorp/terraform-plugin-framework v1.4.2
github.com/hashicorp/terraform-plugin-framework-validators v0.12.0
github.com/hashicorp/terraform-plugin-go v0.19.1
github.com/hashicorp/terraform-plugin-log v0.9.0
github.com/hashicorp/terraform-plugin-testing v1.6.0
github.com/jfrog/terraform-provider-shared v1.21.1
github.com/samber/lo v1.39.0
@@ -44,8 +46,6 @@ require (
github.com/hashicorp/hcl/v2 v2.19.1 // indirect
github.com/hashicorp/logutils v1.0.0 // indirect
github.com/hashicorp/terraform-exec v0.19.0 // indirect
github.com/hashicorp/terraform-json v0.18.0 // indirect
github.com/hashicorp/terraform-plugin-log v0.9.0 // indirect
github.com/hashicorp/terraform-plugin-sdk/v2 v2.30.0 // indirect
github.com/hashicorp/terraform-registry-address v0.2.3 // indirect
github.com/hashicorp/terraform-svchost v0.1.1 // indirect
29 changes: 27 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
@@ -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/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI=
github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc=
@@ -7,9 +8,11 @@ github.com/Masterminds/sprig/v3 v3.2.1/go.mod h1:UoaO7Yp8KlPnJIYWTFkMaqPUYKTfGFP
github.com/Masterminds/sprig/v3 v3.2.2 h1:17jRggJu518dr3QaafizSXOjKYp94wKfABxUmyxvxX8=
github.com/Masterminds/sprig/v3 v3.2.2/go.mod h1:UoaO7Yp8KlPnJIYWTFkMaqPUYKTfGFPhxNuwnnxkKlk=
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/acomagu/bufpipe v1.0.4 h1:e3H4WUzM3npvo5uv95QuJM3cQspFNtFBzvJ2oNjKIDQ=
github.com/acomagu/bufpipe v1.0.4/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ2sYmHc4=
github.com/agext/levenshtein v1.2.2 h1:0S/Yg6LYmFJ5stwQeRp6EeOcCbj7xiqQSdNelsXvaqE=
github.com/agext/levenshtein v1.2.2/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558=
github.com/apparentlymart/go-textseg/v12 v12.0.0/go.mod h1:S/4uRK2UtaQttw1GenVJEynmyUenKwP++x/+DdGV/Ec=
@@ -21,25 +24,34 @@ github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgI
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 h1:fE/Qz0QdIGqeWfnwq0RE0R7MI51s0M2E4Ga9kq5AEMs=
github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA=
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=
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.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w=
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE=
github.com/frankban/quicktest v1.14.3/go.mod h1:mgiwOwqx65TmIk1wJ6Q7wvnVMocbUorkibMOrVTHZps=
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.9.0 h1:cD9SFA7sHVRdJ7AYck1ZaAa/yeuBvGPxwXDL8cxrObY=
github.com/go-git/go-git/v5 v5.9.0/go.mod h1:RKIqga24sWdMGZF+1Ekv9kylsDz6LzdTSI2s/OsZWE0=
github.com/go-resty/resty/v2 v2.10.0 h1:Qla4W/+TMmv0fOeeRqzEpXPLfTUnR5HZ1+lGs+CkiCo=
github.com/go-resty/resty/v2 v2.10.0/go.mod h1:iiP/OpA0CkcL3IGt1O0+/SIItFUbkkyw5BGXiVdTu+A=
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.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
@@ -114,16 +126,22 @@ 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/jfrog/terraform-provider-shared v1.21.0 h1:E653Oos09FWBP5Pnw1D1vGSY93pd9pYbKlH3Jkl23tE=
github.com/jfrog/terraform-provider-shared v1.21.0/go.mod h1:Ioq1OBLb2h9uj4t4KzBEfA1piHbUg+Lgvn84Vbzk5uI=
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
github.com/jfrog/terraform-provider-shared v1.21.1 h1:hBlk7087fjMVk7fdx2BkpZM3RnLIzS6fGNZEJc5HLYc=
github.com/jfrog/terraform-provider-shared v1.21.1/go.mod h1:Ioq1OBLb2h9uj4t4KzBEfA1piHbUg+Lgvn84Vbzk5uI=
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/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/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
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.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
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=
@@ -151,21 +169,25 @@ github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx
github.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw=
github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4=
github.com/pjbgf/sha1cd v0.3.0/go.mod h1:nZ1rrWOcGJ5uZgEEVL1VUM9iRQiZvWdbZjkKyFzPPsI=
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.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
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/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k=
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
github.com/russross/blackfriday v1.6.0 h1:KqfZb0pUVN2lYqZUYRddxF4OR8ZMURnJIG5Y3VRLtww=
github.com/russross/blackfriday v1.6.0/go.mod h1:ti0ldHuxg49ri4ksnFxlkCfN+hvslNlmVHqNRXXJNAY=
github.com/samber/lo v1.39.0 h1:4gTz1wUhNYLhFSKl6O+8peW0v2F4BCY034GRpU9WnuA=
github.com/samber/lo v1.39.0/go.mod h1:+m/ZKRl6ClXCE2Lgf3MsQlWfh4bn1bz6CXEOxnEXnEA=
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.0 h1:h9r9cf0+u7wSE+M183ZtMGgOJKiL96brpaz5ekfJCpM=
github.com/skeema/knownhosts v1.2.0/go.mod h1:g4fPeYpque7P0xefxtGzV81ihjC8sX2IqpAoNkjxbMo=
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=
@@ -184,6 +206,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/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
github.com/zclconf/go-cty v1.14.1 h1:t9fyA35fwjjUMcmL5hLER+e/rEPqrbCK1/OSE4SI9KA=
github.com/zclconf/go-cty v1.14.1/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE=
@@ -262,6 +285,7 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn
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.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
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=
@@ -279,6 +303,7 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
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.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
1 change: 1 addition & 0 deletions pkg/platform/provider.go
Original file line number Diff line number Diff line change
@@ -142,6 +142,7 @@ func (p *PlatformProvider) DataSources(ctx context.Context) []func() datasource.
func (p *PlatformProvider) Resources(ctx context.Context) []func() resource.Resource {
return []func() resource.Resource{
NewWorkerServiceResource,
NewReverseProxyResource,
}
}

369 changes: 369 additions & 0 deletions pkg/platform/resource_reverse_proxy.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,369 @@
package platform

import (
"context"
"fmt"
"net/http"
"strings"

"github.com/hashicorp/terraform-plugin-framework-validators/int64validator"
"github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
"github.com/hashicorp/terraform-plugin-framework/diag"
"github.com/hashicorp/terraform-plugin-framework/path"
"github.com/hashicorp/terraform-plugin-framework/resource"
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/boolplanmodifier"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/int64default"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/int64planmodifier"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier"
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/jfrog/terraform-provider-shared/util"
utilfw "github.com/jfrog/terraform-provider-shared/util/fw"
)

const reversProxyEndpoint = "/artifactory/api/system/configuration/webServer"
const maxPortNumber = 65535

var supportedDockerProxyMethods = []string{"SUBDOMAIN", "REPOPATHPREFIX", "PORTPERREPO"}
var supportedServerProviderTypes = []string{"DIRECT", "NGINX", "APACHE"}

var _ resource.Resource = (*reverseProxyResource)(nil)

type reverseProxyResource struct {
ProviderData util.ProvderMetadata
}

func NewReverseProxyResource() resource.Resource {
return &reverseProxyResource{}
}

func (r *reverseProxyResource) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
resp.TypeName = req.ProviderTypeName + "_reverse_proxy"
}
func (r *reverseProxyResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
resp.Schema = schema.Schema{
Attributes: map[string]schema.Attribute{
"docker_reverse_proxy_method": schema.StringAttribute{
Optional: true,
Computed: true,
Description: fmt.Sprintf("Docker access method. The default value is SUBDOMAIN. Supported values: %s.", strings.Join(supportedDockerProxyMethods, ", ")),
Default: stringdefault.StaticString("SUBDOMAIN"),
Validators: []validator.String{stringvalidator.OneOf(supportedDockerProxyMethods...)},
PlanModifiers: []planmodifier.String{
stringplanmodifier.UseStateForUnknown(),
},
},
"server_provider": schema.StringAttribute{
Required: true,
Description: fmt.Sprintf("Set the server provider type. Supported values: %s.", strings.Join(supportedServerProviderTypes, ", ")),
Validators: []validator.String{stringvalidator.OneOf(supportedServerProviderTypes...)},
},
"public_server_name": schema.StringAttribute{
Optional: true,
Description: "The server name that will be used to access Artifactory. Should be correlated with the base URL value. Must be set when `server_provider` is set to `NIGNIX` or `APACHE`",
Validators: []validator.String{
stringvalidator.LengthAtLeast(1),
},
PlanModifiers: []planmodifier.String{
stringplanmodifier.UseStateForUnknown(),
},
},
"internal_hostname": schema.StringAttribute{
Optional: true,
Description: "The internal server name for Artifactory which will be used by the web server to access the Artifactory machine. If the web server is installed on the same machine as Artifactory you can use localhost, otherwise use the IP or hostname. Must be set when `server_provider` is set to `NIGNIX` or `APACHE`",
Validators: []validator.String{
stringvalidator.LengthAtLeast(1),
},
PlanModifiers: []planmodifier.String{
stringplanmodifier.UseStateForUnknown(),
},
},
"use_https": schema.BoolAttribute{
Optional: true,
Computed: true,
Default: booldefault.StaticBool(false),
PlanModifiers: []planmodifier.Bool{
boolplanmodifier.UseStateForUnknown(),
},
Description: "When set, Artifactory will be accessible via HTTPS at the corresponding port that is set. Only settable when `server_provider` is set to `NIGNIX` or `APACHE`",
},
"http_port": schema.Int64Attribute{
Optional: true,
Computed: true,
Default: int64default.StaticInt64(80),
Validators: []validator.Int64{
int64validator.AtMost(maxPortNumber),
},
PlanModifiers: []planmodifier.Int64{
int64planmodifier.UseStateForUnknown(),
},
Description: "The port for access via HTTP. The default value is 80. Only settable when `server_provider` is set to `NIGNIX` or `APACHE`",
},
"https_port": schema.Int64Attribute{
Optional: true,
Computed: true,
Default: int64default.StaticInt64(443),
Validators: []validator.Int64{
int64validator.AtMost(maxPortNumber),
},
PlanModifiers: []planmodifier.Int64{
int64planmodifier.UseStateForUnknown(),
},
Description: "The port for access via HTTPS. The default value is 443. Only settable when `use_https` is set to `true`",
},
"ssl_key_path": schema.StringAttribute{
Optional: true,
Description: "The full path of the key file on the web server, e.g. `/etc/ssl/private/myserver.key`. Must be set when `use_https` is set to `true`",
Validators: []validator.String{
stringvalidator.LengthAtLeast(1),
},
PlanModifiers: []planmodifier.String{
stringplanmodifier.UseStateForUnknown(),
},
},
"ssl_certificate_path": schema.StringAttribute{
Optional: true,
Description: "The full path of the certificate file on the web server, e.g. `/etc/ssl/certs/myserver.crt`. Must be set when `use_https` is set to `true`",
Validators: []validator.String{
stringvalidator.LengthAtLeast(1),
},
PlanModifiers: []planmodifier.String{
stringplanmodifier.UseStateForUnknown(),
},
},
},
MarkdownDescription: "Provides a JFrog [Reverse Proxy](https://jfrog.com/help/r/jfrog-artifactory-documentation/reverse-proxy-settings) resource.\n\n~>Only available for self-hosted instances.",
}
}

type reverseProxyResourceModel struct {
DockerReverseProxyMethod types.String `tfsdk:"docker_reverse_proxy_method"`
ServerProvider types.String `tfsdk:"server_provider"`
PublicServerName types.String `tfsdk:"public_server_name"`
InternalHostname types.String `tfsdk:"internal_hostname"`
UseHttps types.Bool `tfsdk:"use_https"`
HttpPort types.Int64 `tfsdk:"http_port"`
HttpsPort types.Int64 `tfsdk:"https_port"`
SslKeyPath types.String `tfsdk:"ssl_key_path"`
SslCertificatePath types.String `tfsdk:"ssl_certificate_path"`
}

func (r *reverseProxyResourceModel) toAPIModel(ctx context.Context, apiModel *reverseProxyAPIModel) (ds diag.Diagnostics) {
*apiModel = reverseProxyAPIModel{
Key: strings.ToLower(r.ServerProvider.ValueString()),
WebServerType: r.ServerProvider.ValueString(),
ArtifactoryAppContext: "artifactory",
PublicAppContext: "artifactory",
ServerName: r.PublicServerName.ValueString(),
ArtifactoryServerName: r.InternalHostname.ValueString(),
DockerReverseProxyMethod: r.DockerReverseProxyMethod.ValueString(),
UseHttp: true,
UseHttps: r.UseHttps.ValueBool(),
HttpPort: r.HttpPort.ValueInt64(),
HttpsPort: r.HttpsPort.ValueInt64(),
SslKey: r.SslKeyPath.ValueString(),
SslCertificate: r.SslCertificatePath.ValueString(),
}

return nil
}

func (r *reverseProxyResourceModel) fromAPIModel(ctx context.Context, apiModel *reverseProxyAPIModel) (ds diag.Diagnostics) {
r.ServerProvider = types.StringValue(apiModel.WebServerType)
r.DockerReverseProxyMethod = types.StringValue(apiModel.DockerReverseProxyMethod)
r.PublicServerName = types.StringValue(apiModel.ServerName)
r.InternalHostname = types.StringValue(apiModel.ArtifactoryServerName)
r.UseHttps = types.BoolValue(apiModel.UseHttps)
r.HttpPort = types.Int64Value(apiModel.HttpPort)
r.HttpsPort = types.Int64Value(apiModel.HttpsPort)

// API will return empty string if not configured. Therefore we only update if it isn't empty
if apiModel.SslKey != "" {
r.SslKeyPath = types.StringValue(apiModel.SslKey)
}

// API will return empty string if not configured. Therefore we only update if it isn't empty
if apiModel.SslCertificate != "" {
r.SslCertificatePath = types.StringValue(apiModel.SslCertificate)
}

return
}

type reverseProxyAPIModel struct {
Key string `json:"key"`
WebServerType string `json:"webServerType"`
ArtifactoryAppContext string `json:"artifactoryAppContext"`
PublicAppContext string `json:"publicAppContext"`
ServerName string `json:"serverName"`
ArtifactoryServerName string `json:"artifactoryServerName"`
DockerReverseProxyMethod string `json:"dockerReverseProxyMethod"`
UseHttp bool `json:"useHttp"`
UseHttps bool `json:"useHttps"`
HttpPort int64 `json:"httpPort"`
HttpsPort int64 `json:"httpsPort"`
SslKey string `json:"sslKey,omitempty"`
SslCertificate string `json:"sslCertificate,omitempty"`
}

func (r *reverseProxyResource) Configure(ctx context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) {
// Prevent panic if the provider has not been configured.
if req.ProviderData == nil {
return
}
r.ProviderData = req.ProviderData.(util.ProvderMetadata)
}

func (r *reverseProxyResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
var plan reverseProxyResourceModel

resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
if resp.Diagnostics.HasError() {
return
}

var reverseProxy reverseProxyAPIModel
resp.Diagnostics.Append(plan.toAPIModel(ctx, &reverseProxy)...)
if resp.Diagnostics.HasError() {
return
}

response, err := r.ProviderData.Client.R().
SetBody(&reverseProxy).
Post(reversProxyEndpoint)
if err != nil {
utilfw.UnableToCreateResourceError(resp, err.Error())
return
}

// Return error if the HTTP status code is not 201 Created
if response.StatusCode() != http.StatusCreated {
utilfw.UnableToCreateResourceError(resp, response.String())
return
}

resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...)
}

func (r *reverseProxyResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
var state reverseProxyResourceModel

resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
if resp.Diagnostics.HasError() {
return
}

var reverseProxy reverseProxyAPIModel

response, err := r.ProviderData.Client.R().
SetResult(&reverseProxy).
Get(reversProxyEndpoint)

// Treat HTTP 404 Not Found status as a signal to recreate resource
// and return early
if err != nil {
utilfw.UnableToRefreshResourceError(resp, response.String())
return
}

// Convert from the API data model to the Terraform data model
// and refresh any attribute values.
resp.Diagnostics.Append(state.fromAPIModel(ctx, &reverseProxy)...)
if resp.Diagnostics.HasError() {
return
}

resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
}

func (r *reverseProxyResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
var plan reverseProxyResourceModel

resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
if resp.Diagnostics.HasError() {
return
}

var reverseProxy reverseProxyAPIModel
resp.Diagnostics.Append(plan.toAPIModel(ctx, &reverseProxy)...)
if resp.Diagnostics.HasError() {
return
}

response, err := r.ProviderData.Client.R().
SetBody(&reverseProxy).
Post(reversProxyEndpoint)
if err != nil {
utilfw.UnableToUpdateResourceError(resp, err.Error())
return
}

// Return error if the HTTP status code is not 201 Created
if response.StatusCode() != http.StatusCreated {
utilfw.UnableToUpdateResourceError(resp, response.String())
return
}

resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...)
}

func (r *reverseProxyResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
resp.Diagnostics.AddWarning(
"Unable to Delete Resource",
"Reverse proxy cannot be deleted.",
)
}

func (r *reverseProxyResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) {
resource.ImportStatePassthroughID(ctx, path.Root("server_provider"), req, resp)
}

func (r reverseProxyResource) ValidateConfig(ctx context.Context, req resource.ValidateConfigRequest, resp *resource.ValidateConfigResponse) {
var config reverseProxyResourceModel

resp.Diagnostics.Append(req.Config.Get(ctx, &config)...)
if resp.Diagnostics.HasError() {
return
}

switch serverProvider := config.ServerProvider.ValueString(); serverProvider {
case "NGINX", "APACHE":
if config.InternalHostname.IsNull() || config.InternalHostname.IsUnknown() {
resp.Diagnostics.AddAttributeError(
path.Root("internal_hostname"),
"Missing Attribute Configuration",
fmt.Sprintf("internal_hostname must be configured when server_provider is set to '%s'.", serverProvider),
)
}

if config.PublicServerName.IsNull() || config.PublicServerName.IsUnknown() {
resp.Diagnostics.AddAttributeError(
path.Root("public_server_name"),
"Missing Attribute Configuration",
fmt.Sprintf("public_server_name must be configured when server_provider is set to '%s'.", serverProvider),
)
}
}

if config.UseHttps.ValueBool() {
if config.SslKeyPath.IsNull() || config.SslKeyPath.IsUnknown() {
resp.Diagnostics.AddAttributeError(
path.Root("ssl_key_path"),
"Missing Attribute Configuration",
"ssl_key_path must be configured when use_https is set to 'true'.",
)
}

if config.SslCertificatePath.IsNull() || config.SslCertificatePath.IsUnknown() {
resp.Diagnostics.AddAttributeError(
path.Root("ssl_certificate_path"),
"Missing Attribute Configuration",
"ssl_certificate_path must be configured when use_https is set to 'true'.",
)
}
}
}
246 changes: 246 additions & 0 deletions pkg/platform/resource_reverse_proxy_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,246 @@
package platform_test

import (
"fmt"
"regexp"
"testing"

"github.com/hashicorp/terraform-plugin-testing/helper/resource"
"github.com/jfrog/terraform-provider-shared/testutil"
)

func TestAccReverseProxy_full(t *testing.T) {
_, fqrn, reverseProxyName := testutil.MkNames("test-reverse-proxy", "platform_reverse_proxy")

temp := `
resource "platform_reverse_proxy" "{{ .name }}" {
docker_reverse_proxy_method = "{{ .dockerProxyMethod }}"
server_provider = "{{ .serverProvider }}"
public_server_name = "{{ .serverName }}"
internal_hostname = "localhost"
}`

testData := map[string]string{
"name": reverseProxyName,
"dockerProxyMethod": "SUBDOMAIN",
"serverProvider": "NGINX",
"serverName": "tempurl.org",
}

config := testutil.ExecuteTemplate(reverseProxyName, temp, testData)

updatedTemp := `
resource "platform_reverse_proxy" "{{ .name }}" {
docker_reverse_proxy_method = "{{ .dockerProxyMethod }}"
server_provider = "{{ .serverProvider }}"
public_server_name = "{{ .serverName }}"
internal_hostname = "localhost"
http_port = {{ .httpPort }}
use_https = {{ .useHttps }}
https_port = {{ .httpsPort }}
ssl_key_path = "{{ .sslKeyPath }}"
ssl_certificate_path = "{{ .sslCertPath }}"
}`

updatedTestData := map[string]string{
"name": reverseProxyName,
"dockerProxyMethod": "REPOPATHPREFIX",
"serverProvider": "NGINX",
"serverName": "tempurl.org",
"httpPort": "88",
"useHttps": "true",
"httpsPort": "666",
"sslKeyPath": "foo/bar.key",
"sslCertPath": "foo/bar.crt",
}
updatedConfig := testutil.ExecuteTemplate(reverseProxyName, updatedTemp, updatedTestData)

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
ProtoV6ProviderFactories: testAccProviders(),
Steps: []resource.TestStep{
{
Config: config,
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(fqrn, "docker_reverse_proxy_method", testData["dockerProxyMethod"]),
resource.TestCheckResourceAttr(fqrn, "server_provider", testData["serverProvider"]),
resource.TestCheckResourceAttr(fqrn, "public_server_name", testData["serverName"]),
resource.TestCheckResourceAttr(fqrn, "internal_hostname", "localhost"),
resource.TestCheckResourceAttr(fqrn, "use_https", "false"),
resource.TestCheckResourceAttr(fqrn, "http_port", "80"),
resource.TestCheckResourceAttr(fqrn, "https_port", "443"),
resource.TestCheckNoResourceAttr(fqrn, "ssl_key_path"),
resource.TestCheckNoResourceAttr(fqrn, "ssl_certificate_path"),
),
},
{
Config: updatedConfig,
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(fqrn, "docker_reverse_proxy_method", updatedTestData["dockerProxyMethod"]),
resource.TestCheckResourceAttr(fqrn, "server_provider", updatedTestData["serverProvider"]),
resource.TestCheckResourceAttr(fqrn, "public_server_name", updatedTestData["serverName"]),
resource.TestCheckResourceAttr(fqrn, "internal_hostname", "localhost"),
resource.TestCheckResourceAttr(fqrn, "use_https", updatedTestData["useHttps"]),
resource.TestCheckResourceAttr(fqrn, "http_port", updatedTestData["httpPort"]),
resource.TestCheckResourceAttr(fqrn, "https_port", updatedTestData["httpsPort"]),
resource.TestCheckResourceAttr(fqrn, "ssl_key_path", updatedTestData["sslKeyPath"]),
resource.TestCheckResourceAttr(fqrn, "ssl_certificate_path", updatedTestData["sslCertPath"]),
),
},
{
ResourceName: fqrn,
ImportState: true,
ImportStateId: reverseProxyName,
ImportStateVerify: true,
ImportStateVerifyIdentifierAttribute: "server_provider",
},
},
})
}

func TestAccReverseProxy_invalid_server_provider(t *testing.T) {
for _, serverProvider := range []string{"NGINX", "APACHE"} {
t.Run(serverProvider, func(t *testing.T) {
resource.Test(testAccReverseProxy_missing_internal_hostname(t, serverProvider))
resource.Test(testAccReverseProxy_missing_public_server_name(t, serverProvider))
})
}
}

func testAccReverseProxy_missing_internal_hostname(t *testing.T, serverProvider string) (*testing.T, resource.TestCase) {
_, _, reverseProxyName := testutil.MkNames("test-reverse-proxy", "platform_reverse_proxy")

temp := `
resource "platform_reverse_proxy" "{{ .name }}" {
docker_reverse_proxy_method = "SUBDOMAIN"
server_provider = "{{ .serverProvider }}"
public_server_name = "{{ .serverName }}"
}`

testData := map[string]string{
"name": reverseProxyName,
"dockerProxyMethod": "SUBDOMAIN",
"serverProvider": serverProvider,
"serverName": "tempurl.org",
}

config := testutil.ExecuteTemplate(reverseProxyName, temp, testData)

return t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
ProtoV6ProviderFactories: testAccProviders(),
Steps: []resource.TestStep{
{
Config: config,
ExpectError: regexp.MustCompile(fmt.Sprintf(`.*internal_hostname must be configured when server_provider is set to '%s'.*`, serverProvider)),
},
},
}
}

func testAccReverseProxy_missing_public_server_name(t *testing.T, serverProvider string) (*testing.T, resource.TestCase) {
_, _, reverseProxyName := testutil.MkNames("test-reverse-proxy", "platform_reverse_proxy")

temp := `
resource "platform_reverse_proxy" "{{ .name }}" {
docker_reverse_proxy_method = "SUBDOMAIN"
server_provider = "{{ .serverProvider }}"
internal_hostname = "localhost"
}`

testData := map[string]string{
"name": reverseProxyName,
"dockerProxyMethod": "SUBDOMAIN",
"serverProvider": serverProvider,
}

config := testutil.ExecuteTemplate(reverseProxyName, temp, testData)

return t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
ProtoV6ProviderFactories: testAccProviders(),
Steps: []resource.TestStep{
{
Config: config,
ExpectError: regexp.MustCompile(`.*public_server_name must be configured when server_provider is set to.*`),
},
},
}
}

func TestAccReverseProxy_invalid_https(t *testing.T) {
for _, serverProvider := range []string{"NGINX", "APACHE"} {
t.Run(serverProvider, func(t *testing.T) {
resource.Test(testAccReverseProxy_missing_ssl_key_path(t, serverProvider))
resource.Test(testAccReverseProxy_missing_ssl_certificate_path(t, serverProvider))
})
}
}

func testAccReverseProxy_missing_ssl_key_path(t *testing.T, serverProvider string) (*testing.T, resource.TestCase) {
_, _, reverseProxyName := testutil.MkNames("test-reverse-proxy", "platform_reverse_proxy")

temp := `
resource "platform_reverse_proxy" "{{ .name }}" {
docker_reverse_proxy_method = "SUBDOMAIN"
server_provider = "NGINX"
public_server_name = "{{ .serverName }}"
internal_hostname = "localhost"
use_https = true
ssl_certificate_path = "/foo/bar.crt"
}`

testData := map[string]string{
"name": reverseProxyName,
"dockerProxyMethod": "SUBDOMAIN",
"serverProvider": serverProvider,
"serverName": "tempurl.org",
}

config := testutil.ExecuteTemplate(reverseProxyName, temp, testData)

return t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
ProtoV6ProviderFactories: testAccProviders(),
Steps: []resource.TestStep{
{
Config: config,
ExpectError: regexp.MustCompile(`ssl_key_path must be configured when use_https is set to 'true'.`),
},
},
}
}

func testAccReverseProxy_missing_ssl_certificate_path(t *testing.T, serverProvider string) (*testing.T, resource.TestCase) {
_, _, reverseProxyName := testutil.MkNames("test-reverse-proxy", "platform_reverse_proxy")

temp := `
resource "platform_reverse_proxy" "{{ .name }}" {
docker_reverse_proxy_method = "SUBDOMAIN"
server_provider = "NGINX"
public_server_name = "{{ .serverName }}"
internal_hostname = "localhost"
use_https = true
ssl_key_path = "/foo/bar.key"
}`

testData := map[string]string{
"name": reverseProxyName,
"dockerProxyMethod": "SUBDOMAIN",
"serverProvider": serverProvider,
"serverName": "tempurl.org",
}

config := testutil.ExecuteTemplate(reverseProxyName, temp, testData)

return t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
ProtoV6ProviderFactories: testAccProviders(),
Steps: []resource.TestStep{
{
Config: config,
ExpectError: regexp.MustCompile(`ssl_certificate_path must be configured when use_https is set to 'true'.`),
},
},
}
}