gcpdiag.queries.lb
28class LoadBalancerType(Enum): 29 """Load balancer type.""" 30 31 LOAD_BALANCER_TYPE_UNSPECIFIED = 0 32 EXTERNAL_PASSTHROUGH_LB = 1 33 INTERNAL_PASSTHROUGH_LB = 2 34 TARGET_POOL_LB = 3 # deprecated but customers still have them 35 GLOBAL_EXTERNAL_PROXY_NETWORK_LB = 4 # envoy based proxy lb 36 REGIONAL_INTERNAL_PROXY_NETWORK_LB = 5 37 REGIONAL_EXTERNAL_PROXY_NETWORK_LB = 6 38 CROSS_REGION_INTERNAL_PROXY_NETWORK_LB = 7 39 CLASSIC_PROXY_NETWORK_LB = 8 40 GLOBAL_EXTERNAL_APPLICATION_LB = 9 # envoy based application lb 41 REGIONAL_INTERNAL_APPLICATION_LB = 10 42 REGIONAL_EXTERNAL_APPLICATION_LB = 11 43 CROSS_REGION_INTERNAL_APPLICATION_LB = 12 44 CLASSIC_APPLICATION_LB = 13
Load balancer type.
47def get_load_balancer_type_name(lb_type: LoadBalancerType) -> str: 48 """Returns a human-readable name for the given load balancer type.""" 49 50 type_names = { 51 LoadBalancerType.LOAD_BALANCER_TYPE_UNSPECIFIED: 52 'Unspecified', 53 LoadBalancerType.EXTERNAL_PASSTHROUGH_LB: 54 ('External Passthrough Network Load Balancer'), 55 LoadBalancerType.INTERNAL_PASSTHROUGH_LB: 56 ('Internal Passthrough Network Load Balancer'), 57 LoadBalancerType.TARGET_POOL_LB: 58 'Target Pool Network Load Balancer', 59 LoadBalancerType.GLOBAL_EXTERNAL_PROXY_NETWORK_LB: 60 ('Global External Proxy Network Load Balancer'), 61 LoadBalancerType.REGIONAL_INTERNAL_PROXY_NETWORK_LB: 62 ('Regional Internal Proxy Network Load Balancer'), 63 LoadBalancerType.REGIONAL_EXTERNAL_PROXY_NETWORK_LB: 64 ('Regional External Proxy Network Load Balancer'), 65 LoadBalancerType.CROSS_REGION_INTERNAL_PROXY_NETWORK_LB: 66 ('Cross-Region Internal Proxy Network Load Balancer'), 67 LoadBalancerType.CLASSIC_PROXY_NETWORK_LB: 68 ('Classic Proxy Network Load Balancer'), 69 LoadBalancerType.GLOBAL_EXTERNAL_APPLICATION_LB: 70 ('Global External Application Load Balancer'), 71 LoadBalancerType.REGIONAL_INTERNAL_APPLICATION_LB: 72 ('Regional Internal Application Load Balancer'), 73 LoadBalancerType.REGIONAL_EXTERNAL_APPLICATION_LB: 74 ('Regional External Application Load Balancer'), 75 LoadBalancerType.CROSS_REGION_INTERNAL_APPLICATION_LB: 76 ('Cross-Region Internal Application Load Balancer'), 77 LoadBalancerType.CLASSIC_APPLICATION_LB: 78 ('Classic Application Load Balancer'), 79 } 80 return type_names.get(lb_type, 'Unspecified')
Returns a human-readable name for the given load balancer type.
83def get_load_balancer_type( 84 load_balancing_scheme: str, 85 scope: str, 86 layer: Literal['application', 'network'], 87 backend_service_based: bool = True, 88) -> LoadBalancerType: 89 if load_balancing_scheme == 'EXTERNAL': 90 if not scope or scope == 'global': 91 if layer == 'application': 92 return LoadBalancerType.CLASSIC_APPLICATION_LB 93 else: 94 return LoadBalancerType.CLASSIC_PROXY_NETWORK_LB 95 else: 96 return (LoadBalancerType.EXTERNAL_PASSTHROUGH_LB 97 if backend_service_based else LoadBalancerType.TARGET_POOL_LB) 98 elif load_balancing_scheme == 'INTERNAL': 99 return LoadBalancerType.INTERNAL_PASSTHROUGH_LB 100 elif load_balancing_scheme == 'INTERNAL_MANAGED': 101 if not scope or scope == 'global': 102 if layer == 'application': 103 return LoadBalancerType.CROSS_REGION_INTERNAL_APPLICATION_LB 104 else: 105 return LoadBalancerType.CROSS_REGION_INTERNAL_PROXY_NETWORK_LB 106 else: 107 if layer == 'application': 108 return LoadBalancerType.REGIONAL_INTERNAL_APPLICATION_LB 109 else: 110 return LoadBalancerType.REGIONAL_INTERNAL_PROXY_NETWORK_LB 111 elif load_balancing_scheme == 'EXTERNAL_MANAGED': 112 if not scope or scope == 'global': 113 if layer == 'application': 114 return LoadBalancerType.GLOBAL_EXTERNAL_APPLICATION_LB 115 else: 116 return LoadBalancerType.GLOBAL_EXTERNAL_PROXY_NETWORK_LB 117 else: 118 if layer == 'application': 119 return LoadBalancerType.REGIONAL_EXTERNAL_APPLICATION_LB 120 else: 121 return LoadBalancerType.REGIONAL_EXTERNAL_PROXY_NETWORK_LB 122 return LoadBalancerType.LOAD_BALANCER_TYPE_UNSPECIFIED
125def normalize_url(url: str) -> str: 126 """Returns normalized url.""" 127 result = re.match(r'https://www.googleapis.com/compute/v1/(.*)', url) 128 if result: 129 return result.group(1) 130 else: 131 return ''
Returns normalized url.
134class BackendServices(models.Resource): 135 """A Backend Service resource.""" 136 137 _resource_data: dict 138 _type: str 139 140 def __init__(self, project_id, resource_data): 141 super().__init__(project_id=project_id) 142 self._resource_data = resource_data 143 144 @property 145 def name(self) -> str: 146 return self._resource_data['name'] 147 148 @property 149 def id(self) -> str: 150 return self._resource_data['id'] 151 152 @property 153 def full_path(self) -> str: 154 result = re.match(r'https://www.googleapis.com/compute/v1/(.*)', 155 self.self_link) 156 if result: 157 return result.group(1) 158 else: 159 return f'>> {self.self_link}' 160 161 @property 162 def short_path(self) -> str: 163 path = self.project_id + '/' + self.name 164 return path 165 166 @property 167 def self_link(self) -> str: 168 return self._resource_data['selfLink'] 169 170 @property 171 def session_affinity(self) -> str: 172 return self._resource_data.get('sessionAffinity', 'NONE') 173 174 @property 175 def timeout_sec(self) -> int: 176 return self._resource_data.get('timeoutSec', None) 177 178 @property 179 def locality_lb_policy(self) -> str: 180 return self._resource_data.get('localityLbPolicy', 'ROUND_ROBIN') 181 182 @property 183 def is_enable_cdn(self) -> str: 184 return self._resource_data.get('enableCDN', False) 185 186 @property 187 def draining_timeout_sec(self) -> int: 188 return self._resource_data.get('connectionDraining', 189 {}).get('drainingTimeoutSec', 0) 190 191 @property 192 def load_balancing_scheme(self) -> str: 193 return self._resource_data.get('loadBalancingScheme', None) 194 195 @property 196 def health_check(self): 197 if 'healthChecks' not in self._resource_data: 198 return None 199 health_check_url = self._resource_data['healthChecks'][0] 200 matches = re.search(r'/([^/]+)$', health_check_url) 201 if matches: 202 healthcheck_name = matches.group(1) 203 return healthcheck_name 204 else: 205 return None 206 207 @property 208 def health_check_region(self): 209 if 'healthChecks' not in self._resource_data: 210 return None 211 health_check_url = self._resource_data['healthChecks'][0] 212 m = re.search(r'/regions/([^/]+)', health_check_url) 213 if m: 214 return m.group(1) 215 else: 216 return None 217 218 @property 219 def backends(self) -> List[dict]: 220 return self._resource_data.get('backends', []) 221 222 @property 223 def region(self): 224 try: 225 url = self._resource_data.get('region') 226 if url is not None: 227 match = re.search(r'/([^/]+)/?$', url) 228 if match is not None: 229 region = match.group(1) 230 return region 231 else: 232 return None 233 except KeyError: 234 return None 235 236 @property 237 def protocol(self) -> str: 238 return self._resource_data.get('protocol', None) 239 240 @property 241 def port_name(self) -> str: 242 return self._resource_data.get('portName', None) 243 244 @property 245 def used_by_refs(self) -> List[str]: 246 used_by = [] 247 for x in self._resource_data.get('usedBy', []): 248 reference = x.get('reference') 249 if reference: 250 match = re.match(r'https://www.googleapis.com/compute/v1/(.*)', 251 reference) 252 if match: 253 used_by.append(match.group(1)) 254 return used_by 255 256 @property 257 def load_balancer_type(self) -> LoadBalancerType: 258 application_protocols = ['HTTP', 'HTTPS', 'HTTP2'] 259 return get_load_balancer_type( 260 self.load_balancing_scheme, 261 self.region, 262 'application' if self.protocol in application_protocols else 'network', 263 backend_service_based=True, 264 )
A Backend Service resource.
152 @property 153 def full_path(self) -> str: 154 result = re.match(r'https://www.googleapis.com/compute/v1/(.*)', 155 self.self_link) 156 if result: 157 return result.group(1) 158 else: 159 return f'>> {self.self_link}'
Returns the full path of this resource.
Example: 'projects/gcpdiag-gke-1-9b90/zones/europe-west4-a/clusters/gke1'
161 @property 162 def short_path(self) -> str: 163 path = self.project_id + '/' + self.name 164 return path
Returns the short name for this resource.
Note that it isn't clear from this name what kind of resource it is.
Example: 'gke1'
195 @property 196 def health_check(self): 197 if 'healthChecks' not in self._resource_data: 198 return None 199 health_check_url = self._resource_data['healthChecks'][0] 200 matches = re.search(r'/([^/]+)$', health_check_url) 201 if matches: 202 healthcheck_name = matches.group(1) 203 return healthcheck_name 204 else: 205 return None
244 @property 245 def used_by_refs(self) -> List[str]: 246 used_by = [] 247 for x in self._resource_data.get('usedBy', []): 248 reference = x.get('reference') 249 if reference: 250 match = re.match(r'https://www.googleapis.com/compute/v1/(.*)', 251 reference) 252 if match: 253 used_by.append(match.group(1)) 254 return used_by
256 @property 257 def load_balancer_type(self) -> LoadBalancerType: 258 application_protocols = ['HTTP', 'HTTPS', 'HTTP2'] 259 return get_load_balancer_type( 260 self.load_balancing_scheme, 261 self.region, 262 'application' if self.protocol in application_protocols else 'network', 263 backend_service_based=True, 264 )
267@caching.cached_api_call(in_memory=True) 268def get_backend_services(project_id: str) -> List[BackendServices]: 269 logging.debug('fetching Backend Services: %s', project_id) 270 compute = apis.get_api('compute', 'v1', project_id) 271 backend_services = [] 272 request = compute.backendServices().aggregatedList(project=project_id) 273 response = request.execute(num_retries=config.API_RETRIES) 274 backend_services_by_region = response['items'] 275 for _, data_ in backend_services_by_region.items(): 276 if 'backendServices' not in data_: 277 continue 278 backend_services.extend([ 279 BackendServices(project_id, backend_service) 280 for backend_service in data_['backendServices'] 281 ]) 282 return backend_services
285@caching.cached_api_call(in_memory=True) 286def get_backend_service(project_id: str, 287 backend_service_name: str, 288 region: str = None) -> BackendServices: 289 """Returns instance object matching backend service name and region""" 290 compute = apis.get_api('compute', 'v1', project_id) 291 try: 292 if not region or region == 'global': 293 request = compute.backendServices().get( 294 project=project_id, backendService=backend_service_name) 295 else: 296 request = compute.regionBackendServices().get( 297 project=project_id, 298 region=region, 299 backendService=backend_service_name) 300 301 response = request.execute(num_retries=config.API_RETRIES) 302 return BackendServices(project_id, resource_data=response) 303 except googleapiclient.errors.HttpError as err: 304 raise utils.GcpApiError(err) from err
Returns instance object matching backend service name and region
307def get_backend_service_by_self_link( 308 backend_service_self_link: str,) -> Optional[BackendServices]: 309 backend_service_name = backend_service_self_link.split('/')[-1] 310 backend_service_scope = backend_service_self_link.split('/')[-3] 311 match = re.match(r'projects/([^/]+)/', backend_service_self_link) 312 if not match: 313 return None 314 project_id = match.group(1) 315 return get_backend_service(project_id, backend_service_name, 316 backend_service_scope)
319class BackendHealth: 320 """A Backend Service resource.""" 321 322 _resource_data: dict 323 324 def __init__(self, resource_data, group): 325 self._resource_data = resource_data 326 self._group = group 327 328 @property 329 def instance(self) -> str: 330 return self._resource_data['instance'] 331 332 @property 333 def group(self) -> str: 334 return self._group 335 336 @property 337 def health_state(self) -> str: 338 return self._resource_data.get('healthState', 'UNHEALTHY')
A Backend Service resource.
341@caching.cached_api_call(in_memory=True) 342def get_backend_service_health( 343 context: models.Context, 344 backend_service_name: str, 345 backend_service_region: str = None, 346) -> List[BackendHealth]: 347 """Returns health data for backend service. 348 349 Args: 350 context: The project context. 351 backend_service_name: The name of the backend service. 352 backend_service_region: The region of the backend service. 353 354 Returns: 355 A list of BackendHealth objects. 356 """ 357 project_id = context.project_id 358 try: 359 backend_service = get_backend_service(project_id, backend_service_name, 360 backend_service_region) 361 except googleapiclient.errors.HttpError: 362 return [] 363 364 backend_health_statuses: List[BackendHealth] = [] 365 compute = apis.get_api('compute', 'v1', project_id) 366 request_map = {} 367 368 for backend in backend_service.backends: 369 group = backend['group'] 370 if not backend_service.region: 371 request = compute.backendServices().getHealth( 372 project=project_id, 373 backendService=backend_service.name, 374 body={'group': group}) 375 else: 376 request = compute.regionBackendServices().getHealth( 377 project=project_id, 378 region=backend_service.region, 379 backendService=backend_service.name, 380 body={'group': group}) 381 request_map[request] = group 382 383 for i, response, exception in apis_utils.execute_concurrently( 384 api=compute, requests=list(request_map.keys()), context=context): 385 group = request_map[i] 386 if exception: 387 logging.warning( 388 'getHealth API call failed for backend service %s, group %s: %s', 389 backend_service_name, group, exception) 390 continue 391 392 # None is returned when backend type doesn't support health check 393 if response is not None: 394 for health_status in response.get('healthStatus', []): 395 backend_health_statuses.append(BackendHealth(health_status, group)) 396 397 return backend_health_statuses
Returns health data for backend service.
Arguments:
- context: The project context.
- backend_service_name: The name of the backend service.
- backend_service_region: The region of the backend service.
Returns:
A list of BackendHealth objects.
400class SslCertificate(models.Resource): 401 """A SSL Certificate resource.""" 402 403 _resource_data: dict 404 _type: str 405 406 def __init__(self, project_id, resource_data): 407 super().__init__(project_id=project_id) 408 self._resource_data = resource_data 409 410 @property 411 def name(self) -> str: 412 return self._resource_data['name'] 413 414 @property 415 def id(self) -> str: 416 return self._resource_data['id'] 417 418 @property 419 def full_path(self) -> str: 420 result = re.match(r'https://www.googleapis.com/compute/v1/(.*)', 421 self.self_link) 422 if result: 423 return result.group(1) 424 else: 425 return f'>> {self.self_link}' 426 427 @property 428 def self_link(self) -> str: 429 return self._resource_data['selfLink'] 430 431 @property 432 def type(self) -> str: 433 return self._resource_data.get('type', 'SELF_MANAGED') 434 435 @property 436 def status(self) -> str: 437 return self._resource_data.get('managed', {}).get('status') 438 439 @property 440 def domains(self) -> List[str]: 441 return self._resource_data.get('managed', {}).get('domains', []) 442 443 @property 444 def domain_status(self) -> Dict[str, str]: 445 return self._resource_data.get('managed', {}).get('domainStatus', {})
A SSL Certificate resource.
418 @property 419 def full_path(self) -> str: 420 result = re.match(r'https://www.googleapis.com/compute/v1/(.*)', 421 self.self_link) 422 if result: 423 return result.group(1) 424 else: 425 return f'>> {self.self_link}'
Returns the full path of this resource.
Example: 'projects/gcpdiag-gke-1-9b90/zones/europe-west4-a/clusters/gke1'
448@caching.cached_api_call(in_memory=True) 449def get_ssl_certificate( 450 project_id: str, 451 certificate_name: str, 452) -> SslCertificate: 453 """Returns object matching certificate name and region""" 454 compute = apis.get_api('compute', 'v1', project_id) 455 456 request = compute.sslCertificates().get(project=project_id, 457 sslCertificate=certificate_name) 458 459 response = request.execute(num_retries=config.API_RETRIES) 460 return SslCertificate(project_id, resource_data=response)
Returns object matching certificate name and region
463class ForwardingRules(models.Resource): 464 """A Forwarding Rule resource.""" 465 466 _resource_data: dict 467 _type: str 468 469 def __init__(self, project_id, resource_data): 470 super().__init__(project_id=project_id) 471 self._resource_data = resource_data 472 473 @property 474 def name(self) -> str: 475 return self._resource_data['name'] 476 477 @property 478 def id(self) -> str: 479 return self._resource_data['id'] 480 481 @property 482 def full_path(self) -> str: 483 result = re.match(r'https://www.googleapis.com/compute/v1/(.*)', 484 self.self_link) 485 if result: 486 return result.group(1) 487 else: 488 return f'>> {self.self_link}' 489 490 @property 491 def short_path(self) -> str: 492 path = self.project_id + '/' + self.name 493 return path 494 495 @property 496 def region(self): 497 url = self._resource_data.get('region', '') 498 if url is not None: 499 match = re.search(r'/([^/]+)/?$', url) 500 if match is not None: 501 region = match.group(1) 502 return region 503 return 'global' 504 505 @property 506 def self_link(self) -> str: 507 return self._resource_data['selfLink'] 508 509 @property 510 def global_access_allowed(self) -> bool: 511 return self._resource_data.get('allowGlobalAccess', False) 512 513 @property 514 def load_balancing_scheme(self) -> str: 515 return self._resource_data.get('loadBalancingScheme', None) 516 517 @property 518 def target(self) -> str: 519 full_path = self._resource_data.get('target', '') 520 result = re.match(r'https://www.googleapis.com/compute/v1/(.*)', full_path) 521 if result: 522 return result.group(1) 523 else: 524 return '' 525 526 @property 527 def backend_service(self) -> str: 528 full_path = self._resource_data.get('backendService', '') 529 result = re.match(r'https://www.googleapis.com/compute/v1/(.*)', full_path) 530 if result: 531 return result.group(1) 532 else: 533 return '' 534 535 @property 536 def ip_address(self) -> str: 537 return self._resource_data.get('IPAddress', '') 538 539 @property 540 def port_range(self) -> str: 541 return self._resource_data.get('portRange', '') 542 543 @caching.cached_api_call(in_memory=True) 544 def get_related_backend_services(self) -> List[BackendServices]: 545 """Returns the backend services related to the forwarding rule.""" 546 if self.backend_service: 547 resource = get_backend_service_by_self_link(self.backend_service) 548 return [resource] if resource else [] 549 if self.target: 550 target_proxy_target = get_target_proxy_reference(self.target) 551 if not target_proxy_target: 552 return [] 553 target_proxy_target_type = target_proxy_target.split('/')[-2] 554 if target_proxy_target_type == 'backendServices': 555 resource = get_backend_service_by_self_link(target_proxy_target) 556 return [resource] if resource else [] 557 elif target_proxy_target_type == 'urlMaps': 558 # Currently it doesn't work for shared-vpc backend services 559 backend_services = get_backend_services(self.project_id) 560 return [ 561 backend_service for backend_service in backend_services 562 if target_proxy_target in backend_service.used_by_refs 563 ] 564 return [] 565 566 @property 567 def load_balancer_type(self) -> LoadBalancerType: 568 target_type = None 569 if self.target: 570 parts = self.target.split('/') 571 if len(parts) >= 2: 572 target_type = parts[-2] 573 574 application_targets = [ 575 'targetHttpProxies', 576 'targetHttpsProxies', 577 'targetGrpcProxies', 578 ] 579 580 return get_load_balancer_type( 581 self.load_balancing_scheme, 582 self.region, 583 'application' if target_type in application_targets else 'network', 584 target_type != 'targetPools', 585 )
A Forwarding Rule resource.
481 @property 482 def full_path(self) -> str: 483 result = re.match(r'https://www.googleapis.com/compute/v1/(.*)', 484 self.self_link) 485 if result: 486 return result.group(1) 487 else: 488 return f'>> {self.self_link}'
Returns the full path of this resource.
Example: 'projects/gcpdiag-gke-1-9b90/zones/europe-west4-a/clusters/gke1'
490 @property 491 def short_path(self) -> str: 492 path = self.project_id + '/' + self.name 493 return path
Returns the short name for this resource.
Note that it isn't clear from this name what kind of resource it is.
Example: 'gke1'
566 @property 567 def load_balancer_type(self) -> LoadBalancerType: 568 target_type = None 569 if self.target: 570 parts = self.target.split('/') 571 if len(parts) >= 2: 572 target_type = parts[-2] 573 574 application_targets = [ 575 'targetHttpProxies', 576 'targetHttpsProxies', 577 'targetGrpcProxies', 578 ] 579 580 return get_load_balancer_type( 581 self.load_balancing_scheme, 582 self.region, 583 'application' if target_type in application_targets else 'network', 584 target_type != 'targetPools', 585 )
588@caching.cached_api_call(in_memory=True) 589def get_target_proxy_reference(target_proxy_self_link: str) -> str: 590 """Retrieves the URL map or backend service associated with a given target proxy. 591 592 Args: 593 target_proxy_self_link: self link of the target proxy 594 595 Returns: 596 The url map or the backend service self link 597 """ 598 target_proxy_type = target_proxy_self_link.split('/')[-2] 599 target_proxy_name = target_proxy_self_link.split('/')[-1] 600 target_proxy_scope = target_proxy_self_link.split('/')[-3] 601 match_result = re.match(r'projects/([^/]+)/', target_proxy_self_link) 602 if not match_result: 603 return '' 604 project_id = match_result.group(1) 605 compute = apis.get_api('compute', 'v1', project_id) 606 607 request = None 608 if target_proxy_type == 'targetHttpsProxies': 609 if target_proxy_scope == 'global': 610 request = compute.targetHttpsProxies().get( 611 project=project_id, targetHttpsProxy=target_proxy_name) 612 else: 613 request = compute.regionTargetHttpsProxies().get( 614 project=project_id, 615 region=target_proxy_scope, 616 targetHttpsProxy=target_proxy_name, 617 ) 618 elif target_proxy_type == 'targetHttpProxies': 619 if target_proxy_scope == 'global': 620 request = compute.targetHttpProxies().get( 621 project=project_id, targetHttpProxy=target_proxy_name) 622 else: 623 request = compute.regionTargetHttpProxies().get( 624 project=project_id, 625 region=target_proxy_scope, 626 targetHttpProxy=target_proxy_name, 627 ) 628 elif target_proxy_type == 'targetTcpProxies': 629 if target_proxy_scope == 'global': 630 request = compute.targetTcpProxies().get(project=project_id, 631 targetTcpProxy=target_proxy_name) 632 else: 633 request = compute.regionTargetTcpProxies().get( 634 project=project_id, 635 region=target_proxy_scope, 636 targetTcpProxy=target_proxy_name, 637 ) 638 elif target_proxy_type == 'targetSslProxies': 639 request = compute.targetSslProxies().get(project=project_id, 640 targetSslProxy=target_proxy_name) 641 elif target_proxy_type == 'targetGrcpProxies': 642 request = compute.targetGrpcProxies().get(project=project_id, 643 targetGrpcProxy=target_proxy_name) 644 if not request: 645 # target is not target proxy 646 return '' 647 response = request.execute(num_retries=config.API_RETRIES) 648 if 'urlMap' in response: 649 return normalize_url(response['urlMap']) 650 if 'service' in response: 651 return normalize_url(response['service']) 652 return ''
Retrieves the URL map or backend service associated with a given target proxy.
Arguments:
- target_proxy_self_link: self link of the target proxy
Returns:
The url map or the backend service self link
655@caching.cached_api_call(in_memory=True) 656def get_forwarding_rules(project_id: str) -> List[ForwardingRules]: 657 logging.debug('fetching Forwarding Rules: %s', project_id) 658 compute = apis.get_api('compute', 'v1', project_id) 659 forwarding_rules = [] 660 request = compute.forwardingRules().aggregatedList(project=project_id) 661 response = request.execute(num_retries=config.API_RETRIES) 662 forwarding_rules_by_region = response['items'] 663 for _, data_ in forwarding_rules_by_region.items(): 664 if 'forwardingRules' not in data_: 665 continue 666 forwarding_rules.extend([ 667 ForwardingRules(project_id, forwarding_rule) 668 for forwarding_rule in data_['forwardingRules'] 669 ]) 670 return forwarding_rules
673@caching.cached_api_call(in_memory=True) 674def get_forwarding_rule(project_id: str, 675 forwarding_rule_name: str, 676 region: str = None) -> ForwardingRules: 677 compute = apis.get_api('compute', 'v1', project_id) 678 if not region or region == 'global': 679 request = compute.globalForwardingRules().get( 680 project=project_id, forwardingRule=forwarding_rule_name) 681 else: 682 request = compute.forwardingRules().get(project=project_id, 683 region=region, 684 forwardingRule=forwarding_rule_name) 685 response = request.execute(num_retries=config.API_RETRIES) 686 return ForwardingRules(project_id, resource_data=response)
689class TargetHttpsProxy(models.Resource): 690 """A Target HTTPS Proxy resource.""" 691 692 _resource_data: dict 693 _type: str 694 695 def __init__(self, project_id, resource_data): 696 super().__init__(project_id=project_id) 697 self._resource_data = resource_data 698 699 @property 700 def name(self) -> str: 701 return self._resource_data['name'] 702 703 @property 704 def id(self) -> str: 705 return self._resource_data['id'] 706 707 @property 708 def full_path(self) -> str: 709 result = re.match(r'https://www.googleapis.com/compute/v1/(.*)', 710 self.self_link) 711 if result: 712 return result.group(1) 713 else: 714 return f'>> {self.self_link}' 715 716 @property 717 def self_link(self) -> str: 718 return self._resource_data['selfLink'] 719 720 @property 721 def region(self): 722 url = self._resource_data.get('region', '') 723 if url is not None: 724 match = re.search(r'/([^/]+)/?$', url) 725 if match is not None: 726 region = match.group(1) 727 return region 728 return 'global' 729 730 @property 731 def ssl_certificates(self) -> List[str]: 732 return self._resource_data.get('sslCertificates', []) 733 734 @property 735 def certificate_map(self) -> str: 736 certificate_map = self._resource_data.get('certificateMap', '') 737 result = re.match(r'https://certificatemanager.googleapis.com/v1/(.*)', 738 certificate_map) 739 if result: 740 return result.group(1) 741 return certificate_map
A Target HTTPS Proxy resource.
707 @property 708 def full_path(self) -> str: 709 result = re.match(r'https://www.googleapis.com/compute/v1/(.*)', 710 self.self_link) 711 if result: 712 return result.group(1) 713 else: 714 return f'>> {self.self_link}'
Returns the full path of this resource.
Example: 'projects/gcpdiag-gke-1-9b90/zones/europe-west4-a/clusters/gke1'
744@caching.cached_api_call(in_memory=True) 745def get_target_https_proxies(project_id: str) -> List[TargetHttpsProxy]: 746 logging.debug('fetching Target HTTPS Proxies: %s', project_id) 747 compute = apis.get_api('compute', 'v1', project_id) 748 target_https_proxies = [] 749 request = compute.targetHttpsProxies().aggregatedList(project=project_id) 750 response = request.execute(num_retries=config.API_RETRIES) 751 target_https_proxies_by_region = response['items'] 752 for _, data_ in target_https_proxies_by_region.items(): 753 if 'targetHttpsProxies' not in data_: 754 continue 755 target_https_proxies.extend([ 756 TargetHttpsProxy(project_id, target_https_proxy) 757 for target_https_proxy in data_['targetHttpsProxies'] 758 ]) 759 760 return target_https_proxies
763class TargetSslProxy(models.Resource): 764 """A Target SSL Proxy resource.""" 765 766 _resource_data: dict 767 _type: str 768 769 def __init__(self, project_id, resource_data): 770 super().__init__(project_id=project_id) 771 self._resource_data = resource_data 772 773 @property 774 def name(self) -> str: 775 return self._resource_data['name'] 776 777 @property 778 def id(self) -> str: 779 return self._resource_data['id'] 780 781 @property 782 def full_path(self) -> str: 783 result = re.match(r'https://www.googleapis.com/compute/v1/(.*)', 784 self.self_link) 785 if result: 786 return result.group(1) 787 else: 788 return f'>> {self.self_link}' 789 790 @property 791 def self_link(self) -> str: 792 return self._resource_data['selfLink'] 793 794 @property 795 def region(self): 796 url = self._resource_data.get('region', '') 797 if url is not None: 798 match = re.search(r'/([^/]+)/?$', url) 799 if match is not None: 800 region = match.group(1) 801 return region 802 return 'global' 803 804 @property 805 def ssl_certificates(self) -> List[str]: 806 return self._resource_data.get('sslCertificates', []) 807 808 @property 809 def certificate_map(self) -> str: 810 certificate_map = self._resource_data.get('certificateMap', '') 811 result = re.match(r'https://certificatemanager.googleapis.com/v1/(.*)', 812 certificate_map) 813 if result: 814 return result.group(1) 815 return certificate_map
A Target SSL Proxy resource.
781 @property 782 def full_path(self) -> str: 783 result = re.match(r'https://www.googleapis.com/compute/v1/(.*)', 784 self.self_link) 785 if result: 786 return result.group(1) 787 else: 788 return f'>> {self.self_link}'
Returns the full path of this resource.
Example: 'projects/gcpdiag-gke-1-9b90/zones/europe-west4-a/clusters/gke1'
818@caching.cached_api_call(in_memory=True) 819def get_target_ssl_proxies(project_id: str) -> List[TargetSslProxy]: 820 logging.debug('fetching Target SSL Proxies: %s', project_id) 821 compute = apis.get_api('compute', 'v1', project_id) 822 request = compute.targetSslProxies().list(project=project_id) 823 response = request.execute(num_retries=config.API_RETRIES) 824 825 return [ 826 TargetSslProxy(project_id, item) for item in response.get('items', []) 827 ]
830class LoadBalancerInsight(models.Resource): 831 """Represents a Load Balancer Insights object""" 832 833 @property 834 def full_path(self) -> str: 835 return self._resource_data['name'] 836 837 @property 838 def description(self) -> str: 839 return self._resource_data['description'] 840 841 @property 842 def insight_subtype(self) -> str: 843 return self._resource_data['insightSubtype'] 844 845 @property 846 def details(self) -> dict: 847 return self._resource_data['content'] 848 849 @property 850 def is_firewall_rule_insight(self) -> bool: 851 firewall_rule_subtypes = ( 852 'HEALTH_CHECK_FIREWALL_NOT_CONFIGURED', 853 'HEALTH_CHECK_FIREWALL_FULLY_BLOCKING', 854 'HEALTH_CHECK_FIREWALL_PARTIALLY_BLOCKING', 855 'HEALTH_CHECK_FIREWALL_INCONSISTENT', 856 ) 857 return self.insight_subtype.startswith(firewall_rule_subtypes) 858 859 @property 860 def is_health_check_port_mismatch_insight(self) -> bool: 861 return self.insight_subtype == 'HEALTH_CHECK_PORT_MISMATCH' 862 863 def __init__(self, project_id, resource_data): 864 super().__init__(project_id=project_id) 865 self._resource_data = resource_data
Represents a Load Balancer Insights object
Returns the full path of this resource.
Example: 'projects/gcpdiag-gke-1-9b90/zones/europe-west4-a/clusters/gke1'
849 @property 850 def is_firewall_rule_insight(self) -> bool: 851 firewall_rule_subtypes = ( 852 'HEALTH_CHECK_FIREWALL_NOT_CONFIGURED', 853 'HEALTH_CHECK_FIREWALL_FULLY_BLOCKING', 854 'HEALTH_CHECK_FIREWALL_PARTIALLY_BLOCKING', 855 'HEALTH_CHECK_FIREWALL_INCONSISTENT', 856 ) 857 return self.insight_subtype.startswith(firewall_rule_subtypes)
868@caching.cached_api_call 869def get_lb_insights_for_a_project(project_id: str, region: str = 'global'): 870 api = apis.get_api('recommender', 'v1', project_id) 871 872 insight_name = (f'projects/{project_id}/locations/{region}/insightTypes/' 873 'google.networkanalyzer.networkservices.loadBalancerInsight') 874 insights = [] 875 for insight in apis_utils.list_all( 876 request=api.projects().locations().insightTypes().insights().list( 877 parent=insight_name), 878 next_function=api.projects().locations().insightTypes().insights(). 879 list_next, 880 response_keyword='insights', 881 ): 882 insights.append(LoadBalancerInsight(project_id, insight)) 883 return insights