Class: CemWinSpec::IapTunnel

Inherits:
Object
  • Object
show all
Includes:
Logging
Defined in:
lib/cem_win_spec/iap_tunnel.rb

Overview

This class is used to create a tunnel to a GCP instance

Constant Summary collapse

EPHEMERAL_PORT_RANGE =

We don’t go all the way to 65_535 because gcloud shits the bed on MacOS when you assign port 65_535 to a tunnel for some reason.

(49_152..65_534).to_a.freeze

Constants included from Logging

Logging::LEVEL_MAP

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Logging

#current_log_format, current_log_format, current_log_level, #current_log_level, included, log_setup!, #log_setup!, logger, #logger, new_log_formatter, #new_log_formatter, new_log_level, #new_log_level

Constructor Details

#initialize(project_id = nil, zone = nil, instance_name = nil) ⇒ IapTunnel

Returns a new instance of IapTunnel.



19
20
21
22
23
24
25
# File 'lib/cem_win_spec/iap_tunnel.rb', line 19

def initialize(project_id = nil, zone = nil, instance_name = nil)
  @project_id = project_id || get_project_id
  @zone = zone || get_zone
  @instance_name = instance_name || get_instance_name
  @port = find_available_port # Get a random port from the ephemeral port range
  @pid = nil
end

Instance Attribute Details

#instance_nameObject (readonly)

Returns the value of attribute instance_name.



17
18
19
# File 'lib/cem_win_spec/iap_tunnel.rb', line 17

def instance_name
  @instance_name
end

#pidObject (readonly)

Returns the value of attribute pid.



17
18
19
# File 'lib/cem_win_spec/iap_tunnel.rb', line 17

def pid
  @pid
end

#portObject (readonly)

Returns the value of attribute port.



17
18
19
# File 'lib/cem_win_spec/iap_tunnel.rb', line 17

def port
  @port
end

#project_idObject (readonly)

Returns the value of attribute project_id.



17
18
19
# File 'lib/cem_win_spec/iap_tunnel.rb', line 17

def project_id
  @project_id
end

#zoneObject (readonly)

Returns the value of attribute zone.



17
18
19
# File 'lib/cem_win_spec/iap_tunnel.rb', line 17

def zone
  @zone
end

Instance Method Details

#running?Boolean

Returns:

  • (Boolean)


27
28
29
30
31
# File 'lib/cem_win_spec/iap_tunnel.rb', line 27

def running?
  !@pid.nil? && Process.getpgid(@pid)
rescue Errno::ESRCH
  false
end

#startObject



42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/cem_win_spec/iap_tunnel.rb', line 42

def start
  return if running?

  logger.info 'Starting IAP tunnel...'
  logger.debug "Running command: #{tunnel_cmd}"
  @pid = spawn(tunnel_cmd)
  sleep(3) # Give the tunnel a few seconds to start
  Process.getpgid(@pid) # Check if the process starts successfully
  logger.info "IAP tunnel started on port #{port}"
rescue Errno::ESRCH
  @pid = nil
  raise IapTunnelStartError, "Failed to start IAP tunnel on port #{port}: #{$ERROR_INFO}"
end

#stop(wait: true, log: true) ⇒ Object

This method stops the IAP tunnel

Parameters:

  • wait (Boolean) (defaults to: true)

    Whether to wait for the tunnel to stop before returning

  • log (Boolean) (defaults to: true)

    Whether to log messages. This must be set to false if you are calling this method from within a trap block, otherwise the logger will throw an exception.



60
61
62
63
64
65
66
67
68
69
# File 'lib/cem_win_spec/iap_tunnel.rb', line 60

def stop(wait: true, log: true)
  return unless running?

  logger.info 'Stopping IAP tunnel...' if log
  logger.debug "Killing PID: #{@pid}" if log
  Process.kill('TERM', @pid)
  Process.waitpid(@pid) if wait
  @pid = nil
  logger.info 'IAP tunnel stopped' if log
end

#withObject



33
34
35
36
37
38
39
40
# File 'lib/cem_win_spec/iap_tunnel.rb', line 33

def with
  return unless block_given?

  start
  yield port
ensure
  stop
end