[node-patches] Change in ovirt-node[master]: Initial push of puppet plugin code to ovirt repo

fabiand at fedoraproject.org fabiand at fedoraproject.org
Wed Jun 19 15:28:19 UTC 2013


Hello Ryan Barry,

I'd like you to do a code review.  Please visit

    http://gerrit.ovirt.org/15895

to review the following change.

Change subject: Initial push of puppet plugin code to ovirt repo
......................................................................

Initial push of puppet plugin code to ovirt repo

Move puppet plugin location

Change-Id: Ie4a6141e6c78e5dcd5d9357ce701573cd0433082
Signed-off-by: Ryan Barry <rbarry at redhat.com>
---
M .gitignore
M ovirt-node.spec.in
M plugins/Makefile.am
A plugins/ovirt.rb
A plugins/puppet-operatingsystem.rb.patch
A plugins/puppet.minimize
A plugins/puppet/provider/lib/ovirt_node.rb
A plugins/puppet/provider/type/ovirt_node.rb
M src/Makefile.am
A src/ovirt/node/setup/puppet/__init__.py
A src/ovirt/node/setup/puppet/puppet_page.py
11 files changed, 599 insertions(+), 1 deletion(-)


  git pull ssh://gerrit.ovirt.org:29418/ovirt-node refs/changes/95/15895/1

diff --git a/.gitignore b/.gitignore
index c692167..1f2a6ac 100644
--- a/.gitignore
+++ b/.gitignore
@@ -31,3 +31,6 @@
 tmp
 .checkstyle
 semodule/ovirt.te
+plugins/puppet/build
+*.swp
+*.swo
diff --git a/ovirt-node.spec.in b/ovirt-node.spec.in
index d3fc108..d02c4e7 100644
--- a/ovirt-node.spec.in
+++ b/ovirt-node.spec.in
@@ -112,6 +112,114 @@
 This package is not to be installed on the %{product_family},
 however on a development machine to work with the image.
 
+%package plugin-puppet
+Summary:        Puppet plugin for %{product_family} image
+Group:          Applications/System
+Requires:       puppet
+
+%description plugin-puppet
+This package provides a puppet plugin for use with %{product_family} image.
+
+%post plugin-puppet
+patch -d /usr/share/ruby/vendor_ruby/facter -p0 < \
+   %{app_root}/puppet-plugin/puppet-operatingsystem.rb.patch
+
+cd /etc/puppet
+patch -p0 << EOF
+--- puppet.conf 2013-03-21 14:55:43.969130799 -0700
++++ puppet.conf.new 2013-03-21 14:56:02.690178578 -0700
+@@ -1,4 +1,6 @@
+ [main]
++    server = ""
++    certname = ""
+     # The Puppet log directory.
+     # The default value is '$vardir/log'.
+     logdir = /var/log/puppet
+EOF
+
+cd /usr/libexec
+patch -p0 << EOF
+--- ovirt-init-functions.sh 2013-03-21 15:30:13.078014954 -0700
++++ ovirt-init-functions-new.sh 2013-03-21 16:33:52.893135359 -0700
+@@ -223,6 +223,9 @@
+     #   rhn_proxyuser=PROXY-USERNAME
+     #   rhn_proxypassword=PROXY-PASSWORD
+     #   snmp_password=<authpassphrase>
++    #   puppet_enabled=<y|n>
++    #   puppet_server=server
++    #   puppet_certname=<certname>
+
+     #   BOOTIF=link|eth*|<MAC> (appended by pxelinux)
+     # network boot interface is assumed to be on management network where
+@@ -329,6 +332,14 @@
+     cim_passwd=
+     cim_enabled=
+
++    # Puppet related options
++    # puppet_enabled=y|n
++    # puppet_server=server
++    # puppet_certname=<certname>
++    puppet_enabled=
++    puppet_server=
++    puppet_certame=
++
+     #   pxelinux format: ip=<client-ip>:<boot-server-ip>:<gw-ip>:<netmask>
+     #   anaconda format: ip=<client-ip> netmask=<netmask> gateway=<gw-ip>
+     #   or               ip=dhcp|off
+@@ -613,6 +624,19 @@
+             snmp_password=${i#snmp_password=}
+             ;;
+
++            puppet_enabled=n | puppet_enabled=0)
++            puppet_enabled=0
++            ;;
++            puppet_enabled* | puppet_enabled=y | puppet_enabled=1)
++            puppet_enabled=1
++            ;;
++            puppet_server=*)
++            puppet_server=${i#puppet_server=}
++            ;;
++            puppet_certname=*)
++            puppet_certname=${i#puppet_certname=}
++            ;;
++
+             mem_overcommit* | ovirt_overcommit*)
+             i=${i#mem_overcommit=}
+             i=${i#ovirt_overcommit=}
+@@ -797,7 +821,7 @@
+
+
+     # save boot parameters as defaults for ovirt-config-*
+-    params="bootif init init_app vol_boot_size vol_efi_size vol_swap_size vol_root_size vol_config_size vol_logging_size vol_data_size vol_swap2_size vol_data2_size crypt_swap crypt_swap2 upgrade standalone overcommit ip_address ip_netmask ip_gateway ipv6 dns ntp vlan ssh_pwauth syslog_server syslog_port collectd_server collectd_port bootparams hostname firstboot rhn_type rhn_url rhn_ca_cert rhn_username rhn_password rhn_profile rhn_activationkey rhn_org rhn_proxy rhn_proxyuser rhn_proxypassword runtime_mode kdump_nfs iscsi_name snmp_password install netconsole_server netconsole_port stateless cim_enabled wipe_fakeraid iscsi_init iscsi_target_name iscsi_target_host iscsi_target_port iscsi_install"
++    params="bootif init init_app vol_boot_size vol_efi_size vol_swap_size vol_root_size vol_config_size vol_logging_size vol_data_size vol_swap2_size vol_data2_size crypt_swap crypt_swap2 upgrade standalone overcommit ip_address ip_netmask ip_gateway ipv6 dns ntp vlan ssh_pwauth syslog_server syslog_port collectd_server collectd_port bootparams hostname firstboot rhn_type rhn_url rhn_ca_cert rhn_username rhn_password rhn_profile rhn_activationkey rhn_org rhn_proxy rhn_proxyuser rhn_proxypassword runtime_mode kdump_nfs iscsi_name snmp_password install netconsole_server netconsole_port stateless cim_enabled wipe_fakeraid iscsi_init iscsi_target_name iscsi_target_host iscsi_target_port iscsi_install puppet_enabled puppet_server puppet_certname"
+     # mount /config unless firstboot is forced
+     if [ "$firstboot" != "1" ]; then
+         mount_config
+@@ -855,6 +879,13 @@
+         /usr/sbin/usermod -p "$rootpw" root
+         chage -d 0 root
+     fi
++    if [ "$puppet_enabled" = 1]; then
++        if [ `hostname` != "localhost" ] | [ -n $puppet_certname ]; then
++            python -c "from ovirt.node.setup.puppet_page import *; ActivatePuppet()"
++        else
++            log "Puppet disabled. Hostname not set and puppet_certname not specified"
++        fi
++    fi
+     # check if root or admin password is expired, this might be upon reboot
+     # in case of automated installed with rootpw or adminpw parameter!
+     if LC_ALL=C chage -l root | grep  -q "password must be changed" \
+@@ -1373,8 +1404,6 @@
+     return $?
+ }
+
+-
+-
+ #
+ # If called with a param from .service file:
+ #
+EOF
+
 
 %package plugin-snmp
 Summary:        SNMP plugin for %{product_family} image
@@ -443,6 +551,12 @@
 %{_sbindir}/testable-node
 %{_mandir}/man8/edit-node.8.gz
 
+%files plugin-puppet
+%{python_sitelib}/ovirt/node/setup/puppet/__init__.py*
+%{python_sitelib}/ovirt/node/setup/puppet/puppet_page.py*
+%{_localstatedir}/lib/puppet/facts/ovirt.rb
+%{_sysconfdir}/ovirt-plugins.d/puppet.minimize
+%{app_root}/puppet-plugin/puppet-operatingsystem.rb.patch
 
 %files plugin-snmp
 %{python_sitelib}/ovirt_config_setup/snmp.py
diff --git a/plugins/Makefile.am b/plugins/Makefile.am
index 17e85d2..e59699b 100644
--- a/plugins/Makefile.am
+++ b/plugins/Makefile.am
@@ -18,6 +18,8 @@
 pluginsdir = $(sysconfdir)/ovirt-plugins.d
 pyovirtconfigsetupdir =$(pythondir)/ovirt_config_setup
 pyovirtconfigbootdir = $(sysconfdir)/ovirt-config-boot.d
+puppetplugindir = ${prefix}/share/ovirt-node/puppet-plugin/
+rbovirtsetupdir = $(localstatedir)/lib/puppet/facts
 
 # FIXME this can be removed
 dist_pyovirtconfigsetup_SCRIPTS = \
@@ -26,7 +28,17 @@
 
 dist_plugins_DATA = \
   snmp.minimize \
-  cim.minimize
+  cim.minimize \
+  puppet.minimize
 
 dist_pyovirtconfigboot_SCRIPTS = \
   snmp_autoinstall.py
+
+rbovirtsetup_SCRIPTS = \
+  ovirt.rb
+
+dist_puppetplugin_DATA = \
+  puppet-operatingsystem.rb.patch
+
+EXTRA_DIST = \
+  *.rb
diff --git a/plugins/ovirt.rb b/plugins/ovirt.rb
new file mode 100644
index 0000000..0b914b3
--- /dev/null
+++ b/plugins/ovirt.rb
@@ -0,0 +1,54 @@
+# ovirt.rb - Copyright (C) 2013 Red Hat, Inc.
+# Written by Ryan Barry <rbarry 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.
+
+Facter.add(:operatingsystem) do
+    has_weight 100_000_000
+    confine :kernel => :linux
+    setcode do
+        if FileTest.exists?("/etc/system-release")
+            txt = File.read("/etc/system-release")
+            if txt =~ /^(.*?)\srelease.*/
+                $1
+            end
+        elsif FileTest.exists?("/etc/default/version")
+            txt = File.read("/etc/default/version")
+            if txt =~ /^PRODUCT='(.*?)\s/
+                $1
+            end
+        end
+    end
+end
+
+Facter.add(:operatingsystemrelease) do
+    confine :operatingsystem => %w{oVirt}
+    setcode do
+        if FileText.exists?("/etc/system-release")
+            txt = File.text("/etc/system-release")
+            if txt =~ /.*?release\s(.*?)\s/
+                $1
+            end
+        elsif FileTest.exists?("/etc/default/version")
+            txt = File.read("/etc/default/version")
+            if txt =~ /^VERSION=(.*)/
+                $1
+            else
+                "unknown"
+            end
+        end
+    end
+end
diff --git a/plugins/puppet-operatingsystem.rb.patch b/plugins/puppet-operatingsystem.rb.patch
new file mode 100644
index 0000000..ff19ba5
--- /dev/null
+++ b/plugins/puppet-operatingsystem.rb.patch
@@ -0,0 +1,26 @@
+    --- operatingsystem.rb  2013-03-19 16:12:46.610079038 -0700 124
++++ operatingsystemnew.rb   2013-03-21 11:51:59.199657472 -0700 125
+@@ -10,6 +10,9 @@   126
+ #  127
+ # Caveats: 128
+ #  129
++#  130
++\$LOAD_PATH.unshift('/var/lib/puppet/facts')   131
++require 'ovirt.rb' 132
+133
+ Facter.add(:operatingsystem) do    134
+   confine :kernel => :sunos    135
+@@ -25,7 +28,12 @@  136
+ Facter.add(:operatingsystem) do    137
+   confine :kernel => :linux    138
+   setcode do   139
+-    if Facter.value(:lsbdistid) == "Ubuntu"    140
++    if FileTest.exists?("/etc/default/version")    141
++        txt = File.read("/etc/default/version")    142
++        if txt =~ /^PRODUCT='(.*?)\s/  143
++            $1 144
++        end    145
++    elsif Facter.value(:lsbdistid) == "Ubuntu" 146
+        "Ubuntu"    147
+     elsif FileTest.exists?("/etc/debian_version")  148
+       "Debian"
diff --git a/plugins/puppet.minimize b/plugins/puppet.minimize
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/plugins/puppet.minimize
diff --git a/plugins/puppet/provider/lib/ovirt_node.rb b/plugins/puppet/provider/lib/ovirt_node.rb
new file mode 100644
index 0000000..9b63868
--- /dev/null
+++ b/plugins/puppet/provider/lib/ovirt_node.rb
@@ -0,0 +1,131 @@
+# ovirt_node.rb - Copyright (C) 2013 Red Hat, Inc.
+# Written by Ryan Barry <rbarry 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.
+
+require 'fileutils'
+require 'filetest'
+require 'augeas'
+
+Puppet::Type.type(:ovirt_node).provide(:ovirt) do
+    commands :python => "/usr/bin/python"
+
+    def initialize(value={})
+        super(value)
+        @property_flush = {}
+    end
+
+    def update_wrapper(type, value)
+        python("-c 'from ovirt.node.config import defaults; model = defaults.#{type}(); model.update(#{value}); tx = model.transaction(); tx()'")
+    end
+
+    def instances
+        config_vars = %w[hostname ssh_pwauth dns ip_address ip_gateway ip_netmask
+                         management_server use_strong_rng]
+        if FileTests.exists?("/etc/pki/vdsm/certs/engine_web_ca.pem")
+          engine = %x(openssl x509 -in /etc/pki/vdsm/certs/engine_web_ca.pem -noout -issuer).
+              match(/CN=CA-(.*?)\.\d+$/)
+          if engine?
+              vars = {}
+#              augtool = %x(augtool print /files/etc/default/ovirt | grep = | awk '{print $1}')
+              keys = Hash[keys.split("\n").collect.map { |x| [x, nil] } ]
+              keys.each.key do |key|
+                  if config_vars.include? "OVIRT_#{key}".downcase
+                      Augeas::open do |aug|
+                          x = aug.get(key)
+                          vars[key.split("/").last.to_sym] = x
+                      end
+                  end
+              end
+              new(vars)
+          end
+        end
+    end
+
+    def exists?
+        `openssl x509 -in /etc/pki/vdsm/certs/engine_web_ca.pem -noout -issuer`
+        .match(/CN=CA-#{@resource[:address]}/) ? true : false
+    end
+
+    def address=(engine)
+        puts "Do nothing"
+        #Waiting to see logic from new VDSM plugin
+    end
+
+    def nfsdomain=(domain)
+        # The py snippet below will only change the runtime configuratio (NFSv4 domain)
+        # To make persistent changes we'll need to use the ovirt.node.config.defaults
+        # module, which gives us access to all topics which are covered by Node's logic.
+        # ovirt.node.utils.* modules only change the runtime config, but don't persist the
+        # changes.
+        # See ssh_pwauth for a complete example
+        update_wrapper("NFS", domain)
+    end
+
+    def iscsi_initiator=(name)
+        update_wrapper("iSCSI", name)
+    end
+
+    def ssh=(bool)
+        # It needs to be ensured that #{bool} is either True or False (so a bool in py syntax)
+        value = ""
+        if bool
+            value = "True"
+        else
+            value = "False"
+        end
+        update_wrapper("SSH", value)
+    end
+
+    def kdump=(options)
+        kdump = options.first
+        kdump.each do |type, server|
+            if type.downcase == "ssh"
+                #It's SSH
+                update_wrapper("KDump", "None, #{server}, None")
+            elsif type.downcase == "nfs"
+                update_wrapper("KDump", "#{server}, None, None")
+            end
+        end
+    end
+
+    def rsyslog=(server)
+        server, port = server.split(":")[0]
+        port = port ? port : 514
+        update_wrapper("Syslog", "#{server}, #{port}")
+    end
+
+    def netconsole=(server)
+        server, port = server.split(":")[0]
+        port = port ? port : 6666
+        update_wrapper("Netconsole", "#{server}, #{port}")
+    end
+
+    def monitoring=(server)
+        server, port = server.split(":")[0]
+        port = port ? port : 7634
+        update_wrapper("Collectd", "#{server}, #{port}")
+    end
+
+    def ntp=(servers)
+        update_wrapper("Timeservers", "[#{servers.join(", ")}]")
+    end
+
+    def ntp=(servers)
+        update_wrapper("Nameservers", "[#{servers.join(", ")}]")
+    end
+
+end
diff --git a/plugins/puppet/provider/type/ovirt_node.rb b/plugins/puppet/provider/type/ovirt_node.rb
new file mode 100644
index 0000000..09961a0
--- /dev/null
+++ b/plugins/puppet/provider/type/ovirt_node.rb
@@ -0,0 +1,67 @@
+# ovirt_node.rb - Copyright (C) 2013 Red Hat, Inc.
+# Written by Ryan Barry <rbarry 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.
+
+Puppet::Type.newtype(:ovirt_node) do
+
+    ensurable
+
+    newparam(:address, :namevar => true) do
+        desc "The address of the engine"
+    end
+
+    newparam(:nfsdomain) do
+        desc "The NFSv4 domain for the node"
+    end
+
+    newparam(:iscsi_initiator) do
+        desc "The iSCSI Initiator Name"
+    end
+
+    newparam(:kdump) do
+        desc "kdump configuration"
+    end
+
+    newparam(:ssh) do
+        desc "Enable SSH authentication"
+        newvalues(:True, :true, :False, :false)
+        defaultto :False
+
+        munge do |value|
+            case value
+            when :true
+                :True
+            when :false
+                :False
+            else
+                super
+            end
+        end
+    end
+
+    newparam(:rsyslog) do
+        desc "RSyslog server"
+    end
+
+    newparam(:netconsole) do
+        desc "Netconsole server"
+    end
+
+    newparam(:monitoring) do
+        desc "Monitoring server"
+    end
+end
diff --git a/src/Makefile.am b/src/Makefile.am
index 11fca04..29de658 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -66,6 +66,7 @@
 # Paths to CIM and SNMP setup plugins
 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_PYTHON = \
@@ -151,3 +152,8 @@
   ovirt/node/setup/snmp/__init__.py \
   ovirt/node/setup/snmp/snmp_page.py \
   ovirt/node/setup/snmp/snmp_model.py
+
+# Setup Puppet Plugin
+pyovirt_node_setup_puppet_PYTHON = \
+  ovirt/node/setup/puppet/__init__.py \
+  ovirt/node/setup/puppet/puppet_page.py
diff --git a/src/ovirt/node/setup/puppet/__init__.py b/src/ovirt/node/setup/puppet/__init__.py
new file mode 100644
index 0000000..896b241
--- /dev/null
+++ b/src/ovirt/node/setup/puppet/__init__.py
@@ -0,0 +1,32 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+#
+# __init__.py - Copyright (C) 2013 Red Hat, Inc.
+# Written by Fabian Deutsch <fabiand 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.
+
+"""
+Puppet Plugin
+"""
+import puppet_page
+
+
+#
+# Magic function to register all plugins to be used
+#
+def createPlugins(application):
+    puppet_page.Plugin(application)
diff --git a/src/ovirt/node/setup/puppet/puppet_page.py b/src/ovirt/node/setup/puppet/puppet_page.py
new file mode 100644
index 0000000..258187f
--- /dev/null
+++ b/src/ovirt/node/setup/puppet/puppet_page.py
@@ -0,0 +1,153 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+#
+# puppet_page.py - Copyright (C) 2013 Red Hat, Inc.
+# Written by Ryan Barry <rbarry 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
+from ovirt.node.config.defaults import NodeConfigFileSection
+from ovirt.node.plugins import Changeset
+import logging
+import socket
+import re
+
+"""
+Configure Puppet
+"""
+
+
+class Plugin(plugins.NodePlugin):
+    _server = None
+
+    def name(self):
+        return "Puppet"
+
+    def rank(self):
+        return 105
+
+    def model(self):
+        cfg = Puppet().retrieve()
+        model = {
+            "puppet.enabled": True if cfg["enabled"] else False,
+            "puppet.server": cfg["server"] or "puppet",
+            "puppet.certname": cfg["certname"] or socket.gethostname()
+        }
+        return model
+
+    def validators(self):
+        return {"puppet.server": valid.FQDNOrIPAddress() | valid.Empty(),
+                }
+
+    def ui_content(self):
+        ws = [ui.Header("header[0]", "Puppet Configuration"),
+              ui.Checkbox("puppet.enabled", "Enable Puppet"),
+              ui.Entry("puppet.server", "Puppet Server:"),
+              ui.Entry("puppet.certname", "Puppet Certificate Name"),
+              ui.Divider("divider[0]"),
+              ]
+
+        page = ui.Page("page", ws)
+        page.buttons = [ui.SaveButton("action.register", "Save & Run")]
+
+        self.widgets.add(page)
+        return page
+
+    def on_change(self, changes):
+        pass
+
+    def on_merge(self, effective_changes):
+        self.logger.info("Saving Puppet config")
+        changes = Changeset(self.pending_changes(False))
+        effective_model = Changeset(self.model())
+        effective_model.update(effective_changes)
+
+        puppet_keys = ["puppet.enabled", "puppet.server", "puppet.certname"]
+        if changes.contains_any(puppet_keys):
+            Puppet().update(*effective_model.values_for(puppet_keys))
+
+        self.logger.debug("Changes: %s" % changes)
+        self.logger.debug("Effective Model: %s" % effective_model)
+
+        txs = utils.Transaction("Configuring Puppet")
+
+        if effective_changes.contains_any(["action.register"]):
+            self.logger.debug("Connecting to puppet")
+            txs += [ActivatePuppet()]
+
+        if len(txs) > 0:
+            progress_dialog = ui.TransactionProgressDialog("dialog.txs", txs,
+                                                           self)
+            progress_dialog.run()
+
+        # Acts like a page reload
+        return self.ui_content()
+
+
+#
+#
+# Functions and classes to support the UI
+#
+#
+class Puppet(NodeConfigFileSection):
+    """Class to handle Puppet configuration in /etc/default/ovirt file
+
+    >>> from ovirt.node.config.defaults import ConfigFile, SimpleProvider
+    >>> fn = "/tmp/cfg_dummy"
+    >>> cfgfile = ConfigFile(fn, SimpleProvider)
+    >>> n = Puppet(cfgfile)
+    >>> n.update("puppet.example.com")
+    >>> sorted(n.retrieve().items())
+    [(server, 'puppet.example.com')]
+    """
+    keys = ("OVIRT_PUPPET_ENABLED",
+            "OVIRT_PUPPET_SERVER",
+            "OVIRT_PUPPET_CERTIFICATE_NAME"
+            )
+
+    @NodeConfigFileSection.map_and_update_defaults_decorator
+    def update(self, enabled, server, certname):
+        valid.Boolean()(enabled)
+        (valid.Empty() | valid.FQDNOrIPAddress())(server)
+        (valid.Empty() | valid.FQDN())(certname)
+        return {"OVIRT_PUPPET_ENABLED": "yes" if enabled else False}
+
+
+class ActivatePuppet(utils.Transaction.Element):
+
+    title = "Activating Puppet"
+
+    def commit(self):
+
+        self.logger.info("Connecting to Puppet server")
+
+        cfg = Puppet().retrieve()
+
+        with open("/etc/puppet/puppet.conf") as conf:
+            lines = conf.readlines()
+        with open("/etc/puppet/puppet.conf", "w") as conf:
+            for line in lines:
+                try:
+                    item = re.match(r'^\s+(\w+) =', line).group(1)
+                    if item in cfg:
+                        conf.write(re.sub(r'(^.*?' + item + ' =).*', r'\1 "' +
+                                          cfg[item] + '"', line))
+                except:
+                    conf.write(line)
+
+        utils.process.call("service puppet stop")
+        utils.process.check_call("puppet agent --test")
+        utils.process.call("service puppet start")


-- 
To view, visit http://gerrit.ovirt.org/15895
To unsubscribe, visit http://gerrit.ovirt.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Ie4a6141e6c78e5dcd5d9357ce701573cd0433082
Gerrit-PatchSet: 1
Gerrit-Project: ovirt-node
Gerrit-Branch: master
Gerrit-Owner: Fabian Deutsch <fabiand at fedoraproject.org>
Gerrit-Reviewer: Ryan Barry <rbarry at redhat.com>



More information about the node-patches mailing list