Automation SVN + Apache + LDAP
A lot of things have been written on the above mentioned link, however, I always felt some inconvenience when opening a new repository: it was necessary to create a new location in the configuration file, create a repository using svnadmin, and restart apache. When such work has to be done once a month, this is tolerable, however, when such work has to be done several times a week, it is worth considering automation of this process. Actually, we are talking about this under the cut.
Looking ahead, I want to start with the configuration of apache itself.
Main configuration file /etc/httpd/conf/httpd.conf
Actually, everything is clear here (this is the default location of the config when installing apache from the standard CentOS 5.6 repositories)
/etc/httpd/conf.d/subversion.conf file
This configuration file describes the actual repository configuration. It is worth noting that we put all the locations in the configuration files into the conf.d / subversion.d directory. Why is this necessary? Firstly, it’s easier for us to track which repositories are included, and secondly, we get rid of the parsing of the config when the script starts (more on that below).
File /etc/httpd/conf.d/subversion.d/example_repo.conf
Here we indicate the name and location of the repository, indicate with which account we will look at the AD directory (yes, in this case, AD is used), the password for this account, a string and a search filter. Further, using the directory, we indicate that viewing the repository is allowed to all users authorized in the domain (however, you can specify a specific group in the domain). Next, the next directory, we indicate which group of users in the domain (in this case, example_group) is allowed to perform all other actions with the repository.
Everything is clear with the apache configuration, now we will begin to implement a script with which we will create new repositories. The script should
I used python version 2.7 installed from source with options --prefix = / opt / python2.7 --with-threads --enable-unicode = ucs4 --includedir = / usr / include --disable-ipv6. It will also be necessary to install the python-ldap module (I used setuptools). Below is the actual script itself.
As you can see from the script, I pushed each action into separate functions. I want to note that the configuration file for the repository is created from the skeleton.tpl template, which must be put inside the /etc/httpd/conf.d/subversion.d directory. Template Content
Actually everything. However, users need to provide a list of repositories, through which they can get into any repository and download the desired file from there. This is done in the /etc/httpd/conf.d/subversion.conf file by adding the SVNListParentPath On directive. However, it is necessary that the page with the menu look in a corporate style. And again, I called python to help. In the apache initialization script /etc/init.d/httpd, in the start () function, added the line
File / opt / svn / repo / svn_gen
Here I specifically removed the links to css, so as not to give out the organization in which I work (the colors are too recognizable), but as you understand, you can implement the page to your liking. In this case, you can also use the template, however, the svn_gen script was written even before I was tired of adding repositories with pens.
What I would like to implement in the future
PS Link to the archive with scripts and teplayte addsvnrepo.tar
PSS The code is not perfect, so I will gladly accept any comments.
Looking ahead, I want to start with the configuration of apache itself.
Main configuration file /etc/httpd/conf/httpd.conf
......
# Load config files from the config directory "/etc/httpd/conf.d".#Include conf.d/*.conf
......
Actually, everything is clear here (this is the default location of the config when installing apache from the standard CentOS 5.6 repositories)
/etc/httpd/conf.d/subversion.conf file
LoadModule dav_svn_module modules/mod_dav_svn.so
LoadModule authz_svn_module modules/mod_authz_svn.so
LoadModule authnz_ldap_module modules/mod_authnz_ldap.so
<VirtualHost *:5553>ServerName svn.company.ru
ServerAdmin svn_admin@company.ru
DocumentRoot /opt/svn/repo
LimitRequestBody 2147483647
CustomLog /var/log/httpd/subversion.log combined
ErrorLog /var/log/httpd/subversion-error.log
<IfModule rewrite_module>RewriteLogLevel 0
RewriteEngineOnRewriteCond"%{REQUEST_METHOD}" !"^(GET|POST|HEAD)$"RewriteCond"%{REQUEST_FILENAME}""^/([^/\.]+)$"RewriteCond"/opt/svn/repo/%1" -d
RewriteRule"^/([^/\.]+)$""/$1/" [passthrough]</IfModule>Include conf.d/subversion.d/*.conf
</VirtualHost>This configuration file describes the actual repository configuration. It is worth noting that we put all the locations in the configuration files into the conf.d / subversion.d directory. Why is this necessary? Firstly, it’s easier for us to track which repositories are included, and secondly, we get rid of the parsing of the config when the script starts (more on that below).
File /etc/httpd/conf.d/subversion.d/example_repo.conf
<Location "/example_repo/">
DAV svn
SVNPath /opt/svn/repo/example_repo
SVNListParentPath on
AuthType Basic
AuthName "SVN Server"
AuthBasicProvider ldap
AuthzLDAPAuthoritative Off
AuthLDAPBindDN "cn=ldpcat,cn=users,dc=company,dc=ru"
AuthLDAPBindPassword "12345678"
AuthLDAPURL ldap://ldap.company.ru:389/ou=user,dc=company,dc=ru?sAMAccountName?sub?(objectClass=*)
AuthBasicAuthoritative off
<LimitGET PROPFIND>
Require valid-user
</Limit>
<LimitGET PROFIND PROPPATCH DELETE MERGE PUT POST MKCOL MKACTIVITY COPYMOVELOCK UNLOCK>
Require ldap-group cn=example_group,ou=user,dc=company,dc=ru
</Limit>
</Location>
Here we indicate the name and location of the repository, indicate with which account we will look at the AD directory (yes, in this case, AD is used), the password for this account, a string and a search filter. Further, using the directory, we indicate that viewing the repository is allowed to all users authorized in the domain (however, you can specify a specific group in the domain). Next, the next directory, we indicate which group of users in the domain (in this case, example_group) is allowed to perform all other actions with the repository.
Everything is clear with the apache configuration, now we will begin to implement a script with which we will create new repositories. The script should
- Create an empty repository
- Create configuration file for repository
- Send an information letter to the members of the group that has the right to make changes to the repository
Let's get started.
I used python version 2.7 installed from source with options --prefix = / opt / python2.7 --with-threads --enable-unicode = ucs4 --includedir = / usr / include --disable-ipv6. It will also be necessary to install the python-ldap module (I used setuptools). Below is the actual script itself.
#!/usr/bin/env python2.7# -*- coding: utf-8 -*-import os
import ldap
import ldap.sasl
import sys
import smtplib
from email.mime.text import MIMEText
server_init_file = '/etc/init.d/httpd'
apache_config_dir = '/etc/httpd/conf.d/subversion.d/'
repo_path = '/opt/svn/repo/'
user_owner_repo = 'apache'
group_owner_repo = 'apache'
mail_server = 'mail.company.ru'
mail_smtp_port = 25
mail_from = 'redmine@company.ru'
list_mail = [ ]
root_svn_url = 'http://svn.company.ru/'if len(sys.argv)<=2:
printu"Нет параметров командной строки"printu"в качестве параметра укажи имя репозитория и группу с правом на запись"printu"Пример: addsvnrepo example_repo example_group"
sys.exit()
server = 'ldap://ldap'
user_id = 'ldpcat'
pw = '12345678'
dn_search = 'OU=User,DC=company,DC=ru'
repo_name = sys.argv[1]
group_commit = sys.argv[2]
if repo_name != None:
print"Создаю репозиторий "+repo_name
else:
sys.exit()
defmain():try:
con = ldap.initialize(server)
con.set_option(ldap.OPT_REFERRALS, 0)
con.simple_bind_s(user_id, pw)
print'Подключение выполнено'except ldap.INVALID_CREDENTIALS:
print"Ваш логин или пароль неверны"
sys.exit()
except ldap.LDAPError, e:
if type(e.message) == dict and e.message.has_key('desc'):
print'Error - ' + e.message['desc']
else:
print'Error - ' + str(e)
sys.exit()
finally:
print'Подлючено'
search(con, group_commit)
repo_create()
config_write()
server_reload()
mailer()
defsearch(con, group_commit):try:
base_dn = 'dc=company,dc=ru'
filter = "(memberOf=CN="+group_commit+","+dn_search+")"
attrs = ['mail']
timeout = 3
results = con.search_s(base_dn, ldap.SCOPE_SUBTREE, filter, attrs)
for dn,entry in results:
if dn != None:
list_mail.extend(entry['mail'])
con.unbind()
print list_mail
printu"Подключение закрвыто"except ldap.LDAPError, e:
print'Error - ' + str(e)
sys.exit()
defmailer():
text = u'Репозитоий '
text2 = repo_name
text3 = u' создан.\nРепозиторий доступен по адрессу '
text4 = root_svn_url+repo_name
text5 = u'/\nС наилучшими пожеланиями!\nРобот'
text_s = text+text2+text3+text4+text5
subj = u'Создан репозиторий '+repo_name
msg = MIMEText(text_s, "", "cp1251")
msg['Subject'] = subj
msg['From'] = mail_from
msg['To'] = ', '.join( list_mail )
printu"Мы им отправим"print msg['To']
s = smtplib.SMTP(mail_server, mail_smtp_port)
s.sendmail(msg['From'], list_mail, msg.as_string())
s.quit()
printu"Отправили...."defrepo_create():
svnadmin_create_msg = result = os.popen("svnadmin create "+repo_path+repo_name).read()
print svnadmin_create_msg
chmod_msg = result = os.popen("chown -R "+user_owner_repo+":"+group_owner_repo+" "+repo_path+repo_name).read()
print chmod_msg
defconfig_write():if os.path.exists(apache_config_dir+repo_name+".conf") :
printu"Файл конфигурации уже существует"
sys.exit()
else:
print"Создаём файл конфигурации......"
f1 = open(apache_config_dir+repo_name+".conf", 'w')
f = open(apache_config_dir+"skeleton.tpl", 'r')
body_config = f.read()
f.close()
f1.write(body_config.format(repo_name, repo_path, group_commit, server, dn_search))
f1.close()
defserver_reload():printu'Перезагружаем apache.......'
reload_msg = result = os.popen(server_init_file+" restart").read()
print reload_msg
if __name__=="__main__":
main()
As you can see from the script, I pushed each action into separate functions. I want to note that the configuration file for the repository is created from the skeleton.tpl template, which must be put inside the /etc/httpd/conf.d/subversion.d directory. Template Content
<Location "/{0}/">
DAV svn
SVNPath {1}{0}
SVNListParentPath on
AuthType Basic
AuthName "SVN Server"
AuthBasicProvider ldap
AuthzLDAPAuthoritative Off
AuthLDAPBindDN "cn=ldpcat,cn=users,dc=company,dc=ru"
AuthLDAPBindPassword "12345678"
AuthLDAPURL {3}/{4}?sAMAccountName?sub?(objectClass=*)
AuthBasicAuthoritative off
<LimitGET PROPFIND>
Require valid-user
</Limit>
<Limit PROPPATCH DELETE MERGE PUT POST MKCOL MKACTIVITY COPYMOVELOCK UNLOCK>
Require ldap-group cn={2},{4}
</Limit>
</Location>
Actually everything. However, users need to provide a list of repositories, through which they can get into any repository and download the desired file from there. This is done in the /etc/httpd/conf.d/subversion.conf file by adding the SVNListParentPath On directive. However, it is necessary that the page with the menu look in a corporate style. And again, I called python to help. In the apache initialization script /etc/init.d/httpd, in the start () function, added the line
/opt/svn/repo/svn_gen > /opt/svn/repo/index.htmlFile / opt / svn / repo / svn_gen
#!/usr/bin/env python2.7import os
sdir='/opt/svn/repo/'
r, d, f = os.walk(sdir).next()
lb=len(d)
y=0
addrrepo='http://svn.company.ru/'print"<ul>"while y<lb:
print"<li>"print"<a href='"print addrrepo+d[y]
print"/"print"'"print">"print d[y]
print"</a>"print"<br \>"
y=y+1else:
print"</ul>"print"<hr /"print'<h2>PopoWeb Server running on BolgenOS Server 1.6(fundamentally new system of Denis Popov)</ h2>'Here I specifically removed the links to css, so as not to give out the organization in which I work (the colors are too recognizable), but as you understand, you can implement the page to your liking. In this case, you can also use the template, however, the svn_gen script was written even before I was tired of adding repositories with pens.
What I would like to implement in the future
- Adding configs already for existing repositories
- Disabling and connecting repositories
- List repositories with details (disconnected / connected, which group can commit
- Import from other repositories
- Ideally, create a group and add users to it. However, the addition of objects in AD is not in my
competencearea of responsibility
PS Link to the archive with scripts and teplayte addsvnrepo.tar
PSS The code is not perfect, so I will gladly accept any comments.