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) -> str: 197 health_check_url = self._resource_data['healthChecks'][0] 198 matches = re.search(r'/([^/]+)$', health_check_url) 199 if matches: 200 healthcheck_name = matches.group(1) 201 return healthcheck_name 202 else: 203 return '' 204 205 @property 206 def backends(self) -> List[dict]: 207 return self._resource_data.get('backends', []) 208 209 @property 210 def region(self): 211 try: 212 url = self._resource_data.get('region') 213 if url is not None: 214 match = re.search(r'/([^/]+)/?$', url) 215 if match is not None: 216 region = match.group(1) 217 return region 218 else: 219 return None 220 except KeyError: 221 return None 222 223 @property 224 def protocol(self) -> str: 225 return self._resource_data.get('protocol', None) 226 227 @property 228 def used_by_refs(self) -> List[str]: 229 used_by = [] 230 for x in self._resource_data.get('usedBy', []): 231 reference = x.get('reference') 232 if reference: 233 match = re.match(r'https://www.googleapis.com/compute/v1/(.*)', 234 reference) 235 if match: 236 used_by.append(match.group(1)) 237 return used_by 238 239 @property 240 def load_balancer_type(self) -> LoadBalancerType: 241 application_protocols = ['HTTP', 'HTTPS', 'HTTP2'] 242 return get_load_balancer_type( 243 self.load_balancing_scheme, 244 self.region, 245 'application' if self.protocol in application_protocols else 'network', 246 backend_service_based=True, 247 )
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'
227 @property 228 def used_by_refs(self) -> List[str]: 229 used_by = [] 230 for x in self._resource_data.get('usedBy', []): 231 reference = x.get('reference') 232 if reference: 233 match = re.match(r'https://www.googleapis.com/compute/v1/(.*)', 234 reference) 235 if match: 236 used_by.append(match.group(1)) 237 return used_by
239 @property 240 def load_balancer_type(self) -> LoadBalancerType: 241 application_protocols = ['HTTP', 'HTTPS', 'HTTP2'] 242 return get_load_balancer_type( 243 self.load_balancing_scheme, 244 self.region, 245 'application' if self.protocol in application_protocols else 'network', 246 backend_service_based=True, 247 )
250@caching.cached_api_call(in_memory=True) 251def get_backend_services(project_id: str) -> List[BackendServices]: 252 logging.debug('fetching Backend Services: %s', project_id) 253 compute = apis.get_api('compute', 'v1', project_id) 254 backend_services = [] 255 request = compute.backendServices().aggregatedList(project=project_id) 256 response = request.execute(num_retries=config.API_RETRIES) 257 backend_services_by_region = response['items'] 258 for _, data_ in backend_services_by_region.items(): 259 if 'backendServices' not in data_: 260 continue 261 backend_services.extend([ 262 BackendServices(project_id, backend_service) 263 for backend_service in data_['backendServices'] 264 ]) 265 return backend_services
268@caching.cached_api_call(in_memory=True) 269def get_backend_service(project_id: str, 270 backend_service_name: str, 271 region: str = None) -> BackendServices: 272 """Returns instance object matching backend service name and region""" 273 compute = apis.get_api('compute', 'v1', project_id) 274 if not region or region == 'global': 275 request = compute.backendServices().get(project=project_id, 276 backendService=backend_service_name) 277 else: 278 request = compute.regionBackendServices().get( 279 project=project_id, region=region, backendService=backend_service_name) 280 281 response = request.execute(num_retries=config.API_RETRIES) 282 return BackendServices(project_id, resource_data=response)
Returns instance object matching backend service name and region
285def get_backend_service_by_self_link( 286 backend_service_self_link: str,) -> Optional[BackendServices]: 287 backend_service_name = backend_service_self_link.split('/')[-1] 288 backend_service_scope = backend_service_self_link.split('/')[-3] 289 match = re.match(r'projects/([^/]+)/', backend_service_self_link) 290 if not match: 291 return None 292 project_id = match.group(1) 293 return get_backend_service(project_id, backend_service_name, 294 backend_service_scope)
297class BackendHealth: 298 """A Backend Service resource.""" 299 300 _resource_data: dict 301 302 def __init__(self, resource_data, group): 303 self._resource_data = resource_data 304 self._group = group 305 306 @property 307 def instance(self) -> str: 308 return self._resource_data['instance'] 309 310 @property 311 def group(self) -> str: 312 return self._group 313 314 @property 315 def health_state(self) -> str: 316 return self._resource_data.get('healthState', 'UNHEALTHY')
A Backend Service resource.
319@caching.cached_api_call(in_memory=True) 320def get_backend_service_health( 321 project_id: str, 322 backend_service_name: str, 323 backend_service_region: str = None, 324) -> List[BackendHealth]: 325 """Returns health data for backend service.""" 326 try: 327 backend_service = get_backend_service(project_id, backend_service_name, 328 backend_service_region) 329 except googleapiclient.errors.HttpError: 330 return [] 331 332 backend_heath_statuses: List[BackendHealth] = [] 333 334 compute = apis.get_api('compute', 'v1', project_id) 335 336 for backend in backend_service.backends: 337 group = backend['group'] 338 if not backend_service.region: 339 response = compute.backendServices().getHealth( 340 project=project_id, 341 backendService=backend_service.name, 342 body={ 343 'group': group 344 }, 345 ).execute(num_retries=config.API_RETRIES) 346 # None is returned when backend type doesn't support health check 347 if response is not None: 348 for health_status in response.get('healthStatus', []): 349 backend_heath_statuses.append(BackendHealth(health_status, group)) 350 else: 351 response = compute.regionBackendServices().getHealth( 352 project=project_id, 353 region=backend_service.region, 354 backendService=backend_service.name, 355 body={ 356 'group': group 357 }, 358 ).execute(num_retries=config.API_RETRIES) 359 if response is not None: 360 for health_status in response.get('healthStatus', []): 361 backend_heath_statuses.append(BackendHealth(health_status, group)) 362 363 return backend_heath_statuses
Returns health data for backend service.
366class SslCertificate(models.Resource): 367 """A SSL Certificate resource.""" 368 369 _resource_data: dict 370 _type: str 371 372 def __init__(self, project_id, resource_data): 373 super().__init__(project_id=project_id) 374 self._resource_data = resource_data 375 376 @property 377 def name(self) -> str: 378 return self._resource_data['name'] 379 380 @property 381 def id(self) -> str: 382 return self._resource_data['id'] 383 384 @property 385 def full_path(self) -> str: 386 result = re.match(r'https://www.googleapis.com/compute/v1/(.*)', 387 self.self_link) 388 if result: 389 return result.group(1) 390 else: 391 return f'>> {self.self_link}' 392 393 @property 394 def self_link(self) -> str: 395 return self._resource_data['selfLink'] 396 397 @property 398 def type(self) -> str: 399 return self._resource_data.get('type', 'SELF_MANAGED') 400 401 @property 402 def status(self) -> str: 403 return self._resource_data.get('managed', {}).get('status') 404 405 @property 406 def domains(self) -> List[str]: 407 return self._resource_data.get('managed', {}).get('domains', []) 408 409 @property 410 def domain_status(self) -> Dict[str, str]: 411 return self._resource_data.get('managed', {}).get('domainStatus', {})
A SSL Certificate resource.
384 @property 385 def full_path(self) -> str: 386 result = re.match(r'https://www.googleapis.com/compute/v1/(.*)', 387 self.self_link) 388 if result: 389 return result.group(1) 390 else: 391 return f'>> {self.self_link}'
Returns the full path of this resource.
Example: 'projects/gcpdiag-gke-1-9b90/zones/europe-west4-a/clusters/gke1'
414@caching.cached_api_call(in_memory=True) 415def get_ssl_certificate( 416 project_id: str, 417 certificate_name: str, 418) -> SslCertificate: 419 """Returns object matching certificate name and region""" 420 compute = apis.get_api('compute', 'v1', project_id) 421 422 request = compute.sslCertificates().get(project=project_id, 423 sslCertificate=certificate_name) 424 425 response = request.execute(num_retries=config.API_RETRIES) 426 return SslCertificate(project_id, resource_data=response)
Returns object matching certificate name and region
429class ForwardingRules(models.Resource): 430 """A Forwarding Rule resource.""" 431 432 _resource_data: dict 433 _type: str 434 435 def __init__(self, project_id, resource_data): 436 super().__init__(project_id=project_id) 437 self._resource_data = resource_data 438 439 @property 440 def name(self) -> str: 441 return self._resource_data['name'] 442 443 @property 444 def id(self) -> str: 445 return self._resource_data['id'] 446 447 @property 448 def full_path(self) -> str: 449 result = re.match(r'https://www.googleapis.com/compute/v1/(.*)', 450 self.self_link) 451 if result: 452 return result.group(1) 453 else: 454 return f'>> {self.self_link}' 455 456 @property 457 def short_path(self) -> str: 458 path = self.project_id + '/' + self.name 459 return path 460 461 @property 462 def region(self): 463 url = self._resource_data.get('region', '') 464 if url is not None: 465 match = re.search(r'/([^/]+)/?$', url) 466 if match is not None: 467 region = match.group(1) 468 return region 469 return 'global' 470 471 @property 472 def self_link(self) -> str: 473 return self._resource_data['selfLink'] 474 475 @property 476 def global_access_allowed(self) -> bool: 477 return self._resource_data.get('allowGlobalAccess', False) 478 479 @property 480 def load_balancing_scheme(self) -> str: 481 return self._resource_data.get('loadBalancingScheme', None) 482 483 @property 484 def target(self) -> str: 485 full_path = self._resource_data.get('target', '') 486 result = re.match(r'https://www.googleapis.com/compute/v1/(.*)', full_path) 487 if result: 488 return result.group(1) 489 else: 490 return '' 491 492 @property 493 def backend_service(self) -> str: 494 full_path = self._resource_data.get('backendService', '') 495 result = re.match(r'https://www.googleapis.com/compute/v1/(.*)', full_path) 496 if result: 497 return result.group(1) 498 else: 499 return '' 500 501 @property 502 def ip_address(self) -> str: 503 return self._resource_data.get('IPAddress', '') 504 505 @property 506 def port_range(self) -> str: 507 return self._resource_data.get('portRange', '') 508 509 @caching.cached_api_call(in_memory=True) 510 def get_related_backend_services(self) -> List[BackendServices]: 511 """Returns the backend services related to the forwarding rule.""" 512 if self.backend_service: 513 resource = get_backend_service_by_self_link(self.backend_service) 514 return [resource] if resource else [] 515 if self.target: 516 target_proxy_target = get_target_proxy_reference(self.target) 517 if not target_proxy_target: 518 return [] 519 target_proxy_target_type = target_proxy_target.split('/')[-2] 520 if target_proxy_target_type == 'backendServices': 521 resource = get_backend_service_by_self_link(target_proxy_target) 522 return [resource] if resource else [] 523 elif target_proxy_target_type == 'urlMaps': 524 # Currently it doesn't work for shared-vpc backend services 525 backend_services = get_backend_services(self.project_id) 526 return [ 527 backend_service for backend_service in backend_services 528 if target_proxy_target in backend_service.used_by_refs 529 ] 530 return [] 531 532 @property 533 def load_balancer_type(self) -> LoadBalancerType: 534 target_type = None 535 if self.target: 536 parts = self.target.split('/') 537 if len(parts) >= 2: 538 target_type = parts[-2] 539 540 application_targets = [ 541 'targetHttpProxies', 542 'targetHttpsProxies', 543 'targetGrpcProxies', 544 ] 545 546 return get_load_balancer_type( 547 self.load_balancing_scheme, 548 self.region, 549 'application' if target_type in application_targets else 'network', 550 target_type != 'targetPools', 551 )
A Forwarding Rule resource.
447 @property 448 def full_path(self) -> str: 449 result = re.match(r'https://www.googleapis.com/compute/v1/(.*)', 450 self.self_link) 451 if result: 452 return result.group(1) 453 else: 454 return f'>> {self.self_link}'
Returns the full path of this resource.
Example: 'projects/gcpdiag-gke-1-9b90/zones/europe-west4-a/clusters/gke1'
456 @property 457 def short_path(self) -> str: 458 path = self.project_id + '/' + self.name 459 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'
532 @property 533 def load_balancer_type(self) -> LoadBalancerType: 534 target_type = None 535 if self.target: 536 parts = self.target.split('/') 537 if len(parts) >= 2: 538 target_type = parts[-2] 539 540 application_targets = [ 541 'targetHttpProxies', 542 'targetHttpsProxies', 543 'targetGrpcProxies', 544 ] 545 546 return get_load_balancer_type( 547 self.load_balancing_scheme, 548 self.region, 549 'application' if target_type in application_targets else 'network', 550 target_type != 'targetPools', 551 )
554@caching.cached_api_call(in_memory=True) 555def get_target_proxy_reference(target_proxy_self_link: str) -> str: 556 """Retrieves the URL map or backend service associated with a given target proxy. 557 558 Args: 559 target_proxy_self_link: self link of the target proxy 560 561 Returns: 562 The url map or the backend service self link 563 """ 564 target_proxy_type = target_proxy_self_link.split('/')[-2] 565 target_proxy_name = target_proxy_self_link.split('/')[-1] 566 target_proxy_scope = target_proxy_self_link.split('/')[-3] 567 match_result = re.match(r'projects/([^/]+)/', target_proxy_self_link) 568 if not match_result: 569 return '' 570 project_id = match_result.group(1) 571 compute = apis.get_api('compute', 'v1', project_id) 572 573 request = None 574 if target_proxy_type == 'targetHttpsProxies': 575 if target_proxy_scope == 'global': 576 request = compute.targetHttpsProxies().get( 577 project=project_id, targetHttpsProxy=target_proxy_name) 578 else: 579 request = compute.regionTargetHttpsProxies().get( 580 project=project_id, 581 region=target_proxy_scope, 582 targetHttpsProxy=target_proxy_name, 583 ) 584 elif target_proxy_type == 'targetHttpProxies': 585 if target_proxy_scope == 'global': 586 request = compute.targetHttpProxies().get( 587 project=project_id, targetHttpProxy=target_proxy_name) 588 else: 589 request = compute.regionTargetHttpProxies().get( 590 project=project_id, 591 region=target_proxy_scope, 592 targetHttpProxy=target_proxy_name, 593 ) 594 elif target_proxy_type == 'targetTcpProxies': 595 if target_proxy_scope == 'global': 596 request = compute.targetTcpProxies().get(project=project_id, 597 targetTcpProxy=target_proxy_name) 598 else: 599 request = compute.regionTargetTcpProxies().get( 600 project=project_id, 601 region=target_proxy_scope, 602 targetTcpProxy=target_proxy_name, 603 ) 604 elif target_proxy_type == 'targetSslProxies': 605 request = compute.targetSslProxies().get(project=project_id, 606 targetSslProxy=target_proxy_name) 607 elif target_proxy_type == 'targetGrcpProxies': 608 request = compute.targetGrpcProxies().get(project=project_id, 609 targetGrpcProxy=target_proxy_name) 610 if not request: 611 # target is not target proxy 612 return '' 613 response = request.execute(num_retries=config.API_RETRIES) 614 if 'urlMap' in response: 615 return normalize_url(response['urlMap']) 616 if 'service' in response: 617 return normalize_url(response['service']) 618 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
621@caching.cached_api_call(in_memory=True) 622def get_forwarding_rules(project_id: str) -> List[ForwardingRules]: 623 logging.debug('fetching Forwarding Rules: %s', project_id) 624 compute = apis.get_api('compute', 'v1', project_id) 625 forwarding_rules = [] 626 request = compute.forwardingRules().aggregatedList(project=project_id) 627 response = request.execute(num_retries=config.API_RETRIES) 628 forwarding_rules_by_region = response['items'] 629 for _, data_ in forwarding_rules_by_region.items(): 630 if 'forwardingRules' not in data_: 631 continue 632 forwarding_rules.extend([ 633 ForwardingRules(project_id, forwarding_rule) 634 for forwarding_rule in data_['forwardingRules'] 635 ]) 636 return forwarding_rules
639@caching.cached_api_call(in_memory=True) 640def get_forwarding_rule(project_id: str, 641 forwarding_rule_name: str, 642 region: str = None) -> ForwardingRules: 643 compute = apis.get_api('compute', 'v1', project_id) 644 if not region or region == 'global': 645 request = compute.globalForwardingRules().get( 646 project=project_id, forwardingRule=forwarding_rule_name) 647 else: 648 request = compute.forwardingRules().get(project=project_id, 649 region=region, 650 forwardingRule=forwarding_rule_name) 651 response = request.execute(num_retries=config.API_RETRIES) 652 return ForwardingRules(project_id, resource_data=response)
655class TargetHttpsProxy(models.Resource): 656 """A Target HTTPS Proxy resource.""" 657 658 _resource_data: dict 659 _type: str 660 661 def __init__(self, project_id, resource_data): 662 super().__init__(project_id=project_id) 663 self._resource_data = resource_data 664 665 @property 666 def name(self) -> str: 667 return self._resource_data['name'] 668 669 @property 670 def id(self) -> str: 671 return self._resource_data['id'] 672 673 @property 674 def full_path(self) -> str: 675 result = re.match(r'https://www.googleapis.com/compute/v1/(.*)', 676 self.self_link) 677 if result: 678 return result.group(1) 679 else: 680 return f'>> {self.self_link}' 681 682 @property 683 def self_link(self) -> str: 684 return self._resource_data['selfLink'] 685 686 @property 687 def region(self): 688 url = self._resource_data.get('region', '') 689 if url is not None: 690 match = re.search(r'/([^/]+)/?$', url) 691 if match is not None: 692 region = match.group(1) 693 return region 694 return 'global' 695 696 @property 697 def ssl_certificates(self) -> List[str]: 698 return self._resource_data.get('sslCertificates', []) 699 700 @property 701 def certificate_map(self) -> str: 702 certificate_map = self._resource_data.get('certificateMap', '') 703 result = re.match(r'https://certificatemanager.googleapis.com/v1/(.*)', 704 certificate_map) 705 if result: 706 return result.group(1) 707 return certificate_map
A Target HTTPS Proxy resource.
673 @property 674 def full_path(self) -> str: 675 result = re.match(r'https://www.googleapis.com/compute/v1/(.*)', 676 self.self_link) 677 if result: 678 return result.group(1) 679 else: 680 return f'>> {self.self_link}'
Returns the full path of this resource.
Example: 'projects/gcpdiag-gke-1-9b90/zones/europe-west4-a/clusters/gke1'
710@caching.cached_api_call(in_memory=True) 711def get_target_https_proxies(project_id: str) -> List[TargetHttpsProxy]: 712 logging.debug('fetching Target HTTPS Proxies: %s', project_id) 713 compute = apis.get_api('compute', 'v1', project_id) 714 target_https_proxies = [] 715 request = compute.targetHttpsProxies().aggregatedList(project=project_id) 716 response = request.execute(num_retries=config.API_RETRIES) 717 target_https_proxies_by_region = response['items'] 718 for _, data_ in target_https_proxies_by_region.items(): 719 if 'targetHttpsProxies' not in data_: 720 continue 721 target_https_proxies.extend([ 722 TargetHttpsProxy(project_id, target_https_proxy) 723 for target_https_proxy in data_['targetHttpsProxies'] 724 ]) 725 726 return target_https_proxies
729class TargetSslProxy(models.Resource): 730 """A Target SSL Proxy resource.""" 731 732 _resource_data: dict 733 _type: str 734 735 def __init__(self, project_id, resource_data): 736 super().__init__(project_id=project_id) 737 self._resource_data = resource_data 738 739 @property 740 def name(self) -> str: 741 return self._resource_data['name'] 742 743 @property 744 def id(self) -> str: 745 return self._resource_data['id'] 746 747 @property 748 def full_path(self) -> str: 749 result = re.match(r'https://www.googleapis.com/compute/v1/(.*)', 750 self.self_link) 751 if result: 752 return result.group(1) 753 else: 754 return f'>> {self.self_link}' 755 756 @property 757 def self_link(self) -> str: 758 return self._resource_data['selfLink'] 759 760 @property 761 def region(self): 762 url = self._resource_data.get('region', '') 763 if url is not None: 764 match = re.search(r'/([^/]+)/?$', url) 765 if match is not None: 766 region = match.group(1) 767 return region 768 return 'global' 769 770 @property 771 def ssl_certificates(self) -> List[str]: 772 return self._resource_data.get('sslCertificates', []) 773 774 @property 775 def certificate_map(self) -> str: 776 certificate_map = self._resource_data.get('certificateMap', '') 777 result = re.match(r'https://certificatemanager.googleapis.com/v1/(.*)', 778 certificate_map) 779 if result: 780 return result.group(1) 781 return certificate_map
A Target SSL Proxy resource.
747 @property 748 def full_path(self) -> str: 749 result = re.match(r'https://www.googleapis.com/compute/v1/(.*)', 750 self.self_link) 751 if result: 752 return result.group(1) 753 else: 754 return f'>> {self.self_link}'
Returns the full path of this resource.
Example: 'projects/gcpdiag-gke-1-9b90/zones/europe-west4-a/clusters/gke1'
784@caching.cached_api_call(in_memory=True) 785def get_target_ssl_proxies(project_id: str) -> List[TargetSslProxy]: 786 logging.debug('fetching Target SSL Proxies: %s', project_id) 787 compute = apis.get_api('compute', 'v1', project_id) 788 request = compute.targetSslProxies().list(project=project_id) 789 response = request.execute(num_retries=config.API_RETRIES) 790 791 return [ 792 TargetSslProxy(project_id, item) for item in response.get('items', []) 793 ]
796class LoadBalancerInsight(models.Resource): 797 """Represents a Load Balancer Insights object""" 798 799 @property 800 def full_path(self) -> str: 801 return self._resource_data['name'] 802 803 @property 804 def description(self) -> str: 805 return self._resource_data['description'] 806 807 @property 808 def insight_subtype(self) -> str: 809 return self._resource_data['insightSubtype'] 810 811 @property 812 def details(self) -> dict: 813 return self._resource_data['content'] 814 815 @property 816 def is_firewall_rule_insight(self) -> bool: 817 firewall_rule_subtypes = ( 818 'HEALTH_CHECK_FIREWALL_NOT_CONFIGURED', 819 'HEALTH_CHECK_FIREWALL_FULLY_BLOCKING', 820 'HEALTH_CHECK_FIREWALL_PARTIALLY_BLOCKING', 821 'HEALTH_CHECK_FIREWALL_INCONSISTENT', 822 ) 823 return self.insight_subtype.startswith(firewall_rule_subtypes) 824 825 @property 826 def is_health_check_port_mismatch_insight(self) -> bool: 827 return self.insight_subtype == 'HEALTH_CHECK_PORT_MISMATCH' 828 829 def __init__(self, project_id, resource_data): 830 super().__init__(project_id=project_id) 831 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'
815 @property 816 def is_firewall_rule_insight(self) -> bool: 817 firewall_rule_subtypes = ( 818 'HEALTH_CHECK_FIREWALL_NOT_CONFIGURED', 819 'HEALTH_CHECK_FIREWALL_FULLY_BLOCKING', 820 'HEALTH_CHECK_FIREWALL_PARTIALLY_BLOCKING', 821 'HEALTH_CHECK_FIREWALL_INCONSISTENT', 822 ) 823 return self.insight_subtype.startswith(firewall_rule_subtypes)
834@caching.cached_api_call 835def get_lb_insights_for_a_project(project_id: str, region: str = 'global'): 836 api = apis.get_api('recommender', 'v1', project_id) 837 838 insight_name = (f'projects/{project_id}/locations/{region}/insightTypes/' 839 'google.networkanalyzer.networkservices.loadBalancerInsight') 840 insights = [] 841 for insight in apis_utils.list_all( 842 request=api.projects().locations().insightTypes().insights().list( 843 parent=insight_name), 844 next_function=api.projects().locations().insightTypes().insights(). 845 list_next, 846 response_keyword='insights', 847 ): 848 insights.append(LoadBalancerInsight(project_id, insight)) 849 return insights