Browse Source

Add extra details to salt update messages

master
Sean Johnson 3 years ago
parent
commit
0ba8e88e9f
WARNING! Although there is a key with this ID in the database it does not verify this commit! This commit is SUSPICIOUS.
GPG Key ID: 9FA15B87469EA850
  1. 7
      .ci/salt_hook.sh
  2. 74
      ci/pipeline.yml
  3. 152
      ci/repipe
  4. 15
      ci/settings.yml
  5. 62
      saltbox/orchestrator/templates/orch_update_fileserver.j2
  6. 40
      saltbox/orchestrator/templates/reactor_update_fileserver.j2

7
.ci/salt_hook.sh

@ -1,7 +0,0 @@
#!/usr/bin/env sh
curl -sS --fail -X POST \
-H "X-Salt-Project: ${CI_PROJECT_PATH_SLUG}" \
-H "X-Salt-SHA: ${CI_COMMIT_SHA}" \
-H "X-Salt-Secret: ${SALT_FILESYSTEM_SECRET}" \
"${CI_ENVIRONMENT_URL}/hook/fileserver/update"

74
ci/pipeline.yml

@ -0,0 +1,74 @@
---
# TODO: Concourse's `git` resource type provides some additional commit
# information inside of the output's `.git` folder. Figure out how to
# read those files into variables / params we can pass to another build step.
meta:
request:
form_data:
pillar: "{update_pillar}"
headers:
X-Salt-Secret: "((saltbox.webhook_secret))"
X-Salt-Project: "{project}"
X-Salt-Git-SHA: "-@{project}/.git/ref"
X-Salt-Git-Committer: "-@{project}/.git/committer"
X-Salt-Git-Commit-Message: "-@{project}/.git/commit_message"
X-Salt-Build-Pipeline-Name: "{BUILD_PIPELINE_NAME}"
X-Salt-Build-Job-Name: "{BUILD_JOB_NAME}"
X-Salt-Build-Name: "{BUILD_NAME}"
X-Salt-Build-Id: "{BUILD_ID}"
resource_types:
- name: http-api
type: registry-image
source:
repository: pirogoeth/concourse-http-api-resource
tag: latest
resources:
- name: states
type: git
source:
uri: git@glow.dev.maio.me:saltbox/states.git
branch: master
private_key: ((saltbox.ci_repository_secret_key))
- name: pillars
type: git
source:
uri: git@glow.dev.maio.me:saltbox/pillars.git
branch: master
private_key: ((saltbox.ci_repository_secret_key))
- name: salt-update
type: http-api
source:
uri: "((saltbox.webhook_url))/hook/fileserver/update"
method: "POST"
headers:
.: (( inject meta.request.headers ))
form_data:
.: (( inject meta.request.form_data ))
jobs:
- name: update-states
public: false
plan:
- get: states
trigger: true
- put: salt-update
params:
update_pillar: false
project: "states"
- name: update-pillars
public: false
plan:
- get: pillars
trigger: true
- put: salt-update
params:
update_pillar: true
project: "pillars"

152
ci/repipe

@ -0,0 +1,152 @@
#!/bin/bash
#
# repipe.sh
#
# Script for merging together pipeline configuration files
# (via Spruce!) and configuring Concourse.
#
# author: James Hunt <james@niftylogic.com>
# Dennis Bell <dennis.j.bell@gmail.com>
# created: 2016-03-04
need_command() {
local cmd=${1:?need_command() - no command name given}
if [[ ! -x "$(command -v $cmd)" ]]; then
echo >&2 "${cmd} is not installed."
if [[ "${cmd}" == "spruce" ]]; then
echo >&2 "Please download it from https://github.com/geofffranks/spruce/releases"
fi
exit 2
fi
}
NO_FLY=
SAVE_MANIFEST=
VALIDATE_PIPELINE=
NON_INTERACTIVE=
cleanup() {
rm -f save-manifest.yml
if [[ -n ${SAVE_MANIFEST} && -e .deploy.yml ]]; then
mv .deploy.yml save-manifest.yml
fi
rm -f .deploy.yml
}
usage() {
echo Command line arguments:
echo "no-fly Do not execute any fly commands"
echo "save-manifest Save manifest to file save-manifest"
echo "validate Validate pipeline instead of set pipeline"
echo "validate-strict Validate pipeline with strict mode"
echo "non-interactive Run set-pipeline in non-interactive mode"
echo "open Open pipeline dashboard to browser (if possible)"
}
open_pipeline() {
url=$(show_pipeline_url)
cleanup
if [[ -x /usr/bin/open ]]; then
exec /usr/bin/open "$url"
else
echo "Sorry, but I was not able to automagically open"
echo "your Concourse Pipeline in the browser."
echo
echo "Here's a link you can click on, though:"
echo
echo " $url"
echo
exit 0;
fi
}
show_pipeline_url() {
spruce merge --skip-eval pipeline.yml ${settings_file} > .deploy.yml
concourse_url=$(spruce json .deploy.yml | jq -r ".meta.url")
team=$(spruce json .deploy.yml | jq -r ".meta.team // \"main\"")
pipeline=$(spruce merge --skip-eval \
--cherry-pick meta.pipeline \
--cherry-pick meta.name \
.deploy.yml | spruce merge - | spruce json | jq -r ".meta.pipeline")
echo "$concourse_url/teams/$team/pipelines/$pipeline"
exit 0
}
for arg do
case "${arg}" in
no-fly|no_fly) NO_FLY="yes" ;;
save-manifest|save_manifest) SAVE_MANIFEST="yes" ;;
validate) VALIDATE_PIPELINE="normal" ;;
validate-strict|validate_strict) VALIDATE_PIPELINE="strict" ;;
non-interactive|non_interactive) NON_INTERACTIVE="--non-interactive" ;;
url) SHOW_PIPELINE_URL="yes" ;;
open) OPEN_PIPELINE="yes" ;;
help|-h|--help) usage; exit 0 ;;
*) echo Invalid argument
usage
exit 1
esac
done
cd $(dirname $BASH_SOURCE[0])
echo >&2 "Working in $(pwd)"
need_command spruce
# Allow for target-specific settings
settings_file="$(ls -1 settings.yml ${CONCOURSE_TARGET:+"settings-${CONCOURSE_TARGET}.yml"} 2>/dev/null | tail -n1)"
if [[ -z "$settings_file" ]]
then
echo >&2 "Missing local settings in ci/settings.yml${CONCOURSE_TARGET:+" or ci/settings-${CONCOURSE_TARGET}.yml"}!"
exit 1
fi
echo >&2 "Using settings found in ${settings_file}"
set -e
trap "cleanup" QUIT TERM EXIT INT
[[ -n ${SHOW_PIPELINE_URL} ]] && { show_pipeline_url; exit 0; }
[[ -n ${OPEN_PIPELINE} ]] && { open_pipeline; exit 0; }
FRAGMENTS=$(find ../ -type f -name "pipeline.yml")
spruce merge --prune meta ${FRAGMENTS} ${settings_file} > .deploy.yml
PIPELINE=$(spruce json settings.yml | jq -r '.meta.pipeline // ""')
if [[ -z ${PIPELINE} ]]; then
echo >&2 "Missing pipeline name in ci/settings.yml!"
exit 1
fi
TARGET_FROM_SETTINGS=$(spruce json settings.yml | jq -r '.meta.target // ""')
if [[ -z ${CONCOURSE_TARGET} ]]; then
TARGET=${TARGET_FROM_SETTINGS}
elif [[ "$CONCOURSE_TARGET" != "$TARGET_FROM_SETTINGS" ]]
then
echo >&2 "Target in {$settings_file} differs from target in \$CONCOURSE_TARGET"
echo >&2 " \$CONCOURSE_TARGET: $CONCOURSE_TARGET"
echo >&2 " Target in file: $TARGET_FROM_SETTINGS"
exit 1
else
TARGET=${CONCOURSE_TARGET}
fi
if [[ -z ${TARGET} ]]; then
echo >&2 "Missing Concourse Target in ci/settings.yml!"
exit 1
fi
fly_cmd="${FLY_CMD:-fly}"
[[ -n ${NO_FLY} ]] && { echo no fly execution requested ; exit 0; }
case "${VALIDATE_PIPELINE}" in
normal) fly_opts="validate-pipeline" ;;
strict) fly_opts="validate-pipeline --strict" ;;
*) fly_opts="set-pipeline ${NON_INTERACTIVE} --pipeline ${PIPELINE}" ;;
esac
set +x
$fly_cmd --target ${TARGET} ${fly_opts} --config .deploy.yml
[[ -n ${VALIDATE_PIPELINE} ]] && exit 0
$fly_cmd --target ${TARGET} unpause-pipeline --pipeline ${PIPELINE}

15
ci/settings.yml

@ -0,0 +1,15 @@
meta:
name: saltbox-resources
target: glow
url: https://concourse.dev.maio.me
team: main
pipeline: saltbox-resources
registry:
repository: containers.dev.maio.me/library
auth:
username: ((glow_registry_ci.username))
password: ((glow_registry_ci.password))
saltbox:
secret: ((saltbox.webhook_secret))

62
saltbox/orchestrator/templates/orch_update_fileserver.j2

@ -1,20 +1,33 @@
{% raw %}
---
{% set remote_addr = salt.pillar.get('remote_addr') %}
{% set project_trigger = salt.pillar.get('project_trigger') %}
{% set last_commit_sha = salt.pillar.get('last_commit_sha') %}
{% set update_git_pillar = salt.pillar.get('update_git_pillar') %}
{% set telegram = salt.pillar.get('telegram') %}
{% set telegram = salt.pillar.get("telegram") %}
{% set remote_addr = salt.pillar.get("remote_addr") %}
{% set update_git_pillar = salt.pillar.get("update_git_pillar") %}
{% set project_trigger = salt.pillar.get("triggered_by:project") %}
{% set last_commit_sha = salt.pillar.get("triggered_by:last_commit_sha") %}
{% set committer = salt.pillar.get("triggered_by:committer") %}
{% set commit_message = salt.pillar.get("triggered_by:commit_message") %}
{% set build_pipeline_name = salt.pillar.get("build:pipeline_name") %}
{% set build_job_name = salt.pillar.get("build:job_name") %}
{% set build_name = salt.pillar.get("build:name") %}
{% set build_id = salt.pillar.get("build:id") %}
fire update event:
salt.runner:
- name: event.send
- tag: 'hook/fileserver/update/begin'
- tag: "hook/fileserver/update/begin"
- data:
src_ip: '{{ remote_addr }}'
src_ip: "{{ remote_addr }}"
triggered_by:
project: '{{ project_trigger }}'
commit_sha: '{{ last_commit_sha }}'
project: "{{ project_trigger }}"
commit_ref: "{{ last_commit_sha }}"
commit_message: "{{ commit_message }}"
committer: "{{ committer }}"
build:
pipeline_name: "{{ build_pipeline_name }}"
job_name: "{{ build_job_name }}"
name: "{{ build_name }}"
id: "{{ build_id }}"
clear git locks:
salt.runner:
@ -33,7 +46,7 @@ sync grains:
refresh grains:
salt.function:
- name: saltutil.refresh_grains
- tgt: '*'
- tgt: "*"
sync modules:
salt.runner:
@ -42,18 +55,25 @@ sync modules:
refresh modules:
salt.function:
- name: saltutil.refresh_modules
- tgt: '*'
- tgt: "*"
{% if update_git_pillar %}
fire pillar update event:
salt.runner:
- name: event.send
- tag: 'hook/git_pillar/update/begin'
- tag: "hook/git_pillar/update/begin"
- data:
src_ip: '{{ remote_addr }}'
src_ip: "{{ remote_addr }}"
triggered_by:
project: '{{ project_trigger }}'
commit_sha: '{{ last_commit_sha }}'
project: "{{ project_trigger }}"
commit_ref: "{{ last_commit_sha }}"
commit_message: "{{ commit_message }}"
committer: "{{ committer }}"
build:
pipeline_name: "{{ build_pipeline_name }}"
job_name: "{{ build_job_name }}"
name: "{{ build_name }}"
id: "{{ build_id }}"
update git pillar:
salt.runner:
@ -66,13 +86,19 @@ sync pillar:
refresh pillar:
salt.function:
- name: saltutil.refresh_pillar
- tgt: '*'
- tgt: "*"
{% endif %}
telegram notification:
salt.runner:
- name: event.send
- tag: 'notify/telegram'
- tag: "notify/telegram"
- data:
message: "Fileserver update completed! Triggered by `{{ project_trigger }}` commit `{{ last_commit_sha }}`."
message: |
Fileserver update completed! Triggered by commit `{{ last_commit_sha }}` by `{{ committer }}` on `{{ project_trigger }}`.
Built via pipeline `{{ build_pipeline_name }}`, job `{{ build_job_name }}`.
https://concourse.dev.maio.me/teams/main/pipelines/{{ build_pipeline_name }}/jobs/{{ build_job_name }}/builds/{{ build_id }}
---
Commit {{ last_commit_sha }} by {{ committer }}:
{{ commit_message }}
{% endraw %}

40
saltbox/orchestrator/templates/reactor_update_fileserver.j2

@ -1,15 +1,21 @@
---
{{ '{% set secret_key = "' }}{{ salt.pillar.get('hooks:fileserver:secret') }}{{ '" -%}' }}
{% set telegram = salt.pillar.get('telegram', {}) -%}
{{ '{% set secret_key = "' }}{{ salt.pillar.get("hooks:fileserver:secret") }}{{ '" -%}' }}
{% set telegram = salt.pillar.get("telegram", {}) -%}
{% raw %}
{% set headers = data.get('headers', {}) %}
{% set given_key = headers.get('X-Salt-Secret') %}
{% set update_git_pillar = data.get('post', {}).get('pillar', 'false').lower() == 'true' %}
{% set remote_addr = headers.get('Remote-Addr') %}
{% set project_trigger = headers.get('X-Salt-Project') %}
{% set last_commit_sha = headers.get('X-Salt-Sha') %}
{% set headers = data.get("headers", {})
{% set given_key = headers.get("X-Salt-Secret") %}
{% set update_git_pillar = data.get("post", {}).get("pillar", "false").lower() == "true" %}
{% set remote_addr = headers.get("Remote-Addr") %}
{% set project_trigger = headers.get("X-Salt-Project") %}
{% set committer = headers.get("X-Salt-Git-Committer") %}
{% set commit_sha = headers.get("X-Salt-Git-SHA") %}
{% set commit_message = headers.get("X-Salt-Git-Commit-Message") %}
{% set build_pipeline = headers.get("X-Salt-Build-Pipeline-Name") %}
{% set build_job = headers.get("X-Salt-Build-Job-Name") %}
{% set build_name = headers.get("X-Salt-Build-Name") %}
{% set build_id = headers.get("X-Salt-Build-Id") %}
{% if given_key == secret_key %}
{% endraw %}
@ -18,9 +24,17 @@ orchestrate_update_fileserver:
- args:
- mods: orchestrate.update_fileserver
- pillar:
update_git_pillar: {{ '{{ update_git_pillar }}' }}
project_trigger: {{ '{{ project_trigger }}' }}
last_commit_sha: {{ '{{ last_commit_sha }}' }}
remote_addr: {{ '{{ remote_addr }}' }}
telegram: {{ telegram | json }}
{{ '{% endif %}' }}
remote_addr: {{ "{{ remote_addr }}" }}
update_git_pillar: {{ "{{ update_git_pillar }}" }}
triggered_by:
project: {{ "{{ project_trigger }}" }}
last_commit_sha: {{ "{{ commit_sha }}" }}
committer: {{ "{{ committer }}" }}
commit_message: {{ "{{ commit_message }}" }}
build:
pipeline_name: {{ "{{ build_pipeline }}" }}
job_name: {{ "{{ build_job }}" }}
name: {{ "{{ build_name }}" }}
id: {{ "{{ build_id }}" }}
{{ "{% endif %}" }}

Loading…
Cancel
Save