@@ -263,6 +263,53 @@ impl AzureMetadata {
263263 pub fn get_function_runtime_version ( & self ) -> & str {
264264 get_value_or_unknown ! ( self . function_runtime_version)
265265 }
266+
267+ /// Returns Azure App Services tags as an iterator of (tag_name, tag_value) tuples.
268+ /// These tags are specific to Azure App Services.
269+ pub fn get_app_service_tags ( & self ) -> impl ExactSizeIterator < Item = ( & ' static str , & str ) > {
270+ [
271+ (
272+ "aas.environment.extension_version" ,
273+ self . get_extension_version ( ) ,
274+ ) ,
275+ ( "aas.environment.instance_id" , self . get_instance_id ( ) ) ,
276+ ( "aas.environment.instance_name" , self . get_instance_name ( ) ) ,
277+ ( "aas.environment.os" , self . get_operating_system ( ) ) ,
278+ ( "aas.resource.group" , self . get_resource_group ( ) ) ,
279+ ( "aas.resource.id" , self . get_resource_id ( ) ) ,
280+ ( "aas.site.kind" , self . get_site_kind ( ) ) ,
281+ ( "aas.site.name" , self . get_site_name ( ) ) ,
282+ ( "aas.site.type" , self . get_site_type ( ) ) ,
283+ ( "aas.subscription.id" , self . get_subscription_id ( ) ) ,
284+ ]
285+ . into_iter ( )
286+ }
287+
288+ /// Returns Azure Functions tags as an iterator of (tag_name, tag_value) tuples.
289+ /// These tags are specific to Azure Functions.
290+ pub fn get_function_tags ( & self ) -> impl ExactSizeIterator < Item = ( & ' static str , & str ) > {
291+ [
292+ ( "aas.environment.instance_id" , self . get_instance_id ( ) ) ,
293+ ( "aas.environment.instance_name" , self . get_instance_name ( ) ) ,
294+ ( "aas.environment.os" , self . get_operating_system ( ) ) ,
295+ ( "aas.environment.runtime" , self . get_runtime ( ) ) ,
296+ (
297+ "aas.environment.runtime_version" ,
298+ self . get_runtime_version ( ) ,
299+ ) ,
300+ (
301+ "aas.environment.function_runtime" ,
302+ self . get_function_runtime_version ( ) ,
303+ ) ,
304+ ( "aas.resource.group" , self . get_resource_group ( ) ) ,
305+ ( "aas.resource.id" , self . get_resource_id ( ) ) ,
306+ ( "aas.site.kind" , self . get_site_kind ( ) ) ,
307+ ( "aas.site.name" , self . get_site_name ( ) ) ,
308+ ( "aas.site.type" , self . get_site_type ( ) ) ,
309+ ( "aas.subscription.id" , self . get_subscription_id ( ) ) ,
310+ ]
311+ . into_iter ( )
312+ }
266313}
267314
268315pub static AAS_METADATA : LazyLock < Option < AzureMetadata > > =
@@ -712,6 +759,158 @@ mod tests {
712759 assert_eq ! ( expected_runtime_version, metadata. get_runtime_version( ) ) ;
713760 }
714761
762+ #[ test]
763+ fn test_get_app_service_tags ( ) {
764+ let expected_site_name = "my_site_name" ;
765+ let expected_resource_group = "my_resource_group" ;
766+ let expected_site_version = "v42" ;
767+ let expected_operating_system = "FreeBSD" ;
768+ let expected_instance_name = "my_instance_name" ;
769+ let expected_instance_id = "my_instance_id" ;
770+ let expected_subscription_id = "sub-123" ;
771+ let expected_resource_id = "/subscriptions/sub-123/resourcegroups/my_resource_group/providers/microsoft.web/sites/my_site_name" ;
772+
773+ let mocked_env = MockEnv :: new ( & [
774+ ( WEBSITE_SITE_NAME , expected_site_name) ,
775+ ( WEBSITE_RESOURCE_GROUP , expected_resource_group) ,
776+ ( SITE_EXTENSION_VERSION , expected_site_version) ,
777+ ( WEBSITE_OS , expected_operating_system) ,
778+ ( INSTANCE_NAME , expected_instance_name) ,
779+ ( INSTANCE_ID , expected_instance_id) ,
780+ ( SERVICE_CONTEXT , "1" ) ,
781+ (
782+ WEBSITE_OWNER_NAME ,
783+ & format ! ( "{}+rg-webspace" , expected_subscription_id) ,
784+ ) ,
785+ ] ) ;
786+
787+ let metadata = AzureMetadata :: new ( mocked_env) . unwrap ( ) ;
788+
789+ // Collect tags into a HashMap for easy lookup
790+ let tags: std:: collections:: HashMap < & str , & str > = metadata. get_app_service_tags ( ) . collect ( ) ;
791+
792+ // Verify all 10 App Service tags are present
793+ assert_eq ! ( tags. len( ) , 10 ) ;
794+ assert_eq ! ( tags. get( "aas.resource.id" ) , Some ( & expected_resource_id) ) ;
795+ assert_eq ! (
796+ tags. get( "aas.environment.extension_version" ) ,
797+ Some ( & expected_site_version)
798+ ) ;
799+ assert_eq ! (
800+ tags. get( "aas.environment.instance_id" ) ,
801+ Some ( & expected_instance_id)
802+ ) ;
803+ assert_eq ! (
804+ tags. get( "aas.environment.instance_name" ) ,
805+ Some ( & expected_instance_name)
806+ ) ;
807+ assert_eq ! (
808+ tags. get( "aas.environment.os" ) ,
809+ Some ( & expected_operating_system)
810+ ) ;
811+ assert_eq ! (
812+ tags. get( "aas.resource.group" ) ,
813+ Some ( & expected_resource_group)
814+ ) ;
815+ assert_eq ! ( tags. get( "aas.site.name" ) , Some ( & expected_site_name) ) ;
816+ assert_eq ! ( tags. get( "aas.site.kind" ) , Some ( & "app" ) ) ;
817+ assert_eq ! ( tags. get( "aas.site.type" ) , Some ( & "app" ) ) ;
818+ assert_eq ! (
819+ tags. get( "aas.subscription.id" ) ,
820+ Some ( & expected_subscription_id)
821+ ) ;
822+
823+ // Verify runtime tags are NOT present
824+ assert_eq ! ( tags. get( "aas.environment.runtime" ) , None ) ;
825+ assert_eq ! ( tags. get( "aas.environment.runtime_version" ) , None ) ;
826+ assert_eq ! ( tags. get( "aas.environment.function_runtime" ) , None ) ;
827+
828+ // Verify it's an ExactSizeIterator
829+ let iter = metadata. get_app_service_tags ( ) ;
830+ assert_eq ! ( iter. len( ) , 10 ) ;
831+ }
832+
833+ #[ test]
834+ fn test_get_function_tags ( ) {
835+ let expected_site_name = "my_site_name" ;
836+ let expected_resource_group = "my_resource_group" ;
837+ let expected_operating_system = "FreeBSD" ;
838+ let expected_instance_name = "my_instance_name" ;
839+ let expected_instance_id = "my_instance_id" ;
840+ let expected_function_extension_version = "~4" ;
841+ let expected_runtime = "node" ;
842+ let expected_runtime_version = "18" ;
843+ let expected_subscription_id = "sub-123" ;
844+ let expected_resource_id = "/subscriptions/sub-123/resourcegroups/my_resource_group/providers/microsoft.web/sites/my_site_name" ;
845+
846+ let mocked_env = MockEnv :: new ( & [
847+ ( WEBSITE_SITE_NAME , expected_site_name) ,
848+ ( WEBSITE_RESOURCE_GROUP , expected_resource_group) ,
849+ ( WEBSITE_OS , expected_operating_system) ,
850+ ( INSTANCE_NAME , expected_instance_name) ,
851+ ( INSTANCE_ID , expected_instance_id) ,
852+ ( SERVICE_CONTEXT , "1" ) ,
853+ (
854+ FUNCTIONS_EXTENSION_VERSION ,
855+ expected_function_extension_version,
856+ ) ,
857+ ( FUNCTIONS_WORKER_RUNTIME , expected_runtime) ,
858+ ( FUNCTIONS_WORKER_RUNTIME_VERSION , expected_runtime_version) ,
859+ (
860+ WEBSITE_OWNER_NAME ,
861+ & format ! ( "{}+rg-webspace" , expected_subscription_id) ,
862+ ) ,
863+ ] ) ;
864+
865+ let metadata = AzureMetadata :: new ( mocked_env) . unwrap ( ) ;
866+
867+ // Collect tags into a HashMap for easy lookup
868+ let tags: std:: collections:: HashMap < & str , & str > = metadata. get_function_tags ( ) . collect ( ) ;
869+
870+ // Verify all 12 Function tags are present
871+ assert_eq ! ( tags. len( ) , 12 ) ;
872+ assert_eq ! ( tags. get( "aas.resource.id" ) , Some ( & expected_resource_id) ) ;
873+ assert_eq ! (
874+ tags. get( "aas.environment.instance_id" ) ,
875+ Some ( & expected_instance_id)
876+ ) ;
877+ assert_eq ! (
878+ tags. get( "aas.environment.instance_name" ) ,
879+ Some ( & expected_instance_name)
880+ ) ;
881+ assert_eq ! (
882+ tags. get( "aas.environment.os" ) ,
883+ Some ( & expected_operating_system)
884+ ) ;
885+ assert_eq ! ( tags. get( "aas.environment.runtime" ) , Some ( & expected_runtime) ) ;
886+ assert_eq ! (
887+ tags. get( "aas.environment.runtime_version" ) ,
888+ Some ( & expected_runtime_version)
889+ ) ;
890+ assert_eq ! (
891+ tags. get( "aas.environment.function_runtime" ) ,
892+ Some ( & expected_function_extension_version)
893+ ) ;
894+ assert_eq ! (
895+ tags. get( "aas.resource.group" ) ,
896+ Some ( & expected_resource_group)
897+ ) ;
898+ assert_eq ! ( tags. get( "aas.site.name" ) , Some ( & expected_site_name) ) ;
899+ assert_eq ! ( tags. get( "aas.site.kind" ) , Some ( & "functionapp" ) ) ;
900+ assert_eq ! ( tags. get( "aas.site.type" ) , Some ( & "function" ) ) ;
901+ assert_eq ! (
902+ tags. get( "aas.subscription.id" ) ,
903+ Some ( & expected_subscription_id)
904+ ) ;
905+
906+ // Verify extension_version tag is NOT present
907+ assert_eq ! ( tags. get( "aas.environment.extension_version" ) , None ) ;
908+
909+ // Verify it's an ExactSizeIterator
910+ let iter = metadata. get_function_tags ( ) ;
911+ assert_eq ! ( iter. len( ) , 12 ) ;
912+ }
913+
715914 #[ test]
716915 fn test_get_trimmed_env_var_empty_string ( ) {
717916 env:: remove_var ( "TEST_VAR_NONE" ) ;
0 commit comments