ovirt-node 2.2.0 release
[ovirt-node.git] / scripts / rhn.py
blobf7d56b9c5a0997dc99c15a12b1520b8dec0c0c97
1 #!/usr/bin/python
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.
21 import os
22 import sys
23 from ovirtnode.ovirtfunctions import *
24 from subprocess import Popen, PIPE, STDOUT
25 from snack import *
26 import _snack
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']
34 # Get cacert location
35 if len(serverurl) > 0:
36 args.append('--serverUrl')
37 args.append(serverurl)
38 location="/etc/sysconfig/rhn/%s" % os.path.basename(cacert)
39 if len(cacert) > 0:
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')
49 args.append(location)
50 ovirt_store_config(location)
51 else:
52 logger.error("Error Downloading Satellite CA cert!")
53 return 3
55 if len(activationkey):
56 args.append('--activationkey')
57 args.append(activationkey)
58 elif len(username):
59 args.append('--username')
60 args.append(username)
61 if len(password):
62 args.append('--password')
63 args.append(password)
64 else:
65 # skip RHN registration when neither activationkey
66 # nor username/password is supplied
67 # return success for AUTO w/o rhn_* parameters
68 return 1
70 if len(profilename):
71 args.append('--profilename')
72 args.append(profilename)
74 if len(proxyhost) > 1:
75 args.append('--proxy')
76 args.append(proxyhost)
77 if len(proxyuser):
78 args.append('--proxyUser')
79 args.append(proxyuser)
80 if len(proxypass):
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))
102 return 0
103 else:
104 if "username/password" in rhn_reg_output:
105 rc = 2
106 else:
107 rc = 1
108 logger.error("Error registering to RHN account!")
109 return rc
111 def parse_host_port(u):
112 if u.count('://') == 1:
113 (proto, u) = u.split('://')
114 else:
115 proto = ''
116 if u.count(':') == 1:
117 (u, port) = u.split(':')
118 try:
119 port=int(port)
120 except:
121 port=0
122 elif proto == 'http':
123 port = 80
124 elif proto == 'https':
125 port = 443
126 else:
127 port = 0
128 host = u.split('/')[0]
129 return (host, port)
131 def run_rhsm( serverurl="", cacert="", activationkey="", username="", password="", profilename="", proxyhost="", proxyuser="", proxypass=""):
132 extra_args = ['--force','--autosubscribe']
133 sm = ['/usr/sbin/subscription-manager']
135 args = list(sm)
136 args.append('register')
137 if len(activationkey):
138 args.append('--activationkey')
139 args.append(activationkey)
140 elif len(username):
141 args.append('--username')
142 args.append(username)
143 if len(password):
144 args.append('--password')
145 args.append(password)
146 else:
147 # skip RHN registration when neither activationkey
148 # nor username/password is supplied
149 # return success for AUTO w/o rhn_* parameters
150 return 1
152 if len(serverurl) > 0:
153 (host, port) = parse_host_port(serverurl)
154 if port == 0:
155 port = "443"
156 else:
157 port = str(port)
158 else:
159 host = "subscription.rhn.redhat.com"
160 port = "443"
161 smconf=list(sm)
162 smconf.append('config')
163 smconf.append('--server.hostname')
164 smconf.append(host)
165 smconf.append('--server.port')
166 smconf.append(port)
167 log(str(smconf))
168 smconf_proc = subprocess.Popen(smconf, shell=False, stdout=PIPE, stderr=STDOUT)
169 smconf_output = smconf_proc.stdout.read()
170 log(smconf_proc)
171 if smconf_proc.wait() == 0:
172 ovirt_store_config("/etc/rhsm/rhsm.conf")
174 if len(profilename):
175 args.append('--name')
176 args.append(profilename)
178 if len(proxyhost) > 1:
179 args.append('--proxy')
180 args.append(proxyhost)
181 if len(proxyuser):
182 args.append('--proxyuser')
183 args.append(proxyuser)
184 if len(proxypass):
185 args.append('--proxypassword')
186 args.append(proxypass)
188 args.extend(extra_args)
190 log("Registering to RHN account.....")
192 import glob
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):
198 os.unlink(f)
199 for f in all_rhsm_configs:
200 unlink_if_exists(f)
202 logged_args = str(args).replace(password, "XXXXXXXX")
203 log(logged_args)
204 smreg_proc = subprocess.Popen(args, shell=False, stdout=PIPE, stderr=STDOUT)
205 smreg_output = smreg_proc.stdout.read()
206 log(smreg_output)
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))
211 return 0
212 else:
213 if "username/password" in smreg_output:
214 rc = 2
215 else:
216 rc = 1
217 log("Error registering to RHN account!")
218 return rc
220 def ov(var):
221 if OVIRT_VARS.has_key(var):
222 return OVIRT_VARS[var]
223 else:
224 return ""
226 # AUTO for auto-install
227 #if len(sys.argv):
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)
240 self.rhn_conf = {}
241 def form(self):
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))
267 rhn_grid = Grid(2,2)
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)
312 else:
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)
316 if network_up():
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)
318 else:
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]
324 def action(self):
325 self.ncs.screen.setColor("BUTTON", "black", "red")
326 self.ncs.screen.setColor("ACTBUTTON", "blue", "white")
327 if not network_up():
328 return False
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'])
331 return False
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'])
334 return False
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())
345 else:
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()
358 return True
359 elif reg_rc > 0:
360 if reg_rc == 2:
361 msg = "Invalid Username / Password "
362 elif reg_rc == 3:
363 msg = "Unable to retreive satellite certificate"
364 else:
365 msg = "Check ovirt.log for details"
366 ButtonChoiceWindow(self.ncs.screen, "RHN Configuration", "RHN Configuration Failed\n\n" + msg, buttons = ['Ok'])
367 return False
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
380 msg = ""
381 if not self.rhn_ca.value() == "":
382 if not is_valid_url(self.rhn_ca.value()):
383 msg = "Invalid URL"
384 elif self.rhn_ca.value() == "":
385 msg = "Please input a CA certificate URL"
386 if not msg == "":
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)
394 try:
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()
399 except:
400 pass
401 logger.debug(self.rhn_conf)
402 else:
403 logger.debug("RHN Config does not exist")
404 return
406 def rv(self, var):
407 if self.rhn_conf.has_key(var):
408 return self.rhn_conf[var]
409 else:
410 return ""
412 def public_rhn_callback(self):
413 self.rhn_satellite.setValue(" 0")
414 self.sam.setValue(" 0")
415 self.rhn_url.set("")
416 self.rhn_ca.set("")
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'])
447 def get_plugin(ncs):
448 return Plugin(ncs)