[node-patches] Change in ovirt-node[master]: Add an RHN plugin
rbarry at redhat.com
rbarry at redhat.com
Tue May 13 14:11:38 UTC 2014
Ryan Barry has uploaded a new change for review.
Change subject: Add an RHN plugin
......................................................................
Add an RHN plugin
Merge the RHN plugin into upstream
Change-Id: Ia8b34ddd87440077c95389f5a5f2c36e60ea95a8
Signed-off-by: Ryan Barry <rbarry at redhat.com>
---
M ovirt-node.spec.in
M plugins/Makefile.am
A plugins/rhn_autoinstall.py
A plugins/rhn_autoinstall_args
M src/Makefile.am
A src/ovirt/node/setup/rhn/__init__.py
A src/ovirt/node/setup/rhn/rhn_model.py
A src/ovirt/node/setup/rhn/rhn_page.py
8 files changed, 819 insertions(+), 1 deletion(-)
git pull ssh://gerrit.ovirt.org:29418/ovirt-node refs/changes/38/27638/1
diff --git a/ovirt-node.spec.in b/ovirt-node.spec.in
index e232465..1723c31 100644
--- a/ovirt-node.spec.in
+++ b/ovirt-node.spec.in
@@ -251,6 +251,16 @@
#cleanup tmp directory from cim setup
rm -rf /tmp/cim_schema*
+%package plugin-rhn
+Summary: RHN plugin for %{product_family} image
+Group: Applications/System
+Requires: subscription-manager
+Requires: rhn-virtualization-host
+Requires: rhn-setup
+Requires: virt-who
+
+%description plugin-rhn
+This package provides the necessary rhn plugin tools for use with%{product_family} image.
#
# SELinux subpackage
@@ -636,6 +646,13 @@
%endif
%endif
+%files plugin-rhn
+%{python_sitelib}/ovirt/node/setup/rhn/__init__.py*
+%{python_sitelib}/ovirt/node/setup/rhn/rhn_model.py*
+%{python_sitelib}/ovirt/node/setup/rhn/rhn_page.py*
+%{_sysconfdir}/ovirt-commandline.d/rhn_autoinstall_args
+%{_sysconfdir}/ovirt-config-boot.d/rhn_autoinstall.py*
+
%files selinux
%defattr(-,root,root,0755)
diff --git a/plugins/Makefile.am b/plugins/Makefile.am
index 71134e3..f68350c 100644
--- a/plugins/Makefile.am
+++ b/plugins/Makefile.am
@@ -19,6 +19,7 @@
pluginsargsdir = $(sysconfdir)/ovirt-commandline.d
pyovirtconfigsetupdir =$(pythondir)/ovirt_config_setup
pyovirtconfigbootdir = $(sysconfdir)/ovirt-config-boot.d
+pyovirtconfigbootargdir = $(sysconfdir)/ovirt-commandline.d
puppetplugindir = ${prefix}/share/ovirt-node/puppet-plugin/
rbovirtsetupdir = $(localstatedir)/lib/puppet/facts
@@ -35,9 +36,13 @@
dist_pluginsargs_DATA = \
puppet-args
+dist_pyovirtconfigbootarg_DATA = \
+ rhn_autoinstall_args
+
dist_pyovirtconfigboot_PYTHON = \
snmp_autoinstall.py \
- puppet_autoinstall.py
+ puppet_autoinstall.py \
+ rhn_autoinstall.py
rbovirtsetup_SCRIPTS = \
ovirt.rb
diff --git a/plugins/rhn_autoinstall.py b/plugins/rhn_autoinstall.py
new file mode 100644
index 0000000..827733e
--- /dev/null
+++ b/plugins/rhn_autoinstall.py
@@ -0,0 +1,73 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+#
+# rhn_model.py - Copyright (C) 2013 Red Hat, Inc.
+# Written by Joey Boggs <jboggs at redhat.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301, USA. A copy of the GNU General Public License is
+# also available at http://www.gnu.org/copyleft/gpl.html.
+
+from ovirt.node.utils.console import TransactionProgress
+from ovirt.node.setup.rhn import rhn_model
+import ovirtnode.ovirtfunctions as _functions
+from ovirt.node.plugins import Changeset
+
+args = _functions.get_cmdline_args()
+keys = ["rhn_type", "rhn_url", "rhn_ca_cert", "rhn_username",
+ "rhn_profile", "rhn_activationkey", "rhn_org",
+ "rhn_proxy", "rhn_proxyuser"]
+
+keys_to_model = {"rhn_type": "rhn.rhntype",
+ "rhn_url": "rhn.url",
+ "rhn_ca_cert": "rhn.ca_cert",
+ "rhn_username": "rhn.username",
+ "rhn_profile": "rhn.profile",
+ "rhn_activationkey": "rhn.activationkey",
+ "rhn_org": "rhn.org",
+ "rhn_proxy": "rhn.proxy",
+ "rhn_proxyuser": "rhn.proxyuser",
+ }
+
+changes = dict((keys_to_model[key], args[key]) for key in keys if key in args)
+
+if __name__ == "__main__":
+ rhn = rhn_model.RHN()
+ cfg = rhn.retrieve()
+ rhn_password = _functions.OVIRT_VARS["OVIRT_RHN_PASSWORD"] \
+ if "OVIRT_RHN_PASSWORD" in _functions.OVIRT_VARS else ""
+ rhn_proxypassword = _functions.OVIRT_VARS["OVIRT_RHN_PROXYPASSWORD"] \
+ if "OVIRT_RHN_PROXYPASSWORD" in _functions.OVIRT_VARS \
+ else ""
+ effective_model = Changeset({
+ "rhn.rhntype": cfg['rhntype'],
+ "rhn.url": cfg['url'],
+ "rhn.ca_cert": cfg['ca_cert'],
+ "rhn.username": cfg['username'],
+ "rhn.profile": cfg['profile'],
+ "rhn.activationkey": cfg['activationkey'],
+ "rhn.org": cfg['org'],
+ "rhn.proxy": cfg['proxy'],
+ "rhn.proxyuser": cfg['proxyuser'],
+ })
+ effective_model.update(changes)
+ rhn.update(*effective_model.values_for(
+ [keys_to_model[key] for key in keys]))
+ if cfg['username'] and rhn_password or cfg['activationkey']:
+ tx = rhn.transaction(password=rhn_password, \
+ proxypass=rhn_proxypassword)
+ TransactionProgress(tx, is_dry=False).run()
+ # remove /etc/default/ovirt entries from being persisted
+ pw_keys = ("OVIRT_RHN_PASSWORD", "OVIRT_RHN_PROXYPASSWORD")
+ rhn.clear(keys=pw_keys)
diff --git a/plugins/rhn_autoinstall_args b/plugins/rhn_autoinstall_args
new file mode 100644
index 0000000..50da3d1
--- /dev/null
+++ b/plugins/rhn_autoinstall_args
@@ -0,0 +1,11 @@
+rhn_type
+rhn_url
+rhn_ca_cert
+rhn_username
+rhn_password
+rhn_profile
+rhn_activationkey
+rhn_org
+rhn_proxy
+rhn_proxyuser
+rhn_proxypassword
diff --git a/src/Makefile.am b/src/Makefile.am
index 959ac23..7b2a469 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -70,6 +70,7 @@
pyovirt_node_setup_cimdir = $(pyovirt_node_setupdir)/cim
pyovirt_node_setup_snmpdir = $(pyovirt_node_setupdir)/snmp
pyovirt_node_setup_puppetdir = $(pyovirt_node_setupdir)/puppet
+pyovirt_node_setup_rhndir = $(pyovirt_node_setupdir)/rhn
pyovirt_node_setup_ipmidir = $(pyovirt_node_setupdir)/ipmi
@@ -198,6 +199,13 @@
ovirt/node/setup/puppet/puppet_page.py
+# Setup RHN Plugin
+pyovirt_node_setup_rhn_PYTHON = \
+ ovirt/node/setup/rhn/__init__.py \
+ ovirt/node/setup/rhn/rhn_model.py \
+ ovirt/node/setup/rhn/rhn_page.py
+
+
# Setup ipmi Plugin
pyovirt_node_setup_ipmi_PYTHON = \
ovirt/node/setup/ipmi/__init__.py \
diff --git a/src/ovirt/node/setup/rhn/__init__.py b/src/ovirt/node/setup/rhn/__init__.py
new file mode 100644
index 0000000..5ec97f1
--- /dev/null
+++ b/src/ovirt/node/setup/rhn/__init__.py
@@ -0,0 +1,29 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+#
+# __init__.py - Copyright (C) 2013 Red Hat, Inc.
+# Written by Joey Boggs <jboggs at redhat.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301, USA. A copy of the GNU General Public License is
+# also available at http://www.gnu.org/copyleft/gpl.html.
+
+"""
+RHN Plugin
+"""
+import rhn_page
+
+
+def createPlugins(application):
+ rhn_page.Plugin(application)
diff --git a/src/ovirt/node/setup/rhn/rhn_model.py b/src/ovirt/node/setup/rhn/rhn_model.py
new file mode 100644
index 0000000..226ff56
--- /dev/null
+++ b/src/ovirt/node/setup/rhn/rhn_model.py
@@ -0,0 +1,367 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+#
+# rhn_model.py - Copyright (C) 2013 Red Hat, Inc.
+# Written by Joey Boggs <jboggs at redhat.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301, USA. A copy of the GNU General Public License is
+# also available at http://www.gnu.org/copyleft/gpl.html.
+from ovirt.node import utils
+from ovirt.node.config.defaults import NodeConfigFileSection
+from ovirt.node.utils import process
+from ovirtnode.ovirtfunctions import remove_config, ovirt_store_config, \
+ unmount_config
+from urlparse import urlparse
+import sys
+import os.path
+import glob
+import subprocess
+
+
+RHN_XMLRPC_ADDR = "https://xmlrpc.rhn.redhat.com/XMLRPC"
+RHN_SSL_CERT = "/usr/share/rhn/RHNS-CA-CERT"
+
+
+def parse_host_port(url):
+ if url.count('://') == 1:
+ (proto, url) = url.split('://')
+ else:
+ proto = ''
+ if url.count(':') == 1:
+ (url, port) = url.split(':')
+ try:
+ port = int(port)
+ except:
+ port = 0
+ elif proto == 'http':
+ port = 80
+ elif proto == 'https':
+ port = 443
+ else:
+ port = 0
+ host = url.split('/')[0]
+ return (host, port)
+
+
+class RHN(NodeConfigFileSection):
+ """Configure RHN
+
+ >>> from ovirt.node.utils import fs
+ >>> n = RHN(fs.FakeFs.File("dst"))
+ >>> n.update("secret")
+ >>> n.retrieve().items()
+ [('password', 'secret')]
+ """
+ keys = ("OVIRT_RHN_TYPE",
+ "OVIRT_RHN_URL",
+ "OVIRT_RHN_CA_CERT",
+ "OVIRT_RHN_USERNAME",
+ "OVIRT_RHN_PROFILE",
+ "OVIRT_RHN_ACTIVATIONKEY",
+ "OVIRT_RHN_ORG",
+ "OVIRT_RHN_PROXY",
+ "OVIRT_RHN_PROXYUSER")
+
+ @NodeConfigFileSection.map_and_update_defaults_decorator
+ def update(self, rhntype, url, ca_cert, username, profile,
+ activationkey, org, proxy, proxyuser):
+ pass
+
+ def retrieve(self):
+ cfg = dict(NodeConfigFileSection.retrieve(self))
+ return cfg
+
+ def retrieveCert(self, url, dest):
+ try:
+ cmd = ["wget", "-nd", "--no-check-certificate", "--timeout=30",
+ "--tries=3", "-O", dest, url]
+ subprocess.check_call(cmd)
+ except:
+ raise RuntimeError("Error Downloading SSL Certificate!")
+
+ def transaction(self, password, proxypass=None):
+
+ class ConfigureRHNClassic(utils.Transaction.Element):
+ state = ("RHN" if RHN().retrieve()["rhntype"] == "rhn"
+ else "Satellite")
+ title = "Configuring %s" % state
+
+ def commit(self):
+ cfg = RHN().retrieve()
+ self.logger.debug(cfg)
+ rhntype = cfg["rhntype"]
+ serverurl = cfg["url"]
+ cacert = cfg["ca_cert"]
+ activationkey = cfg["activationkey"]
+ username = cfg["username"]
+ profilename = cfg["profile"]
+ proxy = cfg["proxy"]
+ proxyuser = cfg["proxyuser"]
+
+ # novirtinfo: rhn-virtualization daemon refreshes virtinfo
+ extra_args = ['--novirtinfo', '--norhnsd', '--nopackages',
+ '--force']
+ args = ['/usr/sbin/rhnreg_ks']
+ if rhntype == "rhn":
+ sys.path.append("/usr/share/rhn/up2date_client")
+ import rhnreg
+ rhnreg.cfg.set("serverURL", RHN_XMLRPC_ADDR)
+ rhnreg.cfg.set("sslCACert", RHN_SSL_CERT)
+ rhnreg.cfg.save()
+ self.logger.info("ran update")
+ if serverurl:
+ cacert = cacert if cacert is not None else serverurl + \
+ "/pub/RHN-ORG-TRUSTED-SSL-CERT"
+ if not serverurl.endswith("/XMLRPC"):
+ serverurl = serverurl + "/XMLRPC"
+ args.append('--serverUrl')
+ args.append(serverurl)
+ location = "/etc/sysconfig/rhn/%s" % \
+ os.path.basename(cacert)
+ if cacert:
+ if not os.path.exists(cacert):
+ self.logger.info("Downloading CA cert.....")
+ self.logger.debug("From: %s To: %s" %
+ (cacert, location))
+ RHN().retrieveCert(cacert, location)
+ if os.path.isfile(location):
+ if os.stat(location).st_size > 0:
+ args.append('--sslCACert')
+ args.append(location)
+ ovirt_store_config(location)
+ else:
+ raise RuntimeError("Error Downloading \
+ CA cert!")
+ if activationkey:
+ args.append('--activationkey')
+ args.append(activationkey)
+ elif username:
+ args.append('--username')
+ args.append(username)
+ if password:
+ args.append('--password')
+ args.append(password)
+ else:
+ # skip RHN registration when neither activationkey
+ # nor username/password is supplied
+ self.logger.debug("No actiovationkey or username+password given")
+ return
+
+ if profilename:
+ args.append('--profilename')
+ args.append(profilename)
+
+ if proxy:
+ args.append('--proxy')
+ args.append(proxy)
+ if proxyuser:
+ args.append('--proxyUser')
+ args.append(proxyuser)
+ if proxypass:
+ args.append('--proxyPassword')
+ args.append(proxypass)
+ args.extend(extra_args)
+
+ self.logger.info("Registering to RHN account.....")
+ remove_config("/etc/sysconfig/rhn/systemid")
+ remove_config("/etc/sysconfig/rhn/up2date")
+ logged_args = list(args)
+ remove_values_from_args = ["--password", "--proxyPassword"]
+ for idx, arg in enumerate(logged_args):
+ if arg in remove_values_from_args:
+ logged_args[idx+1] = "XXXXXXX"
+ logged_args = str(logged_args)
+ self.logger.debug(logged_args)
+ try:
+ subprocess.check_call(args)
+ ovirt_store_config("/etc/sysconfig/rhn/up2date")
+ ovirt_store_config("/etc/sysconfig/rhn/systemid")
+ self.logger.info("System %s sucessfully registered to %s" %
+ (profilename, serverurl))
+ # sync profile if reregistering, fixes problem with
+ # virt guests not showing
+ sys.path.append("/usr/share/rhn")
+ from virtualization import support
+ support.refresh(True)
+ except:
+ self.logger.exception("Failed to call: %s" % logged_args)
+ raise RuntimeError("Error registering to RHN account")
+
+ class ConfigureSAM(utils.Transaction.Element):
+ title = "Configuring SAM"
+
+ def commit(self):
+ cfg = RHN().retrieve()
+ self.logger.debug(cfg)
+ #rhntype = cfg["rhntype"]
+ org = cfg["org"]
+ serverurl = cfg["url"]
+ cacert = cfg["ca_cert"]
+ activationkey = cfg["activationkey"]
+ username = cfg["username"]
+ profilename = cfg["profile"]
+ proxy = cfg["proxy"]
+ proxyuser = cfg["proxyuser"]
+ if os.path.exists("/etc/sysconfig/rhn/systemid"):
+ remove_config("/etc/sysconfig/rhn/systemid")
+
+ extra_args = ['--force']
+ if not activationkey:
+ extra_args.append("--autosubscribe")
+ sm = ['/usr/sbin/subscription-manager']
+
+ args = list(sm)
+ args.append('register')
+ if activationkey and org:
+ args.append('--activationkey')
+ args.append(activationkey)
+ args.append('--org')
+ args.append(org)
+ elif username:
+ args.append('--username')
+ args.append(username)
+ if password:
+ args.append('--password')
+ args.append(password)
+ else:
+ # skip RHN registration when neither activationkey
+ # nor username/password is supplied
+ # return success for AUTO w/o rhn_* parameters
+ return
+
+ if serverurl:
+ (host, port) = parse_host_port(serverurl)
+ parsed_url = urlparse(serverurl)
+ prefix = parsed_url.path
+ if port == 0:
+ port = "443"
+ else:
+ port = str(port)
+ else:
+ prefix = "/subscription"
+ host = "subscription.rhn.redhat.com"
+ port = "443"
+ location = "/etc/rhsm/ca/candlepin-local.pem"
+ if cacert:
+ if not os.path.exists(cacert):
+ self.logger.info("Downloading CA cert.....")
+ RHN().retrieveCert(cacert, location)
+ if os.path.isfile(location):
+ if os.stat(location).st_size > 0:
+ ovirt_store_config(location)
+ else:
+ raise RuntimeError("Error Downloading CA cert!")
+
+ smconf = list(sm)
+ smconf.append('config')
+ smconf.append('--server.hostname')
+ smconf.append(host)
+ smconf.append('--server.port')
+ smconf.append(port)
+ smconf.append('--server.prefix')
+ smconf.append(prefix)
+
+ if cacert:
+ smconf.append('--rhsm.repo_ca_cert')
+ smconf.append('/etc/rhsm/ca/candlepin-local.pem')
+ try:
+ subprocess.check_call(smconf)
+ ovirt_store_config("/etc/rhsm/rhsm.conf")
+ except:
+ raise RuntimeError("Error updating subscription manager \
+ configuration")
+ if profilename:
+ args.append('--name')
+ args.append(profilename)
+
+ if proxy:
+ try:
+ (host, port) = proxy.split(":")
+ process.check_call(["subscription-manager", "config",
+ "--server.proxy_hostname", host])
+ process.check_call(["subscription-manager", "config",
+ "--server.proxy_port", port])
+ if proxyuser:
+ args.append('--proxyuser')
+ args.append(proxyuser)
+ cmd = ["subscription-manager", "config",
+ "--server.proxy_user", proxyuser]
+ process.check_call(cmd)
+ if proxypass:
+ args.append('--proxypassword')
+ args.append(proxypass)
+ cmd = ["subscription-manager", "config",
+ "--server.proxy_password", proxypass]
+ logged_args = list(cmd)
+ remove_values_from_args = ["--server.proxy_password"]
+ for idx, arg in enumerate(cmd):
+ if arg in remove_values_from_args:
+ logged_args[idx+1] = "XXXXXXX"
+ logged_args = str(logged_args)
+ self.logger.info(logged_args)
+ subprocess.check_call(cmd)
+ except:
+ raise RuntimeError("Error updating subscription \
+ manager proxy configuration")
+ args.extend(extra_args)
+
+ self.logger.info("Registering to RHN account.....")
+
+ rhsm_configs = (["/var/lib/rhsm/cache/installed_products.json",
+ "/var/lib/rhsm/facts/facts.json"])
+ unmount_config(rhsm_configs)
+ unmount_config(glob.glob("/etc/pki/consumer/*pem"))
+
+ def unlink_if_exists(f):
+ if os.path.exists(f):
+ os.unlink(f)
+ for f in rhsm_configs:
+ unlink_if_exists(f)
+
+ logged_args = list(args)
+ remove_values_from_args = ["--password", "--proxypassword"]
+ for idx, arg in enumerate(logged_args):
+ if arg in remove_values_from_args:
+ logged_args[idx+1] = "XXXXXXX"
+ logged_args = str(logged_args)
+ self.logger.info(logged_args)
+
+ smreg_output = process.pipe(args)
+ self.logger.debug(smreg_output)
+ if not "been registered" in smreg_output:
+ if "Invalid credentials" in smreg_output:
+ raise RuntimeError("Invalid Username / Password")
+ elif "already been taken" in smreg_output:
+ raise RuntimeError("Hostname is already " +
+ "registered")
+ else:
+ raise RuntimeError("Registration Failed")
+ else:
+ ovirt_store_config(rhsm_configs)
+ ovirt_store_config("/etc/pki/consumer/key.pem")
+ ovirt_store_config("/etc/pki/consumer/cert.pem")
+ self.logger.info("System %s sucessfully registered \
+ to %s" % (profilename, serverurl))
+
+ cfg = self.retrieve()
+ self.logger.debug(cfg)
+ rhntype = cfg["rhntype"]
+ tx = utils.Transaction("Performing RHN Registration")
+
+ if rhntype == "sam":
+ tx.append(ConfigureSAM())
+ else:
+ tx.append(ConfigureRHNClassic())
+ return tx
diff --git a/src/ovirt/node/setup/rhn/rhn_page.py b/src/ovirt/node/setup/rhn/rhn_page.py
new file mode 100644
index 0000000..ba09d0a
--- /dev/null
+++ b/src/ovirt/node/setup/rhn/rhn_page.py
@@ -0,0 +1,308 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+#
+# rhn_page.py - Copyright (C) 2013 Red Hat, Inc.
+# Written by Joey Boggs <jboggs at redhat.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301, USA. A copy of the GNU General Public License is
+# also available at http://www.gnu.org/copyleft/gpl.html.
+from ovirt.node import plugins, valid, ui, utils
+import rhn_model
+from ovirt.node.plugins import Changeset
+from ovirt.node.utils import process
+from ovirt.node.utils.network import NodeNetwork
+import os.path
+import logging
+import sys
+sys.path.append("/usr/share/rhn/up2date_client")
+
+
+RHN_CONFIG_FILE = "/etc/sysconfig/rhn/up2date"
+RHSM_CONFIG_FILE = "/etc/rhsm/rhsm.conf"
+RHN_XMLRPC_ADDR = "https://xmlrpc.rhn.redhat.com/XMLRPC"
+SAM_REG_ADDR = "subscription.rhn.redhat.com"
+CANDLEPIN_CERT_FILE = "/etc/rhsm/ca/candlepin-local.pem"
+
+logger = logging.getLogger(__name__)
+
+
+def get_rhn_config():
+ conf_files = []
+ if os.path.exists(RHN_CONFIG_FILE):
+ conf_files.append(RHN_CONFIG_FILE)
+ if os.path.exists(RHSM_CONFIG_FILE):
+ conf_files.append(RHSM_CONFIG_FILE)
+ rhn_conf = {}
+ for f in conf_files:
+ rhn_config = open(f)
+ for line in rhn_config:
+ if "=" in line and "[comment]" not in line:
+ item, value = line.replace(" ", "").split("=")
+ rhn_conf[item] = value.strip()
+ rhn_config.close()
+ return rhn_conf
+
+
+def rhn_check():
+ filebased = True
+ registered = False
+ if filebased:
+ # The following file exists when the sys is registered with rhn
+ registered = os.path.exists("/etc/sysconfig/rhn/systemid")
+ else:
+ if process.check_call("rhn_check"):
+ registered = True
+ return registered
+
+
+def sam_check():
+ import rhnreg
+ if rhnreg.rhsm_registered():
+ return True
+ return False
+
+
+def get_rhn_status():
+ msg = ""
+ status = 0
+ rhn_conf = get_rhn_config()
+ # local copy, blank proxy password
+ # rhbz#837249
+ for arg in "proxyPassword", "proxy_password":
+ if arg in rhn_conf and rhn_conf[arg] != "":
+ rhn_conf[arg] = "XXXXXXXX"
+ if rhn_check(): # Is Satellite or Hosted
+ status = 1
+ try:
+ if "serverURL" in rhn_conf:
+ if RHN_XMLRPC_ADDR in rhn_conf["serverURL"]:
+ msg = "RHN"
+ else:
+ msg = "Satellite"
+ except:
+ #corrupt up2date config in this case
+ status = 0
+ pass
+ elif sam_check():
+ status = 1
+ msg = "SAM"
+ return (status, msg)
+
+
+class Plugin(plugins.NodePlugin):
+ _model = None
+ _rhn_types = [("rhn", "RHN"),
+ ("satellite", "Satellite"),
+ ("sam", "SAM")]
+
+ def __init__(self, app):
+ super(Plugin, self).__init__(app)
+ self._model = {}
+
+ def has_ui(self):
+ return True
+
+ def name(self):
+ return "RHN Registration"
+
+ def rank(self):
+ return 310
+
+ def model(self):
+ cfg = rhn_model.RHN().retrieve()
+ self.logger.debug(cfg)
+ model = {"rhn.user": "",
+ "rhn.password": "",
+ "rhn.profilename": "",
+ "rhn.type": "",
+ "rhn.url": "",
+ "rhn.ca": "",
+ "rhn.org": "",
+ "rhn.activation_key": "",
+ "rhn.proxyhost": "",
+ "rhn.proxyport": "",
+ "rhn.proxyuser": "",
+ "rhn.proxypassword": "",
+ }
+
+ rhn_conf = get_rhn_config()
+ status, rhn_type = get_rhn_status()
+ model["rhn.type"] = rhn_type.lower()
+ model["rhn.profilename"] = cfg["profile"]
+ if not RHN_XMLRPC_ADDR in rhn_conf["serverURL"] and not sam_check():
+ model["rhn.url"] = rhn_conf["serverURL"] if rhn_conf["serverURL"]\
+ != "https://enter.your.server.url.here/XMLRPC" else ""
+ model["rhn.ca"] = rhn_conf["sslCACert"] if rhn_conf["sslCACert"] \
+ != "/usr/share/rhn/RHN-ORG-TRUSTED-SSL-CERT" else ""
+ elif sam_check():
+ if not SAM_REG_ADDR in rhn_conf["hostname"]:
+ model["rhn.url"] = "https://%s" % rhn_conf["hostname"]
+ if os.path.exists(CANDLEPIN_CERT_FILE):
+ model["rhn.ca"] = CANDLEPIN_CERT_FILE
+ if "proxyUser" in rhn_conf and "proxyPassword" in rhn_conf:
+ if len(rhn_conf["proxyUser"]) > 0:
+ model["rhn.proxyuser"] = rhn_conf["proxyUser"]
+ model["rhn.proxypassword"] = rhn_conf["proxyPassword"]
+ elif "proxy_user" in rhn_conf and "proxy_password" in rhn_conf:
+ model["rhn.proxyuser"] = rhn_conf["proxy_user"]
+ model["rhn.proxypassword"] = rhn_conf["proxy_password"]
+ try:
+ p_server, p_port = rhn_conf["httpProxy"].rsplit(":", 1)
+ model["rhn.proxyhost"] = p_server
+ model["rhn.proxyport"] = p_port
+ except:
+ try:
+ model["rhn.proxyhost"] = rhn_conf["proxy_hostname"]
+ model["rhn.proxyport"] = rhn_conf["proxy_port"]
+ except:
+ pass
+ pass
+ return model
+
+ def validators(self):
+ return {"rhn.user": valid.Text(),
+ "rhn.profilename": valid.Empty() | valid.Text(min_length=3),
+ "rhn.url": valid.Empty() | valid.URL(),
+ "rhn.ca": valid.Empty() | valid.URL(),
+ "rhn.proxyhost": (valid.FQDNOrIPAddress() |
+ valid.URL() | valid.Empty()),
+ "rhn.proxyport": valid.Port() | valid.Empty(),
+ "rhn.proxyuser": valid.Text() | valid.Empty(),
+ }
+
+ def ui_content(self):
+ if self.application.args.dry:
+ net_is_configured = True
+ else:
+ net_is_configured = NodeNetwork().is_configured()
+
+ if not net_is_configured:
+
+ ws = ([ui.Divider("notice.divider"),
+ ui.Notice("network.notice",
+ "Networking is not configured, please " +
+ "configure it before configuring RHN"),
+ ui.Divider("notice.divider")])
+
+ else:
+ status, rhn_type = get_rhn_status()
+ if status == 0:
+ rhn_msg = ("RHN Registration is required only if you wish " +
+ "to use Red Hat Enterprise Linux with virtual " +
+ "guests subscriptions for your guests.")
+ else:
+ rhn_msg = "RHN Registration\n\nRegistration Status: %s" \
+ % rhn_type
+
+ ws = [ui.Header("header[0]", rhn_msg),
+ ui.Entry("rhn.user", "Login:"),
+ ui.PasswordEntry("rhn.password", "Password:"),
+ ui.Entry("rhn.profilename", "Profile Name (optional):"),
+ ui.Divider("divider[0]"),
+ ui.Options("rhn.type", "Type", self._rhn_types),
+ ui.Entry("rhn.url", "URL:"),
+ ui.Entry("rhn.ca", "CA URL:"),
+ ui.Header("header[0]", "HTTP Proxy Configuration"),
+ ui.Entry("rhn.proxyhost", "Server:"),
+ ui.Entry("rhn.proxyport", "Port:"),
+ ui.Entry("rhn.proxyuser", "Username:"),
+ ui.PasswordEntry("rhn.proxypassword", "Password:"),
+ ui.Divider("divider[1]"),
+ ]
+
+ page = ui.Page("page", ws)
+ self.widgets.add(ws)
+ return page
+
+ def on_change(self, changes):
+ net_is_configured = NodeNetwork().is_configured()
+ if "rhn.type" in changes and net_is_configured:
+ self.widgets["rhn.url"].enabled(False)
+ self.widgets["rhn.ca"].enabled(False)
+ if (changes["rhn.type"] == "sam" or
+ changes["rhn.type"] == "satellite"):
+ self.widgets["rhn.url"].enabled(True)
+ self.widgets["rhn.ca"].enabled(True)
+ else:
+ self.widgets["rhn.url"].text("")
+ self.widgets["rhn.ca"].text("")
+
+ def on_merge(self, effective_changes):
+ self.logger.debug("Saving RHN page")
+ changes = Changeset(self.pending_changes(False))
+ effective_model = Changeset(self.model())
+ effective_model.update(effective_changes)
+
+ self.logger.debug("Changes: %s" % changes)
+ self.logger.debug("Effective Model: %s" % effective_model)
+
+ rhn_keys = ["rhn.user", "rhn.password", "rhn.profilename", "rhn.type",
+ "rhn.url", "rhn.ca", "rhn.proxyhost", "rhn.proxyport",
+ "rhn.proxyuser", "rhn.proxypassword", "rhn.org",
+ "rhn.activation_key"]
+
+ txs = utils.Transaction("Updating RHN configuration")
+
+ if changes.contains_any(rhn_keys):
+ self.logger.debug(changes)
+ self.logger.debug(effective_model)
+ user = effective_model["rhn.user"]
+ pw = effective_model["rhn.password"]
+ profilename = effective_model["rhn.profilename"]
+ rhn_type = effective_model["rhn.type"]
+ url = effective_model["rhn.url"]
+ ca = effective_model["rhn.ca"]
+ org = effective_model["rhn.org"]
+ activationkey = effective_model["rhn.activation_key"]
+ proxyhost = effective_model["rhn.proxyhost"]
+ proxyport = effective_model["rhn.proxyport"]
+ proxyuser = effective_model["rhn.proxyuser"]
+ proxypassword = effective_model["rhn.proxypassword"]
+
+ warning_text = ""
+
+ if rhn_type == "sam" or rhn_type == "satellite":
+ if url == "" or url is None:
+ warning_text += "URL "
+
+ if ca == "" or ca is None:
+ if warning_text is "":
+ warning_text += "CA path "
+ else:
+ warning_text += "and CA path "
+
+ if warning_text is not "":
+ txt = "%s must not be empty!" % warning_text
+ self._error_dialog = ui.InfoDialog("dialog.error",
+ "RHN Error",
+ txt)
+ return self._error_dialog
+ else:
+ model = rhn_model.RHN()
+ #join proxy host/port
+ self.logger.debug(proxyhost)
+ self.logger.debug(proxyport)
+ proxy = None
+ if len(proxyhost) > 0 and len(proxyport) > 0:
+ proxy = "%s:%s" % (proxyhost, proxyport)
+ self.logger.debug(proxy)
+ model.update(rhn_type, url, ca, user, profilename,
+ activationkey, org, proxy, proxyuser)
+ txs += model.transaction(password=pw,
+ proxypass=proxypassword)
+ progress_dialog = ui.TransactionProgressDialog("dialog.txs",
+ txs, self)
+ progress_dialog.run()
+ return self.ui_content()
--
To view, visit http://gerrit.ovirt.org/27638
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ia8b34ddd87440077c95389f5a5f2c36e60ea95a8
Gerrit-PatchSet: 1
Gerrit-Project: ovirt-node
Gerrit-Branch: master
Gerrit-Owner: Ryan Barry <rbarry at redhat.com>
More information about the node-patches
mailing list