1# Copyright 2020 gRPC authors. 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14import logging 15from typing import Optional 16 17import dataclasses 18from google.rpc import code_pb2 19import tenacity 20 21from framework.infrastructure import gcp 22 23logger = logging.getLogger(__name__) 24 25 26class NetworkServicesV1Alpha1(gcp.api.GcpStandardCloudApiResource): 27 ENDPOINT_CONFIG_SELECTORS = 'endpointConfigSelectors' 28 29 @dataclasses.dataclass(frozen=True) 30 class EndpointConfigSelector: 31 url: str 32 name: str 33 type: str 34 server_tls_policy: Optional[str] 35 traffic_port_selector: dict 36 endpoint_matcher: dict 37 http_filters: dict 38 update_time: str 39 create_time: str 40 41 def __init__(self, api_manager: gcp.api.GcpApiManager, project: str): 42 super().__init__(api_manager.networkservices(self.api_version), project) 43 # Shortcut to projects/*/locations/ endpoints 44 self._api_locations = self.api.projects().locations() 45 46 @property 47 def api_name(self) -> str: 48 return 'networkservices' 49 50 @property 51 def api_version(self) -> str: 52 return 'v1alpha1' 53 54 def create_endpoint_config_selector(self, name, body: dict): 55 return self._create_resource( 56 self._api_locations.endpointConfigSelectors(), 57 body, 58 endpointConfigSelectorId=name) 59 60 def get_endpoint_config_selector(self, name: str) -> EndpointConfigSelector: 61 result = self._get_resource( 62 collection=self._api_locations.endpointConfigSelectors(), 63 full_name=self.resource_full_name(name, 64 self.ENDPOINT_CONFIG_SELECTORS)) 65 return self.EndpointConfigSelector( 66 name=name, 67 url=result['name'], 68 type=result['type'], 69 server_tls_policy=result.get('serverTlsPolicy', None), 70 traffic_port_selector=result['trafficPortSelector'], 71 endpoint_matcher=result['endpointMatcher'], 72 http_filters=result['httpFilters'], 73 update_time=result['updateTime'], 74 create_time=result['createTime']) 75 76 def delete_endpoint_config_selector(self, name): 77 return self._delete_resource( 78 collection=self._api_locations.endpointConfigSelectors(), 79 full_name=self.resource_full_name(name, 80 self.ENDPOINT_CONFIG_SELECTORS)) 81 82 def _execute(self, *args, **kwargs): # pylint: disable=signature-differs 83 # Workaround TD bug: throttled operations are reported as internal. 84 # Ref b/175345578 85 retryer = tenacity.Retrying( 86 retry=tenacity.retry_if_exception(self._operation_internal_error), 87 wait=tenacity.wait_fixed(10), 88 stop=tenacity.stop_after_delay(5 * 60), 89 before_sleep=tenacity.before_sleep_log(logger, logging.DEBUG), 90 reraise=True) 91 retryer(super()._execute, *args, **kwargs) 92 93 @staticmethod 94 def _operation_internal_error(exception): 95 return (isinstance(exception, gcp.api.OperationError) and 96 exception.error.code == code_pb2.INTERNAL) 97