aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStevan Radaković <stevan.radakovic@linaro.org>2013-03-20 12:15:13 +0100
committerStevan Radaković <stevan.radakovic@linaro.org>2013-03-20 12:15:13 +0100
commitba7c038a979cda38ed0497b2c7950e8023793e89 (patch)
tree465d2798f7f70dbe4979bbd805bc989943356ebf
parent078981901a4c8c74505bb1a6b52b35bacff8b03f (diff)
System sync added.
-rw-r--r--INSTALL7
-rw-r--r--scripts/ldap_sync.py135
2 files changed, 132 insertions, 10 deletions
diff --git a/INSTALL b/INSTALL
index 0116833..eff25ab 100644
--- a/INSTALL
+++ b/INSTALL
@@ -47,6 +47,7 @@ Dependencies
* build-essential
* git
* mercurial (v2.4.1, not in Ubuntu repositories, need to install via pip)
+ * members
* pgadmin3
* postgresql-9.1
* postgresql-server-dev-9.1
@@ -401,8 +402,10 @@ Upgrading the Rhodecode instance
The rhodecode-setup script also supports update of the Rhodecode to the
specific tag or branch, while doing the reinstallation of the Rhodecode
-automatically. Downgrade of the database is not supported by the Rhodecode
-tools, so bare this in mind when updating to an older version/tag/branch.
+automatically.
+
+IMPORTANT: Database downgrade is not supported by the Rhodecode tools,
+so bare this in mind when updating to an older version/tag/branch.
To update the system to a specific tag/branch run the following command
from the rhodecode-config base directory:
diff --git a/scripts/ldap_sync.py b/scripts/ldap_sync.py
index e592211..09a2d6a 100644
--- a/scripts/ldap_sync.py
+++ b/scripts/ldap_sync.py
@@ -11,19 +11,21 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
+import json
import ldap
import logging
import logging.config
+import os
+import subprocess
import urllib2
import uuid
-import json
from ConfigParser import ConfigParser
config = ConfigParser()
-config.read('sync.conf')
+config.read('sync.conf.tmp')
-logging.config.fileConfig('sync.conf')
+logging.config.fileConfig('sync.conf.tmp')
logger = logging.getLogger()
@@ -43,6 +45,60 @@ class UserNotInGroupError(Exception):
''' User is not a member of the target group. '''
+class SystemCommand():
+
+ @classmethod
+ def execute(cls, cmd_args, with_sudo=True):
+ """Runs the command passed."""
+ if not isinstance(cmd_args, list):
+ cmd_args = list(cmd_args)
+ if with_sudo:
+ cmd_args.insert(0, "sudo")
+
+ with open(os.devnull, 'w') as tempf:
+ process = subprocess.Popen(cmd_args, stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE, shell=True,
+ env=os.environ)
+ (stdout, stderr) = process.communicate()
+
+ if process.returncode != 0:
+ logger.warn("Error executing command: '%s'. Reason: %s." %
+ (" ".join(cmd_args), stderr))
+ else:
+ logger.debug("Sucess executing command %s. Output: %s" % (cmd_args,
+ stdout))
+
+ return stdout
+
+ @classmethod
+ def add_group(cls, groupname):
+ cmd_args = ["groupadd", groupname]
+ cls.execute(cmd_args)
+
+ @classmethod
+ def add_user(cls, username):
+ cmd_args = ["adduser", "--disabled-password",
+ "--quiet", "--gecos", "''", username]
+ cls.execute(cmd_args)
+
+ @classmethod
+ def add_user_to_group(cls, groupname, username):
+ cmd_args = ["gpasswd", "-a", username, groupname]
+ cls.execute(cmd_args)
+
+ @classmethod
+ def remove_user_from_group(cls, groupname, username):
+ cmd_args = ["gpasswd", "-d", username, groupname]
+ cls.execute(cmd_args)
+
+ @classmethod
+ def get_group_members(cls, groupname):
+ cmd_args = ["members --all %s" % groupname]
+ output = cls.execute(cmd_args, with_sudo=False)
+ users = output.split()
+ return users
+
+
class RhodecodeAPI():
def __init__(self, url, key):
@@ -155,6 +211,20 @@ class LdapClient():
return groups
+ def get_users(self):
+ """Get all the users in form of dict {username: ssh_key,...}."""
+ searchFilter = "(uid=*)"
+ result = self.client.search_s(self.base_dn, ldap.SCOPE_SUBTREE,
+ searchFilter)
+
+ users = {}
+ for user in result:
+ # Ignore users who don't have the SSH key.
+ if 'sshPublicKey' in user[1]:
+ users[user[1]['uid'][0]] = user[1]['sshPublicKey'][0]
+
+ return users
+
def get_group_users(self, groups, group):
"""Returns all the users belonging to a single group.
@@ -191,11 +261,27 @@ class LdapSync():
self.rhodecode_api = RhodecodeAPI(config.get("ldap_config", "api_url"),
config.get("ldap_config", "api_key"))
+ def get_ldap_groups(self):
+ """Fetch the LDAP groups if they are not already present."""
+ try:
+ return self.ldap_groups
+ except:
+ self.ldap_groups = self.ldap_client.get_groups()
+ return self.ldap_groups
+
+ def get_ldap_users(self):
+ """Fetch the LDAP users if they are not already present."""
+ try:
+ return self.ldap_users
+ except:
+ self.ldap_users = self.ldap_client.get_users()
+ return self.ldap_users
+
def update_groups_from_ldap(self):
"""Add all the groups from LDAP to Rhodecode."""
logger.info("Start importing groups to Rhodecode.")
added = existing = 0
- groups = self.ldap_client.get_groups()
+ groups = self.get_ldap_groups()
for group in groups:
try:
self.rhodecode_api.create_group(group)
@@ -209,9 +295,9 @@ class LdapSync():
"Added: %s, Existing: %s." % (added, existing))
def update_memberships_from_ldap(self, group):
- """Update memberships in rhodecode based on the LDAP groups."""
- groups = self.ldap_client.get_groups()
- group_users = self.ldap_client.get_group_users(groups, group)
+ """Update rhodecode memberships based on the LDAP groups."""
+ group_users = self.ldap_client.get_group_users(self.get_ldap_groups(),
+ group)
# Delete memberships first from each group which are not part
# of the group any more.
@@ -246,12 +332,45 @@ class LdapSync():
"added to the group %s. Reason: %s" % (member, group, e))
+ def update_system_groups(self):
+ """Add all LDAP groups to system."""
+ for group in self.get_ldap_groups():
+ SystemCommand.add_group(group)
+
+ def update_system_memberships(self):
+ """Update system memberships based on the LDAP groups."""
+ group_users = self.ldap_client.get_group_users(self.get_ldap_groups(),
+ group)
+
+ # Delete memberships first from each group which are not part
+ # of the group any more.
+ logger.debug("Remove memberships for users not in LDAP group.")
+
+ system_members = SystemCommand.get_group_members(group)
+
+ for system_member in system_members:
+ if system_member not in group_users:
+ SystemCommand.remove_user_from_group(group, system_member)
+
+ # Add memberships.
+ for member in group_users:
+ SystemCommand.add_user_to_group(group, member)
+
+ def update_system(self):
+ """Update system groups and memberships."""
+ sync.update_system_groups()
+ sync.update_system_memberships()
+
+
if __name__ == '__main__':
sync = LdapSync()
sync.update_groups_from_ldap()
- groups = sync.ldap_client.get_groups()
+ groups = sync.get_ldap_groups()
for group in groups:
sync.update_memberships_from_ldap(group)
+
+ # Update system group, users and memberships
+ sync.update_system()