diff --git a/docs/appendices/0.31.0-migration-guide.md b/docs/appendices/0.31.0-migration-guide.md index 547cbc6cecb..e818193997c 100644 --- a/docs/appendices/0.31.0-migration-guide.md +++ b/docs/appendices/0.31.0-migration-guide.md @@ -1,5 +1,6 @@ -# 0.30.0 Migration Guide +# 0.31.0 Migration Guide ## Changes - Herokuish build cache is now mounted from a docker volume - eg. `cache-node-js-app` - instead of the local filesystem. All existing app cache will be cleared upon upgrading past 0.29.0. +- The `proxy:ports*` commands have been replaced with the new `ports` plugin. Users will be able to use the old `proxy:ports*` commands for a single minor release, and they will be removed in the next minor release. diff --git a/docs/configuration/environment-variables.md b/docs/configuration/environment-variables.md index c4498062fe8..e48084557dd 100644 --- a/docs/configuration/environment-variables.md +++ b/docs/configuration/environment-variables.md @@ -116,7 +116,7 @@ The following config variables have special meanings and can be set in a variety | `DOKKU_PARALLEL_ARGUMENTS`. | none | `dokku config:set` | Allows passing custom arguments to parallel for `ps:*all` commands | | `DOKKU_PROXY_PORT` | automatically assigned | `/etc/environment`
`~dokku/.dokkurc`
`~dokku/.dokkurc/*`
`dokku config:set` | | | `DOKKU_PROXY_SSL_PORT` | automatically assigned | `/etc/environment`
`~dokku/.dokkurc`
`~dokku/.dokkurc/*`
`dokku config:set` | | -| `DOKKU_PROXY_PORT_MAP` | automatically assigned | `dokku proxy:ports-add`
`dokku proxy:ports-remove`, `dokku proxy:ports-clear` | | +| `DOKKU_PROXY_PORT_MAP` | automatically assigned | `dokku ports:add`
`dokku ports:remove`, `dokku ports:clear` | | | `DOKKU_SKIP_ALL_CHECKS` | none | `dokku config:set` | | | `DOKKU_SKIP_CLEANUP` | | `/etc/environment`
`~dokku/.dokkurc`
`~dokku/.dokkurc/*` | When a deploy is triggered, if this is set to a non-empty value, then old docker containers and images will not be removed. | | `DOKKU_SKIP_DEFAULT_CHECKS` | | `dokku config:set` | | diff --git a/docs/configuration/ssl.md b/docs/configuration/ssl.md index 42664a7491e..abb0f9f6293 100644 --- a/docs/configuration/ssl.md +++ b/docs/configuration/ssl.md @@ -134,7 +134,7 @@ Certain versions of nginx have bugs that prevent [HTTP/2](https://nginx.org/en/d ### SSL Port Exposure -When your app is served from port `80` then the `/home/dokku/APP/nginx.conf` file will automatically be updated to instruct nginx to respond to ssl on port 443 as a new cert is added. If your app uses a non-standard port (perhaps you have a dockerfile deploy exposing port `99999`) you may need to manually expose an ssl port via `dokku proxy:ports-add https:443:99999`. +When your app is served from port `80` then the `/home/dokku/APP/nginx.conf` file will automatically be updated to instruct nginx to respond to ssl on port 443 as a new cert is added. If your app uses a non-standard port (perhaps you have a dockerfile deploy exposing port `99999`) you may need to manually expose an ssl port via `dokku ports:add https:443:99999`. ## Other diff --git a/docs/development/plugin-triggers.md b/docs/development/plugin-triggers.md index a141b115f71..f74e6afb12c 100644 --- a/docs/development/plugin-triggers.md +++ b/docs/development/plugin-triggers.md @@ -1498,8 +1498,8 @@ popd &>/dev/null ### `post-proxy-ports-update` -- Description: Allows you to run commands once the proxy port mappings for an app have been updated. It also sends the invoking command. This can be "add", "clear" or "remove". -- Invoked by: `dokku proxy:ports-add`, `dokku proxy:ports-clear`, `dokku proxy:ports-remove` +- Description: Allows you to run commands once the port mappings for an app have been updated. It also sends the invoking command. This can be "add", "clear" or "remove". +- Invoked by: `dokku ports:add`, `dokku ports:clear`, `dokku ports:remove` - Arguments: `$APP` `action name` - Example: @@ -1842,7 +1842,7 @@ set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x ### `proxy-configure-ports` -- Description: Configures the proxy port mapping +- Description: Configures the port mapping - Invoked by: `internally triggered by proxy plugins` - Arguments: `$APP` - Example: diff --git a/docs/getting-started/troubleshooting.md b/docs/getting-started/troubleshooting.md index e0e4d7b6e78..9677f27b970 100644 --- a/docs/getting-started/troubleshooting.md +++ b/docs/getting-started/troubleshooting.md @@ -74,12 +74,12 @@ For example, if you have an `EXPOSE` directive like so: EXPOSE 8000 ``` -The proxy port mapping will be `http:8000:8000`. +The port mapping will be `http:8000:8000`. To avoid this issue, either of the following can be done: -- Remove `EXPOSE` directive: This will require respecting the `$PORT` environment variable (automatically set by Dokku). Once that change is deployed, the port mapping should be cleared via the `dokku proxy:ports-clear $APP` command (where `$APP` is your app name). -- Update the port mapping: Updating the port mapping to redirect port `80` to your app's exposed port via `dokku proxy:ports-set $APP http:80:$EXPOSED_PORT` can also fix the issue. This will also allow certificate management and the letsencrypt plugin to work correctly. +- Remove `EXPOSE` directive: This will require respecting the `$PORT` environment variable (automatically set by Dokku). Once that change is deployed, the port mapping should be cleared via the `dokku ports:clear $APP` command (where `$APP` is your app name). +- Update the port mapping: Updating the port mapping to redirect port `80` to your app's exposed port via `dokku ports:set $APP http:80:$EXPOSED_PORT` can also fix the issue. This will also allow certificate management and the letsencrypt plugin to work correctly. See the [port management documentation](/docs/networking/port-management.md) for more information on how Dokku exposes ports for applications and how you can configure these for your app. @@ -235,16 +235,14 @@ If this solves the issue temporarily, longer term you should consider [configuri ### My application deploys properly, but won't load in browser "connection refused" -This could be a result of a bad proxy configuration (`http:5000:5000` may be incorrect). Run `dokku proxy:report myapp` to check if your app has the correct proxy configuration. It should show something like the following. +This could be a result of a bad proxy configuration (`http:5000:5000` may be incorrect). Run `dokku ports:report node-js-app` to check if your app has the correct proxy configuration. It should show something like the following. ``` -=====> myapp proxy information - Proxy enabled: true - Proxy port map: http:80:5000 https:443:5000 - Proxy type: nginx +=====> node-js-app ports information + Port map: http:80:5000 https:443:5000 ``` -Set `dokku proxy:ports-set front http:80:5000` to get proxy correctly configured for http endpoint. +Set `dokku ports:set node-js-app http:80:5000` to get proxy correctly configured for http endpoint. ### I deployed a new app but now subdomains are miss-routed diff --git a/docs/networking/port-management.md b/docs/networking/port-management.md index 9cab146dcf3..3fcca069656 100644 --- a/docs/networking/port-management.md +++ b/docs/networking/port-management.md @@ -1,37 +1,52 @@ # Port Management -> New as of 0.5.0, Enhanced in 0.6.0 +> New as of 0.31.0, replaces the previous `proxy:ports*` commands ``` -proxy:ports # List proxy port mappings for an app -proxy:ports-add :: [::...] # Add proxy port mappings to an app -proxy:ports-clear # Clear all proxy port mappings for an app -proxy:ports-remove [|::...] # Remove specific proxy port mappings from an app -proxy:ports-set :: [::...] # Set proxy port mappings for an app +ports:list # List port mappings for an app +ports:add :: [::...] # Add port mappings to an app +ports:clear # Clear all port mappings for an app +ports:remove [|::...] # Remove specific port mappings from an app +ports:set :: [::...] # Set port mappings for an app ``` -In Dokku 0.5.0, port proxying was decoupled from the `nginx-vhosts` plugin into the proxy plugin. Dokku 0.6.0 introduced the ability to map host ports to specific container ports. In the future this will allow other proxy software - such as HAProxy or Caddy - to be used in place of nginx. - ## Usage > Warning: Mapping alternative ports may conflict with the active firewall installed on your server or hosting provider. Such software includes - but is not limited to - AWS Security Groups, iptables, and UFW. Please consult the documentation for those softwares as applicable. > > Users should also avoid setting the `PORT` environment variable. Dokku will use port mappings to set this value. Overriding this manually may cause issues in application routing. -> New as of 0.6.0 - -You can now configure `host -> container` port mappings with the `proxy:ports-*` commands. This mapping is currently supported by the built-in nginx-vhosts plugin. +You can now configure `host -> container` port mappings with the `ports:*` commands. This mapping is currently supported by the built-in nginx-vhosts plugin. By default, buildpack apps and dockerfile apps **without** explicitly exposed ports (i.e. using the `EXPOSE` directive) will be configured with a listener on port `80` (and additionally a listener on 443 if ssl is enabled) that will proxy to the application container on port `5000`. Dockerfile apps **with** explicitly exposed ports will be configured with a listener on each exposed port and will proxy to that same port of the deployed application container. -> Note: This default behavior **will not** be automatically changed on subsequent pushes and must be manipulated with the `proxy:ports-*` commands detailed below. +> Note: This default behavior **will not** be automatically changed on subsequent pushes and must be manipulated with the `ports:*` commands detailed below. + +### Port Scheme + +The proxy port scheme is as follows: + +- `SCHEME:HOST_PORT:CONTAINER_PORT` + +The scheme metadata can be used by proxy implementations in order to properly handle proxying of requests. For example, the built-in `nginx-vhosts` proxy implementation supports the `http`, `https`, `grpc` and `grpcs` schemes. +For the `grpc` and `grpcs` see [nginx blog post on grpc](https://www.nginx.com/blog/nginx-1-13-10-grpc/). + +Developers of proxy implementations are encouraged to use whatever schemes make the most sense, and ignore configurations which they do not support. For instance, a `udp` proxy implementation can safely ignore `http` and `https` port mappings. + +To change the proxy implementation in use for an application, use the `proxy:set` command: + +```shell +# no validation will be performed against +# the specified proxy implementation +dokku proxy:set node-js-app nginx +``` ### Listing port mappings -To inspect the port mapping for a given application, use the `proxy:ports` command: +To inspect the port mapping for a given application, use the `ports:list` command: ```shell -dokku proxy:ports node-js-app +dokku ports:list node-js-app ``` ``` @@ -62,10 +77,10 @@ curl http://node-js-app.dokku.me:8080 curl: (7) Failed to connect to node-js-app.dokku.me port 8080: Connection refused ``` -However, we can use the `proxy:ports-add` command to add a second external port mapping - `8080` - to our application's port `5000`. +However, we can use the `ports:add` command to add a second external port mapping - `8080` - to our application's port `5000`. ```shell -dokku proxy:ports-add node-js-app http:8080:5000 +dokku ports:add node-js-app http:8080:5000 ``` ``` @@ -98,10 +113,10 @@ Hello World! ### Setting all port mappings at once -Port mappings can also be force set using the `proxy:ports-set` command. +Port mappings can also be force set using the `ports:set` command. ```shell -dokku proxy:ports-set node-js-app http:8080:5000 +dokku ports:set node-js-app http:8080:5000 ``` ``` @@ -114,21 +129,21 @@ dokku proxy:ports-set node-js-app http:8080:5000 ### Removing a port mapping -A port mapping can be removed using the `proxy:ports-remove` command if it no longer necessary: +A port mapping can be removed using the `ports:remove` command if it no longer necessary: ```shell -dokku proxy:ports-remove node-js-app http:80:5000 +dokku ports:remove node-js-app http:80:5000 ``` Ports may also be removed by specifying only the `host-port` value. This effectively acts as a wildcard and removes all mappings for that particular host port. ```shell -dokku proxy:ports-remove node-js-app http:80 +dokku ports:remove node-js-app http:80 ``` ## Port management by Deployment Method -> Warning: If you set a proxy port map but _do not have a global domain set_, Dokku will reset that map upon first deployment. +> Warning: If you set a port map but _do not have a global domain set_, Dokku will reset that map upon first deployment. ### Buildpacks @@ -156,10 +171,10 @@ The application would be exposed to the user at `node-js-app.dokku.me:1234`. If ```shell # add a port mapping to port 80 -dokku proxy:ports-add node-js-app http:80:1234 +dokku ports:add node-js-app http:80:1234 # remove the incorrect port mapping -dokku proxy:ports-remove node-js-app http:1234:1234 +dokku ports:remove node-js-app http:1234:1234 ``` #### Applications not using EXPOSE @@ -176,7 +191,7 @@ When switching between `EXPOSE` usage modes, it is important to reset your port ```shell # assuming your application is called `node-js-app` dokku config:unset --no-restart node-js-app DOKKU_DOCKERFILE_PORTS PORT -dokku proxy:ports-clear node-js-app +dokku ports:clear node-js-app ``` ### Docker Image @@ -186,7 +201,41 @@ When deploying an image, we will use `docker inspect` to extract the `ExposedPor ```shell # assuming your application is called `node-js-app` dokku config:set node-js-app DOKKU_DOCKERFILE_PORTS="1234/tcp 80/tcp" -dokku proxy:ports-clear node-js-app +dokku ports:clear node-js-app ``` All other port-related behavior is the same as when deploying via Dockerfile. + +### Displaying ports reports for an app + +You can get a report about the app's ports status using the `ports:report` command: + +```shell +dokku ports:report +``` + +``` +=====> node-js-app ports information + Port map: http:80:5000 https:443:5000 +=====> python-sample ports information + Port map: http:80:5000 +=====> ruby-sample ports information + Port map: http:80:5000 +``` + +You can run the command for a specific app also. + +```shell +dokku ports:report node-js-app +``` + +``` +=====> node-js-app ports information + Port map: http:80:5000 https:443:5000 +``` + +You can pass flags which will output only the value of the specific information you want. For example: + +```shell +dokku ports:report node-js-app --ports-map +``` diff --git a/docs/networking/proxies/nginx.md b/docs/networking/proxies/nginx.md index 1f6213f9f39..a5ec6deec78 100644 --- a/docs/networking/proxies/nginx.md +++ b/docs/networking/proxies/nginx.md @@ -506,7 +506,7 @@ See the [proxy documentation](/docs/networking/proxy-management.md) for more inf ### Managing Proxy Port mappings -See the [proxy documentation](/docs/networking/proxy-management.md#proxy-port-mapping) for more information on how to manage ports proxied for your app. +See the [ports documentation](/docs/networking/port-management.md) for more information on how to manage ports proxied for your app. ### Regenerating nginx config diff --git a/docs/networking/proxy-management.md b/docs/networking/proxy-management.md index a716952fb2b..4366acbe4c3 100644 --- a/docs/networking/proxy-management.md +++ b/docs/networking/proxy-management.md @@ -73,15 +73,12 @@ dokku proxy:report =====> node-js-app proxy information Proxy enabled: true Proxy type: nginx - Proxy port map: http:80:5000 https:443:5000 =====> python-sample proxy information Proxy enabled: true Proxy type: nginx - Proxy port map: http:80:5000 =====> ruby-sample proxy information Proxy enabled: true Proxy type: nginx - Proxy port map: http:80:5000 ``` You can run the command for a specific app also. @@ -94,7 +91,6 @@ dokku proxy:report node-js-app =====> node-js-app proxy information Proxy enabled: true Proxy type: nginx - Proxy port map: http:80:5000 https:443:5000 ``` You can pass flags which will output only the value of the specific information you want. For example: @@ -105,22 +101,7 @@ dokku proxy:report node-js-app --proxy-type #### Proxy Port Scheme -The proxy port scheme is as follows: - -- `SCHEME:HOST_PORT:CONTAINER_PORT` - -The scheme metadata can be used by proxy implementations in order to properly handle proxying of requests. For example, the built-in `nginx-vhosts` proxy implementation supports the `http`, `https`, `grpc` and `grpcs` schemes. -For the `grpc` and `grpcs` see [nginx blog post on grpc](https://www.nginx.com/blog/nginx-1-13-10-grpc/). - -Developers of proxy implementations are encouraged to use whatever schemes make the most sense, and ignore configurations which they do not support. For instance, a `udp` proxy implementation can safely ignore `http` and `https` port mappings. - -To change the proxy implementation in use for an application, use the `proxy:set` command: - -```shell -# no validation will be performed against -# the specified proxy implementation -dokku proxy:set node-js-app nginx -``` +See the [port scheme documentation](/docs/networking/port-management.md#port-scheme) for more information on the port mapping scheme used by dokku. ### Proxy port mapping @@ -136,7 +117,7 @@ From Dokku versions `0.5.0` until `0.11.0`, enabling or disabling an application Custom plugins names _must_ have the suffix `-vhosts` or scheduler overriding via `proxy:set` may not function as expected. -At this time, the following dokku commands are used to implement a complete proxy implementation. +At this time, the following dokku commands are used to interact with a complete proxy implementation. - `domains:add`: Adds a given domain to an app. - triggers: `post-domains-update` @@ -158,13 +139,13 @@ At this time, the following dokku commands are used to implement a complete prox - triggers: `proxy-disable` - `proxy:enable`: Enables the proxy configuration for an app. - triggers: `proxy-enable` -- `proxy:ports-add`: Adds one or more port mappings to an app +- `ports:add`: Adds one or more port mappings to an app - triggers: `post-proxy-ports-update` -- `proxy:ports-clear`: Clears out all port mappings for an app. +- `ports:clear`: Clears out all port mappings for an app. - triggers: `post-proxy-ports-update` -- `proxy:ports-remove`: Removes one or more port mappings from an app. +- `ports:remove`: Removes one or more port mappings from an app. - triggers: `post-proxy-ports-update` -- `proxy:ports-set`: Sets all port mappings for an app. +- `ports:set`: Sets all port mappings for an app. - triggers: `post-proxy-ports-update` Proxy implementations may decide to omit some functionality here, or use plugin triggers to supplement config with information from other plugins. diff --git a/plugins/ports/.gitignore b/plugins/ports/.gitignore new file mode 100644 index 00000000000..291036bd409 --- /dev/null +++ b/plugins/ports/.gitignore @@ -0,0 +1,7 @@ +/commands +/subcommands/* +/triggers/* +/triggers +/install +/post-* +/report diff --git a/plugins/ports/Makefile b/plugins/ports/Makefile new file mode 100644 index 00000000000..2149ff8543e --- /dev/null +++ b/plugins/ports/Makefile @@ -0,0 +1,6 @@ +SUBCOMMANDS = subcommands/list subcommands/add subcommands/clear subcommands/remove subcommands/set subcommands/report +TRIGGERS = triggers/post-certs-remove triggers/post-certs-update triggers/report +BUILD = commands subcommands triggers +PLUGIN_NAME = ports + +include ../../common.mk diff --git a/plugins/ports/functions.go b/plugins/ports/functions.go new file mode 100644 index 00000000000..06fdc164115 --- /dev/null +++ b/plugins/ports/functions.go @@ -0,0 +1,188 @@ +package ports + +import ( + "errors" + "fmt" + "os" + "sort" + "strconv" + "strings" + + "github.com/dokku/dokku/plugins/common" + "github.com/dokku/dokku/plugins/config" + "github.com/ryanuber/columnize" +) + +func addPortMaps(appName string, portMaps []PortMap) error { + allPortMaps := getPortMaps(appName) + allPortMaps = append(allPortMaps, portMaps...) + + return setPortMaps(appName, allPortMaps) +} + +func filterAppPortMaps(appName string, scheme string, hostPort int) []PortMap { + var filteredPortMaps []PortMap + for _, portMap := range getPortMaps(appName) { + if portMap.Scheme == scheme && portMap.HostPort == hostPort { + filteredPortMaps = append(filteredPortMaps, portMap) + } + } + + return filteredPortMaps +} + +func getPortMaps(appName string) []PortMap { + value := config.GetWithDefault(appName, "DOKKU_PROXY_PORT_MAP", "") + portMaps, _ := parsePortMapString(value) + return portMaps +} + +func inRange(value int, min int, max int) bool { + return min < value && value < max +} + +func listAppPortMaps(appName string) error { + portMaps := getPortMaps(appName) + + if len(portMaps) == 0 { + return errors.New("No port mappings configured for app") + } + + var lines []string + if os.Getenv("DOKKU_QUIET_OUTPUT") == "" { + lines = append(lines, "-----> scheme:host port:container port") + } + + for _, portMap := range portMaps { + lines = append(lines, portMap.String()) + } + + sort.Strings(lines) + common.LogInfo1Quiet(fmt.Sprintf("Port mappings for %s", appName)) + config := columnize.DefaultConfig() + config.Delim = ":" + config.Prefix = " " + config.Empty = "" + fmt.Println(columnize.Format(lines, config)) + return nil +} + +func parsePortMapString(stringPortMap string) ([]PortMap, error) { + var portMaps []PortMap + + for _, v := range strings.Split(strings.TrimSpace(stringPortMap), " ") { + parts := strings.SplitN(v, ":", 3) + if len(parts) == 1 { + hostPort, err := strconv.Atoi(v) + if err != nil { + return portMaps, fmt.Errorf("Invalid port map %s [err=%s]", v, err.Error()) + } + + if !inRange(hostPort, 0, 65536) { + return portMaps, fmt.Errorf("Invalid port map %s [hostPort=%d]", v, hostPort) + } + + portMaps = append(portMaps, PortMap{ + HostPort: hostPort, + Scheme: "__internal__", + }) + continue + } + + if len(parts) != 3 { + return portMaps, fmt.Errorf("Invalid port map %s [len=%d]", v, len(parts)) + } + + hostPort, err := strconv.Atoi(parts[1]) + if err != nil { + return portMaps, fmt.Errorf("Invalid port map %s [err=%s]", v, err.Error()) + } + + containerPort, err := strconv.Atoi(parts[2]) + if err != nil { + return portMaps, fmt.Errorf("Invalid port map %s [err=%s]", v, err.Error()) + } + + if !inRange(hostPort, 0, 65536) { + return portMaps, fmt.Errorf("Invalid port map %s [hostPort=%d]", v, hostPort) + } + + if !inRange(containerPort, 0, 65536) { + return portMaps, fmt.Errorf("Invalid port map %s [containerPort=%d]", v, containerPort) + } + + portMaps = append(portMaps, PortMap{ + ContainerPort: containerPort, + HostPort: hostPort, + Scheme: parts[0], + }) + } + + return uniquePortMaps(portMaps), nil +} + +func removePortMaps(appName string, portMaps []PortMap) error { + toRemove := map[string]bool{} + toRemoveByPort := map[int]bool{} + + for _, portMap := range portMaps { + if portMap.AllowsPersistence() { + toRemoveByPort[portMap.HostPort] = true + continue + } + toRemove[portMap.String()] = true + } + + var toSet []PortMap + for _, portMap := range getPortMaps(appName) { + if toRemove[portMap.String()] { + continue + } + + if toRemoveByPort[portMap.HostPort] { + continue + } + + toSet = append(toSet, portMap) + } + + if len(toSet) == 0 { + keys := []string{"DOKKU_PROXY_PORT_MAP"} + return config.UnsetMany(appName, keys, false) + } + + return setPortMaps(appName, toSet) +} + +func setPortMaps(appName string, portMaps []PortMap) error { + var value []string + for _, portMap := range uniquePortMaps(portMaps) { + if portMap.AllowsPersistence() { + continue + } + + value = append(value, portMap.String()) + } + + sort.Strings(value) + entries := map[string]string{ + "DOKKU_PROXY_PORT_MAP": strings.Join(value, " "), + } + return config.SetMany(appName, entries, false) +} + +func uniquePortMaps(portMaps []PortMap) []PortMap { + var unique []PortMap + existingPortMaps := map[string]bool{} + + for _, portMap := range portMaps { + if existingPortMaps[portMap.String()] { + continue + } + + existingPortMaps[portMap.String()] = true + unique = append(unique, portMap) + } + + return unique +} diff --git a/plugins/ports/go.mod b/plugins/ports/go.mod new file mode 100644 index 00000000000..2ab83576b63 --- /dev/null +++ b/plugins/ports/go.mod @@ -0,0 +1,23 @@ +module github.com/dokku/dokku/plugins/ports + +go 1.19 + +require ( + github.com/dokku/dokku/plugins/common v0.0.0-00010101000000-000000000000 + github.com/dokku/dokku/plugins/config v0.0.0-00010101000000-000000000000 + github.com/ryanuber/columnize v2.1.2+incompatible + github.com/spf13/pflag v1.0.5 +) + +require ( + github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0 // indirect + github.com/codeskyblue/go-sh v0.0.0-20190412065543-76bd3d59ff27 // indirect + github.com/joho/godotenv v1.2.0 // indirect + github.com/otiai10/copy v1.12.0 // indirect + golang.org/x/sync v0.3.0 // indirect + golang.org/x/sys v0.8.0 // indirect +) + +replace github.com/dokku/dokku/plugins/common => ../common + +replace github.com/dokku/dokku/plugins/config => ../config diff --git a/plugins/ports/go.sum b/plugins/ports/go.sum new file mode 100644 index 00000000000..1a7ae7db219 --- /dev/null +++ b/plugins/ports/go.sum @@ -0,0 +1,22 @@ +github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0 h1:sDMmm+q/3+BukdIpxwO365v/Rbspp2Nt5XntgQRXq8Q= +github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM= +github.com/codeskyblue/go-sh v0.0.0-20190412065543-76bd3d59ff27 h1:HHUr4P/aKh4quafGxDT9LDasjGdlGkzLbfmmrlng3kA= +github.com/codeskyblue/go-sh v0.0.0-20190412065543-76bd3d59ff27/go.mod h1:VQx0hjo2oUeQkQUET7wRwradO6f+fN5jzXgB/zROxxE= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/joho/godotenv v1.2.0 h1:vGTvz69FzUFp+X4/bAkb0j5BoLC+9bpqTWY8mjhA9pc= +github.com/joho/godotenv v1.2.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= +github.com/onsi/gomega v1.27.8 h1:gegWiwZjBsf2DgiSbf5hpokZ98JVDMcWkUiigk6/KXc= +github.com/otiai10/copy v1.12.0 h1:cLMgSQnXBs1eehF0Wy/FAGsgDTDmAqFR7rQylBb1nDY= +github.com/otiai10/copy v1.12.0/go.mod h1:rSaLseMUsZFFbsFGc7wCJnnkTAvdc5L6VWxPE4308Ww= +github.com/otiai10/mint v1.5.1 h1:XaPLeE+9vGbuyEHem1JNk3bYc7KKqyI/na0/mLd/Kks= +github.com/ryanuber/columnize v2.1.2+incompatible h1:C89EOx/XBWwIXl8wm8OPJBd7kPF25UfsK2X7Ph/zCAk= +github.com/ryanuber/columnize v2.1.2+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M= +golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= +golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= diff --git a/plugins/ports/plugin.toml b/plugins/ports/plugin.toml new file mode 100644 index 00000000000..a43ba8fb502 --- /dev/null +++ b/plugins/ports/plugin.toml @@ -0,0 +1,4 @@ +[plugin] +description = "dokku core ports plugin" +version = "0.30.8" +[plugin.config] diff --git a/plugins/proxy/proxy-configure-ports b/plugins/ports/proxy-configure-ports similarity index 90% rename from plugins/proxy/proxy-configure-ports rename to plugins/ports/proxy-configure-ports index 21c94a69e3b..deee9b39da9 100755 --- a/plugins/proxy/proxy-configure-ports +++ b/plugins/ports/proxy-configure-ports @@ -4,8 +4,8 @@ source "$PLUGIN_AVAILABLE_PATH/config/functions" set -eo pipefail [[ $DOKKU_TRACE ]] && set -x -trigger-proxy-proxy-configure-ports() { - declare desc="proxy proxy-configure-ports plugin trigger" +trigger-ports-proxy-configure-ports() { + declare desc="ports proxy-configure-ports plugin trigger" declare trigger="proxy-configure-ports" declare APP="$1" local RAW_TCP_PORTS="$(get_app_raw_tcp_ports "$APP")" @@ -19,7 +19,7 @@ trigger-proxy-proxy-configure-ports() { if [[ -z "$DOKKU_PROXY_PORT" ]] && [[ -z "$RAW_TCP_PORTS" ]]; then if [[ "$IS_APP_VHOST_ENABLED" == "false" ]]; then - dokku_log_info1 "No proxy port set, setting to random open high port" + dokku_log_info1 "No port set, setting to random open high port" local PROXY_PORT=$(get_available_port) else local PROXY_PORT=$(config_get --global DOKKU_PROXY_PORT) @@ -32,7 +32,7 @@ trigger-proxy-proxy-configure-ports() { local PROXY_SSL_PORT=$(config_get --global DOKKU_PROXY_SSL_PORT) PROXY_SSL_PORT=${PROXY_SSL_PORT:=443} if [[ -z "$RAW_TCP_PORTS" ]] && [[ "$IS_APP_VHOST_ENABLED" == "false" ]]; then - dokku_log_info1 "No proxy ssl port set, setting to random open high port" + dokku_log_info1 "No ssl port set, setting to random open high port" PROXY_SSL_PORT=$(get_available_port) fi DOKKU_QUIET_OUTPUT=1 config_set --no-restart "$APP" DOKKU_PROXY_SSL_PORT="$PROXY_SSL_PORT" @@ -61,4 +61,5 @@ trigger-proxy-proxy-configure-ports() { fi fi } -trigger-proxy-proxy-configure-ports "$@" + +trigger-ports-proxy-configure-ports "$@" diff --git a/plugins/ports/proxy.go b/plugins/ports/proxy.go new file mode 100644 index 00000000000..1918a8c531b --- /dev/null +++ b/plugins/ports/proxy.go @@ -0,0 +1,21 @@ +package ports + +import ( + "fmt" +) + +// PortMap is a struct that contains a scheme:host-port:container-port mapping +type PortMap struct { + ContainerPort int + HostPort int + Scheme string +} + +func (p PortMap) String() string { + return fmt.Sprintf("%s:%d:%d", p.Scheme, p.HostPort, p.ContainerPort) +} + +// AllowsPersistence returns true if the port map is not to be persisted +func (p PortMap) AllowsPersistence() bool { + return p.Scheme == "__internal__" +} diff --git a/plugins/ports/report.go b/plugins/ports/report.go new file mode 100644 index 00000000000..bd820554da2 --- /dev/null +++ b/plugins/ports/report.go @@ -0,0 +1,37 @@ +package ports + +import ( + "strings" + + "github.com/dokku/dokku/plugins/common" +) + +// ReportSingleApp is an internal function that displays the ports report for one or more apps +func ReportSingleApp(appName string, format string, infoFlag string) error { + if err := common.VerifyAppName(appName); err != nil { + return err + } + + flags := map[string]common.ReportFunc{ + "--ports-map": reportPortMap, + } + + flagKeys := []string{} + for flagKey := range flags { + flagKeys = append(flagKeys, flagKey) + } + + trimPrefix := false + uppercaseFirstCharacter := true + infoFlags := common.CollectReport(appName, infoFlag, flags) + return common.ReportSingleApp("ports", appName, infoFlag, infoFlags, flagKeys, format, trimPrefix, uppercaseFirstCharacter) +} + +func reportPortMap(appName string) string { + var portMaps []string + for _, portMap := range getPortMaps(appName) { + portMaps = append(portMaps, portMap.String()) + } + + return strings.Join(portMaps, " ") +} diff --git a/plugins/ports/src/commands/commands.go b/plugins/ports/src/commands/commands.go new file mode 100644 index 00000000000..9231d27bf29 --- /dev/null +++ b/plugins/ports/src/commands/commands.go @@ -0,0 +1,60 @@ +package main + +import ( + "flag" + "fmt" + "os" + "strconv" + "strings" + + "github.com/dokku/dokku/plugins/common" +) + +const ( + helpHeader = `Usage: dokku ports[:COMMAND] + +Manage ports for an app + +Additional commands:` + + helpContent = ` + ports:list , List port mappings for app + ports:add [::...], Add port mappings to an app + ports:clear , Clear all port mappings for an app + ports:remove [|::...], Remove specific port mappings from an app + ports:set [::...], Set port mappings for an app + ports:report [] [], Displays a ports report for one or more apps +` +) + +func main() { + flag.Usage = usage + flag.Parse() + + cmd := flag.Arg(0) + switch cmd { + case "ports", "ports:help": + usage() + case "help": + command := common.NewShellCmd(fmt.Sprintf("ps -o command= %d", os.Getppid())) + command.ShowOutput = false + output, err := command.Output() + + if err == nil && strings.Contains(string(output), "--all") { + fmt.Println(helpContent) + } else { + fmt.Print("\n ports, Manage ports for an app\n") + } + default: + dokkuNotImplementExitCode, err := strconv.Atoi(os.Getenv("DOKKU_NOT_IMPLEMENTED_EXIT")) + if err != nil { + fmt.Println("failed to retrieve DOKKU_NOT_IMPLEMENTED_EXIT environment variable") + dokkuNotImplementExitCode = 10 + } + os.Exit(dokkuNotImplementExitCode) + } +} + +func usage() { + common.CommandUsage(helpHeader, helpContent) +} diff --git a/plugins/ports/src/subcommands/subcommands.go b/plugins/ports/src/subcommands/subcommands.go new file mode 100644 index 00000000000..14f97ed9418 --- /dev/null +++ b/plugins/ports/src/subcommands/subcommands.go @@ -0,0 +1,65 @@ +package main + +import ( + "fmt" + "os" + "strings" + + "github.com/dokku/dokku/plugins/common" + "github.com/dokku/dokku/plugins/ports" + + flag "github.com/spf13/pflag" +) + +// main entrypoint to all subcommands +func main() { + parts := strings.Split(os.Args[0], "/") + subcommand := parts[len(parts)-1] + + var err error + switch subcommand { + case "list": + args := flag.NewFlagSet("ports:list", flag.ExitOnError) + args.Parse(os.Args[2:]) + appName := args.Arg(0) + err = ports.CommandList(appName) + case "add": + args := flag.NewFlagSet("ports:add", flag.ExitOnError) + args.Parse(os.Args[2:]) + appName := args.Arg(0) + _, portMaps := common.ShiftString(args.Args()) + err = ports.CommandAdd(appName, portMaps) + case "clear": + args := flag.NewFlagSet("ports:clear", flag.ExitOnError) + args.Parse(os.Args[2:]) + appName := args.Arg(0) + err = ports.CommandClear(appName) + case "remove": + args := flag.NewFlagSet("ports:remove", flag.ExitOnError) + args.Parse(os.Args[2:]) + appName := args.Arg(0) + _, portMaps := common.ShiftString(args.Args()) + err = ports.CommandRemove(appName, portMaps) + case "set": + args := flag.NewFlagSet("ports:set", flag.ExitOnError) + args.Parse(os.Args[2:]) + appName := args.Arg(0) + _, portMaps := common.ShiftString(args.Args()) + err = ports.CommandSet(appName, portMaps) + case "report": + args := flag.NewFlagSet("ports:report", flag.ExitOnError) + format := args.String("format", "stdout", "format: [ stdout | json ]") + osArgs, infoFlag, flagErr := common.ParseReportArgs("ports", os.Args[2:]) + if flagErr == nil { + args.Parse(osArgs) + appName := args.Arg(0) + err = ports.CommandReport(appName, *format, infoFlag) + } + default: + err = fmt.Errorf("Invalid plugin subcommand call: %s", subcommand) + } + + if err != nil { + common.LogFailWithError(err) + } +} diff --git a/plugins/ports/src/triggers/triggers.go b/plugins/ports/src/triggers/triggers.go new file mode 100644 index 00000000000..f159dbf57d2 --- /dev/null +++ b/plugins/ports/src/triggers/triggers.go @@ -0,0 +1,37 @@ +package main + +import ( + "flag" + "fmt" + "os" + "strings" + + "github.com/dokku/dokku/plugins/common" + "github.com/dokku/dokku/plugins/ports" +) + +// main entrypoint to all triggers +func main() { + parts := strings.Split(os.Args[0], "/") + trigger := parts[len(parts)-1] + flag.Parse() + + var err error + switch trigger { + case "post-certs-remove": + appName := flag.Arg(0) + err = ports.TriggerPostCertsRemove(appName) + case "post-certs-update": + appName := flag.Arg(0) + err = ports.TriggerPostCertsUpdate(appName) + case "report": + appName := flag.Arg(0) + err = ports.ReportSingleApp(appName, "", "") + default: + err = fmt.Errorf("Invalid plugin trigger call: %s", trigger) + } + + if err != nil { + common.LogFailWithError(err) + } +} diff --git a/plugins/ports/subcommands.go b/plugins/ports/subcommands.go new file mode 100644 index 00000000000..70ebf905746 --- /dev/null +++ b/plugins/ports/subcommands.go @@ -0,0 +1,116 @@ +package ports + +import ( + "errors" + "strings" + + "github.com/dokku/dokku/plugins/common" + "github.com/dokku/dokku/plugins/config" +) + +// CommandList is a cmd wrapper to list port mappings for an app +func CommandList(appName string) error { + if err := common.VerifyAppName(appName); err != nil { + return err + } + + return listAppPortMaps(appName) +} + +// CommandAdd adds port mappings to an app +func CommandAdd(appName string, portMapStrings []string) error { + if err := common.VerifyAppName(appName); err != nil { + return err + } + + if len(portMapStrings) == 0 { + return errors.New("No port mapping specified") + } + + portMaps, err := parsePortMapString(strings.Join(portMapStrings, " ")) + if err != nil { + return err + } + + if err := addPortMaps(appName, portMaps); err != nil { + return err + } + + return common.PlugnTrigger("post-proxy-ports-update", []string{appName, "add"}...) +} + +// CommandClear clears all port mappings for an app +func CommandClear(appName string) error { + if err := common.VerifyAppName(appName); err != nil { + return err + } + + keys := []string{"DOKKU_PROXY_PORT_MAP"} + if err := config.UnsetMany(appName, keys, false); err != nil { + return err + } + + return common.PlugnTrigger("post-proxy-ports-update", []string{appName, "clear"}...) +} + +// CommandRemove removes specific port mappings from an app +func CommandRemove(appName string, portMapStrings []string) error { + if err := common.VerifyAppName(appName); err != nil { + return err + } + + if len(portMapStrings) == 0 { + return errors.New("No port mapping specified") + } + + portMaps, err := parsePortMapString(strings.Join(portMapStrings, " ")) + if err != nil { + return err + } + + if err := removePortMaps(appName, portMaps); err != nil { + return err + } + + return common.PlugnTrigger("post-proxy-ports-update", []string{appName, "remove"}...) +} + +// CommandSet sets port mappings for an app +func CommandSet(appName string, portMapStrings []string) error { + if err := common.VerifyAppName(appName); err != nil { + return err + } + + if len(portMapStrings) == 0 { + return errors.New("No port mapping specified") + } + + portMaps, err := parsePortMapString(strings.Join(portMapStrings, " ")) + if err != nil { + return err + } + + if err := setPortMaps(appName, portMaps); err != nil { + return err + } + + return common.PlugnTrigger("post-proxy-ports-update", []string{appName, "set"}...) +} + +// CommandReport displays a ports report for one or more apps +func CommandReport(appName string, format string, infoFlag string) error { + if len(appName) == 0 { + apps, err := common.DokkuApps() + if err != nil { + return err + } + for _, appName := range apps { + if err := ReportSingleApp(appName, format, infoFlag); err != nil { + return err + } + } + return nil + } + + return ReportSingleApp(appName, format, infoFlag) +} diff --git a/plugins/ports/triggers.go b/plugins/ports/triggers.go new file mode 100644 index 00000000000..aa209200a7b --- /dev/null +++ b/plugins/ports/triggers.go @@ -0,0 +1,71 @@ +package ports + +import ( + "github.com/dokku/dokku/plugins/config" +) + +// TriggerPostCertsRemove unsets port config vars after SSL cert is added +func TriggerPostCertsRemove(appName string) error { + keys := []string{"DOKKU_PROXY_SSL_PORT"} + if err := config.UnsetMany(appName, keys, false); err != nil { + return err + } + + return removePortMaps(appName, filterAppPortMaps(appName, "https", 443)) +} + +// TriggerPostCertsUpdate sets port config vars after SSL cert is added +func TriggerPostCertsUpdate(appName string) error { + port := config.GetWithDefault(appName, "DOKKU_PROXY_PORT", "") + sslPort := config.GetWithDefault(appName, "DOKKU_PROXY_SSL_PORT", "") + portMaps := getPortMaps(appName) + + toUnset := []string{} + if port == "80" { + toUnset = append(toUnset, "DOKKU_PROXY_PORT") + } + if sslPort == "443" { + toUnset = append(toUnset, "DOKKU_PROXY_SSL_PORT") + } + + if len(toUnset) > 0 { + if err := config.UnsetMany(appName, toUnset, false); err != nil { + return err + } + } + + var http80Ports []PortMap + for _, portMap := range portMaps { + if portMap.Scheme == "http" && portMap.HostPort == 80 { + http80Ports = append(http80Ports, portMap) + } + } + + if len(http80Ports) > 0 { + var https443Ports []PortMap + for _, portMap := range portMaps { + if portMap.Scheme == "https" && portMap.HostPort == 443 { + https443Ports = append(https443Ports, portMap) + } + } + + if err := removePortMaps(appName, https443Ports); err != nil { + return err + } + + var toAdd []PortMap + for _, portMap := range http80Ports { + toAdd = append(toAdd, PortMap{ + Scheme: "https", + HostPort: 443, + ContainerPort: portMap.ContainerPort, + }) + } + + if err := addPortMaps(appName, toAdd); err != nil { + return err + } + } + + return nil +} diff --git a/plugins/proxy/.gitignore b/plugins/proxy/.gitignore index 3b20f2e1cfc..7d9f06e65fe 100644 --- a/plugins/proxy/.gitignore +++ b/plugins/proxy/.gitignore @@ -6,4 +6,4 @@ /install /post-* /report -!/proxy-configure-ports + diff --git a/plugins/proxy/Makefile b/plugins/proxy/Makefile index 21cc25c91fd..6b127937fe9 100644 --- a/plugins/proxy/Makefile +++ b/plugins/proxy/Makefile @@ -1,5 +1,5 @@ SUBCOMMANDS = subcommands/build-config subcommands/clear-config subcommands/disable subcommands/enable subcommands/ports subcommands/ports-add subcommands/ports-clear subcommands/ports-remove subcommands/ports-set subcommands/report subcommands/set -TRIGGERS = triggers/proxy-is-enabled triggers/proxy-type triggers/post-certs-remove triggers/post-certs-update triggers/report +TRIGGERS = triggers/proxy-is-enabled triggers/proxy-type triggers/report BUILD = commands subcommands triggers PLUGIN_NAME = proxy diff --git a/plugins/proxy/functions.go b/plugins/proxy/functions.go index bc12f32a9e6..4b5467f50e3 100644 --- a/plugins/proxy/functions.go +++ b/plugins/proxy/functions.go @@ -1,192 +1,9 @@ package proxy import ( - "errors" - "fmt" - "os" - "sort" - "strconv" - "strings" - - "github.com/dokku/dokku/plugins/common" "github.com/dokku/dokku/plugins/config" - "github.com/ryanuber/columnize" ) -func addProxyPorts(appName string, proxyPortMap []PortMap) error { - allPortMaps := getProxyPortMap(appName) - allPortMaps = append(allPortMaps, proxyPortMap...) - - return setProxyPorts(appName, allPortMaps) -} - -func filterAppProxyPorts(appName string, scheme string, hostPort int) []PortMap { - var filteredProxyMaps []PortMap - for _, portMap := range getProxyPortMap(appName) { - if portMap.Scheme == scheme && portMap.HostPort == hostPort { - filteredProxyMaps = append(filteredProxyMaps, portMap) - } - } - - return filteredProxyMaps -} - func getAppProxyType(appName string) string { return config.GetWithDefault(appName, "DOKKU_APP_PROXY_TYPE", "nginx") } - -func getProxyPortMap(appName string) []PortMap { - value := config.GetWithDefault(appName, "DOKKU_PROXY_PORT_MAP", "") - portMaps, _ := parseProxyPortMapString(value) - return portMaps -} - -func inRange(value int, min int, max int) bool { - return min < value && value < max -} - -func listAppProxyPorts(appName string) error { - proxyPortMap := getProxyPortMap(appName) - - if len(proxyPortMap) == 0 { - return errors.New("No port mappings configured for app") - } - - var lines []string - if os.Getenv("DOKKU_QUIET_OUTPUT") == "" { - lines = append(lines, "-----> scheme:host port:container port") - } - - for _, portMap := range proxyPortMap { - lines = append(lines, portMap.String()) - } - - sort.Strings(lines) - common.LogInfo1Quiet(fmt.Sprintf("Port mappings for %s", appName)) - config := columnize.DefaultConfig() - config.Delim = ":" - config.Prefix = " " - config.Empty = "" - fmt.Println(columnize.Format(lines, config)) - return nil -} - -func parseProxyPortMapString(stringPortMap string) ([]PortMap, error) { - var proxyPortMap []PortMap - - for _, v := range strings.Split(strings.TrimSpace(stringPortMap), " ") { - parts := strings.SplitN(v, ":", 3) - if len(parts) == 1 { - hostPort, err := strconv.Atoi(v) - if err != nil { - return proxyPortMap, fmt.Errorf("Invalid port map %s [err=%s]", v, err.Error()) - } - - if !inRange(hostPort, 0, 65536) { - return proxyPortMap, fmt.Errorf("Invalid port map %s [hostPort=%d]", v, hostPort) - } - - proxyPortMap = append(proxyPortMap, PortMap{ - HostPort: hostPort, - Scheme: "__internal__", - }) - continue - } - - if len(parts) != 3 { - return proxyPortMap, fmt.Errorf("Invalid port map %s [len=%d]", v, len(parts)) - } - - hostPort, err := strconv.Atoi(parts[1]) - if err != nil { - return proxyPortMap, fmt.Errorf("Invalid port map %s [err=%s]", v, err.Error()) - } - - containerPort, err := strconv.Atoi(parts[2]) - if err != nil { - return proxyPortMap, fmt.Errorf("Invalid port map %s [err=%s]", v, err.Error()) - } - - if !inRange(hostPort, 0, 65536) { - return proxyPortMap, fmt.Errorf("Invalid port map %s [hostPort=%d]", v, hostPort) - } - - if !inRange(containerPort, 0, 65536) { - return proxyPortMap, fmt.Errorf("Invalid port map %s [containerPort=%d]", v, containerPort) - } - - proxyPortMap = append(proxyPortMap, PortMap{ - ContainerPort: containerPort, - HostPort: hostPort, - Scheme: parts[0], - }) - } - - return uniqueProxyPortMap(proxyPortMap), nil -} - -func removeProxyPorts(appName string, proxyPortMap []PortMap) error { - toRemove := map[string]bool{} - toRemoveByPort := map[int]bool{} - - for _, portMap := range proxyPortMap { - if portMap.AllowsPersistence() { - toRemoveByPort[portMap.HostPort] = true - continue - } - toRemove[portMap.String()] = true - } - - var toSet []PortMap - for _, portMap := range getProxyPortMap(appName) { - if toRemove[portMap.String()] { - continue - } - - if toRemoveByPort[portMap.HostPort] { - continue - } - - toSet = append(toSet, portMap) - } - - if len(toSet) == 0 { - keys := []string{"DOKKU_PROXY_PORT_MAP"} - return config.UnsetMany(appName, keys, false) - } - - return setProxyPorts(appName, toSet) -} - -func setProxyPorts(appName string, proxyPortMap []PortMap) error { - var value []string - for _, portMap := range uniqueProxyPortMap(proxyPortMap) { - if portMap.AllowsPersistence() { - continue - } - - value = append(value, portMap.String()) - } - - sort.Strings(value) - entries := map[string]string{ - "DOKKU_PROXY_PORT_MAP": strings.Join(value, " "), - } - return config.SetMany(appName, entries, false) -} - -func uniqueProxyPortMap(proxyPortMap []PortMap) []PortMap { - var unique []PortMap - existingPortMaps := map[string]bool{} - - for _, portMap := range proxyPortMap { - if existingPortMaps[portMap.String()] { - continue - } - - existingPortMaps[portMap.String()] = true - unique = append(unique, portMap) - } - - return unique -} diff --git a/plugins/proxy/go.mod b/plugins/proxy/go.mod index 7f9fe76ea43..3590d645a21 100644 --- a/plugins/proxy/go.mod +++ b/plugins/proxy/go.mod @@ -5,7 +5,7 @@ go 1.19 require ( github.com/dokku/dokku/plugins/common v0.0.0-00010101000000-000000000000 github.com/dokku/dokku/plugins/config v0.0.0-00010101000000-000000000000 - github.com/ryanuber/columnize v2.1.2+incompatible + github.com/dokku/dokku/plugins/ports v0.0.0-00010101000000-000000000000 github.com/spf13/pflag v1.0.5 ) @@ -14,6 +14,7 @@ require ( github.com/codeskyblue/go-sh v0.0.0-20190412065543-76bd3d59ff27 // indirect github.com/joho/godotenv v1.2.0 // indirect github.com/otiai10/copy v1.12.0 // indirect + github.com/ryanuber/columnize v2.1.2+incompatible // indirect golang.org/x/sync v0.3.0 // indirect golang.org/x/sys v0.8.0 // indirect ) @@ -21,3 +22,5 @@ require ( replace github.com/dokku/dokku/plugins/common => ../common replace github.com/dokku/dokku/plugins/config => ../config + +replace github.com/dokku/dokku/plugins/ports => ../ports diff --git a/plugins/proxy/proxy.go b/plugins/proxy/proxy.go index ec87bf48c5e..26cfee2ffb4 100644 --- a/plugins/proxy/proxy.go +++ b/plugins/proxy/proxy.go @@ -1,8 +1,6 @@ package proxy import ( - "fmt" - "github.com/dokku/dokku/plugins/common" "github.com/dokku/dokku/plugins/config" ) @@ -11,22 +9,6 @@ import ( // and defaults to -1 (false) const RunInSerial = 0 -// PortMap is a struct that contains a scheme:host-port:container-port mapping -type PortMap struct { - ContainerPort int - HostPort int - Scheme string -} - -func (p PortMap) String() string { - return fmt.Sprintf("%s:%d:%d", p.Scheme, p.HostPort, p.ContainerPort) -} - -// AllowsPersistence returns true if the port map is not to be persisted -func (p PortMap) AllowsPersistence() bool { - return p.Scheme == "__internal__" -} - // BuildConfig rebuilds the proxy config for the specified app func BuildConfig(appName string) error { return common.PlugnTrigger("proxy-build-config", []string{appName}...) diff --git a/plugins/proxy/report.go b/plugins/proxy/report.go index bf4c5c917b4..5db7792a2f6 100644 --- a/plugins/proxy/report.go +++ b/plugins/proxy/report.go @@ -1,8 +1,6 @@ package proxy import ( - "strings" - "github.com/dokku/dokku/plugins/common" ) @@ -13,9 +11,8 @@ func ReportSingleApp(appName string, format string, infoFlag string) error { } flags := map[string]common.ReportFunc{ - "--proxy-enabled": reportEnabled, - "--proxy-type": reportType, - "--proxy-port-map": reportPortMap, + "--proxy-enabled": reportEnabled, + "--proxy-type": reportType, } flagKeys := []string{} @@ -41,12 +38,3 @@ func reportEnabled(appName string) string { func reportType(appName string) string { return getAppProxyType(appName) } - -func reportPortMap(appName string) string { - var proxyPortMap []string - for _, portMap := range getProxyPortMap(appName) { - proxyPortMap = append(proxyPortMap, portMap.String()) - } - - return strings.Join(proxyPortMap, " ") -} diff --git a/plugins/proxy/src/commands/commands.go b/plugins/proxy/src/commands/commands.go index e2f6c016a81..129cc282082 100644 --- a/plugins/proxy/src/commands/commands.go +++ b/plugins/proxy/src/commands/commands.go @@ -22,11 +22,6 @@ Additional commands:` proxy:clear-config [--all|], Clears config for a given app proxy:disable , Disable proxy for app proxy:enable , Enable proxy for app - proxy:ports , List proxy port mappings for app - proxy:ports-add [::...], Add proxy port mappings to an app - proxy:ports-clear , Clear all proxy port mappings for an app - proxy:ports-remove [|::...], Remove specific proxy port mappings from an app - proxy:ports-set [::...], Set proxy port mappings for an app proxy:report [] [], Displays a proxy report for one or more apps proxy:set , Set proxy type for app ` diff --git a/plugins/proxy/src/subcommands/subcommands.go b/plugins/proxy/src/subcommands/subcommands.go index c25db395ccb..0dd97285765 100644 --- a/plugins/proxy/src/subcommands/subcommands.go +++ b/plugins/proxy/src/subcommands/subcommands.go @@ -6,6 +6,7 @@ import ( "strings" "github.com/dokku/dokku/plugins/common" + "github.com/dokku/dokku/plugins/ports" "github.com/dokku/dokku/plugins/proxy" flag "github.com/spf13/pflag" @@ -49,30 +50,35 @@ func main() { args := flag.NewFlagSet("proxy:ports", flag.ExitOnError) args.Parse(os.Args[2:]) appName := args.Arg(0) - err = proxy.CommandPorts(appName) + common.LogWarn("Deprecated: Use 'ports:list' instead") + err = ports.CommandList(appName) case "ports-add": args := flag.NewFlagSet("proxy:ports-add", flag.ExitOnError) args.Parse(os.Args[2:]) appName := args.Arg(0) _, portMaps := common.ShiftString(args.Args()) - err = proxy.CommandPortsAdd(appName, portMaps) + common.LogWarn("Deprecated: Use 'ports:add' instead") + err = ports.CommandAdd(appName, portMaps) case "ports-clear": args := flag.NewFlagSet("proxy:ports-clear", flag.ExitOnError) args.Parse(os.Args[2:]) appName := args.Arg(0) - err = proxy.CommandPortsClear(appName) + common.LogWarn("Deprecated: Use 'ports:clear' instead") + err = ports.CommandClear(appName) case "ports-remove": args := flag.NewFlagSet("proxy:ports-remove", flag.ExitOnError) args.Parse(os.Args[2:]) appName := args.Arg(0) _, portMaps := common.ShiftString(args.Args()) - err = proxy.CommandPortsRemove(appName, portMaps) + common.LogWarn("Deprecated: Use 'ports:remove' instead") + err = ports.CommandRemove(appName, portMaps) case "ports-set": args := flag.NewFlagSet("proxy:ports-set", flag.ExitOnError) args.Parse(os.Args[2:]) appName := args.Arg(0) _, portMaps := common.ShiftString(args.Args()) - err = proxy.CommandPortsSet(appName, portMaps) + common.LogWarn("Deprecated: Use 'ports:set' instead") + err = ports.CommandSet(appName, portMaps) case "report": args := flag.NewFlagSet("proxy:report", flag.ExitOnError) format := args.String("format", "stdout", "format: [ stdout | json ]") diff --git a/plugins/proxy/src/triggers/triggers.go b/plugins/proxy/src/triggers/triggers.go index 11c5bd277ab..713e1976d0c 100644 --- a/plugins/proxy/src/triggers/triggers.go +++ b/plugins/proxy/src/triggers/triggers.go @@ -24,12 +24,6 @@ func main() { case "proxy-type": appName := flag.Arg(0) err = proxy.TriggerProxyType(appName) - case "post-certs-remove": - appName := flag.Arg(0) - err = proxy.TriggerPostCertsRemove(appName) - case "post-certs-update": - appName := flag.Arg(0) - err = proxy.TriggerPostCertsUpdate(appName) case "report": appName := flag.Arg(0) err = proxy.ReportSingleApp(appName, "", "") diff --git a/plugins/proxy/subcommands.go b/plugins/proxy/subcommands.go index 1dcb66558a5..58a57a87029 100644 --- a/plugins/proxy/subcommands.go +++ b/plugins/proxy/subcommands.go @@ -2,7 +2,6 @@ package proxy import ( "errors" - "strings" "github.com/dokku/dokku/plugins/common" "github.com/dokku/dokku/plugins/config" @@ -60,95 +59,6 @@ func CommandEnable(appName string, allApps bool, parallelCount int) error { return Enable(appName) } -// CommandPorts is a cmd wrapper to list proxy port mappings for an app -func CommandPorts(appName string) error { - if err := common.VerifyAppName(appName); err != nil { - return err - } - - return listAppProxyPorts(appName) -} - -// CommandPortsAdd adds proxy port mappings to an app -func CommandPortsAdd(appName string, portMaps []string) error { - if err := common.VerifyAppName(appName); err != nil { - return err - } - - if len(portMaps) == 0 { - return errors.New("No port mapping specified") - } - - proxyPortMap, err := parseProxyPortMapString(strings.Join(portMaps, " ")) - if err != nil { - return err - } - - if err := addProxyPorts(appName, proxyPortMap); err != nil { - return err - } - - return common.PlugnTrigger("post-proxy-ports-update", []string{appName, "add"}...) -} - -// CommandPortsClear clears all proxy port mappings for an app -func CommandPortsClear(appName string) error { - if err := common.VerifyAppName(appName); err != nil { - return err - } - - keys := []string{"DOKKU_PROXY_PORT_MAP"} - if err := config.UnsetMany(appName, keys, false); err != nil { - return err - } - - return common.PlugnTrigger("post-proxy-ports-update", []string{appName, "clear"}...) -} - -// CommandPortsRemove removes specific proxy port mappings from an app -func CommandPortsRemove(appName string, portMaps []string) error { - if err := common.VerifyAppName(appName); err != nil { - return err - } - - if len(portMaps) == 0 { - return errors.New("No port mapping specified") - } - - proxyPortMap, err := parseProxyPortMapString(strings.Join(portMaps, " ")) - if err != nil { - return err - } - - if err := removeProxyPorts(appName, proxyPortMap); err != nil { - return err - } - - return common.PlugnTrigger("post-proxy-ports-update", []string{appName, "remove"}...) -} - -// CommandPortsSet sets proxy port mappings for an app -func CommandPortsSet(appName string, portMaps []string) error { - if err := common.VerifyAppName(appName); err != nil { - return err - } - - if len(portMaps) == 0 { - return errors.New("No port mapping specified") - } - - proxyPortMap, err := parseProxyPortMapString(strings.Join(portMaps, " ")) - if err != nil { - return err - } - - if err := setProxyPorts(appName, proxyPortMap); err != nil { - return err - } - - return common.PlugnTrigger("post-proxy-ports-update", []string{appName, "set"}...) -} - // CommandReport displays a proxy report for one or more apps func CommandReport(appName string, format string, infoFlag string) error { if len(appName) == 0 { diff --git a/plugins/proxy/triggers.go b/plugins/proxy/triggers.go index 626f95a3009..49c0fef0699 100644 --- a/plugins/proxy/triggers.go +++ b/plugins/proxy/triggers.go @@ -2,8 +2,6 @@ package proxy import ( "fmt" - - "github.com/dokku/dokku/plugins/config" ) // TriggerProxyIsEnabled prints true or false depending on whether the proxy is enabled @@ -24,69 +22,3 @@ func TriggerProxyType(appName string) error { return nil } - -// TriggerPostCertsRemove unsets port config vars after SSL cert is added -func TriggerPostCertsRemove(appName string) error { - keys := []string{"DOKKU_PROXY_SSL_PORT"} - if err := config.UnsetMany(appName, keys, false); err != nil { - return err - } - - return removeProxyPorts(appName, filterAppProxyPorts(appName, "https", 443)) -} - -// TriggerPostCertsUpdate sets port config vars after SSL cert is added -func TriggerPostCertsUpdate(appName string) error { - port := config.GetWithDefault(appName, "DOKKU_PROXY_PORT", "") - sslPort := config.GetWithDefault(appName, "DOKKU_PROXY_SSL_PORT", "") - proxyPortMap := getProxyPortMap(appName) - - toUnset := []string{} - if port == "80" { - toUnset = append(toUnset, "DOKKU_PROXY_PORT") - } - if sslPort == "443" { - toUnset = append(toUnset, "DOKKU_PROXY_SSL_PORT") - } - - if len(toUnset) > 0 { - if err := config.UnsetMany(appName, toUnset, false); err != nil { - return err - } - } - - var http80Ports []PortMap - for _, portMap := range proxyPortMap { - if portMap.Scheme == "http" && portMap.HostPort == 80 { - http80Ports = append(http80Ports, portMap) - } - } - - if len(http80Ports) > 0 { - var https443Ports []PortMap - for _, portMap := range proxyPortMap { - if portMap.Scheme == "https" && portMap.HostPort == 443 { - https443Ports = append(https443Ports, portMap) - } - } - - if err := removeProxyPorts(appName, https443Ports); err != nil { - return err - } - - var toAdd []PortMap - for _, portMap := range http80Ports { - toAdd = append(toAdd, PortMap{ - Scheme: "https", - HostPort: 443, - ContainerPort: portMap.ContainerPort, - }) - } - - if err := addProxyPorts(appName, toAdd); err != nil { - return err - } - } - - return nil -} diff --git a/plugins/repo/go.mod b/plugins/repo/go.mod index b8490692f09..e2b67dbc3f4 100644 --- a/plugins/repo/go.mod +++ b/plugins/repo/go.mod @@ -4,14 +4,12 @@ go 1.19 require ( github.com/dokku/dokku/plugins/common v0.0.0-00010101000000-000000000000 - github.com/dokku/dokku/plugins/config v0.0.0-00010101000000-000000000000 github.com/spf13/pflag v1.0.5 ) require ( github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0 // indirect github.com/codeskyblue/go-sh v0.0.0-20190412065543-76bd3d59ff27 // indirect - github.com/joho/godotenv v1.2.0 // indirect github.com/otiai10/copy v1.12.0 // indirect github.com/ryanuber/columnize v2.1.2+incompatible // indirect golang.org/x/sync v0.3.0 // indirect diff --git a/plugins/repo/go.sum b/plugins/repo/go.sum index 1a7ae7db219..a7b423b1ca5 100644 --- a/plugins/repo/go.sum +++ b/plugins/repo/go.sum @@ -3,8 +3,6 @@ github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcju github.com/codeskyblue/go-sh v0.0.0-20190412065543-76bd3d59ff27 h1:HHUr4P/aKh4quafGxDT9LDasjGdlGkzLbfmmrlng3kA= github.com/codeskyblue/go-sh v0.0.0-20190412065543-76bd3d59ff27/go.mod h1:VQx0hjo2oUeQkQUET7wRwradO6f+fN5jzXgB/zROxxE= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= -github.com/joho/godotenv v1.2.0 h1:vGTvz69FzUFp+X4/bAkb0j5BoLC+9bpqTWY8mjhA9pc= -github.com/joho/godotenv v1.2.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= github.com/onsi/gomega v1.27.8 h1:gegWiwZjBsf2DgiSbf5hpokZ98JVDMcWkUiigk6/KXc= github.com/otiai10/copy v1.12.0 h1:cLMgSQnXBs1eehF0Wy/FAGsgDTDmAqFR7rQylBb1nDY= github.com/otiai10/copy v1.12.0/go.mod h1:rSaLseMUsZFFbsFGc7wCJnnkTAvdc5L6VWxPE4308Ww= diff --git a/tests/unit/apps_2.bats b/tests/unit/apps_2.bats index 2afb61fa827..ce91b5e7897 100644 --- a/tests/unit/apps_2.bats +++ b/tests/unit/apps_2.bats @@ -114,7 +114,7 @@ teardown() { echo "output: $output" echo "status: $status" assert_success - run /bin/bash -c "dokku --quiet proxy:ports app-without-ssl | xargs" + run /bin/bash -c "dokku --quiet ports:list app-without-ssl | xargs" echo "output: $output" echo "status: $status" assert_output "http 80 5000" diff --git a/tests/unit/caddy.bats b/tests/unit/caddy.bats index 2362ababdc7..7a3c38651ec 100644 --- a/tests/unit/caddy.bats +++ b/tests/unit/caddy.bats @@ -137,7 +137,7 @@ teardown() { assert_success assert_output "$TEST_APP.dokku.me" - run /bin/bash -c "dokku proxy:report $TEST_APP --proxy-port-map" + run /bin/bash -c "dokku ports:report $TEST_APP --ports-map" echo "output: $output" echo "status: $status" assert_output "http:80:5000" diff --git a/tests/unit/haproxy.bats b/tests/unit/haproxy.bats index cf74e6f6771..faa757bf122 100644 --- a/tests/unit/haproxy.bats +++ b/tests/unit/haproxy.bats @@ -154,7 +154,7 @@ teardown() { assert_success assert_output "true" - run /bin/bash -c "dokku proxy:report $TEST_APP --proxy-port-map" + run /bin/bash -c "dokku ports:report $TEST_APP --ports-map" echo "output: $output" echo "status: $status" assert_output "http:80:5000" diff --git a/tests/unit/nginx-vhosts_3.bats b/tests/unit/nginx-vhosts_3.bats index babc690c5fd..0a7ad5fa7c2 100644 --- a/tests/unit/nginx-vhosts_3.bats +++ b/tests/unit/nginx-vhosts_3.bats @@ -18,14 +18,14 @@ teardown() { @test "(nginx-vhosts) grpc endpoint" { deploy_app gogrpc - dokku proxy:ports-add "$TEST_APP" "grpc:80:50051" + dokku ports:add "$TEST_APP" "grpc:80:50051" run /bin/bash -c "docker run --rm ${TEST_APP}-docker-image /go/bin/greeter_client -address ${TEST_APP}.dokku.me:80 -name grpc" assert_output "Greeting: Hello grpc" } @test "(nginx-vhosts) grpc endpoint on a port other than 80" { deploy_app gogrpc - dokku proxy:ports-add "$TEST_APP" "grpc:8080:50051" + dokku ports:add "$TEST_APP" "grpc:8080:50051" run /bin/bash -c "docker run --rm ${TEST_APP}-docker-image /go/bin/greeter_client -address ${TEST_APP}.dokku.me:8080 -name grpc8080" assert_output "Greeting: Hello grpc8080" } @@ -33,7 +33,7 @@ teardown() { @test "(nginx-vhosts) grpcs endpoint" { setup_test_tls deploy_app gogrpc - dokku proxy:ports-add "$TEST_APP" "grpcs:443:50051" + dokku ports:add "$TEST_APP" "grpcs:443:50051" run /bin/bash -c "docker run --rm ${TEST_APP}-docker-image /go/bin/greeter_client -address ${TEST_APP}.dokku.me:443 -name grpcs -tls" assert_output "Greeting: Hello grpcs" } diff --git a/tests/unit/nginx-vhosts_8.bats b/tests/unit/nginx-vhosts_8.bats index 248296737ac..d0b02ae4c1c 100644 --- a/tests/unit/nginx-vhosts_8.bats +++ b/tests/unit/nginx-vhosts_8.bats @@ -125,7 +125,7 @@ teardown() { assert_output_contains "Ignoring detected https port mapping without an accompanying ssl certificate" 0 teardown_test_tls - run /bin/bash -c "dokku proxy:report $TEST_APP --proxy-port-map" + run /bin/bash -c "dokku ports:report $TEST_APP --ports-map" echo "output: $output" echo "status: $status" assert_output "http:80:5000 https:443:5000" @@ -135,7 +135,7 @@ teardown() { echo "status: $status" assert_output_contains "Ignoring detected https port mapping without an accompanying ssl certificate" 1 - run /bin/bash -c "dokku proxy:report $TEST_APP --proxy-port-map" + run /bin/bash -c "dokku ports:report $TEST_APP --ports-map" echo "output: $output" echo "status: $status" assert_output "http:80:5000 https:443:5000" diff --git a/tests/unit/ports.bats b/tests/unit/ports.bats new file mode 100644 index 00000000000..2bef9aa78fa --- /dev/null +++ b/tests/unit/ports.bats @@ -0,0 +1,106 @@ +#!/usr/bin/env bats + +load test_helper + +setup() { + global_setup + [[ -f "$DOKKU_ROOT/VHOST" ]] && cp -fp "$DOKKU_ROOT/VHOST" "$DOKKU_ROOT/VHOST.bak" + create_app +} + +teardown() { + destroy_app 0 $TEST_APP + [[ -f "$DOKKU_ROOT/VHOST.bak" ]] && mv "$DOKKU_ROOT/VHOST.bak" "$DOKKU_ROOT/VHOST" && chown dokku:dokku "$DOKKU_ROOT/VHOST" + global_teardown +} + +@test "(ports) ports:help" { + run /bin/bash -c "dokku ports" + echo "output: $output" + echo "status: $status" + assert_output_contains "Manage ports for an app" + help_output="$output" + + run /bin/bash -c "dokku ports:help" + echo "output: $output" + echo "status: $status" + assert_output_contains "Manage ports for an app" + assert_output "$help_output" +} + +@test "(ports) ports subcommands (list/add/set/remove/clear)" { + run /bin/bash -c "dokku ports:set $TEST_APP http:1234:5001" + echo "output: $output" + echo "status: $status" + assert_success + + run /bin/bash -c "dokku --quiet ports:list $TEST_APP | xargs" + echo "output: $output" + echo "status: $status" + assert_output "http 1234 5001" + + run /bin/bash -c "dokku ports:add $TEST_APP http:8080:5002 https:8443:5003" + echo "output: $output" + echo "status: $status" + assert_success + + run /bin/bash -c "dokku --quiet ports:list $TEST_APP | xargs" + echo "output: $output" + echo "status: $status" + assert_output "http 1234 5001 http 8080 5002 https 8443 5003" + + run /bin/bash -c "dokku ports:set $TEST_APP http:8080:5000 https:8443:5000 http:1234:5001" + echo "output: $output" + echo "status: $status" + assert_success + + run /bin/bash -c "dokku --quiet ports:list $TEST_APP | xargs" + echo "output: $output" + echo "status: $status" + assert_output "http 1234 5001 http 8080 5000 https 8443 5000" + + run /bin/bash -c "dokku ports:remove $TEST_APP 8080" + echo "output: $output" + echo "status: $status" + assert_success + + run /bin/bash -c "dokku --quiet ports:list $TEST_APP | xargs" + echo "output: $output" + echo "status: $status" + assert_output "http 1234 5001 https 8443 5000" + + run /bin/bash -c "dokku ports:remove $TEST_APP http:1234:5001" + echo "output: $output" + echo "status: $status" + assert_success + + run /bin/bash -c "dokku --quiet ports:list $TEST_APP | xargs" + echo "output: $output" + echo "status: $status" + assert_output "https 8443 5000" + + run /bin/bash -c "dokku ports:clear $TEST_APP" + echo "output: $output" + echo "status: $status" + assert_success + + run /bin/bash -c "dokku --quiet ports:list $TEST_APP | xargs" + echo "output: $output" + echo "status: $status" + assert_output "http 80 5000" +} + +@test "(ports) ports:add (post-deploy add)" { + deploy_app + run /bin/bash -c "dokku ports:add $TEST_APP http:8080:5000 http:8081:5000" + echo "output: $output" + echo "status: $status" + assert_success + + URLS="$(dokku --quiet urls "$TEST_APP")" + for URL in $URLS; do + assert_http_success $URL + done + assert_http_success "http://$TEST_APP.dokku.me:8080" + assert_http_success "http://$TEST_APP.dokku.me:8081" +} diff --git a/tests/unit/proxied-app.bats b/tests/unit/proxied-app.bats index e16928634dd..3d4ed454842 100644 --- a/tests/unit/proxied-app.bats +++ b/tests/unit/proxied-app.bats @@ -29,7 +29,7 @@ teardown() { echo "status: $status" assert_success - run /bin/bash -c "dokku proxy:ports-set $TEST_APP http:80:8080" + run /bin/bash -c "dokku ports:set $TEST_APP http:80:8080" echo "output: $output" echo "status: $status" assert_success diff --git a/tests/unit/proxy.bats b/tests/unit/proxy.bats index be69693fde1..1de3c9db0c4 100644 --- a/tests/unit/proxy.bats +++ b/tests/unit/proxy.bats @@ -113,80 +113,3 @@ teardown() { assert_not_external_port $(<$CID_FILE) done } - -@test "(proxy) proxy:ports (list/add/set/remove/clear)" { - run /bin/bash -c "dokku proxy:ports-set $TEST_APP http:1234:5001" - echo "output: $output" - echo "status: $status" - assert_success - - run /bin/bash -c "dokku --quiet proxy:ports $TEST_APP | xargs" - echo "output: $output" - echo "status: $status" - assert_output "http 1234 5001" - - run /bin/bash -c "dokku proxy:ports-add $TEST_APP http:8080:5002 https:8443:5003" - echo "output: $output" - echo "status: $status" - assert_success - - run /bin/bash -c "dokku --quiet proxy:ports $TEST_APP | xargs" - echo "output: $output" - echo "status: $status" - assert_output "http 1234 5001 http 8080 5002 https 8443 5003" - - run /bin/bash -c "dokku proxy:ports-set $TEST_APP http:8080:5000 https:8443:5000 http:1234:5001" - echo "output: $output" - echo "status: $status" - assert_success - - run /bin/bash -c "dokku --quiet proxy:ports $TEST_APP | xargs" - echo "output: $output" - echo "status: $status" - assert_output "http 1234 5001 http 8080 5000 https 8443 5000" - - run /bin/bash -c "dokku proxy:ports-remove $TEST_APP 8080" - echo "output: $output" - echo "status: $status" - assert_success - - run /bin/bash -c "dokku --quiet proxy:ports $TEST_APP | xargs" - echo "output: $output" - echo "status: $status" - assert_output "http 1234 5001 https 8443 5000" - - run /bin/bash -c "dokku proxy:ports-remove $TEST_APP http:1234:5001" - echo "output: $output" - echo "status: $status" - assert_success - - run /bin/bash -c "dokku --quiet proxy:ports $TEST_APP | xargs" - echo "output: $output" - echo "status: $status" - assert_output "https 8443 5000" - - run /bin/bash -c "dokku proxy:ports-clear $TEST_APP" - echo "output: $output" - echo "status: $status" - assert_success - - run /bin/bash -c "dokku --quiet proxy:ports $TEST_APP | xargs" - echo "output: $output" - echo "status: $status" - assert_output "http 80 5000" -} - -@test "(proxy) proxy:ports (post-deploy add)" { - deploy_app - run /bin/bash -c "dokku proxy:ports-add $TEST_APP http:8080:5000 http:8081:5000" - echo "output: $output" - echo "status: $status" - assert_success - - URLS="$(dokku --quiet urls "$TEST_APP")" - for URL in $URLS; do - assert_http_success $URL - done - assert_http_success "http://$TEST_APP.dokku.me:8080" - assert_http_success "http://$TEST_APP.dokku.me:8081" -} diff --git a/tests/unit/traefik.bats b/tests/unit/traefik.bats index a45725aef53..cfdb343d7e6 100644 --- a/tests/unit/traefik.bats +++ b/tests/unit/traefik.bats @@ -233,7 +233,7 @@ teardown() { assert_success assert_output "5000" - run /bin/bash -c "dokku proxy:report $TEST_APP --proxy-port-map" + run /bin/bash -c "dokku ports:report $TEST_APP --ports-map" echo "output: $output" echo "status: $status" assert_output "http:80:5000"