Skip to content

Automating Collection Uploads

Chris Houseknecht edited this page Jun 11, 2020 · 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

NOTE

If running the following playbook in a development environment, set the galaxy_api_url value to http://localhost:5001/api/automation-hub

You can download the example collection artifact, by clicking this link.

---
- hosts: all
  vars:
    galaxy_api_url: http://localhost/api/galaxy
    galaxy_username: admin
    galaxy_password: password
    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:
            - name: "system:partner-engineers"
        return_content: yes
        status_code: 201
      register: galaxy_namespace_response
      when: galaxy_namespace_check.status == 404

    - 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.

Clone this wiki locally