You've already forked dcmerge
feat: respect individual ports instead of replacing the entire slice of ports
The following patch adapts the logic of the merge strategy existing and last win for service ports. In the past, the complete object has been replaced based on the merge strategy. This behavior has been adapted, that each port should now considered individually per strategy. Both strategies now focus on the src port of the host system. With a last-win, the dest port of the container is overwritten with an existing src port. ```diff service: my-app: ports: - - 0.0.0.0:8080:80 + - 0.0.0.0:8080:8080 - 0.0.0.0:8443:8443 ``` The situation is different with the existing win strategy. There, the destination port can no longer be changed once there is a connection with a sourc port.
This commit is contained in:
@ -526,7 +526,7 @@ type Service struct {
|
||||
Image string `json:"image,omitempty" yaml:"image,omitempty"`
|
||||
Labels []string `json:"labels,omitempty" yaml:"labels,omitempty"`
|
||||
Networks map[string]*ServiceNetwork `json:"networks,omitempty" yaml:"networks,omitempty"`
|
||||
Ports []string `json:"ports,omitempty" yaml:"ports,omitempty"`
|
||||
Ports []Port `json:"ports,omitempty" yaml:"ports,omitempty"`
|
||||
Secrets []string `json:"secrets,omitempty" yaml:"secrets,omitempty"`
|
||||
ULimits *ServiceULimits `json:"ulimits,omitempty" yaml:"ulimits,omitempty"`
|
||||
Volumes []string `json:"volumes,omitempty" yaml:"volumes,omitempty"`
|
||||
@ -557,39 +557,22 @@ func (s *Service) ExistsLabel(name string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// ExistsPort returns true if the port definition is already present.
|
||||
func (s *Service) ExistsPort(src string, dest string, protocol string) bool {
|
||||
for _, port := range s.Ports {
|
||||
s, d, p := splitStringInPortMapping(port)
|
||||
if s == src && d == dest && p == protocol {
|
||||
// ExistsPort returns true if the port definition is already present. The port defines a mapping between the host system
|
||||
// port and the container port. It is also possible to specify the individual ip address of the host system or the
|
||||
// container. Additionally, the protocol can be specified as suffix.
|
||||
//
|
||||
// // Example
|
||||
// s := new(Service)
|
||||
// b := s.ExistsPort("80:80")
|
||||
// b = s.ExistsPort("0.0.0.0:80:80/tcp")
|
||||
// b = s.ExistsPort("0.0.0.0:80:80/tcp")
|
||||
// b = s.ExistsPort("192.168.178.10:80:172.25.18.20:80/tcp")
|
||||
func (s *Service) ExistsPort(port string) bool {
|
||||
for _, p := range s.Ports {
|
||||
if string(p) == port {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// ExistsDestinationPort returns true if the destination port is already used.
|
||||
func (s *Service) ExistsDestinationPort(dest string) bool {
|
||||
for _, port := range s.Ports {
|
||||
_, d, _ := splitStringInPortMapping(port)
|
||||
if d == dest {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// ExistsSourcePort returns true if the source port is already used.
|
||||
func (s *Service) ExistsSourcePort(src string) bool {
|
||||
for _, port := range s.Ports {
|
||||
s, _, _ := splitStringInPortMapping(port)
|
||||
if s == src {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
@ -847,7 +830,7 @@ func (s *Service) mergeExistingWinNetworks(networks map[string]*ServiceNetwork)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Service) mergeExistingWinPorts(ports []string) {
|
||||
func (s *Service) mergeExistingWinPorts(ports []Port) {
|
||||
switch {
|
||||
case s.Ports == nil && ports != nil:
|
||||
s.Ports = ports
|
||||
@ -862,10 +845,10 @@ func (s *Service) mergeExistingWinPorts(ports []string) {
|
||||
continue LOOP
|
||||
}
|
||||
|
||||
newPort := port(ports[i])
|
||||
newPort := Port(ports[i])
|
||||
|
||||
for j := range s.Ports {
|
||||
existingPort := port(s.Ports[j])
|
||||
existingPort := Port(s.Ports[j])
|
||||
switch {
|
||||
case newPort.existsSrcIP() && existingPort.existsSrcIP() &&
|
||||
newPort.getSrc() == existingPort.getSrc():
|
||||
@ -1061,7 +1044,7 @@ func (s *Service) mergeLastWinNetworks(networks map[string]*ServiceNetwork) {
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Service) mergeLastWinPorts(ports []string) {
|
||||
func (s *Service) mergeLastWinPorts(ports []Port) {
|
||||
switch {
|
||||
case s.Ports == nil && ports != nil:
|
||||
s.Ports = ports
|
||||
@ -1070,13 +1053,11 @@ func (s *Service) mergeLastWinPorts(ports []string) {
|
||||
case s.Ports == nil && ports == nil:
|
||||
return
|
||||
default:
|
||||
for _, port := range ports {
|
||||
if len(port) <= 0 {
|
||||
for i := range ports {
|
||||
if len(ports[i]) <= 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
src, dest, protocol := splitStringInPortMapping(port)
|
||||
s.SetPort(src, dest, protocol)
|
||||
s.SetPort(string(ports[i]))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1139,8 +1120,7 @@ func (s *Service) RemoveEnvironment(name string) {
|
||||
s.Environments = environments
|
||||
}
|
||||
|
||||
// RemoveLabel remove all found labels from the internal slice matching by the
|
||||
// passed name.
|
||||
// RemoveLabel remove all found labels from the internal slice matching by the passed name.
|
||||
func (s *Service) RemoveLabel(name string) {
|
||||
labels := make([]string, 0)
|
||||
for _, label := range s.Labels {
|
||||
@ -1152,25 +1132,47 @@ func (s *Service) RemoveLabel(name string) {
|
||||
s.Labels = labels
|
||||
}
|
||||
|
||||
// RemovePort remove all found ports from the internal slice matching by the
|
||||
// passed dest port.
|
||||
func (s *Service) RemovePort(dest string) {
|
||||
ports := make([]string, 0)
|
||||
// RemovePortByDst remove all found ports from the internal slice matching by the passed destination. The destination
|
||||
// can contains only the destination port, but also the destination ip address.
|
||||
//
|
||||
// // Example
|
||||
// s := new(Service)
|
||||
// s.RemovePortByDst("8080")
|
||||
// s.RemovePortByDst("172.25.18.20:8080")
|
||||
func (s *Service) RemovePortByDst(dest string) {
|
||||
ports := make([]Port, 0)
|
||||
for _, port := range s.Ports {
|
||||
srcPort, destPort, protocol := splitStringInPortMapping(port)
|
||||
|
||||
switch {
|
||||
case destPort == dest && len(protocol) <= 0:
|
||||
s.Ports = append(s.Ports, fmt.Sprintf("%s%s%s", srcPort, portDelimiter, destPort))
|
||||
case destPort == dest && len(protocol) > 0:
|
||||
s.Ports = append(s.Ports, fmt.Sprintf("%s%s%s%s%s", srcPort, portDelimiter, destPort, portProtocolDelimiter, protocol))
|
||||
case port.getDst() == dest:
|
||||
continue
|
||||
default:
|
||||
ports = append(ports, port)
|
||||
}
|
||||
}
|
||||
s.Ports = ports
|
||||
}
|
||||
|
||||
// RemoveVolume remove all found volumes from the internal slice matching by the
|
||||
// dest path.
|
||||
// RemovePortBySrc remove all found ports from the internal slice matching by the passed source. The source can contains
|
||||
// only the source port, but also the source ip address.
|
||||
//
|
||||
// // Example
|
||||
// s := new(Service)
|
||||
// s.RemovePortBySrc("8080")
|
||||
// s.RemovePortBySrc("192.168.178.10:8080")
|
||||
func (s *Service) RemovePortBySrc(src string) {
|
||||
ports := make([]Port, 0)
|
||||
for _, port := range s.Ports {
|
||||
switch {
|
||||
case port.getSrc() == src:
|
||||
continue
|
||||
default:
|
||||
ports = append(ports, port)
|
||||
}
|
||||
}
|
||||
s.Ports = ports
|
||||
}
|
||||
|
||||
// RemoveVolume remove all found volumes from the internal slice matching by the dest path.
|
||||
func (s *Service) RemoveVolume(dest string) {
|
||||
volumes := make([]string, 0)
|
||||
for _, volume := range s.Volumes {
|
||||
@ -1198,14 +1200,16 @@ func (s *Service) SetLabel(name string, value string) {
|
||||
s.Labels = append(s.Labels, fmt.Sprintf("%s%s%s", name, labelDelimiter, value))
|
||||
}
|
||||
|
||||
// SetPort add or overwrite an existing port.
|
||||
func (s *Service) SetPort(src string, dest string, protocol string) {
|
||||
s.RemovePort(dest)
|
||||
if len(protocol) <= 0 {
|
||||
s.Ports = append(s.Ports, fmt.Sprintf("%s%s%s", src, volumeDelimiter, dest))
|
||||
} else {
|
||||
s.Ports = append(s.Ports, fmt.Sprintf("%s%s%s%s%s", src, portDelimiter, dest, portProtocolDelimiter, protocol))
|
||||
}
|
||||
// SetPort add or overwrite an existing source port.
|
||||
//
|
||||
// // Example
|
||||
// s := new(Service)
|
||||
// s.SetPort("0.0.0.0:443:172.25.18.20:8443/tcp") // Add new port
|
||||
// s.SetPort("0.0.0.0:443:10.254.611.66:443/tcp") // Overwrite port determined by source port
|
||||
func (s *Service) SetPort(port string) {
|
||||
newPort := Port(port)
|
||||
s.RemovePortBySrc(newPort.getSrc())
|
||||
s.Ports = append(s.Ports, newPort)
|
||||
}
|
||||
|
||||
// SetVolume add or overwrite an existing volume.
|
||||
@ -1228,7 +1232,7 @@ func NewService() *Service {
|
||||
ExtraHosts: make([]string, 0),
|
||||
Labels: make([]string, 0),
|
||||
Networks: make(map[string]*ServiceNetwork),
|
||||
Ports: make([]string, 0),
|
||||
Ports: make([]Port, 0),
|
||||
Secrets: make([]string, 0),
|
||||
ULimits: new(ServiceULimits),
|
||||
Volumes: make([]string, 0),
|
||||
@ -1976,8 +1980,10 @@ func splitStringInKeyValue(s, sep string) (string, string) {
|
||||
// // Output: "80" "80" "tcp"
|
||||
// s, d, p := splitStringInPortMapping("0.0.0.0:80:80/tcp")
|
||||
// // Output: "0.0.0.0:80" "80" "tcp"
|
||||
//
|
||||
// Deprecated: Instead of using the splitStringInPortMapping function, use the method of the type Port{}.
|
||||
func splitStringInPortMapping(s string) (string, string, string) {
|
||||
p := port(s)
|
||||
p := Port(s)
|
||||
|
||||
var src string
|
||||
switch {
|
||||
@ -2013,36 +2019,36 @@ var (
|
||||
regExpPort = regexp.MustCompile(`^((?<srcIP>([\d]{1,3}\.){3}[\d]{1,3}):)?(?<srcPort>[\d]{1,5}):((?<dstIP>([\d]{1,3}\.){3}[\d]{1,3}):)?(?<dstPort>[\d]{1,5})(\/(?<protocol>[a-z]*))?$`)
|
||||
)
|
||||
|
||||
type port string
|
||||
type Port string
|
||||
|
||||
// existsDstPort returns true, if the port string contains a trailing destination port definition.
|
||||
func (p port) existsDstPort() bool {
|
||||
func (p Port) existsDstPort() bool {
|
||||
return len(p.getDstPort()) > 0
|
||||
}
|
||||
|
||||
// existsDstIP returns true, if the port string contains a trailing destination ip definition.
|
||||
func (p port) existsDstIP() bool {
|
||||
func (p Port) existsDstIP() bool {
|
||||
return len(p.getDstIP()) > 0
|
||||
}
|
||||
|
||||
// existsProtocol returns true, if the port string contains a protocol definition.
|
||||
func (p port) existsProtocol() bool {
|
||||
func (p Port) existsProtocol() bool {
|
||||
return len(p.getProtocol()) > 0
|
||||
}
|
||||
|
||||
// existsSrcIP returns true, if the port string contains a leading src ip definition.
|
||||
func (p port) existsSrcIP() bool {
|
||||
func (p Port) existsSrcIP() bool {
|
||||
return len(p.getSrcIP()) > 0
|
||||
}
|
||||
|
||||
// existsSrcPort returns true, if the port string contains a leading src port definition.
|
||||
func (p port) existsSrcPort() bool {
|
||||
func (p Port) existsSrcPort() bool {
|
||||
return len(p.getSrcPort()) > 0
|
||||
}
|
||||
|
||||
// getDst returns the concatenation of the destination ip and port. If the destination ip is empty, only the port will
|
||||
// be returned.
|
||||
func (p port) getDst() string {
|
||||
func (p Port) getDst() string {
|
||||
switch {
|
||||
case p.existsDstIP():
|
||||
return fmt.Sprintf("%s%s%s", p.getDstIP(), portDelimiter, p.getDstPort())
|
||||
@ -2052,7 +2058,7 @@ func (p port) getDst() string {
|
||||
}
|
||||
|
||||
// getSrcIP returns the destination ip, if the port string contains a destination ip definition.
|
||||
func (p port) getDstIP() string {
|
||||
func (p Port) getDstIP() string {
|
||||
matches := regExpPort.FindStringSubmatch(string(p))
|
||||
i := regExpPort.SubexpIndex("dstIP")
|
||||
|
||||
@ -2067,7 +2073,7 @@ func (p port) getDstIP() string {
|
||||
}
|
||||
|
||||
// getSrcPort returns the destination port, if the port string contains an destination port definition.
|
||||
func (p port) getDstPort() string {
|
||||
func (p Port) getDstPort() string {
|
||||
matches := regExpPort.FindStringSubmatch(string(p))
|
||||
i := regExpPort.SubexpIndex("dstPort")
|
||||
|
||||
@ -2082,7 +2088,7 @@ func (p port) getDstPort() string {
|
||||
}
|
||||
|
||||
// getProtocol returns the protocol, if the port string contains a protocol definition.
|
||||
func (p port) getProtocol() string {
|
||||
func (p Port) getProtocol() string {
|
||||
matches := regExpPort.FindStringSubmatch(string(p))
|
||||
i := regExpPort.SubexpIndex("protocol")
|
||||
|
||||
@ -2098,7 +2104,7 @@ func (p port) getProtocol() string {
|
||||
|
||||
// getSrc returns the concatenation of the source ip and port. If the source ip is empty, only the port will be
|
||||
// returned.
|
||||
func (p port) getSrc() string {
|
||||
func (p Port) getSrc() string {
|
||||
switch {
|
||||
case p.existsSrcIP():
|
||||
return fmt.Sprintf("%s%s%s", p.getSrcIP(), portDelimiter, p.getSrcPort())
|
||||
@ -2108,7 +2114,7 @@ func (p port) getSrc() string {
|
||||
}
|
||||
|
||||
// getSrcIP returns the source ip, if the port string contains an src ip definition.
|
||||
func (p port) getSrcIP() string {
|
||||
func (p Port) getSrcIP() string {
|
||||
matches := regExpPort.FindStringSubmatch(string(p))
|
||||
i := regExpPort.SubexpIndex("srcIP")
|
||||
|
||||
@ -2123,7 +2129,7 @@ func (p port) getSrcIP() string {
|
||||
}
|
||||
|
||||
// getSrcPort returns the source port, if the port string contains an src port definition.
|
||||
func (p port) getSrcPort() string {
|
||||
func (p Port) getSrcPort() string {
|
||||
matches := regExpPort.FindStringSubmatch(string(p))
|
||||
i := regExpPort.SubexpIndex("srcPort")
|
||||
|
||||
|
@ -122,7 +122,7 @@ func TestPort_DstIP(t *testing.T) {
|
||||
}
|
||||
|
||||
for i, testCase := range testCases {
|
||||
p := port(testCase.s)
|
||||
p := Port(testCase.s)
|
||||
require.Equal(testCase.expectedBool, p.existsDstIP(), "TestCase %v", i)
|
||||
require.Equal(testCase.expectedString, p.getDstIP(), "TestCase %v", i)
|
||||
}
|
||||
@ -191,7 +191,7 @@ func TestPort_DstPort(t *testing.T) {
|
||||
}
|
||||
|
||||
for i, testCase := range testCases {
|
||||
p := port(testCase.s)
|
||||
p := Port(testCase.s)
|
||||
require.Equal(testCase.expectedBool, p.existsDstPort(), "TestCase %v", i)
|
||||
require.Equal(testCase.expectedString, p.getDstPort(), "TestCase %v", i)
|
||||
}
|
||||
@ -263,7 +263,7 @@ func TestPort_Protocol(t *testing.T) {
|
||||
}
|
||||
|
||||
for i, testCase := range testCases {
|
||||
p := port(testCase.s)
|
||||
p := Port(testCase.s)
|
||||
require.Equal(testCase.expectedBool, p.existsProtocol(), "TestCase %v", i)
|
||||
require.Equal(testCase.expectedString, p.getProtocol(), "TestCase %v", i)
|
||||
}
|
||||
@ -342,7 +342,7 @@ func TestPort_SrcIP(t *testing.T) {
|
||||
}
|
||||
|
||||
for i, testCase := range testCases {
|
||||
p := port(testCase.s)
|
||||
p := Port(testCase.s)
|
||||
require.Equal(testCase.expectedBool, p.existsSrcIP(), "TestCase %v", i)
|
||||
require.Equal(testCase.expectedString, p.getSrcIP(), "TestCase %v", i)
|
||||
}
|
||||
@ -411,7 +411,7 @@ func TestPort_SrcPort(t *testing.T) {
|
||||
}
|
||||
|
||||
for i, testCase := range testCases {
|
||||
p := port(testCase.s)
|
||||
p := Port(testCase.s)
|
||||
require.Equal(testCase.expectedBool, p.existsSrcPort(), "TestCase %v", i)
|
||||
require.Equal(testCase.expectedString, p.getSrcPort(), "TestCase %v", i)
|
||||
}
|
||||
|
@ -232,7 +232,7 @@ func TestService_Equal(t *testing.T) {
|
||||
Image: "",
|
||||
Labels: []string{},
|
||||
Networks: map[string]*dockerCompose.ServiceNetwork{},
|
||||
Ports: []string{},
|
||||
Ports: []dockerCompose.Port{},
|
||||
Secrets: []string{},
|
||||
ULimits: nil,
|
||||
Volumes: []string{},
|
||||
@ -247,7 +247,7 @@ func TestService_Equal(t *testing.T) {
|
||||
Image: "",
|
||||
Labels: []string{},
|
||||
Networks: map[string]*dockerCompose.ServiceNetwork{},
|
||||
Ports: []string{},
|
||||
Ports: []dockerCompose.Port{},
|
||||
Secrets: []string{},
|
||||
ULimits: nil,
|
||||
Volumes: []string{},
|
||||
@ -418,19 +418,19 @@ func TestService_Equal(t *testing.T) {
|
||||
},
|
||||
{
|
||||
equalableA: &dockerCompose.Service{
|
||||
Ports: []string{"80:80/tcp"},
|
||||
Ports: []dockerCompose.Port{"80:80/tcp"},
|
||||
},
|
||||
equalableB: &dockerCompose.Service{
|
||||
Ports: []string{"80:80/tcp"},
|
||||
Ports: []dockerCompose.Port{"80:80/tcp"},
|
||||
},
|
||||
expectedResult: true,
|
||||
},
|
||||
{
|
||||
equalableA: &dockerCompose.Service{
|
||||
Ports: []string{"80:80/tcp"},
|
||||
Ports: []dockerCompose.Port{"80:80/tcp"},
|
||||
},
|
||||
equalableB: &dockerCompose.Service{
|
||||
Ports: []string{"80:80/udp"},
|
||||
Ports: []dockerCompose.Port{"80:80/udp"},
|
||||
},
|
||||
expectedResult: false,
|
||||
},
|
||||
@ -1108,13 +1108,13 @@ func TestService_MergeExistingWin(t *testing.T) {
|
||||
},
|
||||
{
|
||||
serviceDeploymentA: &dockerCompose.Service{
|
||||
Ports: []string{},
|
||||
Ports: []dockerCompose.Port{},
|
||||
},
|
||||
serviceDeploymentB: &dockerCompose.Service{
|
||||
Ports: nil,
|
||||
},
|
||||
expectedService: &dockerCompose.Service{
|
||||
Ports: []string{},
|
||||
Ports: []dockerCompose.Port{},
|
||||
},
|
||||
},
|
||||
{
|
||||
@ -1122,79 +1122,79 @@ func TestService_MergeExistingWin(t *testing.T) {
|
||||
Ports: nil,
|
||||
},
|
||||
serviceDeploymentB: &dockerCompose.Service{
|
||||
Ports: []string{},
|
||||
Ports: []dockerCompose.Port{},
|
||||
},
|
||||
expectedService: &dockerCompose.Service{
|
||||
Ports: []string{},
|
||||
Ports: []dockerCompose.Port{},
|
||||
},
|
||||
},
|
||||
{
|
||||
serviceDeploymentA: &dockerCompose.Service{
|
||||
Ports: []string{},
|
||||
Ports: []dockerCompose.Port{},
|
||||
},
|
||||
serviceDeploymentB: &dockerCompose.Service{
|
||||
Ports: []string{},
|
||||
Ports: []dockerCompose.Port{},
|
||||
},
|
||||
expectedService: &dockerCompose.Service{
|
||||
Ports: []string{},
|
||||
Ports: []dockerCompose.Port{},
|
||||
},
|
||||
},
|
||||
{
|
||||
serviceDeploymentA: &dockerCompose.Service{
|
||||
Ports: []string{"80:80"},
|
||||
Ports: []dockerCompose.Port{"80:80"},
|
||||
},
|
||||
serviceDeploymentB: &dockerCompose.Service{
|
||||
Ports: []string{"80:80"},
|
||||
Ports: []dockerCompose.Port{"80:80"},
|
||||
},
|
||||
expectedService: &dockerCompose.Service{
|
||||
Ports: []string{"80:80"},
|
||||
Ports: []dockerCompose.Port{"80:80"},
|
||||
},
|
||||
},
|
||||
{
|
||||
serviceDeploymentA: &dockerCompose.Service{
|
||||
Ports: []string{"80:80"},
|
||||
Ports: []dockerCompose.Port{"80:80"},
|
||||
},
|
||||
serviceDeploymentB: &dockerCompose.Service{
|
||||
Ports: []string{"10080:80"},
|
||||
Ports: []dockerCompose.Port{"80:8080"},
|
||||
},
|
||||
expectedService: &dockerCompose.Service{
|
||||
Ports: []string{"80:80"},
|
||||
Ports: []dockerCompose.Port{"80:80"},
|
||||
},
|
||||
},
|
||||
{
|
||||
serviceDeploymentA: &dockerCompose.Service{
|
||||
Ports: []string{"80:80/tcp"},
|
||||
Ports: []dockerCompose.Port{"80:80/tcp"},
|
||||
},
|
||||
serviceDeploymentB: &dockerCompose.Service{
|
||||
Ports: []string{"80:80"},
|
||||
Ports: []dockerCompose.Port{"80:80"},
|
||||
},
|
||||
expectedService: &dockerCompose.Service{
|
||||
Ports: []string{"80:80/tcp"},
|
||||
Ports: []dockerCompose.Port{"80:80/tcp"},
|
||||
},
|
||||
},
|
||||
{
|
||||
serviceDeploymentA: &dockerCompose.Service{
|
||||
Ports: []string{"80:80"},
|
||||
Ports: []dockerCompose.Port{"80:80"},
|
||||
},
|
||||
serviceDeploymentB: &dockerCompose.Service{
|
||||
Ports: []string{"10080:80/udp"},
|
||||
Ports: []dockerCompose.Port{"80:80/udp"},
|
||||
},
|
||||
expectedService: &dockerCompose.Service{
|
||||
Ports: []string{"80:80"},
|
||||
Ports: []dockerCompose.Port{"80:80"},
|
||||
},
|
||||
},
|
||||
{
|
||||
serviceDeploymentA: &dockerCompose.Service{
|
||||
Ports: []string{
|
||||
Ports: []dockerCompose.Port{
|
||||
"0.0.0.0:15005:5005/tcp",
|
||||
"0.0.0.0:18080:8080/tcp",
|
||||
},
|
||||
},
|
||||
serviceDeploymentB: &dockerCompose.Service{
|
||||
Ports: []string{"0.0.0.0:6300:6300/tcp"},
|
||||
Ports: []dockerCompose.Port{"0.0.0.0:6300:6300/tcp"},
|
||||
},
|
||||
expectedService: &dockerCompose.Service{
|
||||
Ports: []string{
|
||||
Ports: []dockerCompose.Port{
|
||||
"0.0.0.0:15005:5005/tcp",
|
||||
"0.0.0.0:18080:8080/tcp",
|
||||
"0.0.0.0:6300:6300/tcp",
|
||||
@ -1203,18 +1203,18 @@ func TestService_MergeExistingWin(t *testing.T) {
|
||||
},
|
||||
{
|
||||
serviceDeploymentA: &dockerCompose.Service{
|
||||
Ports: []string{
|
||||
Ports: []dockerCompose.Port{
|
||||
"0.0.0.0:15005:5005/tcp",
|
||||
"0.0.0.0:18080:8080/tcp",
|
||||
},
|
||||
},
|
||||
serviceDeploymentB: &dockerCompose.Service{
|
||||
Ports: []string{
|
||||
Ports: []dockerCompose.Port{
|
||||
"15005:15005",
|
||||
},
|
||||
},
|
||||
expectedService: &dockerCompose.Service{
|
||||
Ports: []string{
|
||||
Ports: []dockerCompose.Port{
|
||||
"0.0.0.0:15005:5005/tcp",
|
||||
"0.0.0.0:18080:8080/tcp",
|
||||
},
|
||||
@ -2053,13 +2053,13 @@ func TestService_MergeLastWin(t *testing.T) {
|
||||
},
|
||||
{
|
||||
serviceDeploymentA: &dockerCompose.Service{
|
||||
Ports: []string{},
|
||||
Ports: []dockerCompose.Port{},
|
||||
},
|
||||
serviceDeploymentB: &dockerCompose.Service{
|
||||
Ports: nil,
|
||||
},
|
||||
expectedService: &dockerCompose.Service{
|
||||
Ports: []string{},
|
||||
Ports: []dockerCompose.Port{},
|
||||
},
|
||||
},
|
||||
{
|
||||
@ -2067,76 +2067,113 @@ func TestService_MergeLastWin(t *testing.T) {
|
||||
Ports: nil,
|
||||
},
|
||||
serviceDeploymentB: &dockerCompose.Service{
|
||||
Ports: []string{},
|
||||
Ports: []dockerCompose.Port{},
|
||||
},
|
||||
expectedService: &dockerCompose.Service{
|
||||
Ports: []string{},
|
||||
Ports: []dockerCompose.Port{},
|
||||
},
|
||||
},
|
||||
{
|
||||
serviceDeploymentA: &dockerCompose.Service{
|
||||
Ports: []string{},
|
||||
Ports: []dockerCompose.Port{},
|
||||
},
|
||||
serviceDeploymentB: &dockerCompose.Service{
|
||||
Ports: []string{},
|
||||
Ports: []dockerCompose.Port{},
|
||||
},
|
||||
expectedService: &dockerCompose.Service{
|
||||
Ports: []string{},
|
||||
Ports: []dockerCompose.Port{},
|
||||
},
|
||||
},
|
||||
{
|
||||
serviceDeploymentA: &dockerCompose.Service{
|
||||
Ports: []string{"80:80"},
|
||||
Ports: []dockerCompose.Port{"80:80"},
|
||||
},
|
||||
serviceDeploymentB: &dockerCompose.Service{
|
||||
Ports: []string{"80:80"},
|
||||
Ports: []dockerCompose.Port{"80:80"},
|
||||
},
|
||||
expectedService: &dockerCompose.Service{
|
||||
Ports: []string{"80:80"},
|
||||
Ports: []dockerCompose.Port{"80:80"},
|
||||
},
|
||||
},
|
||||
{
|
||||
serviceDeploymentA: &dockerCompose.Service{
|
||||
Ports: []string{"80:80"},
|
||||
Ports: []dockerCompose.Port{"80:80"},
|
||||
},
|
||||
serviceDeploymentB: &dockerCompose.Service{
|
||||
Ports: []string{"10080:80"},
|
||||
Ports: []dockerCompose.Port{"80:10080"},
|
||||
},
|
||||
expectedService: &dockerCompose.Service{
|
||||
Ports: []string{"10080:80"},
|
||||
Ports: []dockerCompose.Port{"80:10080"},
|
||||
},
|
||||
},
|
||||
{
|
||||
serviceDeploymentA: &dockerCompose.Service{
|
||||
Ports: []string{"80:80/tcp"},
|
||||
Ports: []dockerCompose.Port{"80:80/tcp"},
|
||||
},
|
||||
serviceDeploymentB: &dockerCompose.Service{
|
||||
Ports: []string{"80:80"},
|
||||
Ports: []dockerCompose.Port{"80:80"},
|
||||
},
|
||||
expectedService: &dockerCompose.Service{
|
||||
Ports: []string{"80:80"},
|
||||
Ports: []dockerCompose.Port{"80:80"},
|
||||
},
|
||||
},
|
||||
{
|
||||
serviceDeploymentA: &dockerCompose.Service{
|
||||
Ports: []string{"80:80"},
|
||||
Ports: []dockerCompose.Port{"80:80"},
|
||||
},
|
||||
serviceDeploymentB: &dockerCompose.Service{
|
||||
Ports: []string{"10080:80/udp"},
|
||||
Ports: []dockerCompose.Port{"80:80/udp"},
|
||||
},
|
||||
expectedService: &dockerCompose.Service{
|
||||
Ports: []string{"10080:80/udp"},
|
||||
Ports: []dockerCompose.Port{"80:80/udp"},
|
||||
},
|
||||
},
|
||||
{
|
||||
serviceDeploymentA: &dockerCompose.Service{
|
||||
Ports: []string{"80:80"},
|
||||
Ports: []dockerCompose.Port{"80:80"},
|
||||
},
|
||||
serviceDeploymentB: &dockerCompose.Service{
|
||||
Ports: []string{""},
|
||||
Ports: []dockerCompose.Port{""},
|
||||
},
|
||||
expectedService: &dockerCompose.Service{
|
||||
Ports: []string{"80:80"},
|
||||
Ports: []dockerCompose.Port{"80:80"},
|
||||
},
|
||||
},
|
||||
{
|
||||
serviceDeploymentA: &dockerCompose.Service{
|
||||
Ports: []dockerCompose.Port{
|
||||
"0.0.0.0:15005:5005/tcp",
|
||||
"0.0.0.0:18080:8080/tcp",
|
||||
},
|
||||
},
|
||||
serviceDeploymentB: &dockerCompose.Service{
|
||||
Ports: []dockerCompose.Port{"0.0.0.0:6300:6300/tcp"},
|
||||
},
|
||||
expectedService: &dockerCompose.Service{
|
||||
Ports: []dockerCompose.Port{
|
||||
"0.0.0.0:15005:5005/tcp",
|
||||
"0.0.0.0:18080:8080/tcp",
|
||||
"0.0.0.0:6300:6300/tcp",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
serviceDeploymentA: &dockerCompose.Service{
|
||||
Ports: []dockerCompose.Port{
|
||||
"0.0.0.0:15005:5005/tcp",
|
||||
"0.0.0.0:18080:8080/tcp",
|
||||
},
|
||||
},
|
||||
serviceDeploymentB: &dockerCompose.Service{
|
||||
Ports: []dockerCompose.Port{
|
||||
"0.0.0.0:15005:15005",
|
||||
},
|
||||
},
|
||||
expectedService: &dockerCompose.Service{
|
||||
Ports: []dockerCompose.Port{
|
||||
"0.0.0.0:15005:15005",
|
||||
"0.0.0.0:18080:8080/tcp",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
@ -2409,6 +2446,203 @@ func TestService_MergeLastWin(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestService_RemovePortByDst(t *testing.T) {
|
||||
require := require.New(t)
|
||||
|
||||
testCases := []struct {
|
||||
s *dockerCompose.Service
|
||||
removePortsByDst []string
|
||||
expectedPorts []dockerCompose.Port
|
||||
}{
|
||||
{
|
||||
s: &dockerCompose.Service{
|
||||
Ports: []dockerCompose.Port{
|
||||
"80:80/tcp",
|
||||
"0.0.0.0:443:172.25.18.20:443/tcp",
|
||||
"10.11.12.13:53:53/tcp",
|
||||
"10.11.12.13:53:53/udp",
|
||||
},
|
||||
},
|
||||
removePortsByDst: []string{
|
||||
"53",
|
||||
},
|
||||
expectedPorts: []dockerCompose.Port{
|
||||
"80:80/tcp",
|
||||
"0.0.0.0:443:172.25.18.20:443/tcp",
|
||||
},
|
||||
},
|
||||
{
|
||||
s: &dockerCompose.Service{
|
||||
Ports: []dockerCompose.Port{
|
||||
"80:80/tcp",
|
||||
"0.0.0.0:443:172.25.18.20:443/tcp",
|
||||
"10.11.12.13:53:53/tcp",
|
||||
"10.11.12.13:53:53/udp",
|
||||
},
|
||||
},
|
||||
removePortsByDst: []string{
|
||||
"172.25.18.20:443",
|
||||
},
|
||||
expectedPorts: []dockerCompose.Port{
|
||||
"80:80/tcp",
|
||||
"10.11.12.13:53:53/tcp",
|
||||
"10.11.12.13:53:53/udp",
|
||||
},
|
||||
},
|
||||
{
|
||||
s: &dockerCompose.Service{
|
||||
Ports: []dockerCompose.Port{
|
||||
"0.0.0.0:443:443/tcp",
|
||||
},
|
||||
},
|
||||
removePortsByDst: []string{
|
||||
"443",
|
||||
},
|
||||
expectedPorts: []dockerCompose.Port{},
|
||||
},
|
||||
}
|
||||
|
||||
for i, testCase := range testCases {
|
||||
for _, removePortByDst := range testCase.removePortsByDst {
|
||||
testCase.s.RemovePortByDst(removePortByDst)
|
||||
}
|
||||
require.Equal(testCase.expectedPorts, testCase.s.Ports, "TestCase %v", i)
|
||||
}
|
||||
}
|
||||
|
||||
func TestService_RemovePortBySrc(t *testing.T) {
|
||||
require := require.New(t)
|
||||
|
||||
testCases := []struct {
|
||||
s *dockerCompose.Service
|
||||
removePortsBySrc []string
|
||||
expectedPorts []dockerCompose.Port
|
||||
}{
|
||||
{
|
||||
s: &dockerCompose.Service{
|
||||
Ports: []dockerCompose.Port{
|
||||
"80:80/tcp",
|
||||
"0.0.0.0:443:172.25.18.20:443/tcp",
|
||||
"10.11.12.13:53:53/tcp",
|
||||
"10.11.12.13:53:53/udp",
|
||||
},
|
||||
},
|
||||
removePortsBySrc: []string{
|
||||
"10.11.12.13:53",
|
||||
},
|
||||
expectedPorts: []dockerCompose.Port{
|
||||
"80:80/tcp",
|
||||
"0.0.0.0:443:172.25.18.20:443/tcp",
|
||||
},
|
||||
},
|
||||
{
|
||||
s: &dockerCompose.Service{
|
||||
Ports: []dockerCompose.Port{
|
||||
"80:80/tcp",
|
||||
"0.0.0.0:443:172.25.18.20:443/tcp",
|
||||
"10.11.12.13:53:53/tcp",
|
||||
"10.11.12.13:53:53/udp",
|
||||
},
|
||||
},
|
||||
removePortsBySrc: []string{
|
||||
"0.0.0.0:443",
|
||||
},
|
||||
expectedPorts: []dockerCompose.Port{
|
||||
"80:80/tcp",
|
||||
"10.11.12.13:53:53/tcp",
|
||||
"10.11.12.13:53:53/udp",
|
||||
},
|
||||
},
|
||||
{
|
||||
s: &dockerCompose.Service{
|
||||
Ports: []dockerCompose.Port{
|
||||
"0.0.0.0:443:443/tcp",
|
||||
},
|
||||
},
|
||||
removePortsBySrc: []string{
|
||||
"0.0.0.0:443",
|
||||
},
|
||||
expectedPorts: []dockerCompose.Port{},
|
||||
},
|
||||
}
|
||||
|
||||
for i, testCase := range testCases {
|
||||
for _, removePortBySrc := range testCase.removePortsBySrc {
|
||||
testCase.s.RemovePortBySrc(removePortBySrc)
|
||||
}
|
||||
require.Equal(testCase.expectedPorts, testCase.s.Ports, "TestCase %v", i)
|
||||
}
|
||||
}
|
||||
|
||||
func TestService_SetPort(t *testing.T) {
|
||||
require := require.New(t)
|
||||
|
||||
testCases := []struct {
|
||||
s *dockerCompose.Service
|
||||
setPorts []string
|
||||
expectedPorts []dockerCompose.Port
|
||||
}{
|
||||
{
|
||||
s: &dockerCompose.Service{
|
||||
Ports: []dockerCompose.Port{"8080:8080"},
|
||||
},
|
||||
setPorts: []string{},
|
||||
expectedPorts: []dockerCompose.Port{"8080:8080"},
|
||||
},
|
||||
{
|
||||
s: &dockerCompose.Service{
|
||||
Ports: []dockerCompose.Port{"8080:8080"},
|
||||
},
|
||||
setPorts: []string{"8080:8080"},
|
||||
expectedPorts: []dockerCompose.Port{"8080:8080"},
|
||||
},
|
||||
{
|
||||
s: &dockerCompose.Service{
|
||||
Ports: []dockerCompose.Port{"8080:8080"},
|
||||
},
|
||||
setPorts: []string{"8080:80"},
|
||||
expectedPorts: []dockerCompose.Port{"8080:80"},
|
||||
},
|
||||
|
||||
{
|
||||
s: &dockerCompose.Service{
|
||||
Ports: []dockerCompose.Port{"0.0.0.0:8080:8080"},
|
||||
},
|
||||
setPorts: []string{},
|
||||
expectedPorts: []dockerCompose.Port{"0.0.0.0:8080:8080"},
|
||||
},
|
||||
{
|
||||
s: &dockerCompose.Service{
|
||||
Ports: []dockerCompose.Port{"0.0.0.0:8080:8080"},
|
||||
},
|
||||
setPorts: []string{"0.0.0.0:8080:8080"},
|
||||
expectedPorts: []dockerCompose.Port{"0.0.0.0:8080:8080"},
|
||||
},
|
||||
{
|
||||
s: &dockerCompose.Service{
|
||||
Ports: []dockerCompose.Port{"0.0.0.0:8080:8080"},
|
||||
},
|
||||
setPorts: []string{"0.0.0.0:8080:80"},
|
||||
expectedPorts: []dockerCompose.Port{"0.0.0.0:8080:80"},
|
||||
},
|
||||
|
||||
{
|
||||
s: &dockerCompose.Service{
|
||||
Ports: []dockerCompose.Port{"0.0.0.0:8080:8080", "0.0.0.0:8443:8443"},
|
||||
},
|
||||
setPorts: []string{"0.0.0.0:8080:80"},
|
||||
expectedPorts: []dockerCompose.Port{"0.0.0.0:8080:80", "0.0.0.0:8443:8443"},
|
||||
},
|
||||
}
|
||||
|
||||
for i, testCase := range testCases {
|
||||
for _, setPort := range testCase.setPorts {
|
||||
testCase.s.SetPort(setPort)
|
||||
}
|
||||
require.ElementsMatch(testCase.expectedPorts, testCase.s.Ports, "TestCase %v", i)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSecretDeploy_Equal(t *testing.T) {
|
||||
require := require.New(t)
|
||||
|
||||
|
Reference in New Issue
Block a user