Class: Vmpooler::PoolManager::Dns::Gcp
- Inherits:
-
Base
- Object
- Base
- Vmpooler::PoolManager::Dns::Gcp
- Defined in:
- lib/vmpooler/dns/gcp.rb
Overview
This class represent a DNS plugin to CRUD resources in Google Cloud DNS.
Instance Attribute Summary collapse
-
#connection_pool ⇒ Object
readonly
The connection_pool method is normally used only for testing.
Instance Method Summary collapse
- #connect_to_gcp ⇒ Object
- #connection ⇒ Object
- #create_or_replace_record(hostname) ⇒ Object
-
#debug_logger(message, send_to_upstream: false) ⇒ Object
used in local dev environment, set DEBUG_FLAG=true this way the upstream vmpooler manager does not get polluted with logs.
- #delete_record(hostname) ⇒ Object
- #ensured_gcp_connection(connection_pool_object) ⇒ Object
- #gcp_connection_ok?(connection) ⇒ Boolean
-
#initialize(config, logger, metrics, redis_connection_pool, name, options) ⇒ Gcp
constructor
A new instance of Gcp.
- #name ⇒ Object
-
#project ⇒ Object
main configuration options.
- #zone_name ⇒ Object
Constructor Details
#initialize(config, logger, metrics, redis_connection_pool, name, options) ⇒ Gcp
Returns a new instance of Gcp.
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
# File 'lib/vmpooler/dns/gcp.rb', line 15 def initialize(config, logger, metrics, redis_connection_pool, name, ) super(config, logger, metrics, redis_connection_pool, name, ) task_limit = global_config[:config].nil? || global_config[:config]['task_limit'].nil? ? 10 : global_config[:config]['task_limit'].to_i default_connpool_size = [provided_pools.count, task_limit, 2].max connpool_timeout = 60 logger.log('d', "[#{name}] ConnPool - Creating a connection pool of size #{default_connpool_size} with timeout #{connpool_timeout}") @connection_pool = Vmpooler::PoolManager::GenericConnectionPool.new( metrics: metrics, connpool_type: 'dns_connection_pool', connpool_provider: name, size: default_connpool_size, timeout: connpool_timeout ) do logger.log('d', "[#{name}] Connection Pool - Creating a connection object") # Need to wrap the GCP connection object in another object. The generic connection pooler will preserve # the object reference for the connection, which means it cannot "reconnect" by creating an entirely new connection # object. Instead by wrapping it in a Hash, the Hash object reference itself never changes but the content of the # Hash can change, and is preserved across invocations. new_conn = connect_to_gcp { connection: new_conn } end end |
Instance Attribute Details
#connection_pool ⇒ Object (readonly)
The connection_pool method is normally used only for testing
13 14 15 |
# File 'lib/vmpooler/dns/gcp.rb', line 13 def connection_pool @connection_pool end |
Instance Method Details
#connect_to_gcp ⇒ Object
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 |
# File 'lib/vmpooler/dns/gcp.rb', line 106 def connect_to_gcp max_tries = global_config[:config]['max_tries'] || 3 retry_factor = global_config[:config]['retry_factor'] || 10 try = 1 begin Google::Cloud::Dns.configure do |config| config.project_id = project end dns = Google::Cloud::Dns.new metrics.increment('connect.open') dns rescue StandardError => e metrics.increment('connect.fail') raise e if try >= max_tries sleep(try * retry_factor) try += 1 retry end end |
#connection ⇒ Object
88 89 90 91 92 |
# File 'lib/vmpooler/dns/gcp.rb', line 88 def connection @connection_pool.with_metrics do |pool_object| return ensured_gcp_connection(pool_object) end end |
#create_or_replace_record(hostname) ⇒ Object
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
# File 'lib/vmpooler/dns/gcp.rb', line 53 def create_or_replace_record(hostname) retries = 0 ip = get_ip(hostname) if ip.nil? debug_logger("An IP Address was not recorded for #{hostname}") else begin change = connection.zone(zone_name).add(hostname, 'A', 60, ip) debug_logger("#{change.id} - #{change.started_at} - #{change.status} DNS address added") if change rescue Google::Cloud::AlreadyExistsError => _e # the error is Google::Cloud::AlreadyExistsError: alreadyExists: The resource 'entity.change.additions[0]' named 'instance-8.test.vmpooler.net. (A)' already exists # the error is Google::Cloud::AlreadyExistsError: alreadyExists: The resource 'entity.change.additions[0]' named 'instance-8.test.vmpooler.net. (A)' already exists change = connection.zone(zone_name).replace(hostname, 'A', 60, ip) debug_logger("#{change.id} - #{change.started_at} - #{change.status} DNS address previously existed and was replaced") if change rescue Google::Cloud::FailedPreconditionError => e debug_logger("DNS create failed, retrying error: #{e}") sleep 5 retry if (retries += 1) < 30 end end end |
#debug_logger(message, send_to_upstream: false) ⇒ Object
used in local dev environment, set DEBUG_FLAG=true this way the upstream vmpooler manager does not get polluted with logs
131 132 133 134 135 |
# File 'lib/vmpooler/dns/gcp.rb', line 131 def debug_logger(, send_to_upstream: false) # the default logger is simple and does not enforce debug levels (the first argument) puts if ENV['DEBUG_FLAG'] logger.log('[g]', ) if send_to_upstream end |
#delete_record(hostname) ⇒ Object
75 76 77 78 79 80 81 82 83 84 85 86 |
# File 'lib/vmpooler/dns/gcp.rb', line 75 def delete_record(hostname) retries = 0 begin connection.zone(zone_name).remove(hostname, 'A') rescue Google::Cloud::FailedPreconditionError => e # this error was experienced intermittently, will retry to see if it can complete successfully # the error is Google::Cloud::FailedPreconditionError: conditionNotMet: Precondition not met for 'entity.change.deletions[1]' debug_logger("GCP DNS delete_record failed, retrying error: #{e}") sleep 5 retry if (retries += 1) < 30 end end |
#ensured_gcp_connection(connection_pool_object) ⇒ Object
94 95 96 97 |
# File 'lib/vmpooler/dns/gcp.rb', line 94 def ensured_gcp_connection(connection_pool_object) connection_pool_object[:connection] = connect_to_gcp unless gcp_connection_ok?(connection_pool_object[:connection]) connection_pool_object[:connection] end |
#gcp_connection_ok?(connection) ⇒ Boolean
99 100 101 102 103 104 |
# File 'lib/vmpooler/dns/gcp.rb', line 99 def gcp_connection_ok?(connection) _result = connection.id true rescue StandardError false end |
#name ⇒ Object
40 41 42 |
# File 'lib/vmpooler/dns/gcp.rb', line 40 def name 'gcp' end |
#project ⇒ Object
main configuration options
45 46 47 |
# File 'lib/vmpooler/dns/gcp.rb', line 45 def project dns_config['project'] end |
#zone_name ⇒ Object
49 50 51 |
# File 'lib/vmpooler/dns/gcp.rb', line 49 def zone_name dns_config['zone_name'] end |