我已经从 StackOverflow 迁移了这个问题。
我的额外职责是管理我们公司的 Gitlab-Omnibus(社区版)实例。
Gitlab 使用公司的 Active Directory 服务器进行身份验证。我们的网络管理员会为新员工创建 AD 帐户,并在他们离职后将其删除。Gitlab 通常会在首次登录时创建自己的用户帐户,并在删除 AD 帐户后阻止他们登录。
那么清理那些应该很容易”亡灵“。
问题是:用户没有被封锁,员工离职后 Gitlab 帐户的状态仍为“活动”,因为离职后没有人尝试登录 Gitlab。服务器本身无法通过互联网访问,离职员工无法进入办公室,因为他们的通行证被销毁,他们的电脑被拆卸或格式化并安装了全新的操作系统。
因此,我必须手动尝试模拟每个帐户并检查 Gitlab 是否阻止它(感谢 Gitlab 开发人员提供的模拟功能,至少我得到了这个功能)。
我想自动化这个过程,因为 Gitlab 中有超过 100 个用户帐户,并且我没有收到有关已离开公司的员工的通知(我既不是人力资源经理,也不是系统管理员;我通常也不需要它们,因为有很多员工不需要 Gitlab 帐户)。
我的目标是开发一个脚本或 Ruby 代码片段,我可以将其粘贴到 gitlab-rails 控制台中。
此代码片段应扫描在 Gitlab 中注册的所有用户,检查他们在 LDAP 中的存在并阻止 LDAP 中所有缺失的用户。
然后我会审查所有被阻止的用户,将他们的个人项目转交给他们的主管并将其删除。
问题是我既不熟悉 Ruby,也不熟悉 Gitlab 内部结构。
有什么帮助吗?
我愿意:
irb(main):039:0> User.all
=> #<ActiveRecord::Relation [#<User id:98 @n.name>, #<User id:86 @n.name2>, ...]>
但:
irb(main):040:0> for u in User.all do
irb(main):041:1* puts u
irb(main):042:1> done
irb(main):043:1>
irb(main):044:1* ^C
irb(main):044:0>
无输出。
我究竟做错了什么?
更新
正确的循环语法应该是这样的:
User.all.each { |u| puts u.name }
现在是时候等待某人离开并找到要检查的内容以进行设置u.state = "ldap_blocked"
答案1
Python-gitlab结合解决问题https://ldap3.readthedocs.io/
以下是代码:
import time
from ldap3 import Server, Connection
import gitlab
GITLAB_SERVER = 'https://gitlab.example.com'
LDAP_SERVER = 'ldap.example.com'
no_block = {'root', 'ghost', 'other_custom_user'}
def main():
gl = gitlab.Gitlab(GITLAB_SERVER, private_token='')
server = Server(LDAP_SERVER)
conn = Connection(server,
user='CN=Bind User,CN=Users,DC=example,DC=com',
password='highly_secret_password')
conn.bind()
users = gl.users.list(all=True)
gitlab_users = {u.attributes['username']: u for u in users}
ldap_filter = '(&(objectclass=person)(|' + ''.join(['(samaccountname='+u+')' for u in gitlab_users.keys()]) + '))'
print(conn.search('DC=example,DC=com', ldap_filter, attributes=['cn', 'samaccountname']))
ldap_users = {str(u.sAMAccountName) for u in conn.entries}
to_block = set(gitlab_users.keys()).difference(ldap_users).difference(no_block)
print("Following users will be blocked: {}".format(to_block))
print("Waiting 10 seconds, then block")
time.sleep(10)
for u in to_block:
user = gitlab_users[u]
user.block()
user.save()
if __name__ == '__main__':
main()
答案2
如上所述这里rakegitlab:cleanup:block_removed_ldap_users
任务应该可以完成这项工作。我亲自尝试过,GitLab 中所有缺席 AD 的用户都被阻止了。
答案3
除了 wl2776 非常有用的答案之外,没有必要调用“user.save()”方法。如文档中所示例子当用户属性发生变化时,需要调用“save()”。例如,这必须一起执行
user.name = 'Real Name' user.save()
像 user.block() 和 user.unblock() 这样的函数可以立即应用。