11package tree
22
33import (
4- "strings"
5-
64 "github.com/haproxytech/haproxy-unified-gateway/k8s/gate/store"
75 "github.com/haproxytech/haproxy-unified-gateway/k8s/gate/utils"
86 "k8s.io/apimachinery/pkg/types"
97)
108
11- // To identifies a target resource as "namespace/group/kind/name".
12- // An empty name component means the grant applies to any resource name.
13- type To string
14-
15- // From identifies a source resource type as "namespace/group/kind".
16- type From string
17-
189// GrantFrom identifies the source side of a ReferenceGrant check.
1910type GrantFrom struct {
2011 Group string
2112 Kind string
2213 Namespace string
2314}
2415
25- // ToKey converts the descriptor to the internal From key.
26- func (f GrantFrom ) ToKey () From {
27- return From (strings .Join ([]string {f .Namespace , f .Group , f .Kind }, "/" ))
28- }
29-
3016// GrantTo identifies the target side of a ReferenceGrant check.
17+ // An empty Name means the grant applies to any resource name (wildcard).
3118type GrantTo struct {
3219 Group string
3320 Kind string
3421 Namespace string
3522 Name string
3623}
3724
38- // ToKey converts the descriptor to the internal To key.
39- // An empty Name represents a wildcard (any resource name).
40- func (t GrantTo ) ToKey () To {
41- return To (strings .Join ([]string {t .Namespace , t .Group , t .Kind , t .Name }, "/" ))
42- }
43-
44- // wildcardKey returns the To key with an empty name, matching wildcard grants.
45- func (t GrantTo ) wildcardKey () To {
46- return To (strings .Join ([]string {t .Namespace , t .Group , t .Kind , "" }, "/" ))
47- }
48-
4925// ReferenceGrantNamespacedName is the namespace/name key of a ReferenceGrant.
5026type ReferenceGrantNamespacedName types.NamespacedName
5127
5228// ReferenceGrantManager tracks which cross-namespace references are permitted
5329// by ReferenceGrant resources. It maintains three maps:
5430//
55- // - toReferenceGrantFrom: for each target (To), which ReferenceGrants cover it
56- // and from which source types (From). Used to incrementally update toFrom.
31+ // - toReferenceGrantFrom: for each target (GrantTo), which ReferenceGrants
32+ // cover it and from which source types (GrantFrom). Used to incrementally
33+ // update toFrom.
5734//
5835// - referenceGrantsTo: inverse index — for each ReferenceGrant, which targets
59- // (To) it covers. Required to efficiently remove all entries for a deleted grant.
36+ // (GrantTo) it covers. Required to efficiently remove all entries for a
37+ // deleted grant.
6038//
6139// - toFrom: the resolved flat map consumed by IsAccessGranted. Rebuilt from
6240// toReferenceGrantFrom by ComputeToFrom after each reconcile cycle.
6341type ReferenceGrantManager struct {
64- toReferenceGrantFrom map [To ]map [ReferenceGrantNamespacedName ]map [From ]struct {}
65- referenceGrantsTo map [ReferenceGrantNamespacedName ]map [To ]struct {}
66- toFrom map [To ]map [From ]struct {}
42+ toReferenceGrantFrom map [GrantTo ]map [ReferenceGrantNamespacedName ]map [GrantFrom ]struct {}
43+ referenceGrantsTo map [ReferenceGrantNamespacedName ]map [GrantTo ]struct {}
44+ toFrom map [GrantTo ]map [GrantFrom ]struct {}
6745}
6846
6947// ConvertReferenceGrantNamespacedName extracts the namespace/name identity of a
@@ -79,33 +57,31 @@ func ConvertReferenceGrantNamespacedName(referenceGrant ReferenceGrant) Referenc
7957// internal maps allocated.
8058func NewReferenceGrantManager () * ReferenceGrantManager {
8159 return & ReferenceGrantManager {
82- toReferenceGrantFrom : map [To ]map [ReferenceGrantNamespacedName ]map [From ]struct {}{},
83- referenceGrantsTo : map [ReferenceGrantNamespacedName ]map [To ]struct {}{},
84- toFrom : map [To ]map [From ]struct {}{},
60+ toReferenceGrantFrom : map [GrantTo ]map [ReferenceGrantNamespacedName ]map [GrantFrom ]struct {}{},
61+ referenceGrantsTo : map [ReferenceGrantNamespacedName ]map [GrantTo ]struct {}{},
62+ toFrom : map [GrantTo ]map [GrantFrom ]struct {}{},
8563 }
8664}
8765
8866// IsAccessGranted reports whether the resource described by from may reference
8967// the resource described by to. Same-namespace references are always permitted.
9068// Cross-namespace access requires a matching entry in toFrom, covering both
91- // named grants and wildcard grants (empty name ).
69+ // named grants and wildcard grants (empty Name ).
9270func (mgr * ReferenceGrantManager ) IsAccessGranted (from GrantFrom , to GrantTo ) bool {
9371 // Same namespace access is always granted
9472 if to .Namespace == from .Namespace {
9573 return true
9674 }
97- convertedTo := to .ToKey ()
98- convertedToWithoutName := to .wildcardKey ()
99- convertedFrom := from .ToKey ()
100- froms := mgr .toFrom [convertedTo ]
101- fromsWithoutName := mgr .toFrom [convertedToWithoutName ]
102- if froms == nil && fromsWithoutName == nil {
75+ wildcard := GrantTo {Group : to .Group , Kind : to .Kind , Namespace : to .Namespace }
76+ froms := mgr .toFrom [to ]
77+ fromsWildcard := mgr .toFrom [wildcard ]
78+ if froms == nil && fromsWildcard == nil {
10379 // No grants for this 'To'
10480 return false
10581 }
106- _ , granted := froms [convertedFrom ]
82+ _ , granted := froms [from ]
10783 if ! granted {
108- _ , granted = fromsWithoutName [ convertedFrom ]
84+ _ , granted = fromsWildcard [ from ]
10985 }
11086 return granted
11187}
@@ -126,50 +102,50 @@ func (mgr *ReferenceGrantManager) UpsertReferenceGrant(referenceGrant ReferenceG
126102 mgr .removeReferenceGrantWithCheck (referenceGrant , false )
127103 // For each 'To' of the ReferenceGrant
128104 for _ , to := range referenceGrant .K8sResource .Spec .To {
129- convertedTo := ( GrantTo {
105+ grantTo := GrantTo {
130106 Namespace : referenceGrant .K8sResource .Namespace ,
131107 Group : string (to .Group ),
132108 Kind : string (to .Kind ),
133109 Name : string (utils .PointerDefaultValueIfNil (to .Name )),
134- }). ToKey ()
110+ }
135111 // ___________________________
136112 // Update toReferenceGrantFrom
137- referenceGrantFrom := mgr .toReferenceGrantFrom [convertedTo ]
113+ referenceGrantFrom := mgr .toReferenceGrantFrom [grantTo ]
138114 for _ , from := range referenceGrant .K8sResource .Spec .From {
139- convertedFrom := ( GrantFrom {
115+ grantFrom := GrantFrom {
140116 Namespace : string (from .Namespace ),
141117 Group : string (from .Group ),
142118 Kind : string (from .Kind ),
143- }). ToKey ()
119+ }
144120 // We associate the 'To' with the couple 'ReferenceGrant' and 'From'
145121 if referenceGrantFrom == nil {
146122 // First association so we create the map
147- referenceGrantFrom = map [ReferenceGrantNamespacedName ]map [From ]struct {}{
123+ referenceGrantFrom = map [ReferenceGrantNamespacedName ]map [GrantFrom ]struct {}{
148124 referenceGrantNamespacedName : {
149- convertedFrom : {},
125+ grantFrom : {},
150126 },
151127 }
152- mgr .toReferenceGrantFrom [convertedTo ] = referenceGrantFrom
128+ mgr .toReferenceGrantFrom [grantTo ] = referenceGrantFrom
153129 } else {
154130 // Subsequent association so update the association
155131 froms := referenceGrantFrom [referenceGrantNamespacedName ]
156132 if froms == nil {
157- froms = map [From ]struct {}{}
133+ froms = map [GrantFrom ]struct {}{}
158134 referenceGrantFrom [referenceGrantNamespacedName ] = froms
159135 }
160- referenceGrantFrom [referenceGrantNamespacedName ][convertedFrom ] = struct {}{}
136+ referenceGrantFrom [referenceGrantNamespacedName ][grantFrom ] = struct {}{}
161137 }
162138 }
163139 // ________________________
164140 // Update referenceGrantsTo
165141 referenceGrantsTo := mgr .referenceGrantsTo [referenceGrantNamespacedName ]
166142 if referenceGrantsTo == nil {
167- referenceGrantsTo = map [To ]struct {}{
168- convertedTo : {},
143+ referenceGrantsTo = map [GrantTo ]struct {}{
144+ grantTo : {},
169145 }
170146 mgr .referenceGrantsTo [referenceGrantNamespacedName ] = referenceGrantsTo
171147 } else {
172- referenceGrantsTo [convertedTo ] = struct {}{}
148+ referenceGrantsTo [grantTo ] = struct {}{}
173149 }
174150 }
175151}
@@ -233,13 +209,13 @@ func (mgr *ReferenceGrantManager) RemoveReferenceGrant(referenceGrant ReferenceG
233209// after all UpsertReferenceGrant and RemoveReferenceGrant calls for a reconcile cycle
234210// have completed, and before any IsAccessGranted call consults the result.
235211func (mgr * ReferenceGrantManager ) ComputeToFrom () {
236- mgr .toFrom = map [To ]map [From ]struct {}{}
212+ mgr .toFrom = map [GrantTo ]map [GrantFrom ]struct {}{}
237213 for to , referenceGrantFrom := range mgr .toReferenceGrantFrom {
238214 for _ , froms := range referenceGrantFrom {
239215 for from := range froms {
240216 existingFroms := mgr .toFrom [to ]
241217 if existingFroms == nil {
242- existingFroms = map [From ]struct {}{}
218+ existingFroms = map [GrantFrom ]struct {}{}
243219 mgr .toFrom [to ] = existingFroms
244220 }
245221 existingFroms [from ] = struct {}{}
0 commit comments