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: 'Unspecified', 52 LoadBalancerType.EXTERNAL_PASSTHROUGH_LB: ('External Passthrough Network Load Balancer'), 53 LoadBalancerType.INTERNAL_PASSTHROUGH_LB: ('Internal Passthrough Network Load Balancer'), 54 LoadBalancerType.TARGET_POOL_LB: 'Target Pool Network Load Balancer', 55 LoadBalancerType.GLOBAL_EXTERNAL_PROXY_NETWORK_LB: ( 56 'Global External Proxy Network Load Balancer' 57 ), 58 LoadBalancerType.REGIONAL_INTERNAL_PROXY_NETWORK_LB: ( 59 'Regional Internal Proxy Network Load Balancer' 60 ), 61 LoadBalancerType.REGIONAL_EXTERNAL_PROXY_NETWORK_LB: ( 62 'Regional External Proxy Network Load Balancer' 63 ), 64 LoadBalancerType.CROSS_REGION_INTERNAL_PROXY_NETWORK_LB: ( 65 'Cross-Region Internal Proxy Network Load Balancer' 66 ), 67 LoadBalancerType.CLASSIC_PROXY_NETWORK_LB: ('Classic Proxy Network Load Balancer'), 68 LoadBalancerType.GLOBAL_EXTERNAL_APPLICATION_LB: ('Global External Application Load Balancer'), 69 LoadBalancerType.REGIONAL_INTERNAL_APPLICATION_LB: ( 70 'Regional Internal Application Load Balancer' 71 ), 72 LoadBalancerType.REGIONAL_EXTERNAL_APPLICATION_LB: ( 73 'Regional External Application Load Balancer' 74 ), 75 LoadBalancerType.CROSS_REGION_INTERNAL_APPLICATION_LB: ( 76 'Cross-Region Internal Application Load Balancer' 77 ), 78 LoadBalancerType.CLASSIC_APPLICATION_LB: ('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 ( 97 LoadBalancerType.EXTERNAL_PASSTHROUGH_LB 98 if backend_service_based 99 else LoadBalancerType.TARGET_POOL_LB 100 ) 101 elif load_balancing_scheme == 'INTERNAL': 102 return LoadBalancerType.INTERNAL_PASSTHROUGH_LB 103 elif load_balancing_scheme == 'INTERNAL_MANAGED': 104 if not scope or scope == 'global': 105 if layer == 'application': 106 return LoadBalancerType.CROSS_REGION_INTERNAL_APPLICATION_LB 107 else: 108 return LoadBalancerType.CROSS_REGION_INTERNAL_PROXY_NETWORK_LB 109 else: 110 if layer == 'application': 111 return LoadBalancerType.REGIONAL_INTERNAL_APPLICATION_LB 112 else: 113 return LoadBalancerType.REGIONAL_INTERNAL_PROXY_NETWORK_LB 114 elif load_balancing_scheme == 'EXTERNAL_MANAGED': 115 if not scope or scope == 'global': 116 if layer == 'application': 117 return LoadBalancerType.GLOBAL_EXTERNAL_APPLICATION_LB 118 else: 119 return LoadBalancerType.GLOBAL_EXTERNAL_PROXY_NETWORK_LB 120 else: 121 if layer == 'application': 122 return LoadBalancerType.REGIONAL_EXTERNAL_APPLICATION_LB 123 else: 124 return LoadBalancerType.REGIONAL_EXTERNAL_PROXY_NETWORK_LB 125 return LoadBalancerType.LOAD_BALANCER_TYPE_UNSPECIFIED
128def normalize_url(url: str) -> str: 129 """Returns normalized url.""" 130 result = re.match(r'https://www.googleapis.com/compute/v1/(.*)', url) 131 if result: 132 return result.group(1) 133 else: 134 return ''
Returns normalized url.
137class BackendServices(models.Resource): 138 """A Backend Service resource.""" 139 140 _resource_data: dict 141 _type: str 142 143 def __init__(self, project_id, resource_data): 144 super().__init__(project_id=project_id) 145 self._resource_data = resource_data 146 147 @property 148 def name(self) -> str: 149 return self._resource_data['name'] 150 151 @property 152 def id(self) -> str: 153 return self._resource_data['id'] 154 155 @property 156 def full_path(self) -> str: 157 result = re.match(r'https://www.googleapis.com/compute/v1/(.*)', self.self_link) 158 if result: 159 return result.group(1) 160 else: 161 return f'>> {self.self_link}' 162 163 @property 164 def short_path(self) -> str: 165 path = self.project_id + '/' + self.name 166 return path 167 168 @property 169 def self_link(self) -> str: 170 return self._resource_data['selfLink'] 171 172 @property 173 def session_affinity(self) -> str: 174 return self._resource_data.get('sessionAffinity', 'NONE') 175 176 @property 177 def timeout_sec(self) -> int: 178 return self._resource_data.get('timeoutSec', None) 179 180 @property 181 def locality_lb_policy(self) -> str: 182 return self._resource_data.get('localityLbPolicy', 'ROUND_ROBIN') 183 184 @property 185 def is_enable_cdn(self) -> str: 186 return self._resource_data.get('enableCDN', False) 187 188 @property 189 def draining_timeout_sec(self) -> int: 190 return self._resource_data.get('connectionDraining', {}).get('drainingTimeoutSec', 0) 191 192 @property 193 def load_balancing_scheme(self) -> str: 194 return self._resource_data.get('loadBalancingScheme', None) 195 196 @property 197 def health_check(self): 198 if 'healthChecks' not in self._resource_data: 199 return None 200 health_check_url = self._resource_data['healthChecks'][0] 201 matches = re.search(r'/([^/]+)$', health_check_url) 202 if matches: 203 healthcheck_name = matches.group(1) 204 return healthcheck_name 205 else: 206 return None 207 208 @property 209 def health_check_region(self): 210 if 'healthChecks' not in self._resource_data: 211 return None 212 health_check_url = self._resource_data['healthChecks'][0] 213 m = re.search(r'/regions/([^/]+)', health_check_url) 214 if m: 215 return m.group(1) 216 else: 217 return None 218 219 @property 220 def backends(self) -> List[dict]: 221 return self._resource_data.get('backends', []) 222 223 @property 224 def region(self): 225 try: 226 url = self._resource_data.get('region') 227 if url is not None: 228 match = re.search(r'/([^/]+)/?$', url) 229 if match is not None: 230 region = match.group(1) 231 return region 232 else: 233 return None 234 except KeyError: 235 return None 236 237 @property 238 def protocol(self) -> str: 239 return self._resource_data.get('protocol', None) 240 241 @property 242 def port_name(self) -> str: 243 return self._resource_data.get('portName', None) 244 245 @property 246 def used_by_refs(self) -> List[str]: 247 used_by = [] 248 for x in self._resource_data.get('usedBy', []): 249 reference = x.get('reference') 250 if reference: 251 match = re.match(r'https://www.googleapis.com/compute/v1/(.*)', 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.
155 @property 156 def full_path(self) -> str: 157 result = re.match(r'https://www.googleapis.com/compute/v1/(.*)', self.self_link) 158 if result: 159 return result.group(1) 160 else: 161 return f'>> {self.self_link}'
Returns the full path of this resource.
Example: 'projects/gcpdiag-gke-1-9b90/zones/europe-west4-a/clusters/gke1'
163 @property 164 def short_path(self) -> str: 165 path = self.project_id + '/' + self.name 166 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'
196 @property 197 def health_check(self): 198 if 'healthChecks' not in self._resource_data: 199 return None 200 health_check_url = self._resource_data['healthChecks'][0] 201 matches = re.search(r'/([^/]+)$', health_check_url) 202 if matches: 203 healthcheck_name = matches.group(1) 204 return healthcheck_name 205 else: 206 return None
245 @property 246 def used_by_refs(self) -> List[str]: 247 used_by = [] 248 for x in self._resource_data.get('usedBy', []): 249 reference = x.get('reference') 250 if reference: 251 match = re.match(r'https://www.googleapis.com/compute/v1/(.*)', 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) for backend_service in data_['backendServices']] 280 ) 281 return backend_services
284@caching.cached_api_call(in_memory=True) 285def get_backend_service( 286 project_id: str, backend_service_name: str, region: str = None 287) -> BackendServices: 288 """Returns instance object matching backend service name and region""" 289 compute = apis.get_api('compute', 'v1', project_id) 290 try: 291 if not region or region == 'global': 292 request = compute.backendServices().get( 293 project=project_id, backendService=backend_service_name 294 ) 295 else: 296 request = compute.regionBackendServices().get( 297 project=project_id, region=region, backendService=backend_service_name 298 ) 299 300 response = request.execute(num_retries=config.API_RETRIES) 301 return BackendServices(project_id, resource_data=response) 302 except googleapiclient.errors.HttpError as err: 303 raise utils.GcpApiError(err) from err
Returns instance object matching backend service name and region
306def get_backend_service_by_self_link( 307 backend_service_self_link: str, 308) -> 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, backend_service_scope)
318class BackendHealth: 319 """A Backend Service resource.""" 320 321 _resource_data: dict 322 323 def __init__(self, resource_data, group): 324 self._resource_data = resource_data 325 self._group = group 326 327 @property 328 def instance(self) -> str: 329 return self._resource_data['instance'] 330 331 @property 332 def group(self) -> str: 333 return self._group 334 335 @property 336 def health_state(self) -> str: 337 return self._resource_data.get('healthState', 'UNHEALTHY')
A Backend Service resource.
340@caching.cached_api_call(in_memory=True) 341def get_backend_service_health( 342 context: models.Context, 343 backend_service_name: str, 344 backend_service_region: str = None, 345) -> List[BackendHealth]: 346 """Returns health data for backend service. 347 348 Args: 349 context: The project context. 350 backend_service_name: The name of the backend service. 351 backend_service_region: The region of the backend service. 352 353 Returns: 354 A list of BackendHealth objects. 355 """ 356 project_id = context.project_id 357 try: 358 backend_service = get_backend_service(project_id, backend_service_name, backend_service_region) 359 except googleapiclient.errors.HttpError: 360 return [] 361 362 backend_health_statuses: List[BackendHealth] = [] 363 compute = apis.get_api('compute', 'v1', project_id) 364 request_map = {} 365 366 for backend in backend_service.backends: 367 group = backend['group'] 368 if not backend_service.region: 369 request = compute.backendServices().getHealth( 370 project=project_id, backendService=backend_service.name, body={'group': group} 371 ) 372 else: 373 request = compute.regionBackendServices().getHealth( 374 project=project_id, 375 region=backend_service.region, 376 backendService=backend_service.name, 377 body={'group': group}, 378 ) 379 request_map[request] = group 380 381 for i, response, exception in apis_utils.execute_concurrently( 382 api=compute, requests=list(request_map.keys()), context=context 383 ): 384 group = request_map[i] 385 if exception: 386 logging.warning( 387 'getHealth API call failed for backend service %s, group %s: %s', 388 backend_service_name, 389 group, 390 exception, 391 ) 392 continue 393 394 # None is returned when backend type doesn't support health check 395 if response is not None: 396 for health_status in response.get('healthStatus', []): 397 backend_health_statuses.append(BackendHealth(health_status, group)) 398 399 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.
402class SslCertificate(models.Resource): 403 """A SSL Certificate resource.""" 404 405 _resource_data: dict 406 _type: str 407 408 def __init__(self, project_id, resource_data): 409 super().__init__(project_id=project_id) 410 self._resource_data = resource_data 411 412 @property 413 def name(self) -> str: 414 return self._resource_data['name'] 415 416 @property 417 def id(self) -> str: 418 return self._resource_data['id'] 419 420 @property 421 def full_path(self) -> str: 422 result = re.match(r'https://www.googleapis.com/compute/v1/(.*)', self.self_link) 423 if result: 424 return result.group(1) 425 else: 426 return f'>> {self.self_link}' 427 428 @property 429 def self_link(self) -> str: 430 return self._resource_data['selfLink'] 431 432 @property 433 def type(self) -> str: 434 return self._resource_data.get('type', 'SELF_MANAGED') 435 436 @property 437 def status(self) -> str: 438 return self._resource_data.get('managed', {}).get('status') 439 440 @property 441 def domains(self) -> List[str]: 442 return self._resource_data.get('managed', {}).get('domains', []) 443 444 @property 445 def domain_status(self) -> Dict[str, str]: 446 return self._resource_data.get('managed', {}).get('domainStatus', {})
A SSL Certificate resource.
420 @property 421 def full_path(self) -> str: 422 result = re.match(r'https://www.googleapis.com/compute/v1/(.*)', self.self_link) 423 if result: 424 return result.group(1) 425 else: 426 return f'>> {self.self_link}'
Returns the full path of this resource.
Example: 'projects/gcpdiag-gke-1-9b90/zones/europe-west4-a/clusters/gke1'
449@caching.cached_api_call(in_memory=True) 450def get_ssl_certificate( 451 project_id: str, 452 certificate_name: str, 453) -> SslCertificate: 454 """Returns object matching certificate name and region""" 455 compute = apis.get_api('compute', 'v1', project_id) 456 457 request = compute.sslCertificates().get(project=project_id, 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/(.*)', self.self_link) 484 if result: 485 return result.group(1) 486 else: 487 return f'>> {self.self_link}' 488 489 @property 490 def short_path(self) -> str: 491 path = self.project_id + '/' + self.name 492 return path 493 494 @property 495 def region(self): 496 url = self._resource_data.get('region', '') 497 if url is not None: 498 match = re.search(r'/([^/]+)/?$', url) 499 if match is not None: 500 region = match.group(1) 501 return region 502 return 'global' 503 504 @property 505 def self_link(self) -> str: 506 return self._resource_data['selfLink'] 507 508 @property 509 def global_access_allowed(self) -> bool: 510 return self._resource_data.get('allowGlobalAccess', False) 511 512 @property 513 def load_balancing_scheme(self) -> str: 514 return self._resource_data.get('loadBalancingScheme', None) 515 516 @property 517 def target(self) -> str: 518 full_path = self._resource_data.get('target', '') 519 result = re.match(r'https://www.googleapis.com/compute/v1/(.*)', full_path) 520 if result: 521 return result.group(1) 522 else: 523 return '' 524 525 @property 526 def backend_service(self) -> str: 527 full_path = self._resource_data.get('backendService', '') 528 result = re.match(r'https://www.googleapis.com/compute/v1/(.*)', full_path) 529 if result: 530 return result.group(1) 531 else: 532 return '' 533 534 @property 535 def ip_address(self) -> str: 536 return self._resource_data.get('IPAddress', '') 537 538 @property 539 def port_range(self) -> str: 540 return self._resource_data.get('portRange', '') 541 542 @caching.cached_api_call(in_memory=True) 543 def get_related_backend_services(self) -> List[BackendServices]: 544 """Returns the backend services related to the forwarding rule.""" 545 if self.backend_service: 546 resource = get_backend_service_by_self_link(self.backend_service) 547 return [resource] if resource else [] 548 if self.target: 549 target_proxy_target = get_target_proxy_reference(self.target) 550 if not target_proxy_target: 551 return [] 552 target_proxy_target_type = target_proxy_target.split('/')[-2] 553 if target_proxy_target_type == 'backendServices': 554 resource = get_backend_service_by_self_link(target_proxy_target) 555 return [resource] if resource else [] 556 elif target_proxy_target_type == 'urlMaps': 557 # Currently it doesn't work for shared-vpc backend services 558 backend_services = get_backend_services(self.project_id) 559 return [ 560 backend_service 561 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/(.*)', self.self_link) 484 if result: 485 return result.group(1) 486 else: 487 return f'>> {self.self_link}'
Returns the full path of this resource.
Example: 'projects/gcpdiag-gke-1-9b90/zones/europe-west4-a/clusters/gke1'
489 @property 490 def short_path(self) -> str: 491 path = self.project_id + '/' + self.name 492 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 ) 613 else: 614 request = compute.regionTargetHttpsProxies().get( 615 project=project_id, 616 region=target_proxy_scope, 617 targetHttpsProxy=target_proxy_name, 618 ) 619 elif target_proxy_type == 'targetHttpProxies': 620 if target_proxy_scope == 'global': 621 request = compute.targetHttpProxies().get( 622 project=project_id, targetHttpProxy=target_proxy_name 623 ) 624 else: 625 request = compute.regionTargetHttpProxies().get( 626 project=project_id, 627 region=target_proxy_scope, 628 targetHttpProxy=target_proxy_name, 629 ) 630 elif target_proxy_type == 'targetTcpProxies': 631 if target_proxy_scope == 'global': 632 request = compute.targetTcpProxies().get(project=project_id, targetTcpProxy=target_proxy_name) 633 else: 634 request = compute.regionTargetTcpProxies().get( 635 project=project_id, 636 region=target_proxy_scope, 637 targetTcpProxy=target_proxy_name, 638 ) 639 elif target_proxy_type == 'targetSslProxies': 640 request = compute.targetSslProxies().get(project=project_id, targetSslProxy=target_proxy_name) 641 elif target_proxy_type == 'targetGrcpProxies': 642 request = compute.targetGrpcProxies().get(project=project_id, targetGrpcProxy=target_proxy_name) 643 if not request: 644 # target is not target proxy 645 return '' 646 response = request.execute(num_retries=config.API_RETRIES) 647 if 'urlMap' in response: 648 return normalize_url(response['urlMap']) 649 if 'service' in response: 650 return normalize_url(response['service']) 651 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
654@caching.cached_api_call(in_memory=True) 655def get_forwarding_rules(project_id: str) -> List[ForwardingRules]: 656 logging.debug('fetching Forwarding Rules: %s', project_id) 657 compute = apis.get_api('compute', 'v1', project_id) 658 forwarding_rules = [] 659 request = compute.forwardingRules().aggregatedList(project=project_id) 660 response = request.execute(num_retries=config.API_RETRIES) 661 forwarding_rules_by_region = response['items'] 662 for _, data_ in forwarding_rules_by_region.items(): 663 if 'forwardingRules' not in data_: 664 continue 665 forwarding_rules.extend( 666 [ForwardingRules(project_id, forwarding_rule) for forwarding_rule in data_['forwardingRules']] 667 ) 668 return forwarding_rules
671@caching.cached_api_call(in_memory=True) 672def get_forwarding_rule( 673 project_id: str, forwarding_rule_name: str, region: str = None 674) -> ForwardingRules: 675 compute = apis.get_api('compute', 'v1', project_id) 676 if not region or region == 'global': 677 request = compute.globalForwardingRules().get( 678 project=project_id, forwardingRule=forwarding_rule_name 679 ) 680 else: 681 request = compute.forwardingRules().get( 682 project=project_id, region=region, forwardingRule=forwarding_rule_name 683 ) 684 response = request.execute(num_retries=config.API_RETRIES) 685 return ForwardingRules(project_id, resource_data=response)
688class TargetHttpsProxy(models.Resource): 689 """A Target HTTPS Proxy resource.""" 690 691 _resource_data: dict 692 _type: str 693 694 def __init__(self, project_id, resource_data): 695 super().__init__(project_id=project_id) 696 self._resource_data = resource_data 697 698 @property 699 def name(self) -> str: 700 return self._resource_data['name'] 701 702 @property 703 def id(self) -> str: 704 return self._resource_data['id'] 705 706 @property 707 def full_path(self) -> str: 708 result = re.match(r'https://www.googleapis.com/compute/v1/(.*)', self.self_link) 709 if result: 710 return result.group(1) 711 else: 712 return f'>> {self.self_link}' 713 714 @property 715 def self_link(self) -> str: 716 return self._resource_data['selfLink'] 717 718 @property 719 def region(self): 720 url = self._resource_data.get('region', '') 721 if url is not None: 722 match = re.search(r'/([^/]+)/?$', url) 723 if match is not None: 724 region = match.group(1) 725 return region 726 return 'global' 727 728 @property 729 def ssl_certificates(self) -> List[str]: 730 return self._resource_data.get('sslCertificates', []) 731 732 @property 733 def certificate_map(self) -> str: 734 certificate_map = self._resource_data.get('certificateMap', '') 735 result = re.match(r'https://certificatemanager.googleapis.com/v1/(.*)', certificate_map) 736 if result: 737 return result.group(1) 738 return certificate_map
A Target HTTPS Proxy resource.
706 @property 707 def full_path(self) -> str: 708 result = re.match(r'https://www.googleapis.com/compute/v1/(.*)', self.self_link) 709 if result: 710 return result.group(1) 711 else: 712 return f'>> {self.self_link}'
Returns the full path of this resource.
Example: 'projects/gcpdiag-gke-1-9b90/zones/europe-west4-a/clusters/gke1'
741@caching.cached_api_call(in_memory=True) 742def get_target_https_proxies(project_id: str) -> List[TargetHttpsProxy]: 743 logging.debug('fetching Target HTTPS Proxies: %s', project_id) 744 compute = apis.get_api('compute', 'v1', project_id) 745 target_https_proxies = [] 746 request = compute.targetHttpsProxies().aggregatedList(project=project_id) 747 response = request.execute(num_retries=config.API_RETRIES) 748 target_https_proxies_by_region = response['items'] 749 for _, data_ in target_https_proxies_by_region.items(): 750 if 'targetHttpsProxies' not in data_: 751 continue 752 target_https_proxies.extend( 753 [ 754 TargetHttpsProxy(project_id, target_https_proxy) 755 for target_https_proxy in data_['targetHttpsProxies'] 756 ] 757 ) 758 759 return target_https_proxies
762class TargetSslProxy(models.Resource): 763 """A Target SSL Proxy resource.""" 764 765 _resource_data: dict 766 _type: str 767 768 def __init__(self, project_id, resource_data): 769 super().__init__(project_id=project_id) 770 self._resource_data = resource_data 771 772 @property 773 def name(self) -> str: 774 return self._resource_data['name'] 775 776 @property 777 def id(self) -> str: 778 return self._resource_data['id'] 779 780 @property 781 def full_path(self) -> str: 782 result = re.match(r'https://www.googleapis.com/compute/v1/(.*)', self.self_link) 783 if result: 784 return result.group(1) 785 else: 786 return f'>> {self.self_link}' 787 788 @property 789 def self_link(self) -> str: 790 return self._resource_data['selfLink'] 791 792 @property 793 def region(self): 794 url = self._resource_data.get('region', '') 795 if url is not None: 796 match = re.search(r'/([^/]+)/?$', url) 797 if match is not None: 798 region = match.group(1) 799 return region 800 return 'global' 801 802 @property 803 def ssl_certificates(self) -> List[str]: 804 return self._resource_data.get('sslCertificates', []) 805 806 @property 807 def certificate_map(self) -> str: 808 certificate_map = self._resource_data.get('certificateMap', '') 809 result = re.match(r'https://certificatemanager.googleapis.com/v1/(.*)', certificate_map) 810 if result: 811 return result.group(1) 812 return certificate_map
A Target SSL Proxy resource.
780 @property 781 def full_path(self) -> str: 782 result = re.match(r'https://www.googleapis.com/compute/v1/(.*)', self.self_link) 783 if result: 784 return result.group(1) 785 else: 786 return f'>> {self.self_link}'
Returns the full path of this resource.
Example: 'projects/gcpdiag-gke-1-9b90/zones/europe-west4-a/clusters/gke1'
815@caching.cached_api_call(in_memory=True) 816def get_target_ssl_proxies(project_id: str) -> List[TargetSslProxy]: 817 logging.debug('fetching Target SSL Proxies: %s', project_id) 818 compute = apis.get_api('compute', 'v1', project_id) 819 request = compute.targetSslProxies().list(project=project_id) 820 response = request.execute(num_retries=config.API_RETRIES) 821 822 return [TargetSslProxy(project_id, item) for item in response.get('items', [])]
825class LoadBalancerInsight(models.Resource): 826 """Represents a Load Balancer Insights object""" 827 828 @property 829 def full_path(self) -> str: 830 return self._resource_data['name'] 831 832 @property 833 def description(self) -> str: 834 return self._resource_data['description'] 835 836 @property 837 def insight_subtype(self) -> str: 838 return self._resource_data['insightSubtype'] 839 840 @property 841 def details(self) -> dict: 842 return self._resource_data['content'] 843 844 @property 845 def is_firewall_rule_insight(self) -> bool: 846 firewall_rule_subtypes = ( 847 'HEALTH_CHECK_FIREWALL_NOT_CONFIGURED', 848 'HEALTH_CHECK_FIREWALL_FULLY_BLOCKING', 849 'HEALTH_CHECK_FIREWALL_PARTIALLY_BLOCKING', 850 'HEALTH_CHECK_FIREWALL_INCONSISTENT', 851 ) 852 return self.insight_subtype.startswith(firewall_rule_subtypes) 853 854 @property 855 def is_health_check_port_mismatch_insight(self) -> bool: 856 return self.insight_subtype == 'HEALTH_CHECK_PORT_MISMATCH' 857 858 def __init__(self, project_id, resource_data): 859 super().__init__(project_id=project_id) 860 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'
844 @property 845 def is_firewall_rule_insight(self) -> bool: 846 firewall_rule_subtypes = ( 847 'HEALTH_CHECK_FIREWALL_NOT_CONFIGURED', 848 'HEALTH_CHECK_FIREWALL_FULLY_BLOCKING', 849 'HEALTH_CHECK_FIREWALL_PARTIALLY_BLOCKING', 850 'HEALTH_CHECK_FIREWALL_INCONSISTENT', 851 ) 852 return self.insight_subtype.startswith(firewall_rule_subtypes)
863@caching.cached_api_call 864def get_lb_insights_for_a_project(project_id: str, region: str = 'global'): 865 api = apis.get_api('recommender', 'v1', project_id) 866 867 insight_name = ( 868 f'projects/{project_id}/locations/{region}/insightTypes/' 869 'google.networkanalyzer.networkservices.loadBalancerInsight' 870 ) 871 insights = [] 872 for insight in apis_utils.list_all( 873 request=api.projects().locations().insightTypes().insights().list(parent=insight_name), 874 next_function=api.projects().locations().insightTypes().insights().list_next, 875 response_keyword='insights', 876 ): 877 insights.append(LoadBalancerInsight(project_id, insight)) 878 return insights