2 # rhn.py - Copyright (C) 2011 Red Hat, Inc.
3 # Register system to RHN
4 # Written by Joey Boggs <jboggs@redhat.com> and Alan Pevec <apevec@redhat.com>
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; version 2 of the License.
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, write to the Free Software
17 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
18 # MA 02110-1301, USA. A copy of the GNU General Public License is
19 # also available at http://www.gnu.org/copyleft/gpl.html.
23 from ovirtnode
.ovirtfunctions
import *
24 from subprocess
import Popen
, PIPE
, STDOUT
28 RHN_CONFIG_FILE
= "/etc/sysconfig/rhn/up2date"
30 def run_rhnreg( serverurl
="", cacert
="", activationkey
="", username
="", password
="", profilename
="", proxyhost
="", proxyuser
="", proxypass
=""):
31 # novirtinfo: rhn-virtualization daemon refreshes virtinfo
32 extra_args
= ['--novirtinfo','--norhnsd','--nopackages','--force']
33 args
= ['/usr/sbin/rhnreg_ks']
35 if len(serverurl
) > 0:
36 args
.append('--serverUrl')
37 args
.append(serverurl
)
38 location
="/etc/sysconfig/rhn/%s" % os
.path
.basename(cacert
)
40 if not os
.path
.exists(cacert
):
41 logger
.debug("CACert: " + cacert
)
42 logger
.debug("Location: " + location
)
43 logger
.info("Downloading Satellite CA cert.....")
44 logger
.debug("From: " + cacert
+ " To: " + location
)
45 os
.system("wget -q -r -nd --no-check-certificate --timeout=30 --tries=3 -O \"" + location
+"\" \"" + cacert
+ "\"")
46 if os
.path
.isfile(location
):
47 if os
.stat(location
).st_size
> 0:
48 args
.append('--sslCACert')
50 ovirt_store_config(location
)
52 logger
.error("Error Downloading Satellite CA cert!")
55 if len(activationkey
):
56 args
.append('--activationkey')
57 args
.append(activationkey
)
59 args
.append('--username')
62 args
.append('--password')
65 # skip RHN registration when neither activationkey
66 # nor username/password is supplied
67 # return success for AUTO w/o rhn_* parameters
71 args
.append('--profilename')
72 args
.append(profilename
)
74 if len(proxyhost
) > 1:
75 args
.append('--proxy')
76 args
.append(proxyhost
)
78 args
.append('--proxyUser')
79 args
.append(proxyuser
)
81 args
.append('--proxyPassword')
82 args
.append(proxypass
)
84 args
.extend(extra_args
)
86 logger
.info("Registering to RHN account.....")
88 unmount_config("/etc/sysconfig/rhn/systemid")
89 unmount_config("/etc/sysconfig/rhn/up2date")
90 # regenerate up2date config
91 if os
.path
.exists("/etc/sysconfig/rhn/up2date"):
92 os
.unlink("/etc/sysconfig/rhn/up2date")
93 logged_args
= str(args
).replace(password
, "XXXXXXXX")
94 logger
.debug(logged_args
)
95 rhn_reg
= subprocess
.Popen(args
, shell
=False, stdout
=PIPE
, stderr
=STDOUT
)
96 rhn_reg_output
= rhn_reg
.stdout
.read()
97 logger
.debug(rhn_reg_output
)
98 if rhn_reg
.wait() == 0:
99 ovirt_store_config("/etc/sysconfig/rhn/up2date")
100 ovirt_store_config("/etc/sysconfig/rhn/systemid")
101 logger
.info("System %s sucessfully registered to %s" % (profilename
, serverurl
))
104 if "username/password" in rhn_reg_output
:
108 logger
.error("Error registering to RHN account!")
111 def parse_host_port(u
):
112 if u
.count('://') == 1:
113 (proto
, u
) = u
.split('://')
116 if u
.count(':') == 1:
117 (u
, port
) = u
.split(':')
122 elif proto
== 'http':
124 elif proto
== 'https':
128 host
= u
.split('/')[0]
131 def run_rhsm( serverurl
="", cacert
="", activationkey
="", username
="", password
="", profilename
="", proxyhost
="", proxyuser
="", proxypass
=""):
132 extra_args
= ['--force','--autosubscribe']
133 sm
= ['/usr/sbin/subscription-manager']
136 args
.append('register')
137 if len(activationkey
):
138 args
.append('--activationkey')
139 args
.append(activationkey
)
141 args
.append('--username')
142 args
.append(username
)
144 args
.append('--password')
145 args
.append(password
)
147 # skip RHN registration when neither activationkey
148 # nor username/password is supplied
149 # return success for AUTO w/o rhn_* parameters
152 if len(serverurl
) > 0:
153 (host
, port
) = parse_host_port(serverurl
)
159 host
= "subscription.rhn.redhat.com"
162 smconf
.append('config')
163 smconf
.append('--server.hostname')
165 smconf
.append('--server.port')
168 smconf_proc
= subprocess
.Popen(smconf
, shell
=False, stdout
=PIPE
, stderr
=STDOUT
)
169 smconf_output
= smconf_proc
.stdout
.read()
171 if smconf_proc
.wait() == 0:
172 ovirt_store_config("/etc/rhsm/rhsm.conf")
175 args
.append('--name')
176 args
.append(profilename
)
178 if len(proxyhost
) > 1:
179 args
.append('--proxy')
180 args
.append(proxyhost
)
182 args
.append('--proxyuser')
183 args
.append(proxyuser
)
185 args
.append('--proxypassword')
186 args
.append(proxypass
)
188 args
.extend(extra_args
)
190 log("Registering to RHN account.....")
193 all_rhsm_configs
="/var/lib/rhsm/productid.js /var/lib/rhsm/cache/installed_products.json /var/lib/rhsm/facts/facts.json".split()
194 unmount_config(all_rhsm_configs
)
195 unmount_config(glob
.glob("/etc/pki/consumer/*pem"))
196 def unlink_if_exists(f
):
197 if os
.path
.exists(f
):
199 for f
in all_rhsm_configs
:
202 logged_args
= str(args
).replace(password
, "XXXXXXXX")
204 smreg_proc
= subprocess
.Popen(args
, shell
=False, stdout
=PIPE
, stderr
=STDOUT
)
205 smreg_output
= smreg_proc
.stdout
.read()
207 if smreg_proc
.wait() == 0:
208 ovirt_store_config(all_rhsm_configs
)
209 ovirt_store_config(glob
.glob("/etc/pki/consumer/*pem"))
210 log("System %s sucessfully registered to %s" % (profilename
, serverurl
))
213 if "username/password" in smreg_output
:
217 log("Error registering to RHN account!")
221 if OVIRT_VARS
.has_key(var
):
222 return OVIRT_VARS
[var
]
226 # AUTO for auto-install
228 # if sys.argv[1] == "AUTO":
229 # run_rhnreg( ov("OVIRT_RHN_URL"), ov("OVIRT_RHN_CA_CERT"), ov("OVIRT_RHN_ACTIVATIONKEY"), ov("OVIRT_RHN_USERNAME"), ov("OVIRT_RHN_PASSWORD"), ov("OVIRT_RHN_PROFILE"), ov("OVIRT_RHN_PROXY"), ov("OVIRT_RHN_PROXYUSER"), ov("OVIRT_RHN_PROXYPASSWORD") )
232 # configuration UI plugin interface
234 class Plugin(PluginBase
):
235 """Plugin for RHN registration option.
238 def __init__(self
, ncs
):
239 PluginBase
.__init
__(self
, "Red Hat Network", ncs
)
242 elements
= Grid(2, 12)
243 login_grid
= Grid(4,2)
244 self
.rhn_user
= Entry(15, "")
245 self
.rhn_pass
= Entry(15, "", password
= 1)
246 login_grid
.setField(self
.rhn_user
, 1, 0)
247 login_grid
.setField(Label("Login: "), 0, 0, anchorLeft
= 1)
248 login_grid
.setField(Label(" Password: "), 2, 0, anchorLeft
= 1)
249 login_grid
.setField(self
.rhn_pass
, 3, 0, padding
= (0,0,0,1))
250 elements
.setField(login_grid
, 0, 4, anchorLeft
= 1)
251 profile_grid
= Grid(2, 2)
252 self
.profilename
= Entry(30, "")
253 profile_grid
.setField(Label("Profile Name (optional): "), 0, 0, anchorLeft
= 1)
254 profile_grid
.setField(self
.profilename
, 1, 0, anchorLeft
= 1)
255 elements
.setField(profile_grid
, 0, 5, anchorLeft
= 1, padding
= (0, 0, 0, 1))
256 rhn_type_grid
= Grid(3, 2)
257 self
.public_rhn
= Checkbox("RHN ")
258 self
.public_rhn
.setCallback(self
.public_rhn_callback
)
259 self
.rhn_satellite
= Checkbox("Satellite ")
260 self
.rhn_satellite
.setCallback(self
.rhn_satellite_callback
)
261 self
.sam
= Checkbox("Subscription Asset Manager")
262 self
.sam
.setCallback(self
.sam_callback
)
263 rhn_type_grid
.setField(self
.public_rhn
, 0, 0)
264 rhn_type_grid
.setField(self
.rhn_satellite
, 1, 0)
265 rhn_type_grid
.setField(self
.sam
, 2, 0)
266 elements
.setField(rhn_type_grid
, 0, 6, anchorLeft
= 1, padding
= (0, 0, 0, 1))
268 rhn_grid
.setField(Label("URL: "), 0, 0, anchorLeft
= 1)
269 self
.rhn_url
= Entry(40, "")
270 self
.rhn_url
.setCallback(self
.rhn_url_callback
)
271 rhn_grid
.setField(self
.rhn_url
, 1, 0, anchorLeft
= 1, padding
=(1, 0, 0, 0))
272 self
.rhn_ca
= Entry(40, "")
273 self
.rhn_ca
.setCallback(self
.rhn_ca_callback
)
274 rhn_grid
.setField(Label("CA : "), 0, 1, anchorLeft
= 1)
275 rhn_grid
.setField(self
.rhn_ca
, 1, 1, anchorLeft
= 1, padding
=(1, 0, 0, 0))
276 elements
.setField(rhn_grid
, 0, 7, anchorLeft
= 1, padding
= (0, 0, 0, 1))
277 top_proxy_grid
= Grid(4,2)
278 bot_proxy_grid
= Grid(4,2)
279 elements
.setField(Label("HTTP Proxy"), 0, 8, anchorLeft
= 1)
280 self
.proxyhost
= Entry(20, "")
281 self
.proxyport
= Entry(5, "", scroll
= 0)
282 self
.proxyuser
= Entry(14, "")
283 self
.proxypass
= Entry(12, "", password
= 1)
284 self
.proxyhost
.setCallback(self
.proxyhost_callback
)
285 self
.proxyport
.setCallback(self
.proxyport_callback
)
286 top_proxy_grid
.setField(Label("Server: "), 0, 0, anchorLeft
= 1)
287 top_proxy_grid
.setField(self
.proxyhost
, 1, 0, anchorLeft
= 1, padding
= (0, 0, 1, 0))
288 top_proxy_grid
.setField(Label("Port: "), 2, 0, anchorLeft
= 1)
289 top_proxy_grid
.setField(self
.proxyport
, 3, 0, anchorLeft
= 1, padding
= (0, 0, 0, 0))
290 bot_proxy_grid
.setField(Label("Username: "), 0, 0, anchorLeft
= 1)
291 bot_proxy_grid
.setField(self
.proxyuser
, 1, 0, padding
=(0,0,1,0))
292 bot_proxy_grid
.setField(Label("Password: "), 2, 0, anchorLeft
= 1)
293 bot_proxy_grid
.setField(self
.proxypass
, 3, 0, padding
= (0, 0, 0, 0))
294 elements
.setField(top_proxy_grid
, 0, 10, anchorLeft
= 1, padding
= (0, 0, 0, 0))
295 elements
.setField(bot_proxy_grid
, 0, 11, anchorLeft
= 1, padding
= (0, 0, 0, 0))
296 self
.proxyhost
.setCallback(self
.proxyhost_callback
)
297 self
.proxyport
.setCallback(self
.proxyport_callback
)
299 # optional: profilename, proxyhost, proxyuser, proxypass
300 self
.get_rhn_config()
301 if not "https://xmlrpc.rhn.redhat.com/XMLRPC" in self
.rv("serverURL"):
302 self
.rhn_url
.set(self
.rv("serverURL"))
303 self
.rhn_ca
.set(self
.rv("sslCACert"))
304 self
.proxyhost
.set(self
.rv("httpProxy"))
305 self
.proxyuser
.set(self
.rv("proxyUser"))
306 self
.proxypass
.set(self
.rv("proxyPassword"))
307 self
.rhn_actkey
= Entry(40, "")
308 if self
.rhn_url
.value() == "https://xmlrpc.rhn.redhat.com/XMLRPC" or len(self
.rhn_url
.value()) == 0:
309 self
.public_rhn
.setValue("*")
310 self
.rhn_url
.setFlags(_snack
.FLAG_DISABLED
, _snack
.FLAGS_SET
)
311 self
.rhn_ca
.setFlags(_snack
.FLAG_DISABLED
, _snack
.FLAGS_SET
)
313 self
.rhn_satellite
.setValue(" 0")
314 self
.rhn_url
.setFlags(_snack
.FLAG_DISABLED
, _snack
.FLAGS_RESET
)
315 self
.rhn_ca
.setFlags(_snack
.FLAG_DISABLED
, _snack
.FLAGS_RESET
)
317 elements
.setField(Textbox(62,4,"RHN Registration is only required if you wish to use\nRed Hat Enterprise Linux Virtualization or Virtuali-\nzation Platform entitlements for your guests."), 0, 2, anchorLeft
= 1)
319 elements
.setField(Textbox(62,3,"Network Down, Red Hat Network Registration Disabled"), 0, 2, anchorLeft
= 1)
320 for i
in self
.rhn_user
, self
.rhn_pass
, self
.profilename
, self
.public_rhn
, self
.rhn_satellite
, self
.sam
, self
.rhn_url
, self
.rhn_ca
, self
.proxyhost
, self
.proxyport
, self
.proxyuser
, self
.proxypass
:
321 i
.setFlags(_snack
.FLAG_DISABLED
, _snack
.FLAGS_SET
)
322 return [Label(""), elements
]
325 self
.ncs
.screen
.setColor("BUTTON", "black", "red")
326 self
.ncs
.screen
.setColor("ACTBUTTON", "blue", "white")
329 if self
.rhn_satellite
.value() == 1 and self
.rhn_ca
.value() == "":
330 ButtonChoiceWindow(self
.ncs
.screen
, "RHN Configuration", "Please input a CA certificate URL", buttons
= ['Ok'])
332 if len(self
.rhn_user
.value()) < 1 or len(self
.rhn_pass
.value()) < 1:
333 ButtonChoiceWindow(self
.ncs
.screen
, "RHN Configuration", "Login/Password must not be empty\n", buttons
= ['Ok'])
335 if self
.sam
.value() == 1:
336 reg_rc
= run_rhsm( serverurl
=self
.rhn_url
.value(),
337 cacert
=self
.rhn_ca
.value(),
338 activationkey
=self
.rhn_actkey
.value(),
339 username
=self
.rhn_user
.value(),
340 password
=self
.rhn_pass
.value(),
341 profilename
=self
.profilename
.value(),
342 proxyhost
=self
.proxyhost
.value()+ ":" + self
.proxyport
.value(),
343 proxyuser
=self
.proxyuser
.value(),
344 proxypass
=self
.proxypass
.value())
346 reg_rc
= run_rhnreg( serverurl
=self
.rhn_url
.value(),
347 cacert
=self
.rhn_ca
.value(),
348 activationkey
=self
.rhn_actkey
.value(),
349 username
=self
.rhn_user
.value(),
350 password
=self
.rhn_pass
.value(),
351 profilename
=self
.profilename
.value(),
352 proxyhost
=self
.proxyhost
.value()+ ":" + self
.proxyport
.value(),
353 proxyuser
=self
.proxyuser
.value(),
354 proxypass
=self
.proxypass
.value())
355 if reg_rc
== 0 and not False:
356 ButtonChoiceWindow(self
.ncs
.screen
, "RHN Configuration", "RHN Registration Successful", buttons
= ['Ok'])
357 self
.ncs
.reset_screen_colors()
361 msg
= "Invalid Username / Password "
363 msg
= "Unable to retreive satellite certificate"
365 msg
= "Check ovirt.log for details"
366 ButtonChoiceWindow(self
.ncs
.screen
, "RHN Configuration", "RHN Configuration Failed\n\n" + msg
, buttons
= ['Ok'])
369 def rhn_url_callback(self
):
370 # TODO URL validation
371 if not is_valid_url(self
.rhn_url
.value()):
372 self
.ncs
.screen
.setColor("BUTTON", "black", "red")
373 self
.ncs
.screen
.setColor("ACTBUTTON", "blue", "white")
374 ButtonChoiceWindow(self
.ncs
.screen
, "Configuration Check", "Invalid Hostname or Address", buttons
= ['Ok'])
375 if self
.rhn_satellite
.value() == 1:
376 host
= self
.rhn_url
.value().replace("/XMLRPC","")
378 def rhn_ca_callback(self
):
379 # TODO URL validation
381 if not self
.rhn_ca
.value() == "":
382 if not is_valid_url(self
.rhn_ca
.value()):
384 elif self
.rhn_ca
.value() == "":
385 msg
= "Please input a CA certificate URL"
387 self
.ncs
.screen
.setColor("BUTTON", "black", "red")
388 self
.ncs
.screen
.setColor("ACTBUTTON", "blue", "white")
389 ButtonChoiceWindow(self
.ncs
.screen
, "Configuration Check", msg
, buttons
= ['Ok'])
391 def get_rhn_config(self
):
392 if os
.path
.exists(RHN_CONFIG_FILE
):
393 rhn_config
= open(RHN_CONFIG_FILE
)
395 for line
in rhn_config
:
396 if "=" in line
and "[comment]" not in line
:
397 item
, value
= line
.split("=")
398 self
.rhn_conf
[item
] = value
.strip()
401 logger
.debug(self
.rhn_conf
)
403 logger
.debug("RHN Config does not exist")
407 if self
.rhn_conf
.has_key(var
):
408 return self
.rhn_conf
[var
]
412 def public_rhn_callback(self
):
413 self
.rhn_satellite
.setValue(" 0")
414 self
.sam
.setValue(" 0")
417 self
.rhn_url
.setFlags(_snack
.FLAG_DISABLED
, _snack
.FLAGS_SET
)
418 self
.rhn_ca
.setFlags(_snack
.FLAG_DISABLED
, _snack
.FLAGS_SET
)
420 def rhn_satellite_callback(self
):
421 self
.public_rhn
.setValue(" 0")
422 self
.sam
.setValue(" 0")
423 self
.rhn_url
.setFlags(_snack
.FLAG_DISABLED
, _snack
.FLAGS_RESET
)
424 self
.rhn_ca
.setFlags(_snack
.FLAG_DISABLED
, _snack
.FLAGS_RESET
)
426 def sam_callback(self
):
427 self
.public_rhn
.setValue(" 0")
428 self
.rhn_satellite
.setValue(" 0")
429 self
.rhn_url
.setFlags(_snack
.FLAG_DISABLED
, _snack
.FLAGS_RESET
)
430 self
.rhn_ca
.setFlags(_snack
.FLAG_DISABLED
, _snack
.FLAGS_RESET
)
431 ButtonChoiceWindow(self
.ncs
.screen
, "RHN Configuration", "Subscription Asset Manager server is not available presently, please consult\n https://access.redhat.com/kb/docs/DOC-45987", buttons
= ['Ok'])
433 def proxyhost_callback(self
):
434 if len(self
.proxyhost
.value()) > 0:
435 if not is_valid_hostname(self
.proxyhost
.value()):
436 self
.ncs
.screen
.setColor("BUTTON", "black", "red")
437 self
.ncs
.screen
.setColor("ACTBUTTON", "blue", "white")
438 ButtonChoiceWindow(self
.ncs
.screen
, "Configuration Check", "Invalid Proxy Host", buttons
= ['Ok'])
440 def proxyport_callback(self
):
441 if len(self
.proxyport
.value()) > 0:
442 if not is_valid_port(self
.proxyport
.value()):
443 self
.ncs
.screen
.setColor("BUTTON", "black", "red")
444 self
.ncs
.screen
.setColor("ACTBUTTON", "blue", "white")
445 ButtonChoiceWindow(self
.ncs
.screen
, "Configuration Check", "Invalid Proxy Port", buttons
= ['Ok'])