]> git.immae.eu Git - github/fretlink/ansible-rundeck-jobs.git/commitdiff
Add an option to remove existing keys that are not declared in ansible 20/head
authorIsmaël Bouya <ismael.bouya@fretlink.com>
Fri, 25 Feb 2022 17:14:29 +0000 (18:14 +0100)
committerIsmaël Bouya <ismael.bouya@fretlink.com>
Fri, 25 Feb 2022 17:39:20 +0000 (18:39 +0100)
README.md
defaults/main.yml
dhall/package.dhall
files/fetch_keys.sh [new file with mode: 0755]
tasks/key.yml [new file with mode: 0644]
tasks/keys.yml
tasks/main.yml

index 8a5f903a329ad4b6f2a369f8861080b42b428f8b..9962610f75a9563aa10e44865a091091fa6eba34 100644 (file)
--- a/README.md
+++ b/README.md
@@ -19,6 +19,10 @@ Role Variables
 * `rundeck_remove_missing` Whether to delete jobs present in rundeck and not in file. Defaults to true.
 * `rundeck_jobs_group` the group of job to check for removal
 * `rundeck_ignore_creation_errors` whether to ignore job creation error. Default to true to follow the 200 status given by rundeck API
+* `rundeck_jobs_keys` a list of keys to import in rundeck. Each key is a dict with a `path`, a `value` and a `type` as declared in [https://docs.rundeck.com/3.0.x/api/index.html#upload-keys]().
+* `rundeck_keys_scoped_by_project` scope each key by project (In a project/ProjectName subdirectory)
+* `rundeck_keys_scoped_by_group` scope each key by group. Defaults to true if the group is defined, false otherwise
+* `rundeck_remove_missing_keys` remove keys that are not declared in ansible (possibly restrained to the scope defined above)
 
 A [dhall](https://dhall-lang.org/) Type representing the roles' variables is available in the `./dhall/Config.dhall` file to help you configure your projects with some type checking.
 
index dc73d56a0c6f4114a4ecb0685380e44cd7edf55f..c3f096716940597e2cf5fc3bf8ff39ce551a0da2 100644 (file)
@@ -1,6 +1,7 @@
 ---
 rundeck_api_version: 26
 rundeck_remove_missing: true
+rundeck_remove_missing_keys: false
 rundeck_ignore_creation_error: true
 rundeck_keys_scoped_by_project: true
 rundeck_jobs_keys: []
index 7ada0dc0d8e40bad80e2fea952c3204ef0b50280..4e3b668a2f0b1ba2c29efe66b1b3c8985484a380 100644 (file)
@@ -10,6 +10,7 @@ let Config =
           , rundeck_api_token : Text
           , rundeck_api_version : Optional Natural
           , rundeck_remove_missing : Optional Bool
+          , rundeck_remove_missing_keys : Optional Bool
           , rundeck_ignore_creation_error : Optional Bool
           , rundeck_jobs_group : Optional Text
           , rundeck_jobs_keys : List Key
@@ -19,6 +20,7 @@ let Config =
       , default =
         { rundeck_api_version = Some 26
         , rundeck_remove_missing = Some True
+        , rundeck_remove_missing_keys = Some False
         , rundeck_ignore_creation_error = Some True
         , rundeck_jobs_group = None Text
         , rundeck_jobs_keys = [] : List Key
diff --git a/files/fetch_keys.sh b/files/fetch_keys.sh
new file mode 100755 (executable)
index 0000000..e15dc12
--- /dev/null
@@ -0,0 +1,22 @@
+#!/usr/bin/env bash
+
+set -euo pipefail
+
+BASE_URL="$1"
+TOKEN="$2"
+BASE_PATH="$3"
+
+list_path_rec() {
+  path="$1"
+  result=$(curl -ks "$BASE_URL/storage/$path?authtoken=$TOKEN")
+
+  case "$(echo "$result" | jq -r .type)" in
+    "file") echo "$result" | jq -r .path | sed -e "s@^$BASE_PATH/@@"
+      ;;
+    "directory")
+      echo "$result" | jq -r ".resources[]|.path" | while read p; do list_path_rec "$p"; done
+      ;;
+  esac
+}
+
+list_path_rec "$BASE_PATH"
diff --git a/tasks/key.yml b/tasks/key.yml
new file mode 100644 (file)
index 0000000..aa2b2d9
--- /dev/null
@@ -0,0 +1,30 @@
+---
+- name: Build scoped path
+  set_fact:
+    rundeck_key_full_path: "{{ rundeck_keys_base_path }}/{{ item.path }}"
+
+- name: Check key existence
+  uri:
+    url: "{{ rundeck_api_url }}/{{ rundeck_api_version }}/storage/keys/{{ rundeck_key_full_path }}"
+    method: GET
+    headers:
+      Accept: application/json
+      X-Rundeck-Auth-Token: "{{ rundeck_api_token }}"
+    status_code: [200, 404]
+  register: rundeck_existing_key
+
+- name: Set method
+  set_fact:
+    rundeck_key_uri_method: "{{ (rundeck_existing_key.status == 404) | ternary('POST', 'PUT') }}"
+
+- name: Import key
+  uri:
+    url: "{{ rundeck_api_url }}/{{ rundeck_api_version }}/storage/keys/{{ rundeck_key_full_path }}"
+    method: "{{ rundeck_key_uri_method }}"
+    headers:
+      Accept: application/json
+      Content-Type: "{{ item.type }}"
+      X-Rundeck-Auth-Token: "{{ rundeck_api_token }}"
+    status_code: [200, 201]
+    body: "{{ item.value }}"
+    body_format: raw
index 98c613696c327b98ea5bfcaf3eea63ac7e980ddf..7ca09042383c83d2232d9c0ac8b7ca33fede62bb 100644 (file)
@@ -1,33 +1,34 @@
 ---
-- name: Build scoped path
+- name: Set scope variables
   set_fact:
-    rundeck_key_full_path: "{{ rundeck_keys_scoped_by_project | default(true) | ternary('project/' + rundeck_project + '/' + key_group_path, key_group_path) }}"
+    rundeck_keys_base_path: "{{ rundeck_keys_scoped_by_project | default(true) | ternary('project/' + rundeck_project + '/' + rundeck_keys_group_path, rundeck_keys_group_path) }}"
   vars:
     group_name: "{{ rundeck_jobs_group | default('') }}"
-    key_group_path: "{{ rundeck_keys_scoped_by_group | default((group_name|length) > 0) | ternary(group_name + '/' + item.path, item.path) }}"
+    rundeck_keys_group_path: "{{ rundeck_keys_scoped_by_group | default((group_name|length) > 0) | ternary(group_name, '') }}"
 
-- name: Check key existence
-  uri:
-    url: "{{ rundeck_api_url }}/{{ rundeck_api_version }}/storage/keys/{{ rundeck_key_full_path }}"
-    method: GET
-    headers:
-      Accept: application/json
-      X-Rundeck-Auth-Token: "{{ rundeck_api_token }}"
-    status_code: [200, 404]
-  register: rundeck_existing_key
+- name: Include rundeck key
+  include_tasks: key.yml
+  with_items: "{{ rundeck_jobs_keys }}"
+
+- name: Get all stored keys
+  script:
+    cmd: "{{ role_path }}/files/fetch_keys.sh {{ rundeck_api_url }}/{{ rundeck_api_version }} {{ rundeck_api_token }} keys/{{ rundeck_keys_base_path }}"
+  register: rundeck_existing_keys
+  when: rundeck_remove_missing_keys
 
-- name: Set method
+- name: "Prepare list of keys to remove"
   set_fact:
-    rundeck_key_uri_method: "{{ (rundeck_existing_key.status == 404) | ternary('POST', 'PUT') }}"
+    rundeck_existing_keys: "{{ rundeck_existing_keys.stdout_lines | list }}"
+    rundeck_known_keys: "{{ rundeck_jobs_keys | map(attribute='path') | list }}"
+  when: rundeck_remove_missing_keys
 
-- name: Import key
+- name: "Remove jobs not declared"
   uri:
-    url: "{{ rundeck_api_url }}/{{ rundeck_api_version }}/storage/keys/{{ rundeck_key_full_path }}"
-    method: "{{ rundeck_key_uri_method }}"
+    url: "{{ rundeck_api_url }}/{{ rundeck_api_version }}/storage/keys/{{ rundeck_keys_base_path }}/{{ item }}"
+    method: DELETE
     headers:
       Accept: application/json
-      Content-Type: "{{ item.type }}"
       X-Rundeck-Auth-Token: "{{ rundeck_api_token }}"
-    status_code: [200, 201]
-    body: "{{ item.value }}"
-    body_format: raw
+    status_code: [204, 404]
+  with_items: "{{ rundeck_existing_keys | difference(rundeck_known_keys) }}"
+  when: rundeck_remove_missing_keys
index 644fef0b0ca1cf63be00e1217fdb7bf88be6ba28..955d0a993c31af7ef4eb8f2b9956f17f33dfe986 100644 (file)
@@ -4,7 +4,6 @@
   tags:
     - rundeck-jobs
 - name: Include rundeck keys
-  include_tasks: keys.yml
   tags:
     - rundeck-keys
-  with_items: "{{ rundeck_jobs_keys }}"
+  include_tasks: keys.yml