1#!/usr/bin/python 2# -*- coding: utf-8 -*- 3# 4# Copyright (C) 2017 Google 5# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 6# ---------------------------------------------------------------------------- 7# 8# *** AUTO GENERATED CODE *** AUTO GENERATED CODE *** 9# 10# ---------------------------------------------------------------------------- 11# 12# This file is automatically generated by Magic Modules and manual 13# changes will be clobbered when the file is regenerated. 14# 15# Please read more about how to change this file at 16# https://www.github.com/GoogleCloudPlatform/magic-modules 17# 18# ---------------------------------------------------------------------------- 19 20from __future__ import absolute_import, division, print_function 21 22__metaclass__ = type 23 24################################################################################ 25# Documentation 26################################################################################ 27 28ANSIBLE_METADATA = {'metadata_version': '1.1', 'status': ["preview"], 'supported_by': 'community'} 29 30DOCUMENTATION = ''' 31--- 32module: gcp_compute_backend_service 33description: 34- A Backend Service defines a group of virtual machines that will serve traffic for 35 load balancing. This resource is a global backend service, appropriate for external 36 load balancing or self-managed internal load balancing. 37- For managed internal load balancing, use a regional backend service instead. 38- Currently self-managed internal load balancing is only available in beta. 39short_description: Creates a GCP BackendService 40version_added: 2.6 41author: Google Inc. (@googlecloudplatform) 42requirements: 43- python >= 2.6 44- requests >= 2.18.4 45- google-auth >= 1.3.0 46options: 47 state: 48 description: 49 - Whether the given object should exist in GCP 50 choices: 51 - present 52 - absent 53 default: present 54 type: str 55 affinity_cookie_ttl_sec: 56 description: 57 - Lifetime of cookies in seconds if session_affinity is GENERATED_COOKIE. If set 58 to 0, the cookie is non-persistent and lasts only until the end of the browser 59 session (or equivalent). The maximum allowed value for TTL is one day. 60 - When the load balancing scheme is INTERNAL, this field is not used. 61 required: false 62 type: int 63 backends: 64 description: 65 - The set of backends that serve this BackendService. 66 required: false 67 type: list 68 suboptions: 69 balancing_mode: 70 description: 71 - Specifies the balancing mode for this backend. 72 - For global HTTP(S) or TCP/SSL load balancing, the default is UTILIZATION. 73 Valid values are UTILIZATION, RATE (for HTTP(S)) and CONNECTION (for TCP/SSL). 74 - 'Some valid choices include: "UTILIZATION", "RATE", "CONNECTION"' 75 required: false 76 default: UTILIZATION 77 type: str 78 capacity_scaler: 79 description: 80 - A multiplier applied to the group's maximum servicing capacity (based on 81 UTILIZATION, RATE or CONNECTION). 82 - Default value is 1, which means the group will serve up to 100% of its configured 83 capacity (depending on balancingMode). A setting of 0 means the group is 84 completely drained, offering 0% of its available Capacity. Valid range is 85 [0.0,1.0]. 86 required: false 87 default: '1.0' 88 type: str 89 description: 90 description: 91 - An optional description of this resource. 92 - Provide this property when you create the resource. 93 required: false 94 type: str 95 group: 96 description: 97 - The fully-qualified URL of an Instance Group or Network Endpoint Group resource. 98 In case of instance group this defines the list of instances that serve 99 traffic. Member virtual machine instances from each instance group must 100 live in the same zone as the instance group itself. No two backends in a 101 backend service are allowed to use same Instance Group resource. 102 - For Network Endpoint Groups this defines list of endpoints. All endpoints 103 of Network Endpoint Group must be hosted on instances located in the same 104 zone as the Network Endpoint Group. 105 - Backend service can not contain mix of Instance Group and Network Endpoint 106 Group backends. 107 - Note that you must specify an Instance Group or Network Endpoint Group resource 108 using the fully-qualified URL, rather than a partial URL. 109 required: false 110 type: str 111 max_connections: 112 description: 113 - The max number of simultaneous connections for the group. Can be used with 114 either CONNECTION or UTILIZATION balancing modes. 115 - For CONNECTION mode, either maxConnections or one of maxConnectionsPerInstance 116 or maxConnectionsPerEndpoint, as appropriate for group type, must be set. 117 required: false 118 type: int 119 max_connections_per_instance: 120 description: 121 - The max number of simultaneous connections that a single backend instance 122 can handle. This is used to calculate the capacity of the group. Can be 123 used in either CONNECTION or UTILIZATION balancing modes. 124 - For CONNECTION mode, either maxConnections or maxConnectionsPerInstance 125 must be set. 126 required: false 127 type: int 128 max_connections_per_endpoint: 129 description: 130 - The max number of simultaneous connections that a single backend network 131 endpoint can handle. This is used to calculate the capacity of the group. 132 Can be used in either CONNECTION or UTILIZATION balancing modes. 133 - For CONNECTION mode, either maxConnections or maxConnectionsPerEndpoint 134 must be set. 135 required: false 136 type: int 137 version_added: 2.9 138 max_rate: 139 description: 140 - The max requests per second (RPS) of the group. 141 - Can be used with either RATE or UTILIZATION balancing modes, but required 142 if RATE mode. For RATE mode, either maxRate or one of maxRatePerInstance 143 or maxRatePerEndpoint, as appropriate for group type, must be set. 144 required: false 145 type: int 146 max_rate_per_instance: 147 description: 148 - The max requests per second (RPS) that a single backend instance can handle. 149 This is used to calculate the capacity of the group. Can be used in either 150 balancing mode. For RATE mode, either maxRate or maxRatePerInstance must 151 be set. 152 required: false 153 type: str 154 max_rate_per_endpoint: 155 description: 156 - The max requests per second (RPS) that a single backend network endpoint 157 can handle. This is used to calculate the capacity of the group. Can be 158 used in either balancing mode. For RATE mode, either maxRate or maxRatePerEndpoint 159 must be set. 160 required: false 161 type: str 162 version_added: 2.9 163 max_utilization: 164 description: 165 - Used when balancingMode is UTILIZATION. This ratio defines the CPU utilization 166 target for the group. The default is 0.8. Valid range is [0.0, 1.0]. 167 required: false 168 default: '0.8' 169 type: str 170 cdn_policy: 171 description: 172 - Cloud CDN configuration for this BackendService. 173 required: false 174 type: dict 175 suboptions: 176 cache_key_policy: 177 description: 178 - The CacheKeyPolicy for this CdnPolicy. 179 required: false 180 type: dict 181 suboptions: 182 include_host: 183 description: 184 - If true requests to different hosts will be cached separately. 185 required: false 186 type: bool 187 include_protocol: 188 description: 189 - If true, http and https requests will be cached separately. 190 required: false 191 type: bool 192 include_query_string: 193 description: 194 - If true, include query string parameters in the cache key according 195 to query_string_whitelist and query_string_blacklist. If neither is 196 set, the entire query string will be included. 197 - If false, the query string will be excluded from the cache key entirely. 198 required: false 199 type: bool 200 query_string_blacklist: 201 description: 202 - Names of query string parameters to exclude in cache keys. 203 - All other parameters will be included. Either specify query_string_whitelist 204 or query_string_blacklist, not both. 205 - "'&' and '=' will be percent encoded and not treated as delimiters." 206 required: false 207 type: list 208 query_string_whitelist: 209 description: 210 - Names of query string parameters to include in cache keys. 211 - All other parameters will be excluded. Either specify query_string_whitelist 212 or query_string_blacklist, not both. 213 - "'&' and '=' will be percent encoded and not treated as delimiters." 214 required: false 215 type: list 216 signed_url_cache_max_age_sec: 217 description: 218 - Maximum number of seconds the response to a signed URL request will be considered 219 fresh, defaults to 1hr (3600s). After this time period, the response will 220 be revalidated before being served. 221 - 'When serving responses to signed URL requests, Cloud CDN will internally 222 behave as though all responses from this backend had a "Cache-Control: public, 223 max-age=[TTL]" header, regardless of any existing Cache-Control header. 224 The actual headers served in responses will not be altered.' 225 required: false 226 default: '3600' 227 type: int 228 version_added: 2.8 229 connection_draining: 230 description: 231 - Settings for connection draining . 232 required: false 233 type: dict 234 suboptions: 235 draining_timeout_sec: 236 description: 237 - Time for which instance will be drained (not accept new connections, but 238 still work to finish started). 239 required: false 240 default: '300' 241 type: int 242 description: 243 description: 244 - An optional description of this resource. 245 required: false 246 type: str 247 enable_cdn: 248 description: 249 - If true, enable Cloud CDN for this BackendService. 250 required: false 251 type: bool 252 health_checks: 253 description: 254 - The set of URLs to the HttpHealthCheck or HttpsHealthCheck resource for health 255 checking this BackendService. Currently at most one health check can be specified, 256 and a health check is required. 257 - For internal load balancing, a URL to a HealthCheck resource must be specified 258 instead. 259 required: true 260 type: list 261 iap: 262 description: 263 - Settings for enabling Cloud Identity Aware Proxy. 264 required: false 265 type: dict 266 version_added: 2.7 267 suboptions: 268 enabled: 269 description: 270 - Enables IAP. 271 required: false 272 type: bool 273 oauth2_client_id: 274 description: 275 - OAuth2 Client ID for IAP . 276 required: true 277 type: str 278 oauth2_client_secret: 279 description: 280 - OAuth2 Client Secret for IAP . 281 required: true 282 type: str 283 load_balancing_scheme: 284 description: 285 - Indicates whether the backend service will be used with internal or external 286 load balancing. A backend service created for one type of load balancing cannot 287 be used with the other. Must be `EXTERNAL` or `INTERNAL_SELF_MANAGED` for a 288 global backend service. Defaults to `EXTERNAL`. 289 - 'Some valid choices include: "EXTERNAL", "INTERNAL_SELF_MANAGED"' 290 required: false 291 default: EXTERNAL 292 type: str 293 version_added: 2.7 294 name: 295 description: 296 - Name of the resource. Provided by the client when the resource is created. The 297 name must be 1-63 characters long, and comply with RFC1035. Specifically, the 298 name must be 1-63 characters long and match the regular expression `[a-z]([-a-z0-9]*[a-z0-9])?` 299 which means the first character must be a lowercase letter, and all following 300 characters must be a dash, lowercase letter, or digit, except the last character, 301 which cannot be a dash. 302 required: true 303 type: str 304 port_name: 305 description: 306 - Name of backend port. The same name should appear in the instance groups referenced 307 by this service. Required when the load balancing scheme is EXTERNAL. 308 required: false 309 type: str 310 protocol: 311 description: 312 - The protocol this BackendService uses to communicate with backends. 313 - 'Possible values are HTTP, HTTPS, HTTP2, TCP, and SSL. The default is HTTP. 314 **NOTE**: HTTP2 is only valid for beta HTTP/2 load balancer types and may result 315 in errors if used with the GA API.' 316 - 'Some valid choices include: "HTTP", "HTTPS", "HTTP2", "TCP", "SSL"' 317 required: false 318 type: str 319 security_policy: 320 description: 321 - The security policy associated with this backend service. 322 required: false 323 type: str 324 version_added: 2.8 325 session_affinity: 326 description: 327 - Type of session affinity to use. The default is NONE. 328 - When the load balancing scheme is EXTERNAL, can be NONE, CLIENT_IP, or GENERATED_COOKIE. 329 - When the protocol is UDP, this field is not used. 330 - 'Some valid choices include: "NONE", "CLIENT_IP", "GENERATED_COOKIE"' 331 required: false 332 type: str 333 timeout_sec: 334 description: 335 - How many seconds to wait for the backend before considering it a failed request. 336 Default is 30 seconds. Valid range is [1, 86400]. 337 required: false 338 type: int 339 aliases: 340 - timeout_seconds 341extends_documentation_fragment: gcp 342notes: 343- 'API Reference: U(https://cloud.google.com/compute/docs/reference/v1/backendServices)' 344- 'Official Documentation: U(https://cloud.google.com/compute/docs/load-balancing/http/backend-service)' 345''' 346 347EXAMPLES = ''' 348- name: create a instance group 349 gcp_compute_instance_group: 350 name: instancegroup-backendservice 351 zone: us-central1-a 352 project: "{{ gcp_project }}" 353 auth_kind: "{{ gcp_cred_kind }}" 354 service_account_file: "{{ gcp_cred_file }}" 355 state: present 356 register: instancegroup 357 358- name: create a HTTP health check 359 gcp_compute_http_health_check: 360 name: httphealthcheck-backendservice 361 healthy_threshold: 10 362 port: 8080 363 timeout_sec: 2 364 unhealthy_threshold: 5 365 project: "{{ gcp_project }}" 366 auth_kind: "{{ gcp_cred_kind }}" 367 service_account_file: "{{ gcp_cred_file }}" 368 state: present 369 register: healthcheck 370 371- name: create a backend service 372 gcp_compute_backend_service: 373 name: test_object 374 backends: 375 - group: "{{ instancegroup.selfLink }}" 376 health_checks: 377 - "{{ healthcheck.selfLink }}" 378 enable_cdn: 'true' 379 project: test_project 380 auth_kind: serviceaccount 381 service_account_file: "/tmp/auth.pem" 382 state: present 383''' 384 385RETURN = ''' 386affinityCookieTtlSec: 387 description: 388 - Lifetime of cookies in seconds if session_affinity is GENERATED_COOKIE. If set 389 to 0, the cookie is non-persistent and lasts only until the end of the browser 390 session (or equivalent). The maximum allowed value for TTL is one day. 391 - When the load balancing scheme is INTERNAL, this field is not used. 392 returned: success 393 type: int 394backends: 395 description: 396 - The set of backends that serve this BackendService. 397 returned: success 398 type: complex 399 contains: 400 balancingMode: 401 description: 402 - Specifies the balancing mode for this backend. 403 - For global HTTP(S) or TCP/SSL load balancing, the default is UTILIZATION. 404 Valid values are UTILIZATION, RATE (for HTTP(S)) and CONNECTION (for TCP/SSL). 405 returned: success 406 type: str 407 capacityScaler: 408 description: 409 - A multiplier applied to the group's maximum servicing capacity (based on UTILIZATION, 410 RATE or CONNECTION). 411 - Default value is 1, which means the group will serve up to 100% of its configured 412 capacity (depending on balancingMode). A setting of 0 means the group is completely 413 drained, offering 0% of its available Capacity. Valid range is [0.0,1.0]. 414 returned: success 415 type: str 416 description: 417 description: 418 - An optional description of this resource. 419 - Provide this property when you create the resource. 420 returned: success 421 type: str 422 group: 423 description: 424 - The fully-qualified URL of an Instance Group or Network Endpoint Group resource. 425 In case of instance group this defines the list of instances that serve traffic. 426 Member virtual machine instances from each instance group must live in the 427 same zone as the instance group itself. No two backends in a backend service 428 are allowed to use same Instance Group resource. 429 - For Network Endpoint Groups this defines list of endpoints. All endpoints 430 of Network Endpoint Group must be hosted on instances located in the same 431 zone as the Network Endpoint Group. 432 - Backend service can not contain mix of Instance Group and Network Endpoint 433 Group backends. 434 - Note that you must specify an Instance Group or Network Endpoint Group resource 435 using the fully-qualified URL, rather than a partial URL. 436 returned: success 437 type: str 438 maxConnections: 439 description: 440 - The max number of simultaneous connections for the group. Can be used with 441 either CONNECTION or UTILIZATION balancing modes. 442 - For CONNECTION mode, either maxConnections or one of maxConnectionsPerInstance 443 or maxConnectionsPerEndpoint, as appropriate for group type, must be set. 444 returned: success 445 type: int 446 maxConnectionsPerInstance: 447 description: 448 - The max number of simultaneous connections that a single backend instance 449 can handle. This is used to calculate the capacity of the group. Can be used 450 in either CONNECTION or UTILIZATION balancing modes. 451 - For CONNECTION mode, either maxConnections or maxConnectionsPerInstance must 452 be set. 453 returned: success 454 type: int 455 maxConnectionsPerEndpoint: 456 description: 457 - The max number of simultaneous connections that a single backend network endpoint 458 can handle. This is used to calculate the capacity of the group. Can be used 459 in either CONNECTION or UTILIZATION balancing modes. 460 - For CONNECTION mode, either maxConnections or maxConnectionsPerEndpoint must 461 be set. 462 returned: success 463 type: int 464 maxRate: 465 description: 466 - The max requests per second (RPS) of the group. 467 - Can be used with either RATE or UTILIZATION balancing modes, but required 468 if RATE mode. For RATE mode, either maxRate or one of maxRatePerInstance or 469 maxRatePerEndpoint, as appropriate for group type, must be set. 470 returned: success 471 type: int 472 maxRatePerInstance: 473 description: 474 - The max requests per second (RPS) that a single backend instance can handle. 475 This is used to calculate the capacity of the group. Can be used in either 476 balancing mode. For RATE mode, either maxRate or maxRatePerInstance must be 477 set. 478 returned: success 479 type: str 480 maxRatePerEndpoint: 481 description: 482 - The max requests per second (RPS) that a single backend network endpoint can 483 handle. This is used to calculate the capacity of the group. Can be used in 484 either balancing mode. For RATE mode, either maxRate or maxRatePerEndpoint 485 must be set. 486 returned: success 487 type: str 488 maxUtilization: 489 description: 490 - Used when balancingMode is UTILIZATION. This ratio defines the CPU utilization 491 target for the group. The default is 0.8. Valid range is [0.0, 1.0]. 492 returned: success 493 type: str 494cdnPolicy: 495 description: 496 - Cloud CDN configuration for this BackendService. 497 returned: success 498 type: complex 499 contains: 500 cacheKeyPolicy: 501 description: 502 - The CacheKeyPolicy for this CdnPolicy. 503 returned: success 504 type: complex 505 contains: 506 includeHost: 507 description: 508 - If true requests to different hosts will be cached separately. 509 returned: success 510 type: bool 511 includeProtocol: 512 description: 513 - If true, http and https requests will be cached separately. 514 returned: success 515 type: bool 516 includeQueryString: 517 description: 518 - If true, include query string parameters in the cache key according to 519 query_string_whitelist and query_string_blacklist. If neither is set, 520 the entire query string will be included. 521 - If false, the query string will be excluded from the cache key entirely. 522 returned: success 523 type: bool 524 queryStringBlacklist: 525 description: 526 - Names of query string parameters to exclude in cache keys. 527 - All other parameters will be included. Either specify query_string_whitelist 528 or query_string_blacklist, not both. 529 - "'&' and '=' will be percent encoded and not treated as delimiters." 530 returned: success 531 type: list 532 queryStringWhitelist: 533 description: 534 - Names of query string parameters to include in cache keys. 535 - All other parameters will be excluded. Either specify query_string_whitelist 536 or query_string_blacklist, not both. 537 - "'&' and '=' will be percent encoded and not treated as delimiters." 538 returned: success 539 type: list 540 signedUrlCacheMaxAgeSec: 541 description: 542 - Maximum number of seconds the response to a signed URL request will be considered 543 fresh, defaults to 1hr (3600s). After this time period, the response will 544 be revalidated before being served. 545 - 'When serving responses to signed URL requests, Cloud CDN will internally 546 behave as though all responses from this backend had a "Cache-Control: public, 547 max-age=[TTL]" header, regardless of any existing Cache-Control header. The 548 actual headers served in responses will not be altered.' 549 returned: success 550 type: int 551connectionDraining: 552 description: 553 - Settings for connection draining . 554 returned: success 555 type: complex 556 contains: 557 drainingTimeoutSec: 558 description: 559 - Time for which instance will be drained (not accept new connections, but still 560 work to finish started). 561 returned: success 562 type: int 563creationTimestamp: 564 description: 565 - Creation timestamp in RFC3339 text format. 566 returned: success 567 type: str 568fingerprint: 569 description: 570 - Fingerprint of this resource. A hash of the contents stored in this object. This 571 field is used in optimistic locking. 572 returned: success 573 type: str 574description: 575 description: 576 - An optional description of this resource. 577 returned: success 578 type: str 579enableCDN: 580 description: 581 - If true, enable Cloud CDN for this BackendService. 582 returned: success 583 type: bool 584healthChecks: 585 description: 586 - The set of URLs to the HttpHealthCheck or HttpsHealthCheck resource for health 587 checking this BackendService. Currently at most one health check can be specified, 588 and a health check is required. 589 - For internal load balancing, a URL to a HealthCheck resource must be specified 590 instead. 591 returned: success 592 type: list 593id: 594 description: 595 - The unique identifier for the resource. 596 returned: success 597 type: int 598iap: 599 description: 600 - Settings for enabling Cloud Identity Aware Proxy. 601 returned: success 602 type: complex 603 contains: 604 enabled: 605 description: 606 - Enables IAP. 607 returned: success 608 type: bool 609 oauth2ClientId: 610 description: 611 - OAuth2 Client ID for IAP . 612 returned: success 613 type: str 614 oauth2ClientSecret: 615 description: 616 - OAuth2 Client Secret for IAP . 617 returned: success 618 type: str 619 oauth2ClientSecretSha256: 620 description: 621 - OAuth2 Client Secret SHA-256 for IAP . 622 returned: success 623 type: str 624loadBalancingScheme: 625 description: 626 - Indicates whether the backend service will be used with internal or external load 627 balancing. A backend service created for one type of load balancing cannot be 628 used with the other. Must be `EXTERNAL` or `INTERNAL_SELF_MANAGED` for a global 629 backend service. Defaults to `EXTERNAL`. 630 returned: success 631 type: str 632name: 633 description: 634 - Name of the resource. Provided by the client when the resource is created. The 635 name must be 1-63 characters long, and comply with RFC1035. Specifically, the 636 name must be 1-63 characters long and match the regular expression `[a-z]([-a-z0-9]*[a-z0-9])?` 637 which means the first character must be a lowercase letter, and all following 638 characters must be a dash, lowercase letter, or digit, except the last character, 639 which cannot be a dash. 640 returned: success 641 type: str 642portName: 643 description: 644 - Name of backend port. The same name should appear in the instance groups referenced 645 by this service. Required when the load balancing scheme is EXTERNAL. 646 returned: success 647 type: str 648protocol: 649 description: 650 - The protocol this BackendService uses to communicate with backends. 651 - 'Possible values are HTTP, HTTPS, HTTP2, TCP, and SSL. The default is HTTP. **NOTE**: 652 HTTP2 is only valid for beta HTTP/2 load balancer types and may result in errors 653 if used with the GA API.' 654 returned: success 655 type: str 656securityPolicy: 657 description: 658 - The security policy associated with this backend service. 659 returned: success 660 type: str 661sessionAffinity: 662 description: 663 - Type of session affinity to use. The default is NONE. 664 - When the load balancing scheme is EXTERNAL, can be NONE, CLIENT_IP, or GENERATED_COOKIE. 665 - When the protocol is UDP, this field is not used. 666 returned: success 667 type: str 668timeoutSec: 669 description: 670 - How many seconds to wait for the backend before considering it a failed request. 671 Default is 30 seconds. Valid range is [1, 86400]. 672 returned: success 673 type: int 674''' 675 676################################################################################ 677# Imports 678################################################################################ 679 680from ansible.module_utils.gcp_utils import navigate_hash, GcpSession, GcpModule, GcpRequest, remove_nones_from_dict, replace_resource_dict 681import json 682import time 683 684################################################################################ 685# Main 686################################################################################ 687 688 689def main(): 690 """Main function""" 691 692 module = GcpModule( 693 argument_spec=dict( 694 state=dict(default='present', choices=['present', 'absent'], type='str'), 695 affinity_cookie_ttl_sec=dict(type='int'), 696 backends=dict( 697 type='list', 698 elements='dict', 699 options=dict( 700 balancing_mode=dict(default='UTILIZATION', type='str'), 701 capacity_scaler=dict(default=1.0, type='str'), 702 description=dict(type='str'), 703 group=dict(type='str'), 704 max_connections=dict(type='int'), 705 max_connections_per_instance=dict(type='int'), 706 max_connections_per_endpoint=dict(type='int'), 707 max_rate=dict(type='int'), 708 max_rate_per_instance=dict(type='str'), 709 max_rate_per_endpoint=dict(type='str'), 710 max_utilization=dict(default=0.8, type='str'), 711 ), 712 ), 713 cdn_policy=dict( 714 type='dict', 715 options=dict( 716 cache_key_policy=dict( 717 type='dict', 718 options=dict( 719 include_host=dict(type='bool'), 720 include_protocol=dict(type='bool'), 721 include_query_string=dict(type='bool'), 722 query_string_blacklist=dict(type='list', elements='str'), 723 query_string_whitelist=dict(type='list', elements='str'), 724 ), 725 ), 726 signed_url_cache_max_age_sec=dict(default=3600, type='int'), 727 ), 728 ), 729 connection_draining=dict(type='dict', options=dict(draining_timeout_sec=dict(default=300, type='int'))), 730 description=dict(type='str'), 731 enable_cdn=dict(type='bool'), 732 health_checks=dict(required=True, type='list', elements='str'), 733 iap=dict( 734 type='dict', 735 options=dict( 736 enabled=dict(type='bool'), 737 oauth2_client_id=dict(required=True, type='str'), 738 oauth2_client_secret=dict(required=True, type='str', no_log=True), 739 ), 740 ), 741 load_balancing_scheme=dict(default='EXTERNAL', type='str'), 742 name=dict(required=True, type='str'), 743 port_name=dict(type='str'), 744 protocol=dict(type='str'), 745 security_policy=dict(type='str'), 746 session_affinity=dict(type='str'), 747 timeout_sec=dict(type='int', aliases=['timeout_seconds']), 748 ) 749 ) 750 751 if not module.params['scopes']: 752 module.params['scopes'] = ['https://www.googleapis.com/auth/compute'] 753 754 state = module.params['state'] 755 kind = 'compute#backendService' 756 757 fetch = fetch_resource(module, self_link(module), kind) 758 changed = False 759 760 if fetch: 761 if state == 'present': 762 if is_different(module, fetch): 763 update(module, self_link(module), kind, fetch) 764 fetch = fetch_resource(module, self_link(module), kind) 765 changed = True 766 else: 767 delete(module, self_link(module), kind) 768 fetch = {} 769 changed = True 770 else: 771 if state == 'present': 772 fetch = create(module, collection(module), kind) 773 changed = True 774 else: 775 fetch = {} 776 777 fetch.update({'changed': changed}) 778 779 module.exit_json(**fetch) 780 781 782def create(module, link, kind): 783 auth = GcpSession(module, 'compute') 784 return wait_for_operation(module, auth.post(link, resource_to_request(module))) 785 786 787def update(module, link, kind, fetch): 788 update_fields(module, resource_to_request(module), response_to_hash(module, fetch)) 789 auth = GcpSession(module, 'compute') 790 return wait_for_operation(module, auth.put(link, resource_to_request(module))) 791 792 793def update_fields(module, request, response): 794 if response.get('securityPolicy') != request.get('securityPolicy'): 795 security_policy_update(module, request, response) 796 797 798def security_policy_update(module, request, response): 799 auth = GcpSession(module, 'compute') 800 auth.post( 801 ''.join(["https://www.googleapis.com/compute/v1/", "projects/{project}/global/backendServices/{name}/setSecurityPolicy"]).format(**module.params), 802 {u'securityPolicy': module.params.get('security_policy')}, 803 ) 804 805 806def delete(module, link, kind): 807 auth = GcpSession(module, 'compute') 808 return wait_for_operation(module, auth.delete(link)) 809 810 811def resource_to_request(module): 812 request = { 813 u'kind': 'compute#backendService', 814 u'affinityCookieTtlSec': module.params.get('affinity_cookie_ttl_sec'), 815 u'backends': BackendServiceBackendsArray(module.params.get('backends', []), module).to_request(), 816 u'cdnPolicy': BackendServiceCdnpolicy(module.params.get('cdn_policy', {}), module).to_request(), 817 u'connectionDraining': BackendServiceConnectiondraining(module.params.get('connection_draining', {}), module).to_request(), 818 u'description': module.params.get('description'), 819 u'enableCDN': module.params.get('enable_cdn'), 820 u'healthChecks': module.params.get('health_checks'), 821 u'iap': BackendServiceIap(module.params.get('iap', {}), module).to_request(), 822 u'loadBalancingScheme': module.params.get('load_balancing_scheme'), 823 u'name': module.params.get('name'), 824 u'portName': module.params.get('port_name'), 825 u'protocol': module.params.get('protocol'), 826 u'securityPolicy': module.params.get('security_policy'), 827 u'sessionAffinity': module.params.get('session_affinity'), 828 u'timeoutSec': module.params.get('timeout_sec'), 829 } 830 return_vals = {} 831 for k, v in request.items(): 832 if v or v is False: 833 return_vals[k] = v 834 835 return return_vals 836 837 838def fetch_resource(module, link, kind, allow_not_found=True): 839 auth = GcpSession(module, 'compute') 840 return return_if_object(module, auth.get(link), kind, allow_not_found) 841 842 843def self_link(module): 844 return "https://www.googleapis.com/compute/v1/projects/{project}/global/backendServices/{name}".format(**module.params) 845 846 847def collection(module): 848 return "https://www.googleapis.com/compute/v1/projects/{project}/global/backendServices".format(**module.params) 849 850 851def return_if_object(module, response, kind, allow_not_found=False): 852 # If not found, return nothing. 853 if allow_not_found and response.status_code == 404: 854 return None 855 856 # If no content, return nothing. 857 if response.status_code == 204: 858 return None 859 860 try: 861 module.raise_for_status(response) 862 result = response.json() 863 except getattr(json.decoder, 'JSONDecodeError', ValueError): 864 module.fail_json(msg="Invalid JSON response with error: %s" % response.text) 865 866 if navigate_hash(result, ['error', 'errors']): 867 module.fail_json(msg=navigate_hash(result, ['error', 'errors'])) 868 869 return result 870 871 872def is_different(module, response): 873 request = resource_to_request(module) 874 response = response_to_hash(module, response) 875 876 # Remove all output-only from response. 877 response_vals = {} 878 for k, v in response.items(): 879 if k in request: 880 response_vals[k] = v 881 882 request_vals = {} 883 for k, v in request.items(): 884 if k in response: 885 request_vals[k] = v 886 887 return GcpRequest(request_vals) != GcpRequest(response_vals) 888 889 890# Remove unnecessary properties from the response. 891# This is for doing comparisons with Ansible's current parameters. 892def response_to_hash(module, response): 893 return { 894 u'affinityCookieTtlSec': response.get(u'affinityCookieTtlSec'), 895 u'backends': BackendServiceBackendsArray(response.get(u'backends', []), module).from_response(), 896 u'cdnPolicy': BackendServiceCdnpolicy(response.get(u'cdnPolicy', {}), module).from_response(), 897 u'connectionDraining': BackendServiceConnectiondraining(response.get(u'connectionDraining', {}), module).from_response(), 898 u'creationTimestamp': response.get(u'creationTimestamp'), 899 u'fingerprint': response.get(u'fingerprint'), 900 u'description': response.get(u'description'), 901 u'enableCDN': response.get(u'enableCDN'), 902 u'healthChecks': response.get(u'healthChecks'), 903 u'id': response.get(u'id'), 904 u'iap': BackendServiceIap(response.get(u'iap', {}), module).from_response(), 905 u'loadBalancingScheme': module.params.get('load_balancing_scheme'), 906 u'name': module.params.get('name'), 907 u'portName': response.get(u'portName'), 908 u'protocol': response.get(u'protocol'), 909 u'securityPolicy': response.get(u'securityPolicy'), 910 u'sessionAffinity': response.get(u'sessionAffinity'), 911 u'timeoutSec': response.get(u'timeoutSec'), 912 } 913 914 915def async_op_url(module, extra_data=None): 916 if extra_data is None: 917 extra_data = {} 918 url = "https://www.googleapis.com/compute/v1/projects/{project}/global/operations/{op_id}" 919 combined = extra_data.copy() 920 combined.update(module.params) 921 return url.format(**combined) 922 923 924def wait_for_operation(module, response): 925 op_result = return_if_object(module, response, 'compute#operation') 926 if op_result is None: 927 return {} 928 status = navigate_hash(op_result, ['status']) 929 wait_done = wait_for_completion(status, op_result, module) 930 return fetch_resource(module, navigate_hash(wait_done, ['targetLink']), 'compute#backendService') 931 932 933def wait_for_completion(status, op_result, module): 934 op_id = navigate_hash(op_result, ['name']) 935 op_uri = async_op_url(module, {'op_id': op_id}) 936 while status != 'DONE': 937 raise_if_errors(op_result, ['error', 'errors'], module) 938 time.sleep(1.0) 939 op_result = fetch_resource(module, op_uri, 'compute#operation', False) 940 status = navigate_hash(op_result, ['status']) 941 return op_result 942 943 944def raise_if_errors(response, err_path, module): 945 errors = navigate_hash(response, err_path) 946 if errors is not None: 947 module.fail_json(msg=errors) 948 949 950class BackendServiceBackendsArray(object): 951 def __init__(self, request, module): 952 self.module = module 953 if request: 954 self.request = request 955 else: 956 self.request = [] 957 958 def to_request(self): 959 items = [] 960 for item in self.request: 961 items.append(self._request_for_item(item)) 962 return items 963 964 def from_response(self): 965 items = [] 966 for item in self.request: 967 items.append(self._response_from_item(item)) 968 return items 969 970 def _request_for_item(self, item): 971 return remove_nones_from_dict( 972 { 973 u'balancingMode': item.get('balancing_mode'), 974 u'capacityScaler': item.get('capacity_scaler'), 975 u'description': item.get('description'), 976 u'group': item.get('group'), 977 u'maxConnections': item.get('max_connections'), 978 u'maxConnectionsPerInstance': item.get('max_connections_per_instance'), 979 u'maxConnectionsPerEndpoint': item.get('max_connections_per_endpoint'), 980 u'maxRate': item.get('max_rate'), 981 u'maxRatePerInstance': item.get('max_rate_per_instance'), 982 u'maxRatePerEndpoint': item.get('max_rate_per_endpoint'), 983 u'maxUtilization': item.get('max_utilization'), 984 } 985 ) 986 987 def _response_from_item(self, item): 988 return remove_nones_from_dict( 989 { 990 u'balancingMode': item.get(u'balancingMode'), 991 u'capacityScaler': item.get(u'capacityScaler'), 992 u'description': item.get(u'description'), 993 u'group': item.get(u'group'), 994 u'maxConnections': item.get(u'maxConnections'), 995 u'maxConnectionsPerInstance': item.get(u'maxConnectionsPerInstance'), 996 u'maxConnectionsPerEndpoint': item.get(u'maxConnectionsPerEndpoint'), 997 u'maxRate': item.get(u'maxRate'), 998 u'maxRatePerInstance': item.get(u'maxRatePerInstance'), 999 u'maxRatePerEndpoint': item.get(u'maxRatePerEndpoint'), 1000 u'maxUtilization': item.get(u'maxUtilization'), 1001 } 1002 ) 1003 1004 1005class BackendServiceCdnpolicy(object): 1006 def __init__(self, request, module): 1007 self.module = module 1008 if request: 1009 self.request = request 1010 else: 1011 self.request = {} 1012 1013 def to_request(self): 1014 return remove_nones_from_dict( 1015 { 1016 u'cacheKeyPolicy': BackendServiceCachekeypolicy(self.request.get('cache_key_policy', {}), self.module).to_request(), 1017 u'signedUrlCacheMaxAgeSec': self.request.get('signed_url_cache_max_age_sec'), 1018 } 1019 ) 1020 1021 def from_response(self): 1022 return remove_nones_from_dict( 1023 { 1024 u'cacheKeyPolicy': BackendServiceCachekeypolicy(self.request.get(u'cacheKeyPolicy', {}), self.module).from_response(), 1025 u'signedUrlCacheMaxAgeSec': self.request.get(u'signedUrlCacheMaxAgeSec'), 1026 } 1027 ) 1028 1029 1030class BackendServiceCachekeypolicy(object): 1031 def __init__(self, request, module): 1032 self.module = module 1033 if request: 1034 self.request = request 1035 else: 1036 self.request = {} 1037 1038 def to_request(self): 1039 return remove_nones_from_dict( 1040 { 1041 u'includeHost': self.request.get('include_host'), 1042 u'includeProtocol': self.request.get('include_protocol'), 1043 u'includeQueryString': self.request.get('include_query_string'), 1044 u'queryStringBlacklist': self.request.get('query_string_blacklist'), 1045 u'queryStringWhitelist': self.request.get('query_string_whitelist'), 1046 } 1047 ) 1048 1049 def from_response(self): 1050 return remove_nones_from_dict( 1051 { 1052 u'includeHost': self.request.get(u'includeHost'), 1053 u'includeProtocol': self.request.get(u'includeProtocol'), 1054 u'includeQueryString': self.request.get(u'includeQueryString'), 1055 u'queryStringBlacklist': self.request.get(u'queryStringBlacklist'), 1056 u'queryStringWhitelist': self.request.get(u'queryStringWhitelist'), 1057 } 1058 ) 1059 1060 1061class BackendServiceConnectiondraining(object): 1062 def __init__(self, request, module): 1063 self.module = module 1064 if request: 1065 self.request = request 1066 else: 1067 self.request = {} 1068 1069 def to_request(self): 1070 return remove_nones_from_dict({u'drainingTimeoutSec': self.request.get('draining_timeout_sec')}) 1071 1072 def from_response(self): 1073 return remove_nones_from_dict({u'drainingTimeoutSec': self.request.get(u'drainingTimeoutSec')}) 1074 1075 1076class BackendServiceIap(object): 1077 def __init__(self, request, module): 1078 self.module = module 1079 if request: 1080 self.request = request 1081 else: 1082 self.request = {} 1083 1084 def to_request(self): 1085 return remove_nones_from_dict( 1086 { 1087 u'enabled': self.request.get('enabled'), 1088 u'oauth2ClientId': self.request.get('oauth2_client_id'), 1089 u'oauth2ClientSecret': self.request.get('oauth2_client_secret'), 1090 } 1091 ) 1092 1093 def from_response(self): 1094 return remove_nones_from_dict( 1095 { 1096 u'enabled': self.request.get(u'enabled'), 1097 u'oauth2ClientId': self.request.get(u'oauth2ClientId'), 1098 u'oauth2ClientSecret': self.request.get(u'oauth2ClientSecret'), 1099 } 1100 ) 1101 1102 1103if __name__ == '__main__': 1104 main() 1105