Reviewed-by: Hasko, Vladimir <vladimir.hasko@t-systems.com> Co-authored-by: Gode, Sebastian <sebastian.gode@t-systems.com> Co-committed-by: Gode, Sebastian <sebastian.gode@t-systems.com>
		
			
				
	
	
		
			309 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			309 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| # Licensed under the Apache License, Version 2.0 (the "License");
 | |
| # you may not use this file except in compliance with the License.
 | |
| # You may obtain a copy of the License at
 | |
| #
 | |
| #    http://www.apache.org/licenses/LICENSE-2.0
 | |
| #
 | |
| # Unless required by applicable law or agreed to in writing, software
 | |
| # distributed under the License is distributed on an "AS IS" BASIS,
 | |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 | |
| # implied.
 | |
| # See the License for the specific language governing permissions and
 | |
| # limitations under the License.
 | |
| 
 | |
| import copy
 | |
| import warnings
 | |
| 
 | |
| import otc_metadata.data
 | |
| 
 | |
| __all__ = ["Services"]
 | |
| 
 | |
| BUILTIN_DATA = otc_metadata.data.read_data("services.yaml")
 | |
| 
 | |
| 
 | |
| def _normalize_type(service_type):
 | |
|     if service_type:
 | |
|         return service_type.replace("_", "-")
 | |
| 
 | |
| 
 | |
| class Services(object):
 | |
|     """Encapsulation of the OTC Services data"""
 | |
| 
 | |
|     def __init__(self):
 | |
|         self._service_data = BUILTIN_DATA
 | |
| 
 | |
|     def _sort_data(self):
 | |
|         # Sort every doc item by key
 | |
|         sorted_docs = []
 | |
|         for doc in self._service_data["documents"]:
 | |
|             sorted_docs.append(dict(sorted(doc.items(), key=lambda kv: kv[0])))
 | |
| 
 | |
|         # sort docs list by <service_type>_<title>
 | |
|         self._service_data["documents"] = sorted(
 | |
|             sorted_docs,
 | |
|             key=lambda x: f"{x.get('service_type')}{x.get('title')}",
 | |
|         )
 | |
|         # sort services by <service_type>_<service_title>
 | |
|         self._service_data["services"] = sorted(
 | |
|             self._service_data["services"],
 | |
|             key=lambda x: f"{x.get('service_type')}{x.get('service_title')}",
 | |
|         )
 | |
|         # sort service categories by <name>_<title>
 | |
|         self._service_data["service_categories"] = sorted(
 | |
|             self._service_data["service_categories"],
 | |
|             key=lambda x: f"{x.get('name')}{x.get('title')}",
 | |
|         )
 | |
|         other = {'name': 'other', 'title': 'Other'}
 | |
|         if other in self._service_data["service_categories"]:
 | |
|             self._service_data["service_categories"].remove(other)
 | |
|             self._service_data["service_categories"].append(other)
 | |
| 
 | |
|     def _rewrite_data(self):
 | |
|         otc_metadata.data.rewrite_data("services.yaml", self._service_data)
 | |
| 
 | |
|     @property
 | |
|     def all_services(self):
 | |
|         "Service Categories data listing."
 | |
|         return copy.deepcopy(self._service_data["services"])
 | |
| 
 | |
|     @property
 | |
|     def all_docs(self):
 | |
|         "Service Docs data listing."
 | |
|         return copy.deepcopy(self._service_data["documents"])
 | |
| 
 | |
|     @property
 | |
|     def service_dict(self):
 | |
|         "Service Docs data listing."
 | |
|         res = dict()
 | |
|         for srv in self.all_services:
 | |
|             res[srv["service_type"]] = copy.deepcopy(srv)
 | |
|         return res
 | |
| 
 | |
|     @property
 | |
|     def service_categories(self):
 | |
|         """List services categories"""
 | |
|         res = []
 | |
|         for cat in self._service_data["service_categories"]:
 | |
|             res.append(copy.deepcopy(cat))
 | |
|         return res
 | |
| 
 | |
|     def services_by_category(self, category, environment=None):
 | |
|         """List services matching category"""
 | |
|         res = []
 | |
|         for srv in self.all_services:
 | |
|             if environment:
 | |
|                 if "environment" in srv and srv["environment"] != environment:
 | |
|                     continue
 | |
|             if srv["service_category"] == category:
 | |
|                 res.append(copy.deepcopy(srv))
 | |
|         return res
 | |
| 
 | |
|     def services_with_docs_by_category(self, category, environment=None):
 | |
|         """Retrieve service category docs data
 | |
| 
 | |
|         :param str category: Optional Category filter
 | |
|         :param str env: Optional service environment. Influeces "repository"
 | |
|             field
 | |
|         """
 | |
|         res = dict()
 | |
|         services = self.service_dict
 | |
|         for doc in self.all_docs:
 | |
|             cat = doc["service_type"]
 | |
|             service = services.get(cat)
 | |
|             if not service:
 | |
|                 warnings.warn("No Service defition of type %s" % (cat))
 | |
|                 continue
 | |
|             if category and service["service_category"] != category:
 | |
|                 continue
 | |
|             res.setdefault(cat, service)
 | |
|             res_doc = copy.deepcopy(doc)
 | |
|             res_doc.update(**service)
 | |
|             if environment:
 | |
|                 if "environment" in doc and doc["environment"] != environment:
 | |
|                     continue
 | |
|             res[cat].setdefault("docs", [])
 | |
|             res[cat]["docs"].append(res_doc)
 | |
|         return res
 | |
| 
 | |
|     def service_types_with_doc_types(self, environment=None):
 | |
|         """Retrieve type and title from services and corresponding docs.
 | |
|             As well as a list of all available doc types with title.
 | |
| 
 | |
|         :param str environment: Optional service environment.
 | |
|         """
 | |
|         service_list = []
 | |
|         docs = []
 | |
| 
 | |
|         for service in self.all_services:
 | |
|             if "environment" in service:
 | |
|                 if service["environment"] != environment:
 | |
|                     continue
 | |
|             if not service["service_title"]:
 | |
|                 continue
 | |
|             if not service["service_type"]:
 | |
|                 continue
 | |
| 
 | |
|             doc_list = []
 | |
|             for doc in self.all_docs:
 | |
|                 if "environment" in doc:
 | |
|                     if doc["environment"] != environment:
 | |
|                         continue
 | |
|                 if doc["service_type"] == service["service_type"]:
 | |
|                     doc_list.append({
 | |
|                         "title": doc["title"],
 | |
|                         "type": doc["type"]
 | |
|                     })
 | |
| 
 | |
|                 new_doc = {
 | |
|                     "type": doc["type"],
 | |
|                     "title": doc["title"]
 | |
|                 }
 | |
|                 type_exists = any(
 | |
|                     doc_dict["type"] == new_doc["type"] for doc_dict in docs
 | |
|                 )
 | |
|                 if not type_exists:
 | |
|                     docs.append(new_doc)
 | |
| 
 | |
|             service_list.append({
 | |
|                 "service_title": service["service_title"],
 | |
|                 "service_type": service["service_type"],
 | |
|                 "docs": doc_list
 | |
|             })
 | |
| 
 | |
|         res = {
 | |
|             "services": service_list,
 | |
|             "docs": docs
 | |
|         }
 | |
| 
 | |
|         return res
 | |
| 
 | |
|     def docs_by_service_category(self, category, environment=None):
 | |
|         """List services matching category
 | |
| 
 | |
|         :param str category: Category name
 | |
|         :param str env: Optional service environment. Influeces "repository"
 | |
|             field
 | |
|         """
 | |
|         res = []
 | |
|         services = self.service_dict
 | |
|         for doc in self.all_docs:
 | |
|             cat = doc["service_type"]
 | |
|             service = services.get(cat)
 | |
|             if not service:
 | |
|                 warnings.warn("No Service defition of type %s" % (cat))
 | |
|                 continue
 | |
|             if service["service_category"] == category:
 | |
|                 res_doc = copy.deepcopy(doc)
 | |
|                 res_doc.update(**service)
 | |
|                 if environment:
 | |
|                     for srv_env in service["repositories"]:
 | |
|                         if srv_env.get("environment") == environment:
 | |
|                             res_doc["repository"] = srv_env["repo"]
 | |
|                 res.append(res_doc)
 | |
|         return res
 | |
| 
 | |
|     def docs_by_service_type(self, service_type):
 | |
|         """List documents of the service
 | |
| 
 | |
|         :param str service_type: Service type
 | |
|         :returns: generator for documents
 | |
|         """
 | |
|         for doc in self.all_docs:
 | |
|             if doc["service_type"] != service_type:
 | |
|                 continue
 | |
|             yield copy.deepcopy(doc)
 | |
| 
 | |
|     def all_docs_full(self, environment):
 | |
|         """Return list or documents with full service data"""
 | |
|         services = self.service_dict
 | |
|         for doc in self.all_docs:
 | |
|             if not doc["service_type"] in services:
 | |
|                 print(f"No service type {doc['service_type']}")
 | |
|                 continue
 | |
|             service = services[doc["service_type"]]
 | |
|             res_doc = copy.deepcopy(doc)
 | |
|             res_doc.update(**service)
 | |
|             if environment:
 | |
|                 for srv_env in service["repositories"]:
 | |
|                     if srv_env.get("environment") == environment:
 | |
|                         res_doc["repository"] = srv_env["repo"]
 | |
|                 for srv_assignees in service.get("assignees", []):
 | |
|                     if srv_assignees.get("environment") == environment:
 | |
|                         res_doc["assignees"] = srv_assignees["names"]
 | |
|             yield res_doc
 | |
| 
 | |
|     def docs_html_by_category(self, environment):
 | |
|         """Generate structure for doc-exports repository"""
 | |
|         doc_struct = dict()
 | |
|         for srv in self.all_services:
 | |
|             doc_struct.setdefault(srv["service_category"], [])
 | |
|             srv_res = dict(
 | |
|                 service_title=srv["service_title"],
 | |
|                 service_type=srv["service_type"],
 | |
|                 service_category=srv["service_category"],
 | |
|                 service_environment=environment,
 | |
|                 docs=[],
 | |
|             )
 | |
|             if "teams" in srv:
 | |
|                 srv_res["teams"] = [
 | |
|                     x for x in srv["teams"] if x["permission"] == "write"
 | |
|                 ]
 | |
|             if "repositories" in srv and environment:
 | |
|                 internal_exists = False
 | |
|                 for repo in srv["repositories"]:
 | |
|                     if (
 | |
|                         "environment" in repo
 | |
|                         and repo["environment"] == environment
 | |
|                     ):
 | |
|                         srv_res["repository"] = repo["repo"]
 | |
|                         if repo["environment"] == "internal":
 | |
|                             internal_exists = True
 | |
|                 # internal repo does not exist
 | |
|                 # service will be left out from metadata.yaml
 | |
|                 if not internal_exists:
 | |
|                     continue
 | |
|             for doc in self.all_docs:
 | |
|                 if (
 | |
|                     "html_location" in doc
 | |
|                     and doc["service_type"] == srv_res["service_type"]
 | |
|                 ):
 | |
|                     doc_res = dict(
 | |
|                         html_location=doc["html_location"],
 | |
|                         rst_location=doc["rst_location"],
 | |
|                         title=doc["title"],
 | |
|                         type=doc.get("type", "dummy"),
 | |
|                         link=doc["link"],
 | |
|                     )
 | |
|                     if "pdf_name" in doc:
 | |
|                         doc_res["pdf_name"] = doc["pdf_name"]
 | |
|                     if "hc_location" in doc:
 | |
|                         doc_res["hc_location"] = doc["hc_location"]
 | |
|                     if "disable_import" in doc:
 | |
|                         doc_res["disable_import"] = doc["disable_import"]
 | |
|                     else:
 | |
|                         doc_res["disable_import"] = False
 | |
|                     srv_res["docs"].append(doc_res)
 | |
|             if len(srv_res["docs"]) > 0:
 | |
|                 doc_struct[srv["service_category"]].append(srv_res)
 | |
| 
 | |
|         return dict(categories=doc_struct)
 | |
| 
 | |
|     def get_service_with_docs_by_service_type(self, service_type):
 | |
|         """Retrieve service and service docs by service_type
 | |
| 
 | |
|         :param str service_type: Filter by service_type
 | |
|         """
 | |
|         res = dict()
 | |
|         res["service"] = {}
 | |
|         docs = []
 | |
|         services = self._service_data
 | |
|         for doc in services["documents"]:
 | |
|             if doc["service_type"] == service_type:
 | |
|                 docs.append(doc)
 | |
|         res["documents"] = docs
 | |
|         for service in services["services"]:
 | |
|             if service["service_type"] == service_type:
 | |
|                 res["service"] = service
 | |
|                 break
 | |
|         return res
 |