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 }