[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