@@ -3331,6 +3331,30 @@ TEST(infra_is_dockerfile) {
33313331 PASS ();
33323332}
33333333
3334+ TEST (infra_is_kustomize_file ) {
3335+ ASSERT (cbm_is_kustomize_file ("kustomization.yaml" ));
3336+ ASSERT (cbm_is_kustomize_file ("kustomization.yml" ));
3337+ ASSERT (cbm_is_kustomize_file ("KUSTOMIZATION.YAML" )); /* case-insensitive */
3338+ ASSERT (!cbm_is_kustomize_file ("deployment.yaml" ));
3339+ ASSERT (!cbm_is_kustomize_file ("kustomize.yaml" ));
3340+ ASSERT (!cbm_is_kustomize_file (NULL ));
3341+ PASS ();
3342+ }
3343+
3344+ TEST (infra_is_k8s_manifest ) {
3345+ const char * deploy = "apiVersion: apps/v1\nkind: Deployment\nmetadata:\n name: my-app\n" ;
3346+ const char * plain = "name: foo\nvalue: bar\n" ;
3347+ const char * kust = "apiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n" ;
3348+
3349+ ASSERT (cbm_is_k8s_manifest ("deployment.yaml" , deploy ));
3350+ ASSERT (!cbm_is_k8s_manifest ("deployment.yaml" , plain ));
3351+ /* kustomize file should return false even if it has apiVersion */
3352+ ASSERT (!cbm_is_k8s_manifest ("kustomization.yaml" , kust ));
3353+ ASSERT (!cbm_is_k8s_manifest (NULL , deploy ));
3354+ ASSERT (!cbm_is_k8s_manifest ("deployment.yaml" , NULL ));
3355+ PASS ();
3356+ }
3357+
33343358TEST (infra_is_env_file ) {
33353359 ASSERT (cbm_is_env_file (".env" ));
33363360 ASSERT (cbm_is_env_file (".env.local" ));
@@ -4139,6 +4163,75 @@ TEST(infra_pipeline_idempotent) {
41394163 PASS ();
41404164}
41414165
4166+ /* ── K8s / Kustomize extraction tests ──────────────────────────── */
4167+
4168+ TEST (k8s_extract_kustomize ) {
4169+ const char * src =
4170+ "apiVersion: kustomize.config.k8s.io/v1beta1\n"
4171+ "kind: Kustomization\n"
4172+ "resources:\n"
4173+ " - deployment.yaml\n"
4174+ " - service.yaml\n" ;
4175+ CBMFileResult * r = cbm_extract_file (src , (int )strlen (src ), CBM_LANG_KUSTOMIZE ,
4176+ "myproj" , "base/kustomization.yaml" ,
4177+ 0 , NULL , NULL );
4178+ ASSERT (r != NULL );
4179+ ASSERT_GTE (r -> imports .count , 2 );
4180+
4181+ bool found_deploy = false, found_svc = false;
4182+ for (int i = 0 ; i < r -> imports .count ; i ++ ) {
4183+ if (r -> imports .items [i ].module_path &&
4184+ strcmp (r -> imports .items [i ].module_path , "deployment.yaml" ) == 0 )
4185+ found_deploy = true;
4186+ if (r -> imports .items [i ].module_path &&
4187+ strcmp (r -> imports .items [i ].module_path , "service.yaml" ) == 0 )
4188+ found_svc = true;
4189+ }
4190+ ASSERT_TRUE (found_deploy );
4191+ ASSERT_TRUE (found_svc );
4192+
4193+ cbm_free_result (r );
4194+ PASS ();
4195+ }
4196+
4197+ TEST (k8s_extract_manifest ) {
4198+ const char * src =
4199+ "apiVersion: apps/v1\n"
4200+ "kind: Deployment\n"
4201+ "metadata:\n"
4202+ " name: my-app\n"
4203+ " namespace: production\n" ;
4204+ CBMFileResult * r = cbm_extract_file (src , (int )strlen (src ), CBM_LANG_K8S ,
4205+ "myproj" , "k8s/deployment.yaml" ,
4206+ 0 , NULL , NULL );
4207+ ASSERT (r != NULL );
4208+ ASSERT_GTE (r -> defs .count , 1 );
4209+
4210+ bool found_resource = false;
4211+ for (int d = 0 ; d < r -> defs .count ; d ++ ) {
4212+ if (r -> defs .items [d ].label &&
4213+ strcmp (r -> defs .items [d ].label , "Resource" ) == 0 &&
4214+ r -> defs .items [d ].name &&
4215+ strstr (r -> defs .items [d ].name , "Deployment" ) != NULL )
4216+ found_resource = true;
4217+ }
4218+ ASSERT_TRUE (found_resource );
4219+
4220+ cbm_free_result (r );
4221+ PASS ();
4222+ }
4223+
4224+ TEST (k8s_extract_manifest_no_name ) {
4225+ const char * src = "apiVersion: apps/v1\nkind: Deployment\n" ;
4226+ CBMFileResult * r = cbm_extract_file (src , (int )strlen (src ), CBM_LANG_K8S ,
4227+ "myproj" , "k8s/deploy.yaml" , 0 , NULL , NULL );
4228+ ASSERT (r != NULL );
4229+ /* No crash — defs count may be 0 because metadata.name is absent */
4230+ ASSERT (!r -> has_error );
4231+ cbm_free_result (r );
4232+ PASS ();
4233+ }
4234+
41424235/* ── Envscan tests (port of envscan_test.go) ───────────────────── */
41434236
41444237/* Helper: write a file inside a temp dir */
@@ -5055,6 +5148,8 @@ SUITE(pipeline) {
50555148 RUN_TEST (infra_is_cloudbuild_file );
50565149 RUN_TEST (infra_is_shell_script );
50575150 RUN_TEST (infra_is_dockerfile );
5151+ RUN_TEST (infra_is_kustomize_file );
5152+ RUN_TEST (infra_is_k8s_manifest );
50585153 RUN_TEST (infra_is_env_file );
50595154 RUN_TEST (infra_clean_json_brackets );
50605155 RUN_TEST (infra_secret_detection );
@@ -5083,6 +5178,10 @@ SUITE(pipeline) {
50835178 /* Infrascan: pipeline integration */
50845179 RUN_TEST (infra_pipeline_integration );
50855180 RUN_TEST (infra_pipeline_idempotent );
5181+ /* K8s / Kustomize extraction */
5182+ RUN_TEST (k8s_extract_kustomize );
5183+ RUN_TEST (k8s_extract_manifest );
5184+ RUN_TEST (k8s_extract_manifest_no_name );
50865185 /* Env URL scanning */
50875186 RUN_TEST (envscan_dockerfile_env_urls );
50885187 RUN_TEST (envscan_shell_env_urls );
0 commit comments