Example #1
0
// convertEndpointsToPorts converts a slice of gwacl.InputEndpoint into a slice of network.PortRange.
func convertEndpointsToPortRanges(endpoints []gwacl.InputEndpoint) []network.PortRange {
	// group ports by prefix on the endpoint name
	portSets := make(map[string][]network.Port)
	otherPorts := []network.Port{}
	for _, endpoint := range endpoints {
		port := network.Port{
			Protocol: strings.ToLower(endpoint.Protocol),
			Number:   endpoint.Port,
		}
		if strings.Contains(endpoint.Name, "_range_") {
			prefix := strings.Split(endpoint.Name, "_range_")[0]
			portSets[prefix] = append(portSets[prefix], port)
		} else {
			otherPorts = append(otherPorts, port)
		}
	}

	portRanges := []network.PortRange{}

	// convert port sets into port ranges
	for _, ports := range portSets {
		portRanges = append(portRanges, network.CollapsePorts(ports)...)
	}

	portRanges = append(portRanges, network.CollapsePorts(otherPorts)...)
	network.SortPortRanges(portRanges)
	return portRanges
}
Example #2
0
func (*PortSuite) TestCollapsePorts(c *gc.C) {
	testCases := []struct {
		about    string
		ports    []network.Port
		expected []network.PortRange
	}{{
		"single port",
		[]network.Port{{"tcp", 80}},
		[]network.PortRange{{80, 80, "tcp"}},
	},
		{
			"continuous port range",
			[]network.Port{{"tcp", 80}, {"tcp", 81}, {"tcp", 82}, {"tcp", 83}},
			[]network.PortRange{{80, 83, "tcp"}},
		},
		{
			"non-continuous port range",
			[]network.Port{{"tcp", 80}, {"tcp", 81}, {"tcp", 82}, {"tcp", 84}, {"tcp", 85}},
			[]network.PortRange{{80, 82, "tcp"}, {84, 85, "tcp"}},
		},
		{
			"non-continuous port range (udp vs tcp)",
			[]network.Port{{"tcp", 80}, {"tcp", 81}, {"tcp", 82}, {"udp", 84}, {"tcp", 83}},
			[]network.PortRange{{80, 83, "tcp"}, {84, 84, "udp"}},
		},
	}
	for i, t := range testCases {
		c.Logf("test %d: %s", i, t.about)
		c.Assert(network.CollapsePorts(t.ports), gc.DeepEquals, t.expected)
	}
}
Example #3
0
// Helper method to get port from the given firewall rules
func getPorts(envName string, rules []cloudapi.FirewallRule) []network.PortRange {
	portRanges := []network.PortRange{}
	for _, r := range rules {
		rule := r.Rule
		if r.Enabled && strings.HasPrefix(rule, "FROM tag "+envName) && strings.Contains(rule, "PORT") {
			if firewallSinglePortRule.MatchString(rule) {
				parts := firewallSinglePortRule.FindStringSubmatch(rule)
				if len(parts) != 3 {
					continue
				}
				protocol := parts[1]
				n, _ := strconv.Atoi(parts[2])
				portRanges = append(portRanges, network.PortRange{Protocol: protocol, FromPort: n, ToPort: n})
			} else if firewallMultiPortRule.MatchString(rule) {
				parts := firewallMultiPortRule.FindStringSubmatch(rule)
				if len(parts) != 3 {
					continue
				}
				protocol := parts[1]
				ports := []network.Port{}
				portStrings := strings.Split(parts[2], " AND ")
				for _, portString := range portStrings {
					portString = portString[strings.LastIndex(portString, "PORT")+5:]
					port, _ := strconv.Atoi(portString)
					ports = append(ports, network.Port{protocol, port})
				}
				portRanges = append(portRanges, network.CollapsePorts(ports)...)
			}
		}
	}

	network.SortPortRanges(portRanges)
	return portRanges
}
Example #4
0
func validateUnitPorts(st *State, unit *Unit) (
	skippedRanges int,
	mergedRanges []network.PortRange,
	validRanges []PortRange,
) {
	// Collapse individual ports into port ranges.
	mergedRanges = network.CollapsePorts(networkPorts(unit.doc.Ports))
	upgradesLogger.Debugf("merged raw port ranges for unit %q: %v", unit, mergedRanges)

	skippedRanges = 0

	// Validate each merged range.
	for _, mergedRange := range mergedRanges {
		// Convert to state.PortRange, without validation.
		stateRange := PortRange{
			UnitName: unit.Name(),
			FromPort: mergedRange.FromPort,
			ToPort:   mergedRange.ToPort,
			Protocol: strings.ToLower(mergedRange.Protocol),
		}

		// Validate the constructed range.
		if err := stateRange.Validate(); err != nil {
			// Don't give up yet - log it, but try to sanitize first.
			upgradesLogger.Warningf(
				"merged port range %v invalid; trying to sanitize bounds",
				stateRange,
			)
			stateRange = stateRange.SanitizeBounds()
			upgradesLogger.Debugf(
				"merged range %v sanitized as %v",
				mergedRange, stateRange,
			)
			// Now try again.
			if err := stateRange.Validate(); err != nil {
				// Despite trying, the converted port range is still invalid,
				// just skip the migration and log it.
				upgradesLogger.Warningf(
					"cannot migrate unit %q's invalid ports %v: %v (skipping)",
					unit, stateRange, err,
				)
				skippedRanges++
				continue
			}
		}
		validRanges = append(validRanges, stateRange)
	}
	upgradesLogger.Debugf("unit %q valid merged ranges: %v", unit, validRanges)
	return skippedRanges, mergedRanges, validRanges
}
Example #5
0
func (*PortRangeSuite) TestCollapsePorts(c *gc.C) {
	testCases := []struct {
		about    string
		ports    []network.Port
		expected []network.PortRange
	}{{
		"single port",
		[]network.Port{{"tcp", 80}},
		[]network.PortRange{{80, 80, "tcp"}},
	}, {
		"continuous port range (increasing)",
		[]network.Port{{"tcp", 80}, {"tcp", 81}, {"tcp", 82}, {"tcp", 83}},
		[]network.PortRange{{80, 83, "tcp"}},
	}, {
		"continuous port range (decreasing)",
		[]network.Port{{"tcp", 83}, {"tcp", 82}, {"tcp", 81}, {"tcp", 80}},
		[]network.PortRange{{80, 83, "tcp"}},
	}, {
		"non-continuous port range (increasing)",
		[]network.Port{{"tcp", 80}, {"tcp", 81}, {"tcp", 82}, {"tcp", 84}, {"tcp", 85}},
		[]network.PortRange{{80, 82, "tcp"}, {84, 85, "tcp"}},
	}, {
		"non-continuous port range (decreasing)",
		[]network.Port{{"tcp", 85}, {"tcp", 84}, {"tcp", 82}, {"tcp", 81}, {"tcp", 80}},
		[]network.PortRange{{80, 82, "tcp"}, {84, 85, "tcp"}},
	}, {
		"alternating tcp / udp ports (increasing)",
		[]network.Port{{"tcp", 80}, {"udp", 81}, {"tcp", 82}, {"udp", 83}, {"tcp", 84}},
		[]network.PortRange{{80, 80, "tcp"}, {82, 82, "tcp"}, {84, 84, "tcp"}, {81, 81, "udp"}, {83, 83, "udp"}},
	}, {
		"alternating tcp / udp ports (decreasing)",
		[]network.Port{{"tcp", 84}, {"udp", 83}, {"tcp", 82}, {"udp", 81}, {"tcp", 80}},
		[]network.PortRange{{80, 80, "tcp"}, {82, 82, "tcp"}, {84, 84, "tcp"}, {81, 81, "udp"}, {83, 83, "udp"}},
	}, {
		"non-continuous port range (udp vs tcp - increasing)",
		[]network.Port{{"tcp", 80}, {"tcp", 81}, {"tcp", 82}, {"udp", 84}, {"tcp", 83}},
		[]network.PortRange{{80, 83, "tcp"}, {84, 84, "udp"}},
	}, {
		"non-continuous port range (udp vs tcp - decreasing)",
		[]network.Port{{"tcp", 83}, {"udp", 84}, {"tcp", 82}, {"tcp", 81}, {"tcp", 80}},
		[]network.PortRange{{80, 83, "tcp"}, {84, 84, "udp"}},
	}}
	for i, t := range testCases {
		c.Logf("test %d: %s", i, t.about)
		c.Check(network.CollapsePorts(t.ports), jc.DeepEquals, t.expected)
	}
}