Skip to content

Automating Collection Uploads

Adrian Likins edited this page Apr 19, 2021 · 11 revisions

The following provides an example Ansible playbook that automates publishing a collection to a locally running Galaxy server. This is useful for pre-seeding a new Galaxy server with existing collection artifacts.

Prerequisites

  • Ansible installed on the control node
  • Ansible installed on the target host
  • An Ansible inventory file, if not running on localhost
  • Collection artifact(s) contained on the file system of the target host

Playbook

If you installed GalaxyNG using the end-user instructions, set the galaxy_api_url value in the playbook below to http://localhost/api/galaxy/

Download a copy of the playbook upload-collection.yml by running the following:

$ git clone git@gist.github.com:629ba52d68301cc9798227b87704df84.git example
$ cd example

The playbook references an example collection artifact, download the example collection by clicking here.

---
- hosts: all
  vars:
    galaxy_api_url: http://localhost:5001/api/automation-hub/
    galaxy_username: admin
    galaxy_password: admin
    galaxy_namespace:
      name: "newswangerd"
      description: "Example collections"
    galaxy_collection_path: newswangerd-collection_demo-1.0.10.tar.gz
  tasks:
    - name: Authenticate and get an API token
      uri:
        url: "{{ galaxy_api_url }}v3/auth/token/"
        method: POST
        url_username: "{{ galaxy_username }}"
        url_password: "{{ galaxy_password }}"
        force_basic_auth: yes
        status_code: 200
        body_format: json
        return_content: yes
      register: galaxy_auth_response

    - set_fact:
        galaxy_token: "{{ galaxy_auth_response['json']['token'] }}"

    - set_fact:
        galaxy_auth_header: "Token {{ galaxy_token }}"

    - name: Check if the namespace exists
      uri:
        url: "{{galaxy_api_url}}v3/namespaces/{{ galaxy_namespace.name }}/"
        method: GET
        headers:
          Authorization: "{{ galaxy_auth_header }}"
      register: galaxy_namespace_check
      ignore_errors: yes

    - name: Create a namespace
      uri:
        url: "{{galaxy_api_url}}v3/namespaces/"
        method: POST
        headers:
          Authorization: "{{ galaxy_auth_header }}"
        body_format: json
        body:
          name: "{{ galaxy_namespace.name }}"
          description: "{{ galaxy_namespace.description }}"
          groups: []
          # Or to use a group ('folks' in this example)
          # groups:
          #   - name: "folks"
          #     object_permissions:
          #       - upload_to_namespace
          #       - change_namespace
        return_content: yes
        status_code: 201
      register: galaxy_namespace_response
      when: galaxy_namespace_check.status == 404
      ignore_errors: true

    - debug:
        var: galaxy_namespace_response

    - name: create ansible.cfg
      copy:
          dest: ansible.cfg
          content: |
            [galaxy]
            server_list = local_server

            [galaxy_server.local_server]
            url={{ galaxy_api_url }}
            token={{ galaxy_token }}

    - name: publish a collection with ansible-galaxy
      shell:
        cmd: ANSIBLE_CONFIG=./ansible.cfg ansible-galaxy collection publish -v {{ galaxy_collection_path }}

Authenticating with the Galaxy server

In the above example, basic authentication is used to programmatically obtain an API token. This is useful in a CI or DEV environment, where a pre-existing token may not be known, or web browser access is not convenient.

An API token can be obtained by using a web browser to log into the Galaxy server. Once logged in, choose the API Token menu option, and click on the Load Token button to view and copy a token.

The token is passed to the ansible-galaxy client, which uses it to authenticate with the Galaxy server when publishing a collection. In the above example, the token is written to an ansible.cfg file, which ends up looking like the following:

[galaxy]
server_list = local_server

[galaxy_server.local_server]
url=http://localhost/api/galaxy/
token=d9108369dee66fbaeac4adbce3e4

For more information about ansible-galaxy, view the ansible-galaxy docs here.

Publishing a collection

In order to publish a collection, the collection's namespace must exist on the Galaxy server. In the above example, the playbook is only concerned with a single namespace, newswangerd. It checks to see if the namespace exists by sending an API request to /v3/namespaces/<namespace name>/, and when the namespace is not found, creates it by making a POST request to /v3/namespaces. Once the namespace exists, the ansible-galaxy command is used to initiate the upload.

The above example only deals with a single namespace and a single collection artifact, but could easily be extended to iterate over a list of namespaces and a list of artifacts. For more on working with loops in a playbook, view the Loops guide. You might also consider using include_tasks. For more about that, view the include_tasks module.

NOTE

At the time of this writing RBAC has not been introduced to GalaxyNG. This example assumes that the user performing the collection upload is part of the system:partner-engineers group. The admin user is by default part of this group. Whenever a namespace is created, the system:partner-engineers group is given full access to the namespace, so again, by default the admin user will have access to publish collection to any new namespaces created by the playbook. This is not ideal, but sufficient enough for CI and development environments.