@@ -48,9 +48,16 @@ use crate::error;
48
48
use crate :: error:: OperatorResult ;
49
49
use k8s_openapi:: api:: core:: v1:: ConfigMap ;
50
50
use kube:: ResourceExt ;
51
+ use lazy_static:: lazy_static;
52
+ use regex:: Regex ;
51
53
use schemars:: { self , JsonSchema } ;
52
54
use serde:: { Deserialize , Serialize } ;
53
55
56
+ lazy_static ! {
57
+ static ref DOT_REGEX : Regex = Regex :: new( "\\ ." ) . unwrap( ) ;
58
+ /// To remove leading slashes from OPA package name (if present)
59
+ static ref LEADING_SLASH_REGEX : Regex = Regex :: new( "(/*)(.*)" ) . unwrap( ) ;
60
+ }
54
61
/// Indicates the OPA API version. This is required to choose the correct
55
62
/// path when constructing the OPA urls to query.
56
63
pub enum OpaApiVersion {
@@ -101,7 +108,7 @@ impl OpaConfig {
101
108
T : ResourceExt ,
102
109
{
103
110
let package_name = match & self . package {
104
- Some ( p) => p . to_string ( ) ,
111
+ Some ( p) => Self :: sanitize_opa_package_name ( p ) ,
105
112
None => resource. name_any ( ) ,
106
113
} ;
107
114
@@ -212,6 +219,17 @@ impl OpaConfig {
212
219
configmap_name : self . config_map_name . clone ( ) ,
213
220
} )
214
221
}
222
+
223
+ /// Removes leading slashes from OPA package name. Dots are converted to forward slashes.
224
+ ///
225
+ /// # Arguments
226
+ /// * `package_name` - Package name to sanitize
227
+ fn sanitize_opa_package_name ( package_name : & str ) -> String {
228
+ // Package names starting with one or more slashes cause the resulting URL to be invalid, hence removed.
229
+ let no_leading_slashes = LEADING_SLASH_REGEX . replace_all ( package_name, "$2" ) ;
230
+ // All dots must be replaced with forward slashes in order for the URL to be a valid resource
231
+ DOT_REGEX . replace_all ( & no_leading_slashes, "/" ) . to_string ( )
232
+ }
215
233
}
216
234
217
235
#[ cfg( test) ]
@@ -316,4 +334,40 @@ mod tests {
316
334
package : package. map ( |p| p. to_string ( ) ) ,
317
335
}
318
336
}
337
+
338
+ #[ test]
339
+ fn test_opa_package_name_sanitizer ( ) {
340
+ // No sanitization needed
341
+ assert_eq ! (
342
+ OpaConfig :: sanitize_opa_package_name( "kafka/authz" ) ,
343
+ "kafka/authz"
344
+ ) ;
345
+
346
+ // Remove single leading slash and convert dot to slash
347
+ assert_eq ! (
348
+ OpaConfig :: sanitize_opa_package_name( "/kafka.authz" ) ,
349
+ "kafka/authz"
350
+ ) ;
351
+
352
+ // Remove multiple leading slashes and convert dot
353
+ assert_eq ! (
354
+ OpaConfig :: sanitize_opa_package_name( "////kafka.authz" ) ,
355
+ "kafka/authz"
356
+ ) ;
357
+ }
358
+
359
+ #[ test]
360
+ fn test_opa_document_url_sanitization ( ) {
361
+ let opa_config = OpaConfig {
362
+ config_map_name : "simple-opa" . to_owned ( ) ,
363
+ package : Some ( "///kafka.authz" . to_owned ( ) ) ,
364
+ } ;
365
+
366
+ let document_url = opa_config. document_url (
367
+ & k8s_openapi:: api:: core:: v1:: Pod :: default ( ) ,
368
+ None ,
369
+ OpaApiVersion :: V1 ,
370
+ ) ;
371
+ assert_eq ! ( document_url, "v1/data/kafka/authz" )
372
+ }
319
373
}
0 commit comments