1
- # frozen_string_literal: true
2
-
3
1
require 'proxy/kerberos'
4
2
require 'radcli'
5
3
require 'digest'
@@ -10,7 +8,7 @@ class Provider
10
8
include Proxy ::Util
11
9
include Proxy ::Kerberos
12
10
13
- attr_reader :realm , :keytab_path , :principal , :domain_controller , :domain , :ou , :computername_prefix , :computername_hash , :computername_use_fqdn
11
+ attr_reader :realm , :keytab_path , :principal , :domain_controller , :domain , :ou , :computername_prefix , :computername_hash , :computername_use_fqdn , :ignore_computername_exists
14
12
15
13
def initialize ( options = { } )
16
14
@realm = options [ :realm ]
@@ -22,6 +20,7 @@ def initialize(options = {})
22
20
@computername_prefix = options [ :computername_prefix ]
23
21
@computername_hash = options [ :computername_hash ]
24
22
@computername_use_fqdn = options [ :computername_use_fqdn ]
23
+ @ignore_computername_exists = options . fetch ( :ignore_computername_exists , false )
25
24
logger . info 'Proxy::AdRealm: initialize...'
26
25
end
27
26
@@ -90,20 +89,25 @@ def radcli_connect
90
89
# Connect to active directory
91
90
conn = Adcli ::AdConn . new ( @domain )
92
91
conn . set_domain_realm ( @realm )
92
+ # Directly connect to the domain controller if specified, skip the SRV lookup
93
93
conn . set_domain_controller ( @domain_controller ) unless @domain_controller . nil?
94
94
conn . set_login_ccache_name ( '' )
95
95
conn . connect
96
96
conn
97
97
end
98
98
99
+ MAX_RETRIES = 100
100
+ RETRY_DELAY = 0.3
101
+
99
102
def radcli_join ( hostfqdn , computername , password )
100
- # Join computer
101
- enroll = Adcli ::AdEnroll . new ( @adconn )
102
- enroll . set_computer_name ( computername )
103
- enroll . set_host_fqdn ( hostfqdn )
104
- enroll . set_domain_ou ( @ou ) if @ou
105
- enroll . set_computer_password ( password )
106
- enroll . join
103
+ enroll = setup_enroll ( hostfqdn , computername , password )
104
+ begin
105
+ enroll . join
106
+ logger . info "Successfully joined computer #{ computername } with FQDN #{ hostfqdn } "
107
+ true
108
+ rescue RuntimeError => ex
109
+ handle_runtime_error ( ex , enroll )
110
+ end
107
111
end
108
112
109
113
def generate_password
@@ -127,5 +131,66 @@ def radcli_delete(computername)
127
131
enroll . set_domain_ou ( @ou ) if @ou
128
132
enroll . delete
129
133
end
134
+
135
+ private
136
+
137
+ def setup_enroll ( hostfqdn , computername , password )
138
+ enroll = Adcli ::AdEnroll . new ( @adconn )
139
+ enroll . set_computer_name ( computername )
140
+ enroll . set_host_fqdn ( hostfqdn )
141
+ enroll . set_domain_ou ( @ou ) if @ou
142
+ enroll . set_computer_password ( password )
143
+ enroll
144
+ end
145
+
146
+ def handle_runtime_error ( ex , enroll )
147
+ if ex . message =~ /Authentication error/
148
+ retry_authentication_error ( enroll )
149
+ elsif ex . message =~ /already exists/
150
+ handle_already_exists_error
151
+ else
152
+ log_error ( "Failed to join computer: #{ ex . message } " )
153
+ raise ex
154
+ end
155
+ end
156
+
157
+ def retry_authentication_error ( enroll )
158
+ MAX_RETRIES . times do |i |
159
+ sleep ( RETRY_DELAY )
160
+ begin
161
+ if enroll . respond_to? ( :update )
162
+ enroll . update
163
+ else
164
+ enroll . password
165
+ end
166
+ log_info ( "Successfully updated computer after authentication error" )
167
+ return true
168
+ rescue RuntimeError => ex
169
+ if i >= MAX_RETRIES - 1 || ex . message !~ /Authentication error/
170
+ log_error ( "Failed to update computer after #{ MAX_RETRIES } attempts: #{ ex . message } " )
171
+ raise ex
172
+ end
173
+ end
174
+ end
175
+ end
176
+
177
+ def handle_already_exists_error
178
+ if ignore_computername_exists
179
+ log_info ( "Computer name already exists, but ignoring as per configuration" )
180
+ true
181
+ else
182
+ log_error ( "Computer name already exists and cannot proceed" )
183
+ raise "Computer name already exists"
184
+ end
185
+ end
186
+
187
+ def log_info ( message )
188
+ logger . info "Proxy::AdRealm: #{ message } "
189
+ end
190
+
191
+ def log_error ( message )
192
+ logger . error "Proxy::AdRealm: #{ message } "
193
+ end
194
+
130
195
end
131
196
end
0 commit comments