数据工厂系列(17)项目管理模块-初始化项目下篇

1,486 阅读4分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第31天,点击查看活动详情

大家好~我是小方,欢迎大家关注笋货测试笔记体完记得俾个like

回顾

上篇中,我们已经介绍了subprocess模块,并完成了初始化项目其中一种方式-http拉取,今天我们来讲下ssh拉取git项目~

前期了解

  • 我们知道拉取代码有两种方式,一种是https,另一种则是ssh;

  • https拉取代码时,输入对应仓库的git账号和密码进行认证,认证通过才能拉取项目

  • 而SSH,本地生成公钥、私钥,公钥配置在对应的账号/仓库中,当需要拉取代码时,远程发送一个随机字符串,本地用私钥将这个随机字符串进行加密,发送到远程,远程通过存放的公钥进行解密,如果解密后与源字符串相同,就可以拉取项目

那问题来了,ssh的私钥和公钥是如何生成的呢?直接输入这个命令即可

ssh-keygen -t rsa -C "xxxx@qq.com"

红色框住分别为私钥和公钥 那数据工厂这边是要怎么生成的呢?总不能这么麻烦的啊!

paramiko模块

ssh公钥和私钥,大部分人用的是Crypto.PublicKey包中的RSA类来模拟ssh生成秘钥,后来跟一位热心的小伙伴闲聊后,发现paramiko可以满足我们的需求

先来安装一下

pip3 install paramiko

实现过程:

  • config.py文件配置公钥和私钥路径

  • 代码实现
import paramiko
from config import FilePath

def generate_ssh_key():
    key = paramiko.RSAKey.generate(4096)
    # 私钥生成
    key.write_private_key_file(FilePath.RSA_PRI_KEY)
    # 公钥生成
    rsa_pub_key = f"{key.get_name()} {key.get_base64()} FunDataFactory"
    with open(FilePath.RSA_PUB_KEY, 'w') as f:
        f.write(rsa_pub_key)

if __name__ == '__main__':
    generate_ssh_key()

上面的代码比较简单,先不解释啦有兴趣的同学可以学学这个paramiko模块,记得这段代码要放在项目的跟目录哦去到项目跟目录,直接命令python3 create_key.py即可生成公钥和私钥 .gitignore文件,忽略上传公钥和私钥

git clone ssh实现

平常我们配置ssh,直接敲命令生成公钥和私钥,公钥和私钥放在.ssh文件里,这时候直接git clone就可以生效了,但是现在我们的公钥和私钥生成方式跟之前不大一样,所以这里git clone时,需要指定私钥的路径

git clone remote_url.git --config core.sshCommand="ssh -i ~/.ssh/id_rsa"

代码封装一下命令

    @staticmethod
    def git_clone_ssh(git_branch, git_url):
        """
        ssh克隆
        :param git_branch: 分支名
        :param git_url: 代码地址
        :return:
        """
        Git.log.info("ssh克隆开始")
        command_str = f"cd {FilePath.BASE_DIR}\n" \
                      f'git clone -b {git_branch} {git_url} --config core.sshCommand="ssh -i {FilePath.RSA_PRI_KEY}"\n'
        CmdUtils.cmd(command_str)
        Git.log.info("ssh克隆结束")

最后,测试一下,在账号里配置一下公钥 先手动测试一下命令,首次克隆时会有这个提示语,输入yes即可,这个点,我们后续优化一下 代码测试,成功克隆项目

初始化项目接口

写到这里的话,我们已经把拉取项目的逻辑写好了,万事俱备只欠东风~初始化项目的话,我们直接入参一个项目id,然后通过id查询数据库的项目信息进行拉取。

ProjectDao.py新增查询项目详情逻辑

@classmethod
@record_log
def project_detail(cls, id: int, user: dict) -> DataFactoryProject:
  """获取项目详情"""
  with Session() as session:
      ProjectRoleDao.read_permission(id, user)
      project = session.query(DataFactoryProject).filter(DataFactoryProject.id == id,
                                                         DataFactoryProject.del_flag == 0).first()
      if project is None:
          raise NormalException("项目不存在")
      return project

前面几期有介绍到,初始化项目需要的项目查看权限即可,所以这里要加上read_permission逻辑

project.py新增路由函数

@router.get('/init', name="初始化项目", response_model=ResponseDto)
def init_project(id: int, user= Depends(Auth())):
    try:
        project = ProjectDao.project_detail(id, user)
        project_path = os.path.join(FilePath.BASE_DIR, project.git_project)
        if os.path.isdir(project_path):
            raise Exception("项目已存在, 请执行刷新项目!")
        # 拉取项目
        if project.pull_type == 0:
            Git.git_clone_http(project.git_branch, project.git_url, project.git_account, AesUtils.decrypt(project.git_password))
        else:
            Git.git_clone_ssh(project.git_branch, project.git_url)
        return ResponseDto(msg = "初始化成功")
    except Exception as e:
        raise NormalException(str(e))

首先通过项目id查出项目相关信息,再判断是否已经存在项目,存在抛出异常,然后根据拉取拉取方式走不同的拉取命令,这里要注意的是,由于密码是加密的,所以取出来的时候,要解密AesUtils.decrypt 编写完后,记得重启服务~

测试环节

img这个项目同步下来(http方式) http克隆成功 ssh方式同步 ssh克隆成功

已存在img项目,进行刷新

总结

今天讲了ssh克隆代码,截止目前,我们的初始化项目已经开发完毕了,下一期我们开始来编写相关的前端页面