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 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
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module VmpoolerDnsGcp
4
+ VERSION = '1.0.0'
5
+ 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: []