@@ -21,6 +21,8 @@ import (
2121 . "github.com/onsi/gomega" // nolint:revive
2222
2323 "github.com/llm-d/llm-d-router/pkg/common/routing"
24+ "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
25+ "k8s.io/apimachinery/pkg/runtime/schema"
2426 "k8s.io/utils/set"
2527)
2628
@@ -41,6 +43,139 @@ var _ = Describe("AllowlistValidator", func() {
4143 })
4244 })
4345
46+ Context ("poolSelector" , func () {
47+ It ("should extract selector from GA InferencePool (matchLabels)" , func () {
48+ av := & AllowlistValidator {
49+ gvr : schema.GroupVersionResource {
50+ Group : routing .InferencePoolAPIGroup ,
51+ Version : "v1" ,
52+ Resource : "inferencepools" ,
53+ },
54+ }
55+ pool := & unstructured.Unstructured {
56+ Object : map [string ]interface {}{
57+ "apiVersion" : "inference.networking.k8s.io/v1" ,
58+ "kind" : "InferencePool" ,
59+ "metadata" : map [string ]interface {}{"name" : "test-pool" },
60+ "spec" : map [string ]interface {}{
61+ "selector" : map [string ]interface {}{
62+ "matchLabels" : map [string ]interface {}{
63+ "app.kubernetes.io/name" : "my-model" ,
64+ "component" : "serving" ,
65+ },
66+ },
67+ },
68+ },
69+ }
70+
71+ selector , err := av .poolSelector (pool )
72+ Expect (err ).ToNot (HaveOccurred ())
73+ Expect (selector .String ()).To (SatisfyAll (
74+ ContainSubstring ("app.kubernetes.io/name=my-model" ),
75+ ContainSubstring ("component=serving" ),
76+ ))
77+ })
78+
79+ It ("should extract selector from deprecated alpha InferencePool (flat map)" , func () {
80+ av := & AllowlistValidator {
81+ gvr : schema.GroupVersionResource {
82+ Group : "inference.networking.x-k8s.io" ,
83+ Version : "v1alpha2" ,
84+ Resource : "inferencepools" ,
85+ },
86+ }
87+ pool := & unstructured.Unstructured {
88+ Object : map [string ]interface {}{
89+ "apiVersion" : "inference.networking.x-k8s.io/v1alpha2" ,
90+ "kind" : "InferencePool" ,
91+ "metadata" : map [string ]interface {}{"name" : "test-pool" },
92+ "spec" : map [string ]interface {}{
93+ "selector" : map [string ]interface {}{
94+ "app.kubernetes.io/name" : "my-model" ,
95+ "component" : "serving" ,
96+ },
97+ },
98+ },
99+ }
100+
101+ selector , err := av .poolSelector (pool )
102+ Expect (err ).ToNot (HaveOccurred ())
103+ Expect (selector .String ()).To (SatisfyAll (
104+ ContainSubstring ("app.kubernetes.io/name=my-model" ),
105+ ContainSubstring ("component=serving" ),
106+ ))
107+ })
108+
109+ It ("should fail for GA pool with flat selector (no matchLabels)" , func () {
110+ av := & AllowlistValidator {
111+ gvr : schema.GroupVersionResource {
112+ Group : routing .InferencePoolAPIGroup ,
113+ Version : "v1" ,
114+ Resource : "inferencepools" ,
115+ },
116+ }
117+ pool := & unstructured.Unstructured {
118+ Object : map [string ]interface {}{
119+ "apiVersion" : "inference.networking.k8s.io/v1" ,
120+ "kind" : "InferencePool" ,
121+ "metadata" : map [string ]interface {}{"name" : "test-pool" },
122+ "spec" : map [string ]interface {}{
123+ "selector" : map [string ]interface {}{
124+ "app" : "my-model" ,
125+ },
126+ },
127+ },
128+ }
129+
130+ _ , err := av .poolSelector (pool )
131+ Expect (err ).To (HaveOccurred ())
132+ Expect (err .Error ()).To (ContainSubstring ("matchLabels" ))
133+ })
134+
135+ It ("should fail when spec is missing" , func () {
136+ av := & AllowlistValidator {
137+ gvr : schema.GroupVersionResource {
138+ Group : routing .InferencePoolAPIGroup ,
139+ Version : "v1" ,
140+ Resource : "inferencepools" ,
141+ },
142+ }
143+ pool := & unstructured.Unstructured {
144+ Object : map [string ]interface {}{
145+ "apiVersion" : "inference.networking.k8s.io/v1" ,
146+ "kind" : "InferencePool" ,
147+ "metadata" : map [string ]interface {}{"name" : "test-pool" },
148+ },
149+ }
150+
151+ _ , err := av .poolSelector (pool )
152+ Expect (err ).To (HaveOccurred ())
153+ Expect (err .Error ()).To (ContainSubstring ("spec" ))
154+ })
155+
156+ It ("should fail when selector is missing" , func () {
157+ av := & AllowlistValidator {
158+ gvr : schema.GroupVersionResource {
159+ Group : "inference.networking.x-k8s.io" ,
160+ Version : "v1alpha2" ,
161+ Resource : "inferencepools" ,
162+ },
163+ }
164+ pool := & unstructured.Unstructured {
165+ Object : map [string ]interface {}{
166+ "apiVersion" : "inference.networking.x-k8s.io/v1alpha2" ,
167+ "kind" : "InferencePool" ,
168+ "metadata" : map [string ]interface {}{"name" : "test-pool" },
169+ "spec" : map [string ]interface {}{},
170+ },
171+ }
172+
173+ _ , err := av .poolSelector (pool )
174+ Expect (err ).To (HaveOccurred ())
175+ Expect (err .Error ()).To (ContainSubstring ("selector" ))
176+ })
177+ })
178+
44179 Context ("when SSRF protection is enabled" , func () {
45180 var validator * AllowlistValidator
46181
0 commit comments