Class: Kitchen::Driver::Gce
- Inherits:
-
Base
- Object
- Base
- Kitchen::Driver::Gce
- Defined in:
- lib/kitchen/driver/gce.rb
Overview
Google Compute Engine driver for Test Kitchen
Constant Summary collapse
- SCOPE_ALIAS_MAP =
{ "bigquery" => "bigquery", "cloud-platform" => "cloud-platform", "compute-ro" => "compute.readonly", "compute-rw" => "compute", "datastore" => "datastore", "logging-write" => "logging.write", "monitoring" => "monitoring", "monitoring-write" => "monitoring.write", "service-control" => "servicecontrol", "service-management" => "service.management", "sql" => "sqlservice", "sql-admin" => "sqlservice.admin", "storage-full" => "devstorage.full_control", "storage-ro" => "devstorage.read_only", "storage-rw" => "devstorage.read_write", "taskqueue" => "taskqueue", "useraccounts-ro" => "cloud.useraccounts.readonly", "useraccounts-rw" => "cloud.useraccounts", "userinfo-email" => "userinfo.email", }.freeze
- DISK_NAME_REGEX =
/(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?)/
Instance Attribute Summary collapse
-
#state ⇒ Object
Returns the value of attribute state.
Instance Method Summary collapse
- #authorization ⇒ Object
- #auto_migrate? ⇒ Boolean
- #auto_restart? ⇒ Boolean
- #boot_disk_source_image ⇒ Object
- #check_api_call(&block) ⇒ Object
- #connection ⇒ Object
- #create(state) ⇒ Object
- #create_attached_disk(unique_disk_name, disk_config) ⇒ Object
- #create_disks(server_name) ⇒ Object
- #create_disks_config ⇒ Object
- #create_instance_object(server_name) ⇒ Object
- #create_local_disk(unique_disk_name, disk_config) ⇒ Object
- #delete_disk(unique_disk_name) ⇒ Object
- #destroy(state) ⇒ Object
- #disk_self_link(unique_disk_name) ⇒ Object
- #disk_type_url_for(type) ⇒ Object
- #env_user ⇒ Object
- #find_zone ⇒ Object
- #generate_server_name ⇒ Object
- #guest_accelerators ⇒ Object
- #image_exist?(image = image_name) ⇒ Boolean
- #image_name ⇒ Object
- #image_name_for_family(image_family) ⇒ Object
- #image_project ⇒ Object
- #image_url(image = image_name) ⇒ Object
- #instance_guest_accelerators ⇒ Object
- #instance_labels ⇒ Object
- #instance_metadata ⇒ Object
- #instance_network_interfaces ⇒ Object
- #instance_scheduling ⇒ Object
- #instance_service_accounts ⇒ Object
- #instance_tags ⇒ Object
- #interface_access_configs ⇒ Object
- #ip_address_for(server) ⇒ Object
- #machine_type_url ⇒ Object
- #metadata ⇒ Object
- #migrate_setting ⇒ Object
- #name ⇒ Object
- #network_ip ⇒ Object
- #network_project ⇒ Object
- #network_url ⇒ Object
- #new_disk_configuration_present? ⇒ Boolean
- #old_disk_configuration_present? ⇒ Boolean
- #operation_errors(operation_name) ⇒ Object
- #preemptible? ⇒ Boolean
- #private_ip_for(server) ⇒ Object
- #project ⇒ Object
- #public_ip_for(server) ⇒ Object
- #refresh_rate ⇒ Object
- #region ⇒ Object
- #region_for_zone ⇒ Object
- #server_exist?(server_name) ⇒ Boolean
- #server_instance(server_name) ⇒ Object
- #service_account_scope_url(scope) ⇒ Object
- #subnet_project ⇒ Object
- #subnet_url ⇒ Object
- #translate_scope_alias(scope_alias) ⇒ Object
- #update_windows_password(server_name) ⇒ Object
- #valid_disk_name?(disk_name) ⇒ Boolean
- #valid_disk_type?(disk_type) ⇒ Boolean
- #valid_machine_type? ⇒ Boolean
- #valid_network? ⇒ Boolean
- #valid_project? ⇒ Boolean
- #valid_region? ⇒ Boolean
- #valid_subnet? ⇒ Boolean
- #valid_zone? ⇒ Boolean
- #validate! ⇒ Object
- #wait_for_operation(operation) ⇒ Object
- #wait_for_server ⇒ Object
- #wait_for_status(requested_status, &block) ⇒ Object
- #wait_time ⇒ Object
- #winrm_transport? ⇒ Boolean
- #zone ⇒ Object
- #zone_operation(operation_name) ⇒ Object
- #zones_in_region ⇒ Object
Instance Attribute Details
#state ⇒ Object
Returns the value of attribute state.
31 32 33 |
# File 'lib/kitchen/driver/gce.rb', line 31 def state @state end |
Instance Method Details
#authorization ⇒ Object
255 256 257 258 259 260 261 262 |
# File 'lib/kitchen/driver/gce.rb', line 255 def @authorization ||= Google::Auth.get_application_default( [ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/compute", ] ) end |
#auto_migrate? ⇒ Boolean
648 649 650 |
# File 'lib/kitchen/driver/gce.rb', line 648 def auto_migrate? preemptible? ? false : config[:auto_migrate] end |
#auto_restart? ⇒ Boolean
652 653 654 |
# File 'lib/kitchen/driver/gce.rb', line 652 def auto_restart? preemptible? ? false : config[:auto_restart] end |
#boot_disk_source_image ⇒ Object
528 529 530 |
# File 'lib/kitchen/driver/gce.rb', line 528 def boot_disk_source_image @boot_disk_source ||= image_url end |
#check_api_call(&block) ⇒ Object
288 289 290 291 292 293 294 295 |
# File 'lib/kitchen/driver/gce.rb', line 288 def check_api_call(&block) yield rescue Google::Apis::ClientError => e debug("API error: #{e.}") false else true end |
#connection ⇒ Object
242 243 244 245 246 247 248 249 250 251 252 253 |
# File 'lib/kitchen/driver/gce.rb', line 242 def connection return @connection unless @connection.nil? @connection = Google::Apis::ComputeV1::ComputeService.new @connection. = @connection. = Google::Apis::ClientOptions.new.tap do |opts| opts.application_name = "GoogleChefTestKitchen" opts.application_version = Kitchen::Driver::GCE_VERSION end @connection end |
#create(state) ⇒ Object
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 |
# File 'lib/kitchen/driver/gce.rb', line 94 def create(state) @state = state return if state[:server_name] validate! server_name = generate_server_name create_disks_config info("Creating GCE instance <#{server_name}> in project #{project}, zone #{zone}...") operation = connection.insert_instance(project, zone, create_instance_object(server_name)) wait_for_operation(operation) server = server_instance(server_name) state[:server_name] = server_name state[:hostname] = ip_address_for(server) state[:zone] = zone info("Server <#{server_name}> created.") update_windows_password(server_name) info("Waiting for server <#{server_name}> to be ready...") wait_for_server info("GCE instance <#{server_name}> created and ready.") rescue => e error("Error encountered during server creation: #{e.class}: #{e.}") destroy(state) raise end |
#create_attached_disk(unique_disk_name, disk_config) ⇒ Object
490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 |
# File 'lib/kitchen/driver/gce.rb', line 490 def create_attached_disk(unique_disk_name, disk_config) disk = Google::Apis::ComputeV1::Disk.new disk.name = unique_disk_name disk.size_gb = disk_config[:disk_size] disk.type = disk_type_url_for(disk_config[:disk_type]) info("Creating a #{disk_config[:disk_size]} GB disk named #{unique_disk_name}...") wait_for_operation(connection.insert_disk(project, zone, disk)) info("Waiting for disk to be ready...") wait_for_status("READY") { connection.get_disk(project, zone, unique_disk_name) } info("Disk created successfully.") attached_disk = Google::Apis::ComputeV1::AttachedDisk.new attached_disk.source = disk_self_link(unique_disk_name) attached_disk.auto_delete = disk_config[:autodelete_disk] attached_disk end |
#create_disks(server_name) ⇒ Object
446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 |
# File 'lib/kitchen/driver/gce.rb', line 446 def create_disks(server_name) disks = [] config[:disks].each do |disk_name, disk_config| unique_disk_name = "#{server_name}-#{disk_name}" if disk_config[:boot] disk = create_local_disk(unique_disk_name, disk_config) disks.unshift(disk) elsif (disk_config[:disk_type] == "local-ssd") || disk_config[:custom_image] disk = create_local_disk(unique_disk_name, disk_config) disks.push(disk) else disk = create_attached_disk(unique_disk_name, disk_config) disks.push(disk) end end disks end |
#create_disks_config ⇒ Object
155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 |
# File 'lib/kitchen/driver/gce.rb', line 155 def create_disks_config # This can't be present in default_config because we couldn't # determine which disk configuration the user used otherwise disk_default_config = { autodelete_disk: true, disk_size: 10, disk_type: "pd-standard", } if old_disk_configuration_present? # If the old disk configuration is used, # we'll convert it to the new one config[:disks] = { disk1: { boot: true, autodelete_disk: config.fetch(:autodelete_disk, disk_default_config[:autodelete_disk]), disk_size: config.fetch(:disk_size, disk_default_config[:disk_size]), disk_type: config.fetch(:disk_type, disk_default_config[:disk_type]), }, } raise "Disk type #{config[:disks][:disk1][:disk_type]} is not valid" unless valid_disk_type?(config[:disks][:disk1][:disk_type]) elsif new_disk_configuration_present? # If the new disk configuration is present, ensure that for # every disk the needed configuration is set boot_disk_counter = 0 config[:disks].each do |disk_name, disk_config| # te&/ => te raise "Disk name invalid. Must match #{DISK_NAME_REGEX}." unless valid_disk_name?(disk_name) # Update the config for the disk with the fixed config config[:disks][disk_name.to_sym] = disk_default_config.merge(disk_config) # Since the config was altered, we can't use disk_config (as it will be different or keys will not be present) raise "Disk type #{config[:disks][disk_name.to_sym][:disk_type]} for disk #{disk_name} is not valid" unless valid_disk_type?(config[:disks][disk_name.to_sym][:disk_type]) unless disk_config[:boot].nil? boot_disk_counter += 1 raise "Boot disk cannot be local SSD." if disk_config[:disk_type] == "local-ssd" end if disk_config[:disk_type] == "local-ssd" raise "#{disk_name}: Cannot use 'disk_size' with local SSD. They always have 375 GB (https://cloud.google.com/compute/docs/disks/#localssds)." unless disk_config[:disk_size].nil? # Since disk_size is set to 10 in default_config, it needs to be adjusted for local SSDs config[:disks][disk_name.to_sym][:disk_size] = nil end end if boot_disk_counter == 0 first_disk = config[:disks].first[0] first_config = config[:disks].first[1] config[:disks][first_disk] = first_config.merge({ boot: true }) warn("No bootdisk found - Assuming first disk will be boot disk") elsif boot_disk_counter > 1 raise "More than one boot disk specified" end elsif !new_disk_configuration_present? # If no new disk configuration is present, # we'll set up the default configuration for the new style config[:disks] = { "disk1": disk_default_config.merge({ boot: true }), } end end |
#create_instance_object(server_name) ⇒ Object
419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 |
# File 'lib/kitchen/driver/gce.rb', line 419 def create_instance_object(server_name) inst_obj = Google::Apis::ComputeV1::Instance.new inst_obj.name = server_name inst_obj.disks = create_disks(server_name) inst_obj.machine_type = machine_type_url inst_obj.guest_accelerators = instance_guest_accelerators inst_obj. = inst_obj.network_interfaces = instance_network_interfaces inst_obj.scheduling = instance_scheduling inst_obj.service_accounts = instance_service_accounts unless instance_service_accounts.nil? inst_obj. = inst_obj.labels = instance_labels inst_obj end |
#create_local_disk(unique_disk_name, disk_config) ⇒ Object
464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 |
# File 'lib/kitchen/driver/gce.rb', line 464 def create_local_disk(unique_disk_name, disk_config) disk = Google::Apis::ComputeV1::AttachedDisk.new # Specifies the parameters for a new disk that will be created alongside the new instance. params = Google::Apis::ComputeV1::AttachedDiskInitializeParams.new disk.boot = true if !disk_config[:boot].nil? && disk_config[:boot].to_s == "true" disk.auto_delete = disk_config[:autodelete_disk] params.disk_size_gb = disk_config[:disk_size] params.disk_type = disk_type_url_for(disk_config[:disk_type]) if disk_config[:disk_type] == "local-ssd" info("Creating a 375 GB local ssd as scratch disk (https://cloud.google.com/compute/docs/disks/#localssds).") disk.type = "SCRATCH" elsif disk.boot info("Creating a #{disk_config[:disk_size]} GB boot disk named #{unique_disk_name} from image #{image_name}...") params.source_image = boot_disk_source_image unless disk_config[:disk_type] == "local-ssd" params.disk_name = unique_disk_name unless disk_config[:disk_type] == "local-ssd" else info("Creating a #{disk_config[:disk_size]} GB extra disk named #{unique_disk_name} from image #{disk_config[:custom_image]}...") params.source_image = image_url(disk_config[:custom_image]) unless disk_config[:disk_type] == "local-ssd" params.disk_name = unique_disk_name unless disk_config[:disk_type] == "local-ssd" end disk.initialize_params = params disk end |
#delete_disk(unique_disk_name) ⇒ Object
507 508 509 510 511 512 513 514 515 516 517 518 |
# File 'lib/kitchen/driver/gce.rb', line 507 def delete_disk(unique_disk_name) begin connection.get_disk(project, zone, unique_disk_name) rescue Google::Apis::ClientError info("Unable to locate disk #{unique_disk_name} in project #{project}, zone #{zone}") return end info("Waiting for disk #{unique_disk_name} to be deleted...") wait_for_operation(connection.delete_disk(project, zone, unique_disk_name)) info("Disk #{unique_disk_name} deleted successfully.") end |
#destroy(state) ⇒ Object
128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 |
# File 'lib/kitchen/driver/gce.rb', line 128 def destroy(state) @state = state server_name = state[:server_name] return if server_name.nil? unless server_exist?(server_name) info("GCE instance <#{server_name}> does not exist - assuming it has been already destroyed.") return end info("Destroying GCE instance <#{server_name}>...") wait_for_operation(connection.delete_instance(project, zone, server_name)) info("GCE instance <#{server_name}> destroyed.") state.delete(:server_name) state.delete(:hostname) state.delete(:zone) end |
#disk_self_link(unique_disk_name) ⇒ Object
524 525 526 |
# File 'lib/kitchen/driver/gce.rb', line 524 def disk_self_link(unique_disk_name) "projects/#{project}/zones/#{zone}/disks/#{unique_disk_name}" end |
#disk_type_url_for(type) ⇒ Object
520 521 522 |
# File 'lib/kitchen/driver/gce.rb', line 520 def disk_type_url_for(type) "zones/#{zone}/diskTypes/#{type}" end |
#env_user ⇒ Object
602 603 604 |
# File 'lib/kitchen/driver/gce.rb', line 602 def env_user ENV["USER"] || "unknown" end |
#find_zone ⇒ Object
385 386 387 388 389 390 |
# File 'lib/kitchen/driver/gce.rb', line 385 def find_zone zone = zones_in_region.sample raise "Unable to find a suitable zone in #{region}" if zone.nil? zone.name end |
#generate_server_name ⇒ Object
435 436 437 438 439 440 441 442 443 444 |
# File 'lib/kitchen/driver/gce.rb', line 435 def generate_server_name name = config[:inst_name] || "tk-#{instance.name.downcase}-#{SecureRandom.hex(3)}" if name.length > 63 warn("The TK instance name (#{instance.name}) has been removed from the GCE instance name due to size limitations. Consider setting shorter platform or suite names.") name = "tk-#{SecureRandom.uuid}" end name.gsub(/([^-a-z0-9])/, "-") end |
#guest_accelerators ⇒ Object
545 546 547 |
# File 'lib/kitchen/driver/gce.rb', line 545 def guest_accelerators config[:guest_accelerators] end |
#image_exist?(image = image_name) ⇒ Boolean
341 342 343 |
# File 'lib/kitchen/driver/gce.rb', line 341 def image_exist?(image = image_name) check_api_call { connection.get_image(image_project, image) } end |
#image_name ⇒ Object
353 354 355 |
# File 'lib/kitchen/driver/gce.rb', line 353 def image_name @image_name ||= config[:image_name] || image_name_for_family(config[:image_family]) end |
#image_name_for_family(image_family) ⇒ Object
536 537 538 539 |
# File 'lib/kitchen/driver/gce.rb', line 536 def image_name_for_family(image_family) image = connection.get_image_from_family(image_project, image_family) image.name end |
#image_project ⇒ Object
357 358 359 |
# File 'lib/kitchen/driver/gce.rb', line 357 def image_project config[:image_project].nil? ? project : config[:image_project] end |
#image_url(image = image_name) ⇒ Object
532 533 534 |
# File 'lib/kitchen/driver/gce.rb', line 532 def image_url(image = image_name) "projects/#{image_project}/global/images/#{image}" if image_exist?(image) end |
#instance_guest_accelerators ⇒ Object
549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 |
# File 'lib/kitchen/driver/gce.rb', line 549 def instance_guest_accelerators guest_accelerator_configs = [] guest_accelerators.each do |guest_accelerator| next unless guest_accelerator.key?(:type) guest_accelerator_obj = Google::Apis::ComputeV1::AcceleratorConfig.new guest_accelerator_obj.accelerator_type = "zones/#{zone}/acceleratorTypes/#{guest_accelerator[:type]}" count = 1 count = guest_accelerator[:count] if guest_accelerator.key?(:count) guest_accelerator_obj.accelerator_count = count guest_accelerator_configs << guest_accelerator_obj end guest_accelerator_configs end |
#instance_labels ⇒ Object
598 599 600 |
# File 'lib/kitchen/driver/gce.rb', line 598 def instance_labels config[:labels] end |
#instance_metadata ⇒ Object
587 588 589 590 591 592 593 594 595 596 |
# File 'lib/kitchen/driver/gce.rb', line 587 def Google::Apis::ComputeV1::Metadata.new.tap do || .items = .each_with_object([]) do |(k, v), memo| memo << Google::Apis::ComputeV1::Metadata::Item.new.tap do |item| item.key = k.to_s item.value = v.to_s end end end end |
#instance_network_interfaces ⇒ Object
606 607 608 609 610 611 612 613 614 |
# File 'lib/kitchen/driver/gce.rb', line 606 def instance_network_interfaces interface = Google::Apis::ComputeV1::NetworkInterface.new interface.network = network_url if config[:subnet_project].nil? interface.network_ip = network_ip unless network_ip.nil? interface.subnetwork = subnet_url if subnet_url interface.access_configs = interface_access_configs Array(interface) end |
#instance_scheduling ⇒ Object
636 637 638 639 640 641 642 |
# File 'lib/kitchen/driver/gce.rb', line 636 def instance_scheduling Google::Apis::ComputeV1::Scheduling.new.tap do |scheduling| scheduling.automatic_restart = auto_restart?.to_s scheduling.preemptible = preemptible?.to_s scheduling.on_host_maintenance = migrate_setting end end |
#instance_service_accounts ⇒ Object
660 661 662 663 664 665 666 667 668 |
# File 'lib/kitchen/driver/gce.rb', line 660 def instance_service_accounts return if config[:service_account_scopes].nil? || config[:service_account_scopes].empty? service_account = Google::Apis::ComputeV1::ServiceAccount.new service_account.email = config[:service_account_name] service_account.scopes = config[:service_account_scopes].map { |scope| service_account_scope_url(scope) } Array(service_account) end |
#instance_tags ⇒ Object
680 681 682 |
# File 'lib/kitchen/driver/gce.rb', line 680 def Google::Apis::ComputeV1::Tags.new.tap { |tag_obj| tag_obj.items = config[:tags] } end |
#interface_access_configs ⇒ Object
626 627 628 629 630 631 632 633 634 |
# File 'lib/kitchen/driver/gce.rb', line 626 def interface_access_configs return [] if config[:use_private_ip] access_config = Google::Apis::ComputeV1::AccessConfig.new access_config.name = "External NAT" access_config.type = "ONE_TO_ONE_NAT" Array(access_config) end |
#ip_address_for(server) ⇒ Object
403 404 405 |
# File 'lib/kitchen/driver/gce.rb', line 403 def ip_address_for(server) config[:use_private_ip] ? private_ip_for(server) : public_ip_for(server) end |
#machine_type_url ⇒ Object
541 542 543 |
# File 'lib/kitchen/driver/gce.rb', line 541 def machine_type_url "zones/#{zone}/machineTypes/#{config[:machine_type]}" end |
#metadata ⇒ Object
570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 |
# File 'lib/kitchen/driver/gce.rb', line 570 def = { "created-by" => "test-kitchen", "test-kitchen-instance" => instance.name, "test-kitchen-user" => env_user, } if winrm_transport? image_identifier = config[:image_family] || config[:image_name] ["windows-startup-script-ps1"] = 'netsh advfirewall firewall add rule name="winrm" dir=in action=allow protocol=TCP localport=5985;' if !image_identifier.nil? && image_identifier.include?("2008") ["windows-startup-script-ps1"] += "winrm quickconfig -q" end end config[:metadata].merge() end |
#migrate_setting ⇒ Object
656 657 658 |
# File 'lib/kitchen/driver/gce.rb', line 656 def migrate_setting auto_migrate? ? "MIGRATE" : "TERMINATE" end |
#name ⇒ Object
90 91 92 |
# File 'lib/kitchen/driver/gce.rb', line 90 def name "Google Compute (GCE)" end |
#network_ip ⇒ Object
369 370 371 |
# File 'lib/kitchen/driver/gce.rb', line 369 def network_ip config[:network_ip] end |
#network_project ⇒ Object
365 366 367 |
# File 'lib/kitchen/driver/gce.rb', line 365 def network_project config[:network_project].nil? ? project : config[:network_project] end |
#network_url ⇒ Object
616 617 618 |
# File 'lib/kitchen/driver/gce.rb', line 616 def network_url "projects/#{network_project}/global/networks/#{config[:network]}" end |
#new_disk_configuration_present? ⇒ Boolean
151 152 153 |
# File 'lib/kitchen/driver/gce.rb', line 151 def new_disk_configuration_present? !config[:disks].nil? end |
#old_disk_configuration_present? ⇒ Boolean
147 148 149 |
# File 'lib/kitchen/driver/gce.rb', line 147 def old_disk_configuration_present? !config[:autodelete_disk].nil? || !config[:disk_size].nil? || !config[:disk_type].nil? end |
#operation_errors(operation_name) ⇒ Object
744 745 746 747 748 749 |
# File 'lib/kitchen/driver/gce.rb', line 744 def operation_errors(operation_name) operation = zone_operation(operation_name) return [] if operation.error.nil? operation.error.errors end |
#preemptible? ⇒ Boolean
644 645 646 |
# File 'lib/kitchen/driver/gce.rb', line 644 def preemptible? config[:preemptible] end |
#private_ip_for(server) ⇒ Object
407 408 409 410 411 |
# File 'lib/kitchen/driver/gce.rb', line 407 def private_ip_for(server) server.network_interfaces.first.network_ip rescue NoMethodError raise "Unable to determine private IP for instance" end |
#project ⇒ Object
349 350 351 |
# File 'lib/kitchen/driver/gce.rb', line 349 def project config[:project] end |
#public_ip_for(server) ⇒ Object
413 414 415 416 417 |
# File 'lib/kitchen/driver/gce.rb', line 413 def public_ip_for(server) server.network_interfaces.first.access_configs.first.nat_ip rescue NoMethodError raise "Unable to determine public IP for instance" end |
#refresh_rate ⇒ Object
688 689 690 |
# File 'lib/kitchen/driver/gce.rb', line 688 def refresh_rate config[:refresh_rate] end |
#region ⇒ Object
373 374 375 |
# File 'lib/kitchen/driver/gce.rb', line 373 def region config[:region].nil? ? region_for_zone : config[:region] end |
#region_for_zone ⇒ Object
377 378 379 |
# File 'lib/kitchen/driver/gce.rb', line 377 def region_for_zone @region_for_zone ||= connection.get_zone(project, zone).region.split("/").last end |
#server_exist?(server_name) ⇒ Boolean
345 346 347 |
# File 'lib/kitchen/driver/gce.rb', line 345 def server_exist?(server_name) check_api_call { server_instance(server_name) } end |
#server_instance(server_name) ⇒ Object
399 400 401 |
# File 'lib/kitchen/driver/gce.rb', line 399 def server_instance(server_name) connection.get_instance(project, zone, server_name) end |
#service_account_scope_url(scope) ⇒ Object
670 671 672 673 674 |
# File 'lib/kitchen/driver/gce.rb', line 670 def service_account_scope_url(scope) return scope if scope.start_with?("https://www.googleapis.com/auth/") "https://www.googleapis.com/auth/#{translate_scope_alias(scope)}" end |
#subnet_project ⇒ Object
361 362 363 |
# File 'lib/kitchen/driver/gce.rb', line 361 def subnet_project config[:subnet_project].nil? ? project : config[:subnet_project] end |
#subnet_url ⇒ Object
620 621 622 623 624 |
# File 'lib/kitchen/driver/gce.rb', line 620 def subnet_url return unless config[:subnet] "projects/#{subnet_project}/regions/#{region}/subnetworks/#{config[:subnet]}" end |
#translate_scope_alias(scope_alias) ⇒ Object
676 677 678 |
# File 'lib/kitchen/driver/gce.rb', line 676 def translate_scope_alias(scope_alias) SCOPE_ALIAS_MAP.fetch(scope_alias, scope_alias) end |
#update_windows_password(server_name) ⇒ Object
268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 |
# File 'lib/kitchen/driver/gce.rb', line 268 def update_windows_password(server_name) return unless winrm_transport? username = instance.transport[:username] info("Resetting the Windows password for user #{username} on #{server_name}...") opts = { project: project, zone: zone, instance_name: server_name, email: config[:email], username: username, } opts[:timeout] = config[:winpass_timeout] unless config[:winpass_timeout].nil? state[:password] = GoogleComputeWindowsPassword.new(**opts).new_password info("Password reset complete on #{server_name} complete.") end |
#valid_disk_name?(disk_name) ⇒ Boolean
337 338 339 |
# File 'lib/kitchen/driver/gce.rb', line 337 def valid_disk_name?(disk_name) disk_name.to_s.match(DISK_NAME_REGEX).to_s.length == disk_name.length end |
#valid_disk_type?(disk_type) ⇒ Boolean
331 332 333 334 335 |
# File 'lib/kitchen/driver/gce.rb', line 331 def valid_disk_type?(disk_type) return false if disk_type.nil? check_api_call { connection.get_disk_type(project, zone, disk_type) } end |
#valid_machine_type? ⇒ Boolean
301 302 303 304 305 |
# File 'lib/kitchen/driver/gce.rb', line 301 def valid_machine_type? return false if config[:machine_type].nil? check_api_call { connection.get_machine_type(project, zone, config[:machine_type]) } end |
#valid_network? ⇒ Boolean
307 308 309 310 311 |
# File 'lib/kitchen/driver/gce.rb', line 307 def valid_network? return false if config[:network].nil? check_api_call { connection.get_network(network_project, config[:network]) } end |
#valid_project? ⇒ Boolean
297 298 299 |
# File 'lib/kitchen/driver/gce.rb', line 297 def valid_project? check_api_call { connection.get_project(project) } end |
#valid_region? ⇒ Boolean
325 326 327 328 329 |
# File 'lib/kitchen/driver/gce.rb', line 325 def valid_region? return false if config[:region].nil? check_api_call { connection.get_region(project, config[:region]) } end |
#valid_subnet? ⇒ Boolean
313 314 315 316 317 |
# File 'lib/kitchen/driver/gce.rb', line 313 def valid_subnet? return false if config[:subnet].nil? check_api_call { connection.get_subnetwork(subnet_project, region, config[:subnet]) } end |
#valid_zone? ⇒ Boolean
319 320 321 322 323 |
# File 'lib/kitchen/driver/gce.rb', line 319 def valid_zone? return false if config[:zone].nil? check_api_call { connection.get_zone(project, config[:zone]) } end |
#validate! ⇒ Object
219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 |
# File 'lib/kitchen/driver/gce.rb', line 219 def validate! raise "Project #{config[:project]} is not a valid project" unless valid_project? raise "Either zone or region must be specified" unless config[:zone] || config[:region] raise "'any' is no longer a valid region" if config[:region] == "any" raise "Zone #{config[:zone]} is not a valid zone" if config[:zone] && !valid_zone? raise "Region #{config[:region]} is not a valid region" if config[:region] && !valid_region? raise "Machine type #{config[:machine_type]} is not valid" unless valid_machine_type? raise "Either image family or name must be specified" unless config[:image_family] || config[:image_name] raise "Network #{config[:network]} is not valid" unless valid_network? raise "Subnet #{config[:subnet]} is not valid" if config[:subnet] && !valid_subnet? raise "Email address of GCE user is not set" if winrm_transport? && config[:email].nil? raise "You cannot use autodelete_disk, disk_size or disk_type with the new disks configuration" if old_disk_configuration_present? && new_disk_configuration_present? raise "Disk image #{config[:image_name]} is not valid - check your image name and image project" if boot_disk_source_image.nil? warn("Both zone and region specified - region will be ignored.") if config[:zone] && config[:region] warn("Both image family and name specified - image family will be ignored") if config[:image_family] && config[:image_name] warn("Image project not specified - searching current project only") unless config[:image_project] warn("Subnet project not specified - searching current project only") if config[:subnet] && !config[:subnet_project] warn("Auto-migrate disabled for preemptible instance") if preemptible? && config[:auto_migrate] warn("Auto-restart disabled for preemptible instance") if preemptible? && config[:auto_restart] warn("These configs are deprecated - consider using new disks configuration") if old_disk_configuration_present? end |
#wait_for_operation(operation) ⇒ Object
717 718 719 720 721 722 723 724 725 726 727 728 729 730 |
# File 'lib/kitchen/driver/gce.rb', line 717 def wait_for_operation(operation) operation_name = operation.name wait_for_status("DONE") { zone_operation(operation_name) } errors = operation_errors(operation_name) return if errors.empty? errors.each do |error| error("#{error.code}: #{error.}") end raise "Operation #{operation_name} failed." end |
#wait_for_server ⇒ Object
732 733 734 735 736 737 738 |
# File 'lib/kitchen/driver/gce.rb', line 732 def wait_for_server instance.transport.connection(state).wait_until_ready rescue error("Server not reachable. Destroying server...") destroy(state) raise end |
#wait_for_status(requested_status, &block) ⇒ Object
692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 |
# File 'lib/kitchen/driver/gce.rb', line 692 def wait_for_status(requested_status, &block) last_status = "" begin Timeout.timeout(wait_time) do loop do item = yield current_status = item.status unless last_status == current_status last_status = current_status info("Current status: #{current_status}") end break if current_status == requested_status sleep refresh_rate end end rescue Timeout::Error error("Request did not complete in #{wait_time} seconds. Check the Google Cloud Console for more info.") raise end end |
#wait_time ⇒ Object
684 685 686 |
# File 'lib/kitchen/driver/gce.rb', line 684 def wait_time config[:wait_time] end |
#winrm_transport? ⇒ Boolean
264 265 266 |
# File 'lib/kitchen/driver/gce.rb', line 264 def winrm_transport? instance.transport.name.casecmp("winrm") == 0 end |
#zone ⇒ Object
381 382 383 |
# File 'lib/kitchen/driver/gce.rb', line 381 def zone @zone ||= state[:zone] || config[:zone] || find_zone end |
#zone_operation(operation_name) ⇒ Object
740 741 742 |
# File 'lib/kitchen/driver/gce.rb', line 740 def zone_operation(operation_name) connection.get_zone_operation(project, zone, operation_name) end |
#zones_in_region ⇒ Object
392 393 394 395 396 397 |
# File 'lib/kitchen/driver/gce.rb', line 392 def zones_in_region connection.list_zones(project).items.select do |zone| zone.status == "UP" && zone.region.split("/").last == region end end |