#!/usr/bin/env ruby # vim: sw=2 et ts=2: # Export dev info from LDAP, code partially taken from the wiki group sync # a3li@gentoo.org # encoding: UTF-8 %w[ ldap json ].each {|lib| require lib } class GentooLDAP LDAP_HOST = (1..5).map { |x| sprintf('ldap%d.gentoo.org', x) }.join(' ') LDAP_PORT = 389 DEV_BASE = 'ou=devs,dc=gentoo,dc=org' SYSTEM_BASE = 'ou=system,dc=gentoo,dc=org' SCOPE = LDAP::LDAP_SCOPE_SUBTREE DEV_FILTER = '(objectClass=gentooDev)' @@ldap_host = LDAP_HOST @@ldap_port = LDAP_PORT def self.set_host(host) @@ldap_host = host end def self.set_port(port) @@ldap_port = port end def initialize @ldap = LDAP::SSLConn.new(@@ldap_host, @@ldap_port, true) @ldap.set_option(LDAP::LDAP_OPT_PROTOCOL_VERSION, 3) @ldap.set_option(LDAP::LDAP_OPT_NETWORK_TIMEOUT, 3) # per server @ldap.bind end def get_devs devs = {} @ldap.search(DEV_BASE, SCOPE, DEV_FILTER) do |entry| devs[entry['uid'].first] = entry.to_hash end devs end def get_system_users users = {} @ldap.search(SYSTEM_BASE, SCOPE, DEV_FILTER) do |entry| users[entry['uid'].first] = entry.to_hash end users end end def gpgfp_format(input, nick) return nil if input == 'undefined' raw_fp = input.gsub(/\s/, '') unless raw_fp.length == 40 $stderr.puts "Invalid GPG FP for #{nick}: #{input}" return nil end [36, 32, 28, 24, 20, 20, 16, 12, 8, 4].each {|pos| raw_fp = raw_fp.insert(pos, ' ') } raw_fp end def gpgfp_to_longid(input) "0x%s" % input.gsub(/\s/, '').split(//).last(16).join end def export(data) ret = {} # These are always here ret['name'] = data['cn'].first.force_encoding('UTF-8') ret['nick'] = data['uid'].first ret['roles'] = data['gentooRoles'].first if data.has_key? 'gentooRoles' ret['wiki'] = data['gentooWikiUser'].first if data.has_key? 'gentooWikiUser' ret['gpgfp'] = data['gpgfingerprint'].map {|fp| gpgfp_format(fp, ret['nick']) }.compact if data.has_key? 'gpgfingerprint' ret['gpg'] = ret['gpgfp'].map {|fp| gpgfp_to_longid fp } if data.has_key? 'gpgfingerprint' # Geolocation ret['location'] = data['gentooLocation'].first.force_encoding('UTF-8') if data.has_key? 'gentooLocation' if data.has_key? 'lat' and data.has_key? 'lon' ret['lat'] = data['lat'].first.to_f ret['lon'] = data['lon'].first.to_f end ret['commitaccess'] = ((data['gentooAccess'] or []).include? 'git.gentoo.org/repo/gentoo.git') ret end ldap = GentooLDAP.new devs = ldap.get_devs services = ldap.get_system_users current_devs = {} retired_devs = {} devs.each do |dev, data| if data.has_key? 'gentooStatus' and data['gentooStatus'].first == 'active' current_devs[dev] = data else retired_devs[dev] = data end end data = { 'current' => {}, 'retired' => {}, 'system' => {} } current_devs.keys.sort.each do |dev| data['current'][dev] = export(current_devs[dev]) end retired_devs.keys.sort.each do |dev| data['retired'][dev] = export(retired_devs[dev]) end services.keys.sort.each do |user| data['system'][user] = export(services[user]) end puts data.to_json