github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/state/unit_machine_ports.go (about)

     1  // Copyright 2020 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package state
     5  
     6  import (
     7  	"github.com/juju/juju/core/network"
     8  )
     9  
    10  var _ UnitPortRanges = (*unitPortRangesForMachine)(nil)
    11  
    12  // unitPortRanges is a view on the machinePortRanges type that provides
    13  // unit-level information about the set of opened port ranges for various
    14  // application endpoints.
    15  // This unitPortRanges is denormalised. We should really access the ports by units rather than machine.
    16  type unitPortRangesForMachine struct {
    17  	unitName          string
    18  	machinePortRanges *machinePortRanges
    19  }
    20  
    21  // UnitName returns the unit name associated with this set of ports.
    22  func (p *unitPortRangesForMachine) UnitName() string {
    23  	return p.unitName
    24  }
    25  
    26  // ForEndpoint returns a list of port ranges that the unit has opened for the
    27  // specified endpoint.
    28  func (p *unitPortRangesForMachine) ForEndpoint(endpointName string) []network.PortRange {
    29  	unitPortRangeDoc := p.machinePortRanges.doc.UnitRanges[p.unitName]
    30  	if len(unitPortRangeDoc) == 0 || len(unitPortRangeDoc[endpointName]) == 0 {
    31  		return nil
    32  	}
    33  	res := append([]network.PortRange(nil), unitPortRangeDoc[endpointName]...)
    34  	network.SortPortRanges(res)
    35  	return res
    36  }
    37  
    38  // ByEndpoint returns a map where keys are endpoint names and values are the
    39  // port ranges that the unit has opened for each endpoint.
    40  func (p *unitPortRangesForMachine) ByEndpoint() network.GroupedPortRanges {
    41  	unitPortRangeDoc := p.machinePortRanges.doc.UnitRanges[p.unitName]
    42  	if len(unitPortRangeDoc) == 0 {
    43  		return nil
    44  	}
    45  
    46  	res := make(network.GroupedPortRanges)
    47  	for endpointName, portRanges := range unitPortRangeDoc {
    48  		res[endpointName] = append([]network.PortRange(nil), portRanges...)
    49  		network.SortPortRanges(res[endpointName])
    50  	}
    51  	return res
    52  }
    53  
    54  // UniquePortRanges returns a slice of unique open PortRanges across all
    55  // endpoints.
    56  func (p *unitPortRangesForMachine) UniquePortRanges() []network.PortRange {
    57  	uniquePortRanges := p.machinePortRanges.doc.UnitRanges[p.unitName].UniquePortRanges()
    58  	network.SortPortRanges(uniquePortRanges)
    59  	return uniquePortRanges
    60  }
    61  
    62  // Open records a request for opening a particular port range for the specified
    63  // endpoint.
    64  func (p *unitPortRangesForMachine) Open(endpoint string, portRange network.PortRange) {
    65  	if p.machinePortRanges.pendingOpenRanges == nil {
    66  		p.machinePortRanges.pendingOpenRanges = make(map[string]network.GroupedPortRanges)
    67  	}
    68  	if p.machinePortRanges.pendingOpenRanges[p.unitName] == nil {
    69  		p.machinePortRanges.pendingOpenRanges[p.unitName] = make(network.GroupedPortRanges)
    70  	}
    71  
    72  	p.machinePortRanges.pendingOpenRanges[p.unitName][endpoint] = append(
    73  		p.machinePortRanges.pendingOpenRanges[p.unitName][endpoint],
    74  		portRange,
    75  	)
    76  }
    77  
    78  // Close records a request for closing a particular port range for the
    79  // specified endpoint.
    80  func (p *unitPortRangesForMachine) Close(endpoint string, portRange network.PortRange) {
    81  	if p.machinePortRanges.pendingCloseRanges == nil {
    82  		p.machinePortRanges.pendingCloseRanges = make(map[string]network.GroupedPortRanges)
    83  	}
    84  	if p.machinePortRanges.pendingCloseRanges[p.unitName] == nil {
    85  		p.machinePortRanges.pendingCloseRanges[p.unitName] = make(network.GroupedPortRanges)
    86  	}
    87  
    88  	p.machinePortRanges.pendingCloseRanges[p.unitName][endpoint] = append(
    89  		p.machinePortRanges.pendingCloseRanges[p.unitName][endpoint],
    90  		portRange,
    91  	)
    92  }
    93  
    94  // Changes returns a ModelOperation for applying any changes that were made to
    95  // the port ranges for this unit.
    96  func (p *unitPortRangesForMachine) Changes() ModelOperation {
    97  	return &openClosePortRangesOperation{
    98  		mpr:          p.machinePortRanges,
    99  		unitSelector: p.unitName,
   100  	}
   101  }