@@ -8,7 +8,7 @@ class Provider
8
8
include Proxy ::Util
9
9
include Proxy ::Kerberos
10
10
11
- 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
12
12
13
13
def initialize ( options = { } )
14
14
@realm = options [ :realm ]
@@ -20,6 +20,7 @@ def initialize(options = {})
20
20
@computername_prefix = options [ :computername_prefix ]
21
21
@computername_hash = options [ :computername_hash ]
22
22
@computername_use_fqdn = options [ :computername_use_fqdn ]
23
+ @ignore_computername_exists = options . fetch ( :ignore_computername_exists , false )
23
24
logger . info 'Proxy::AdRealm: initialize...'
24
25
end
25
26
@@ -95,14 +96,18 @@ def radcli_connect
95
96
conn
96
97
end
97
98
99
+ MAX_RETRIES = 100
100
+ RETRY_DELAY = 0.3
101
+
98
102
def radcli_join ( hostfqdn , computername , password )
99
- # Join computer
100
- enroll = Adcli ::AdEnroll . new ( @adconn )
101
- enroll . set_computer_name ( computername )
102
- enroll . set_host_fqdn ( hostfqdn )
103
- enroll . set_domain_ou ( @ou ) if @ou
104
- enroll . set_computer_password ( password )
105
- 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
106
111
end
107
112
108
113
def generate_password
@@ -126,5 +131,66 @@ def radcli_delete(computername)
126
131
enroll . set_domain_ou ( @ou ) if @ou
127
132
enroll . delete
128
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
+
129
195
end
130
196
end
0 commit comments