package environment import ( "fmt" "github.com/docker/go-connections/nat" "strconv" ) // Defines the allocations available for a given server. When using the Docker environment // driver these correspond to mappings for the container that allow external connections. type Allocations struct { // Defines the default allocation that should be used for this server. This is // what will be used for {SERVER_IP} and {SERVER_PORT} when modifying configuration // files or the startup arguments for a server. DefaultMapping struct { Ip string `json:"ip"` Port int `json:"port"` } `json:"default"` // Mappings contains all of the ports that should be assigned to a given server // attached to the IP they correspond to. Mappings map[string][]int `json:"mappings"` } // Converts the server allocation mappings into a format that can be understood by Docker. While // we do strive to support multiple environments, using Docker's standardized format for the // bindings certainly makes life a little easier for managing things. func (a *Allocations) Bindings() nat.PortMap { var out = nat.PortMap{} for ip, ports := range a.Mappings { for _, port := range ports { // Skip over invalid ports. if port < 1 || port > 65535 { continue } binding := []nat.PortBinding{ { HostIP: ip, HostPort: strconv.Itoa(port), }, } out[nat.Port(fmt.Sprintf("%d/tcp", port))] = binding out[nat.Port(fmt.Sprintf("%d/udp", port))] = binding } } return out } // Converts the server allocation mappings into a PortSet that can be understood // by Docker. This formatting is slightly different than "Bindings" as it should // return an empty struct rather than a binding. // // To accomplish this, we'll just get the values from "Bindings" and then set them // to empty structs. Because why not. func (a *Allocations) Exposed() nat.PortSet { var out = nat.PortSet{} for port := range a.Bindings() { out[port] = struct{}{} } return out }