Add role to trigger readthedocs via authenticated endpoint

The old API endpoint is deprecated, so add a role that pings the
webhook as described in [1].

Authentication can happen via a token or username/password combo,
which need to be kept in secrets.

The webhook api has an "id" value which some fiddling suggests is an
incrementing integer each time a webhook endpoint is generated (if you
create, delete, create your webhook via the admin interface, you often
as not get the next value).  Unfortunately, it appears you can not
query this in any way automatically; it has to be provided.  However,
I do not believe this has to be secret; you can not trigger the
end-point without authentication (either password or token).

This means the generic playbook here will not work any more.  Because
secrets are bound to the playbook they are defined within, this role
will need to be called directly.  It will be removed in a follow-on.

[1] https://docs.readthedocs.io/en/latest/webhooks.html

Change-Id: I651efdb093df85cea3ab2eaf1a5a9256c87a2ca4
This commit is contained in:
Ian Wienand 2018-07-02 14:45:49 +10:00
parent 1673c75658
commit 70fef1a858
3 changed files with 75 additions and 0 deletions

View File

@ -0,0 +1,35 @@
Trigger readthedocs build for a project
**Role Variables**
.. zuul:rolevar:: rtd_project_name
:default: ``{{ zuul.project.short_name }}``
The readthedocs project name
.. zuul:rolevar:: rtd_webhook_id
The readthedocs webhook API ID. This needs to be taken from the
project's "Integrations" dashboard page in RTD. The URL will look
like ``readthedocs.org/api/v2/webhook/<project-name>/<id>/``.
This may come from a secret, however it can not be triggered
without authentication.
.. zuul:rolevar:: rtd_integration_token
The webhook integration token. You'll find this value on the
project's "Integrations" dashboard page in RTD. This is expected
to come from a secret. This can be used instead of
username/password combo.
.. zuul:rolevar:: rtd_username
The readthedocs username. If set, this will be used to
authenticate in preference to any token set via
``rtd_integration_token``.
.. zuul:rolevar:: rtd_password
Password for ``rtd_username``. Must be set if password is set.
This is expected to come from a secret.

View File

@ -0,0 +1,2 @@
---
rtd_project_name: "{{ zuul.project.short_name }}"

View File

@ -0,0 +1,38 @@
- name: Check for webhook id
fail:
msg: You must define the webhook id. Get this from the webhook info page on RTD
when: rtd_webhook_id is not defined
- name: Check for an authentication type
fail:
msg: Must set either rtd_username or rtd_integration_token
when: (rtd_username is not defined) and (rtd_integration_token is not defined)
- when: rtd_username is defined
block:
- name: Require password
fail:
msg: rtd_password is required when using rtd_username
when: rtd_password is not defined
- name: Trigger readthedocs build webhook via authentication
uri:
method: POST
url: 'https://readthedocs.org/api/v2/webhook/{{ rtd_project_name }}/{{ rtd_webhook_id }}/'
user: '{{ rtd_username }}'
password: '{{ rtd_password }}'
# NOTE(ianw): testing it seems the API doesn't respond with
# 401 so this is required
force_basic_auth: yes
- when: rtd_integration_token is defined and
rtd_username is not defined
block:
- name: Trigger readthedocs build webhook via token
uri:
method: POST
url: 'https://readthedocs.org/api/v2/webhook/{{ rtd_project_name }}/{{ rtd_webhook_id }}/'
body_format: form-urlencoded
body:
token: '{{ rtd_integration_token }}'
follow_redirects: all