Exemplo n.º 1
0
// flushGlobalPorts opens and closes global ports in the environment.
// It keeps a reference count for ports so that only 0-to-1 and 1-to-0 events
// modify the environment.
func (fw *Firewaller) flushGlobalPorts(rawOpen, rawClose []network.Port) error {
	// Filter which ports are really to open or close.
	var toOpen, toClose []network.Port
	for _, port := range rawOpen {
		if fw.globalPortRef[port] == 0 {
			toOpen = append(toOpen, port)
		}
		fw.globalPortRef[port]++
	}
	for _, port := range rawClose {
		fw.globalPortRef[port]--
		if fw.globalPortRef[port] == 0 {
			toClose = append(toClose, port)
			delete(fw.globalPortRef, port)
		}
	}
	// Open and close the ports.
	if len(toOpen) > 0 {
		if err := fw.environ.OpenPorts(network.PortsToPortRanges(toOpen)); err != nil {
			// TODO(mue) Add local retry logic.
			return err
		}
		network.SortPorts(toOpen)
		logger.Infof("opened ports %v in environment", toOpen)
	}
	if len(toClose) > 0 {
		if err := fw.environ.ClosePorts(network.PortsToPortRanges(toClose)); err != nil {
			// TODO(mue) Add local retry logic.
			return err
		}
		network.SortPorts(toClose)
		logger.Infof("closed ports %v in environment", toClose)
	}
	return nil
}
Exemplo n.º 2
0
// reconcileInstances compares the initially started watcher for machines,
// units and services with the opened and closed ports of the instances and
// opens and closes the appropriate ports for each instance.
func (fw *Firewaller) reconcileInstances() error {
	for _, machined := range fw.machineds {
		m, err := machined.machine()
		if params.IsCodeNotFound(err) {
			if err := fw.forgetMachine(machined); err != nil {
				return err
			}
			continue
		} else if err != nil {
			return err
		}
		instanceId, err := m.InstanceId()
		if err != nil {
			return err
		}
		instances, err := fw.environ.Instances([]instance.Id{instanceId})
		if err == environs.ErrNoInstances {
			return nil
		} else if err != nil {
			return err
		}
		machineId := machined.tag.Id()
		initialPortRanges, err := instances[0].Ports(machineId)
		if err != nil {
			return err
		}
		initialPorts := network.PortRangesToPorts(initialPortRanges)
		// Check which ports to open or to close.
		toOpen := Diff(machined.ports, initialPorts)
		toClose := Diff(initialPorts, machined.ports)
		if len(toOpen) > 0 {
			logger.Infof("opening instance ports %v for %q",
				toOpen, machined.tag)
			if err := instances[0].OpenPorts(machineId, network.PortsToPortRanges(toOpen)); err != nil {
				// TODO(mue) Add local retry logic.
				return err
			}
			network.SortPorts(toOpen)
		}
		if len(toClose) > 0 {
			logger.Infof("closing instance ports %v for %q",
				toClose, machined.tag)
			if err := instances[0].ClosePorts(machineId, network.PortsToPortRanges(toClose)); err != nil {
				// TODO(mue) Add local retry logic.
				return err
			}
			network.SortPorts(toClose)
		}
	}
	return nil
}
Exemplo n.º 3
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.PortsToPortRanges(otherPorts)...)
	network.SortPortRanges(portRanges)
	return portRanges
}
Exemplo n.º 4
0
// flushInstancePorts opens and closes ports global on the machine.
func (fw *Firewaller) flushInstancePorts(machined *machineData, toOpen, toClose []network.Port) error {
	// If there's nothing to do, do nothing.
	// This is important because when a machine is first created,
	// it will have no instance id but also no open ports -
	// InstanceId will fail but we don't care.
	if len(toOpen) == 0 && len(toClose) == 0 {
		return nil
	}
	m, err := machined.machine()
	if params.IsCodeNotFound(err) {
		return nil
	}
	if err != nil {
		return err
	}
	machineId := machined.tag.Id()
	instanceId, err := m.InstanceId()
	if err != nil {
		return err
	}
	instances, err := fw.environ.Instances([]instance.Id{instanceId})
	if err != nil {
		return err
	}
	// Open and close the ports.
	if len(toOpen) > 0 {
		if err := instances[0].OpenPorts(machineId, network.PortsToPortRanges(toOpen)); err != nil {
			// TODO(mue) Add local retry logic.
			return err
		}
		network.SortPorts(toOpen)
		logger.Infof("opened ports %v on %q", toOpen, machined.tag)
	}
	if len(toClose) > 0 {
		if err := instances[0].ClosePorts(machineId, network.PortsToPortRanges(toClose)); err != nil {
			// TODO(mue) Add local retry logic.
			return err
		}
		network.SortPorts(toClose)
		logger.Infof("closed ports %v on %q", toClose, machined.tag)
	}
	return nil
}
Exemplo n.º 5
0
// reconcileGlobal compares the initially started watcher for machines,
// units and services with the opened and closed ports globally and
// opens and closes the appropriate ports for the whole environment.
func (fw *Firewaller) reconcileGlobal() error {
	initialPortRanges, err := fw.environ.Ports()
	if err != nil {
		return err
	}
	initialPorts := network.PortRangesToPorts(initialPortRanges)
	collector := make(map[network.Port]bool)
	for _, unitd := range fw.unitds {
		if unitd.serviced.exposed {
			for _, port := range unitd.ports {
				collector[port] = true
			}
		}
	}
	wantedPorts := []network.Port{}
	for port := range collector {
		wantedPorts = append(wantedPorts, port)
	}
	// Check which ports to open or to close.
	toOpen := Diff(wantedPorts, initialPorts)
	toClose := Diff(initialPorts, wantedPorts)
	if len(toOpen) > 0 {
		logger.Infof("opening global ports %v", toOpen)
		if err := fw.environ.OpenPorts(network.PortsToPortRanges(toOpen)); err != nil {
			return err
		}
		network.SortPorts(toOpen)
	}
	if len(toClose) > 0 {
		logger.Infof("closing global ports %v", toClose)
		if err := fw.environ.ClosePorts(network.PortsToPortRanges(toClose)); err != nil {
			return err
		}
		network.SortPorts(toClose)
	}
	return nil
}