Refactor policy parser init so that validate service is in helper

Refactor the rbac_policy_parser __init__ function so that service
validation is done in its own helper to make the code more
readable.

This commit specifically:
  - refactors the code to make it more readable by creating the
    validate_service helper in ``RbacPolicyParser``
  - makes validate_service a classmethod so that the list of
    services can be cached in memory to avoid list_services
    call for every single test
  - this is a light memory footprint because there will only
    ever be a finite (sub-100) number of services running

Change-Id: I6f6a57d5014e0e2aa373c1b099a6bcc371bec165
diff --git a/patrole_tempest_plugin/rbac_policy_parser.py b/patrole_tempest_plugin/rbac_policy_parser.py
index 1047d37..bb34f6c 100644
--- a/patrole_tempest_plugin/rbac_policy_parser.py
+++ b/patrole_tempest_plugin/rbac_policy_parser.py
@@ -66,15 +66,8 @@
         if extra_target_data is None:
             extra_target_data = {}
 
-        # First check if the service is valid
-        service = service.lower().strip() if service else None
-        self.admin_mgr = credentials.AdminManager()
-        services = self.admin_mgr.identity_services_v3_client.\
-            list_services()['services']
-        service_names = [s['name'] for s in services]
-        if not service or not any(service in name for name in service_names):
-            LOG.debug(str(service) + " is NOT a valid service.")
-            raise rbac_exceptions.RbacInvalidService
+        # First check if the service is valid.
+        self.validate_service(service)
 
         # Use default path in /etc/<service_name/policy.json if no path
         # is provided.
@@ -90,6 +83,24 @@
         self.user_id = user_id
         self.extra_target_data = extra_target_data
 
+    @classmethod
+    def validate_service(cls, service):
+        """Validate whether the service passed to ``init`` exists."""
+        service = service.lower().strip() if service else None
+
+        # Cache the list of available services in memory to avoid needlessly
+        # doing an API call every time.
+        if not hasattr(cls, 'available_services'):
+            admin_mgr = credentials.AdminManager()
+            services = admin_mgr.identity_services_v3_client.\
+                list_services()['services']
+            cls.available_services = [s['name'] for s in services]
+
+        if not service or service not in cls.available_services:
+            LOG.debug("%s is NOT a valid service.", service)
+            raise rbac_exceptions.RbacInvalidService(
+                "%s is NOT a valid service." % service)
+
     def allowed(self, rule_name, role):
         is_admin_context = self._is_admin_context(role)
         is_allowed = self._allowed(