vmpooler-dns-gcp 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/lib/vmpooler/dns/gcp.rb +139 -0
- data/lib/vmpooler-dns-gcp/version.rb +5 -0
- metadata +150 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 79c98f6dafd79e083cf541e1e8893e739dee3fb34d49787f805a811daf881098
|
4
|
+
data.tar.gz: 17b710878a2714cefa44480ca3f3938a88b98be7a23bba5d43a8a504db6a2ae5
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 80a7bf801360a1cbc81363feefd0cde13f16697f390089f0f4dc3e11dedba2d03477503a09ece4460e64063ae87f135812f6b1a8eeefde5f5a01805f45b699f3
|
7
|
+
data.tar.gz: e8a4b020fc49453bcc050252106edd6c9d2792bef63f34b814d6472560295b76a0010e07db36e93bff85ce7c016c7fc4adcc3d95cc1d19501d1dff757c0b6670
|
@@ -0,0 +1,139 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'googleauth'
|
4
|
+
require 'google/cloud/dns'
|
5
|
+
require 'vmpooler/dns/base'
|
6
|
+
|
7
|
+
module Vmpooler
|
8
|
+
class PoolManager
|
9
|
+
class Dns
|
10
|
+
# This class represent a DNS plugin to CRUD resources in Google Cloud DNS.
|
11
|
+
class Gcp < Vmpooler::PoolManager::Dns::Base
|
12
|
+
# The connection_pool method is normally used only for testing
|
13
|
+
attr_reader :connection_pool
|
14
|
+
|
15
|
+
def initialize(config, logger, metrics, redis_connection_pool, name, options)
|
16
|
+
super(config, logger, metrics, redis_connection_pool, name, options)
|
17
|
+
|
18
|
+
task_limit = global_config[:config].nil? || global_config[:config]['task_limit'].nil? ? 10 : global_config[:config]['task_limit'].to_i
|
19
|
+
|
20
|
+
default_connpool_size = [provided_pools.count, task_limit, 2].max
|
21
|
+
connpool_timeout = 60
|
22
|
+
logger.log('d', "[#{name}] ConnPool - Creating a connection pool of size #{default_connpool_size} with timeout #{connpool_timeout}")
|
23
|
+
@connection_pool = Vmpooler::PoolManager::GenericConnectionPool.new(
|
24
|
+
metrics: metrics,
|
25
|
+
connpool_type: 'dns_connection_pool',
|
26
|
+
connpool_provider: name,
|
27
|
+
size: default_connpool_size,
|
28
|
+
timeout: connpool_timeout
|
29
|
+
) do
|
30
|
+
logger.log('d', "[#{name}] Connection Pool - Creating a connection object")
|
31
|
+
# Need to wrap the GCP connection object in another object. The generic connection pooler will preserve
|
32
|
+
# the object reference for the connection, which means it cannot "reconnect" by creating an entirely new connection
|
33
|
+
# object. Instead by wrapping it in a Hash, the Hash object reference itself never changes but the content of the
|
34
|
+
# Hash can change, and is preserved across invocations.
|
35
|
+
new_conn = connect_to_gcp
|
36
|
+
{ connection: new_conn }
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def name
|
41
|
+
'gcp'
|
42
|
+
end
|
43
|
+
|
44
|
+
# main configuration options
|
45
|
+
def project
|
46
|
+
dns_config['project']
|
47
|
+
end
|
48
|
+
|
49
|
+
def zone_name
|
50
|
+
dns_config['zone_name']
|
51
|
+
end
|
52
|
+
|
53
|
+
def create_or_replace_record(hostname)
|
54
|
+
retries = 0
|
55
|
+
ip = get_ip(hostname)
|
56
|
+
if ip.nil?
|
57
|
+
debug_logger("An IP Address was not recorded for #{hostname}")
|
58
|
+
else
|
59
|
+
begin
|
60
|
+
change = connection.zone(zone_name).add(hostname, 'A', 60, ip)
|
61
|
+
debug_logger("#{change.id} - #{change.started_at} - #{change.status} DNS address added") if change
|
62
|
+
rescue Google::Cloud::AlreadyExistsError => _e
|
63
|
+
# the error is Google::Cloud::AlreadyExistsError: alreadyExists: The resource 'entity.change.additions[0]' named 'instance-8.test.vmpooler.net. (A)' already exists
|
64
|
+
# the error is Google::Cloud::AlreadyExistsError: alreadyExists: The resource 'entity.change.additions[0]' named 'instance-8.test.vmpooler.net. (A)' already exists
|
65
|
+
change = connection.zone(zone_name).replace(hostname, 'A', 60, ip)
|
66
|
+
debug_logger("#{change.id} - #{change.started_at} - #{change.status} DNS address previously existed and was replaced") if change
|
67
|
+
rescue Google::Cloud::FailedPreconditionError => e
|
68
|
+
debug_logger("DNS create failed, retrying error: #{e}")
|
69
|
+
sleep 5
|
70
|
+
retry if (retries += 1) < 30
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def delete_record(hostname)
|
76
|
+
retries = 0
|
77
|
+
begin
|
78
|
+
connection.zone(zone_name).remove(hostname, 'A')
|
79
|
+
rescue Google::Cloud::FailedPreconditionError => e
|
80
|
+
# this error was experienced intermittently, will retry to see if it can complete successfully
|
81
|
+
# the error is Google::Cloud::FailedPreconditionError: conditionNotMet: Precondition not met for 'entity.change.deletions[1]'
|
82
|
+
debug_logger("GCP DNS delete_record failed, retrying error: #{e}")
|
83
|
+
sleep 5
|
84
|
+
retry if (retries += 1) < 30
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def connection
|
89
|
+
@connection_pool.with_metrics do |pool_object|
|
90
|
+
return ensured_gcp_connection(pool_object)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def ensured_gcp_connection(connection_pool_object)
|
95
|
+
connection_pool_object[:connection] = connect_to_gcp unless gcp_connection_ok?(connection_pool_object[:connection])
|
96
|
+
connection_pool_object[:connection]
|
97
|
+
end
|
98
|
+
|
99
|
+
def gcp_connection_ok?(connection)
|
100
|
+
_result = connection.id
|
101
|
+
true
|
102
|
+
rescue StandardError
|
103
|
+
false
|
104
|
+
end
|
105
|
+
|
106
|
+
def connect_to_gcp
|
107
|
+
max_tries = global_config[:config]['max_tries'] || 3
|
108
|
+
retry_factor = global_config[:config]['retry_factor'] || 10
|
109
|
+
try = 1
|
110
|
+
begin
|
111
|
+
Google::Cloud::Dns.configure do |config|
|
112
|
+
config.project_id = project
|
113
|
+
end
|
114
|
+
|
115
|
+
dns = Google::Cloud::Dns.new
|
116
|
+
|
117
|
+
metrics.increment('connect.open')
|
118
|
+
dns
|
119
|
+
rescue StandardError => e
|
120
|
+
metrics.increment('connect.fail')
|
121
|
+
raise e if try >= max_tries
|
122
|
+
|
123
|
+
sleep(try * retry_factor)
|
124
|
+
try += 1
|
125
|
+
retry
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
# used in local dev environment, set DEBUG_FLAG=true
|
130
|
+
# this way the upstream vmpooler manager does not get polluted with logs
|
131
|
+
def debug_logger(message, send_to_upstream: false)
|
132
|
+
# the default logger is simple and does not enforce debug levels (the first argument)
|
133
|
+
puts message if ENV['DEBUG_FLAG']
|
134
|
+
logger.log('[g]', message) if send_to_upstream
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
metadata
ADDED
@@ -0,0 +1,150 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: vmpooler-dns-gcp
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Puppet by Perforce
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2023-04-19 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
15
|
+
requirements:
|
16
|
+
- - ">="
|
17
|
+
- !ruby/object:Gem::Version
|
18
|
+
version: 0.16.2
|
19
|
+
- - "<"
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 1.3.0
|
22
|
+
name: googleauth
|
23
|
+
prerelease: false
|
24
|
+
type: :runtime
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 0.16.2
|
30
|
+
- - "<"
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 1.3.0
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
requirement: !ruby/object:Gem::Requirement
|
35
|
+
requirements:
|
36
|
+
- - "~>"
|
37
|
+
- !ruby/object:Gem::Version
|
38
|
+
version: 0.35.1
|
39
|
+
name: google-cloud-dns
|
40
|
+
prerelease: false
|
41
|
+
type: :runtime
|
42
|
+
version_requirements: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - "~>"
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: 0.35.1
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
requirements:
|
50
|
+
- - "~>"
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: '3.0'
|
53
|
+
name: vmpooler
|
54
|
+
prerelease: false
|
55
|
+
type: :runtime
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - "~>"
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '3.0'
|
61
|
+
- !ruby/object:Gem::Dependency
|
62
|
+
requirement: !ruby/object:Gem::Requirement
|
63
|
+
requirements:
|
64
|
+
- - ">="
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: 0.17.0
|
67
|
+
name: mock_redis
|
68
|
+
prerelease: false
|
69
|
+
type: :development
|
70
|
+
version_requirements: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - ">="
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: 0.17.0
|
75
|
+
- !ruby/object:Gem::Dependency
|
76
|
+
requirement: !ruby/object:Gem::Requirement
|
77
|
+
requirements:
|
78
|
+
- - ">="
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
version: '3.2'
|
81
|
+
name: rspec
|
82
|
+
prerelease: false
|
83
|
+
type: :development
|
84
|
+
version_requirements: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - ">="
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '3.2'
|
89
|
+
- !ruby/object:Gem::Dependency
|
90
|
+
requirement: !ruby/object:Gem::Requirement
|
91
|
+
requirements:
|
92
|
+
- - "~>"
|
93
|
+
- !ruby/object:Gem::Version
|
94
|
+
version: 1.1.0
|
95
|
+
name: rubocop
|
96
|
+
prerelease: false
|
97
|
+
type: :development
|
98
|
+
version_requirements: !ruby/object:Gem::Requirement
|
99
|
+
requirements:
|
100
|
+
- - "~>"
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: 1.1.0
|
103
|
+
- !ruby/object:Gem::Dependency
|
104
|
+
requirement: !ruby/object:Gem::Requirement
|
105
|
+
requirements:
|
106
|
+
- - ">="
|
107
|
+
- !ruby/object:Gem::Version
|
108
|
+
version: 0.11.2
|
109
|
+
name: simplecov
|
110
|
+
prerelease: false
|
111
|
+
type: :development
|
112
|
+
version_requirements: !ruby/object:Gem::Requirement
|
113
|
+
requirements:
|
114
|
+
- - ">="
|
115
|
+
- !ruby/object:Gem::Version
|
116
|
+
version: 0.11.2
|
117
|
+
description:
|
118
|
+
email:
|
119
|
+
executables: []
|
120
|
+
extensions: []
|
121
|
+
extra_rdoc_files: []
|
122
|
+
files:
|
123
|
+
- lib/vmpooler-dns-gcp/version.rb
|
124
|
+
- lib/vmpooler/dns/gcp.rb
|
125
|
+
homepage: https://github.com/puppetlabs/vmpooler-dns-gcp
|
126
|
+
licenses: []
|
127
|
+
metadata:
|
128
|
+
homepage_uri: https://github.com/puppetlabs/vmpooler-dns-gcp
|
129
|
+
source_code_uri: https://github.com/puppetlabs/vmpooler-dns-gcp
|
130
|
+
changelog_uri: https://github.com/puppetlabs/vmpooler-dns-gcp/blob/main/CHANGELOG.md
|
131
|
+
post_install_message:
|
132
|
+
rdoc_options: []
|
133
|
+
require_paths:
|
134
|
+
- lib
|
135
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
136
|
+
requirements:
|
137
|
+
- - ">="
|
138
|
+
- !ruby/object:Gem::Version
|
139
|
+
version: 2.3.0
|
140
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
141
|
+
requirements:
|
142
|
+
- - ">="
|
143
|
+
- !ruby/object:Gem::Version
|
144
|
+
version: '0'
|
145
|
+
requirements: []
|
146
|
+
rubygems_version: 3.3.25
|
147
|
+
signing_key:
|
148
|
+
specification_version: 4
|
149
|
+
summary: Google Cloud DNS for VMPooler
|
150
|
+
test_files: []
|