dockeransiblegitea

Ansible GITEA server , API call to create multiple repos for 2 users, 1 for Superadmin gitea account and the other for the git standard account


Hi everyone and thanks in advance for your support, I wanna create 1 API call to create 2 repos, 1 assigned to a Superadmin gitea account and the other for standard gitea user named gitea, I assume this would need to be with a list of users in variables and a list of repos in variables also using with_items but I don't seem to get it, down I'm attaching my API call format in Ansible to achieve 1 repo/1user, please someone help:

- name: "gitea - Create repo"
  uri: 
    url: '{{ gitea_api_url }}/user/repos'
    method: POST
    body_format: json
    status_code: 201
    headers:
      Authorization: token {{ saved_tokens if token_ is undefined else token_ }}
    body:
      auto_init: true
      default_branch: "main"
      description: "hi"
      gitignores: ""
      issue_labels: ""
      license: ""
      name: "{{ item }}"
      private: true
      readme: ""
      template: true
      trust_model: "default"
      owner: '{{ gitea.users }}'
  with_items: "{{ repo_names }}"
  register: _repostatus

I only assume it could work with a list of 2 users and a list of 2 repo names using somehow with_items and conditionals together, in this case I have the following:

gitea:
  users: 
    - name: '{{ gitea_admin_account }}'
      admin: true
    - name: '{{ gitea_standard_account }}'
      admin: false


repo_names:
  - test2
  - test3

How to use the 'admin' flag to create 'test2' to the admin and 'test3' to the standard user?


Solution

  • I cannot see an owner key in the Gitea API for [POST] /user/repos, only in the 201 response.

    If you want to add other users besides the repository owner, you should probably use [PUT] /repos/{owner}/{repo}/collaborators/{collaborator} or similar after creating the repository.

    For this request you can loop by using loop keyword:

    - name: "gitea - Add collaborators to total repo_list"
      uri: 
        url: '{{ gitea_api_url }}/repos/{{ repo_owner }}/{{ item.0 }}/collaborators/{{ item.1.name }}'
        method: POST
        body_format: json
        status_code: 204
        headers:
          Authorization: token {{ saved_tokens if token_ is undefined else token_ }}
        body:
          permission: "{{ 'admin_permission_str' if item.1.admin else 'regular_permission_str' }}"
      loop: "{{ repo_names | product(gitea.users) }}"
      register: _repostatus
    

    To iterate over two lists you have to create a cartesian product of them to bring both into one data structure. Then you can iterate over this one data structure. The { repo_names | product(gitea.users) }} results in the following data structure:

    [
      [
        "test2",
        {
            "admin": true,
            "name": "gitea_admin_account"
        }
      ],
      [
        "test2",
        {
            "admin": false,
            "name": "gitea_standard_account"
        }
      ],
      [
        "test3",
        {
            "admin": true,
            "name": "gitea_admin_account"
        }
      ],
      [
        "test3",
        {
            "admin": false,
            "name": "gitea_standard_account"
        }
      ]
    ]
    

    You can use .0 and .1 to address the repository name or the users dict, respectively.

    Alternatively you can work with with_nested/with_cartesian instead of using loop directly, you can find more about this in the Ansible Docs. But this is not necessary if you use loop as described above.