From c70f365cd24e39f36fe9cc0a889bde7065aea22a Mon Sep 17 00:00:00 2001 From: Jarrod Johnson Date: Mon, 14 Jul 2014 14:54:12 -0400 Subject: [PATCH] Add support for RPM builds add supportfor pam authentication --- confluent_client/VERSION | 1 + confluent_client/bin/confetty | 5 ++- confluent_client/buildrpm | 1 + confluent_client/confluent_client.spec.tmpl | 36 ++++++++++++++++++ confluent_client/makesetup | 1 + confluent_client/{setup.py => setup.py.tmpl} | 2 +- confluent_common/VERSION | 1 + confluent_common/confluent_common.spec.tmpl | 34 +++++++++++++++++ confluent_common/{setup.py => setup.py.tmpl} | 2 +- confluent_server/MANIFEST.in | 1 + confluent_server/bin/confluent | 4 +- confluent_server/buildrpm | 9 +++++ confluent_server/confluent/auth.py | 39 +++++++++++++++++++- confluent_server/confluent_server.spec.tmpl | 35 ++++++++++++++++++ confluent_server/makesetup | 3 ++ confluent_server/{setup.py => setup.py.tmpl} | 4 +- confluent_server/sysvinit/confluent | 33 +++++++++++++++++ 17 files changed, 202 insertions(+), 9 deletions(-) create mode 100644 confluent_client/VERSION create mode 120000 confluent_client/buildrpm create mode 100644 confluent_client/confluent_client.spec.tmpl create mode 120000 confluent_client/makesetup rename confluent_client/{setup.py => setup.py.tmpl} (91%) create mode 100644 confluent_common/VERSION create mode 100644 confluent_common/confluent_common.spec.tmpl rename confluent_common/{setup.py => setup.py.tmpl} (91%) create mode 100644 confluent_server/MANIFEST.in create mode 100755 confluent_server/buildrpm create mode 100644 confluent_server/confluent_server.spec.tmpl create mode 100755 confluent_server/makesetup rename confluent_server/{setup.py => setup.py.tmpl} (85%) create mode 100755 confluent_server/sysvinit/confluent diff --git a/confluent_client/VERSION b/confluent_client/VERSION new file mode 100644 index 00000000..9faa1b7a --- /dev/null +++ b/confluent_client/VERSION @@ -0,0 +1 @@ +0.1.5 diff --git a/confluent_client/bin/confetty b/confluent_client/bin/confetty index 837a1bb0..0977621e 100755 --- a/confluent_client/bin/confetty +++ b/confluent_client/bin/confetty @@ -56,8 +56,9 @@ consoleonly = False consolename = "" target = "/" path = os.path.dirname(os.path.realpath(__file__)) -path = os.path.realpath(os.path.join(path, '..')) -sys.path.append(path) +path = os.path.realpath(os.path.join(path, '..', 'lib', 'python')) +if path.startswith('/opt'): + sys.path.append(path) import confluent.tlvdata as tlvdata import confluent.client as client diff --git a/confluent_client/buildrpm b/confluent_client/buildrpm new file mode 120000 index 00000000..e3ac8f68 --- /dev/null +++ b/confluent_client/buildrpm @@ -0,0 +1 @@ +../confluent_server/buildrpm \ No newline at end of file diff --git a/confluent_client/confluent_client.spec.tmpl b/confluent_client/confluent_client.spec.tmpl new file mode 100644 index 00000000..3f692559 --- /dev/null +++ b/confluent_client/confluent_client.spec.tmpl @@ -0,0 +1,36 @@ +%define name confluent_client +%define version #VERSION# +%define release 1 + +Summary: Client libraries and utilities for confluent +Name: %{name} +Version: %{version} +Release: %{release} +Source0: %{name}-%{version}.tar.gz +License: UNKNOWN +Group: Development/Libraries +BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-buildroot +Prefix: %{_prefix} +BuildArch: noarch +Vendor: Jarrod Johnson +Url: http://xcat.sf.net/ +Requires: confluent_common + +%description +This package enables python development and command line access to +a confluent server. + +%prep +%setup -n %{name}-%{version} -n %{name}-%{version} + +%build +python setup.py build + +%install +python setup.py install --single-version-externally-managed -O1 --root=$RPM_BUILD_ROOT --record=INSTALLED_FILES --install-scripts=/opt/confluent/bin --install-purelib=/opt/confluent/lib/python + +%clean +rm -rf $RPM_BUILD_ROOT + +%files -f INSTALLED_FILES +%defattr(-,root,root) diff --git a/confluent_client/makesetup b/confluent_client/makesetup new file mode 120000 index 00000000..4930d195 --- /dev/null +++ b/confluent_client/makesetup @@ -0,0 +1 @@ +../confluent_server/makesetup \ No newline at end of file diff --git a/confluent_client/setup.py b/confluent_client/setup.py.tmpl similarity index 91% rename from confluent_client/setup.py rename to confluent_client/setup.py.tmpl index 78ed2ef9..c0e9b322 100644 --- a/confluent_client/setup.py +++ b/confluent_client/setup.py.tmpl @@ -2,7 +2,7 @@ from setuptools import setup setup( name='confluent_client', - version='0.1.4', + version='#VERSION#', author='Jarrod Johnson', author_email='jbjohnso@us.ibm.com', url='http://xcat.sf.net/', diff --git a/confluent_common/VERSION b/confluent_common/VERSION new file mode 100644 index 00000000..b1e80bb2 --- /dev/null +++ b/confluent_common/VERSION @@ -0,0 +1 @@ +0.1.3 diff --git a/confluent_common/confluent_common.spec.tmpl b/confluent_common/confluent_common.spec.tmpl new file mode 100644 index 00000000..18461bba --- /dev/null +++ b/confluent_common/confluent_common.spec.tmpl @@ -0,0 +1,34 @@ +%define name confluent_common +%define version #VERSION# +%define release 1 + +Summary: common content for confluent client and server +Name: %{name} +Version: %{version} +Release: %{release} +Source0: %{name}-%{version}.tar.gz +License: UNKNOWN +Group: Development/Libraries +BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-buildroot +Prefix: %{_prefix} +BuildArch: noarch +Vendor: Jarrod Johnson +Url: http://xcat.sf.net/ + +%description +This provides the modules common for both client and server + +%prep +%setup -n %{name}-%{version} -n %{name}-%{version} + +%build +python setup.py build + +%install +python setup.py install --single-version-externally-managed -O1 --root=$RPM_BUILD_ROOT --record=INSTALLED_FILES --install-purelib=/opt/confluent/lib/python --install-scripts=/opt/confluent/bin + +%clean +rm -rf $RPM_BUILD_ROOT + +%files -f INSTALLED_FILES +%defattr(-,root,root) diff --git a/confluent_common/setup.py b/confluent_common/setup.py.tmpl similarity index 91% rename from confluent_common/setup.py rename to confluent_common/setup.py.tmpl index ab85f1ed..d378076a 100644 --- a/confluent_common/setup.py +++ b/confluent_common/setup.py.tmpl @@ -2,7 +2,7 @@ from setuptools import setup setup( name='confluent_common', - version='0.1.2', + version='#VERSION#', author='Jarrod Johnson', author_email='jbjohnso@us.ibm.com', description='common content for confluent client and server', diff --git a/confluent_server/MANIFEST.in b/confluent_server/MANIFEST.in new file mode 100644 index 00000000..9a596b39 --- /dev/null +++ b/confluent_server/MANIFEST.in @@ -0,0 +1 @@ +include sysvinit/* diff --git a/confluent_server/bin/confluent b/confluent_server/bin/confluent index 9187ad0e..256fc097 100755 --- a/confluent_server/bin/confluent +++ b/confluent_server/bin/confluent @@ -18,8 +18,8 @@ import sys import os path = os.path.dirname(os.path.realpath(__file__)) -path = os.path.realpath(os.path.join(path, '..')) -if not path.startswith('/usr'): +path = os.path.realpath(os.path.join(path, '..', 'lib', 'python')) +if path.startswith('/opt'): # if installed into system path, do not muck with things sys.path.append(path) from confluent import main diff --git a/confluent_server/buildrpm b/confluent_server/buildrpm new file mode 100755 index 00000000..a641885e --- /dev/null +++ b/confluent_server/buildrpm @@ -0,0 +1,9 @@ +#!/bin/sh +cd `dirname $0` +./makesetup +VERSION=`cat VERSION` +PKGNAME=$(basename $(pwd)) +python setup.py sdist > /dev/null 2>&1 +cp dist/*.tar.gz ~/rpmbuild/SOURCES +sed -e 's/#VERSION#/'$VERSION/ $PKGNAME.spec.tmpl > ~/rpmbuild/SPECS/$PKGNAME.spec +rpmbuild -ba ~/rpmbuild/SPECS/$PKGNAME.spec 2> /dev/null |grep ^Wrote: diff --git a/confluent_server/confluent/auth.py b/confluent_server/confluent/auth.py index 2276dfac..c1576e9b 100644 --- a/confluent_server/confluent/auth.py +++ b/confluent_server/confluent/auth.py @@ -26,14 +26,35 @@ import Crypto.Protocol.KDF as KDF import hashlib import hmac import multiprocessing +import PAM import time +_pamservice = 'confluent' _passcache = {} _passchecking = {} authworkers = None +class Credentials(object): + def __init__(self, username, passphrase): + self.username = username + self.passphrase = passphrase + self.haspam = False + + def pam_conv(self, auth, query_list): + # use stored credentials in a pam conversation + self.haspam = True + resp = [] + for query_entry in query_list: + query, pamtype = query_entry + if query.startswith('Password'): + resp.append((self.passphrase, 0)) + else: + return None + return resp + + def _prune_passcache(): # This function makes sure we don't remember a passphrase in memory more # than 10 seconds @@ -72,7 +93,8 @@ def _get_usertenant(name, tenant=False): yield tenant -def authorize(name, element, tenant=False, operation='create'): +def authorize(name, element, tenant=False, operation='create', + skipuserobj=False): #TODO: actually use the element to ascertain if this user is good enough """Determine whether the given authenticated name is authorized. @@ -90,6 +112,8 @@ def authorize(name, element, tenant=False, operation='create'): if tenant is not None and not configmanager.is_tenant(tenant): return None manager = configmanager.ConfigManager(tenant) + if skipuserobj: + return None, manager, user, tenant userobj = manager.get_user(user) if userobj: # returning return userobj, manager, user, tenant @@ -127,6 +151,17 @@ def check_user_passphrase(name, passphrase, element=None, tenant=False): # would normally make an event and wait # but here there's no need for that eventlet.sleep(0.5) + credobj = Credentials(user, passphrase) + try: + pammy = PAM.pam() + pammy.start(_pamservice, user, credobj.pam_conv) + pammy.authenticate() + pammy.acct_mgmt() + del pammy + return authorize(user, element, tenant, skipuserobj=True) + except PAM.error: + if credobj.haspam: + return None if (user, tenant) in _passcache: if passphrase == _passcache[(user, tenant)]: return authorize(user, element, tenant) @@ -184,4 +219,4 @@ def init_auth(): global authworkers # for now we'll just have one auth worker and see if there is any # demand for more. I personally doubt it. - authworkers = multiprocessing.Pool(processes=1) \ No newline at end of file + authworkers = multiprocessing.Pool(processes=1) diff --git a/confluent_server/confluent_server.spec.tmpl b/confluent_server/confluent_server.spec.tmpl new file mode 100644 index 00000000..ed2113e2 --- /dev/null +++ b/confluent_server/confluent_server.spec.tmpl @@ -0,0 +1,35 @@ +%define name confluent_server +%define version #VERSION# +%define release 1 + +Summary: confluent systems management server +Name: %{name} +Version: %{version} +Release: %{release} +Source0: %{name}-%{version}.tar.gz +License: Apache2 +Group: Development/Libraries +BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-buildroot +Prefix: %{_prefix} +BuildArch: noarch +Requires: pyghmi, eventlet, greenlet, confluent_common, pycrypto >= 2.6.1 +Vendor: Jarrod Johnson +Url: http://xcat.sf.net/ + +%description +Server for console management and systems management aggregation + +%prep +%setup -n %{name}-%{version} -n %{name}-%{version} + +%build +python setup.py build + +%install +python setup.py install --single-version-externally-managed -O1 --root=$RPM_BUILD_ROOT --record=INSTALLED_FILES --install-purelib=/opt/confluent/lib/python --install-scripts=/opt/confluent/bin + +%clean +rm -rf $RPM_BUILD_ROOT + +%files -f INSTALLED_FILES +%defattr(-,root,root) diff --git a/confluent_server/makesetup b/confluent_server/makesetup new file mode 100755 index 00000000..490da3b7 --- /dev/null +++ b/confluent_server/makesetup @@ -0,0 +1,3 @@ +cd `dirname $0` +VERSION=`cat VERSION` +sed -e "s/#VERSION#/$VERSION/" setup.py.tmpl > setup.py diff --git a/confluent_server/setup.py b/confluent_server/setup.py.tmpl similarity index 85% rename from confluent_server/setup.py rename to confluent_server/setup.py.tmpl index 7667a49f..42e02f12 100644 --- a/confluent_server/setup.py +++ b/confluent_server/setup.py.tmpl @@ -1,8 +1,9 @@ from setuptools import setup +import os setup( name='confluent_server', - version='0.1.10', + version='#VERSION#', author='Jarrod Johnson', author_email='jbjohnso@us.ibm.com', url='http://xcat.sf.net/', @@ -13,4 +14,5 @@ setup( install_requires=['pycrypto>=2.6', 'confluent_client>=0.1.0', 'eventlet', 'pyghmi>=0.6.5'], scripts=['bin/confluent'], + data_files=[('/etc/init.d', ['sysvinit/confluent'])], ) diff --git a/confluent_server/sysvinit/confluent b/confluent_server/sysvinit/confluent new file mode 100755 index 00000000..f23435ca --- /dev/null +++ b/confluent_server/sysvinit/confluent @@ -0,0 +1,33 @@ +#!/bin/sh +# IBM(c) 2014 Apache 2.0 +# chkconfig: 345 85 60 +# description: Confluent hardware manager + +### BEGIN INIT INFO +# Provides: confluent +# Default-Start: 3 4 5 +# Default-Stop: 0 1 2 6 +### END INIT INFO + +. /etc/init.d/functions +case $1 in + restart) + echo -n 'Stopping Confluent ' + kill `cat /var/run/confluent/pid` + sleep 5 + echo -n 'Starting Confluent ' + /opt/confluent/bin/confluent + success + ;; + start) + echo -n 'Starting Confluent ' + /opt/confluent/bin/confluent + success + ;; + stop) + echo -n 'Stopping Confluent ' + kill `cat /var/run/confluent/pid` + success + ;; +esac +