Skip to content

Commit

Permalink
add actions for service catalogue
Browse files Browse the repository at this point in the history
  • Loading branch information
james-jdgtl committed Jul 24, 2024
1 parent f7992aa commit 778f4e2
Show file tree
Hide file tree
Showing 5 changed files with 273 additions and 11 deletions.
48 changes: 48 additions & 0 deletions .github/actions/get-sc-data/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
name: "Get Service Catalogue Data"
description: "Composite action for getting Service Catalogue data"
outputs:
component_description:
description: "Description of the component"
value: "${{ steps.get-sc-data.outputs.component_description }}"
component_github_template_repo:
description: "Template used to create the github project"
value: "${{ steps.get-sc-data.outputs.component_github_template_repo }}"
component_github_project_teams_write:
description: "Project teams wtih write access to the github project"
value: "${{ steps.get-sc-data.outputs.component_github_project_teams_write }}"
component_github_project_teams_admin:
description: "Project teams wtih admin access to the github project"
value: "${{ steps.get-sc-data.outputs.component_github_project_teams_admin }}"
component_github_project_teams_maintain:
description: "Project teams wtih maintain access to the github project"
value: "${{ steps.get-sc-data.outputs.component_github_project_teams_maintain }}"
component_github_project_visibility:
description: "Visibility of the github project"
value: "${{ steps.get-sc-data.outputs.component_github_project_visibility }}"
component_github_project_branch_protection_restricted_teams:
description: "Branch protection teams configuration"
value: "${{ steps.get-sc-data.outputs.component_github_project_branch_protection_restricted_teams }}"
component_circleci_project_k8s_namespace:
description: "Project Kubernetes namespace"
value: "${{ steps.get-sc-data.outputs.component_circleci_project_k8s_namespace }}"
component_circleci_context_k8s_namespaces:
description: "Project Kubernetes namespace"
value: "${{ steps.get-sc-data.outputs.component_circleci_context_k8s_namespaces }} "
component_jira_project_keys:
description: "Project jira keys"
value: "${{ steps.get-sc-data.outputs.component_jira_project_keys }}"
product_hmpps_product_id:
description: "Product ID"
value: "${{ steps.get-sc-data.outputs.product_pid }} "
runs:
using: "composite"
steps:
- name: Checkout code
uses: actions/checkout@v4
- id: get-sc-data
name: Get Service Catalogue Data
run: bash ./scripts/get-sc-data.sh >> $GITHUB_OUTPUT
shell: bash
env:
COMPONENT_NAME: "${{ env.github_repo_name }}"
SERVICE_CATALOGUE_API_KEY: "${{ env.service_catalogue_api_key }}"
20 changes: 20 additions & 0 deletions .github/actions/update-quayio/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# https://docs.github.com/en/actions/creating-actions/creating-a-composite-action
name: Update quay.io with repository details
description: Uses service catalogue data to update quay.io
# Part of a collection of actions that will ultimately replace bootstrap.sh
runs:
using: "composite"
steps:
- name: Checkout code
uses: actions/checkout@v4
- id: update-quayio
name: update-quayio
run: bash ./scripts/update-quayio.sh
shell: bash
env:
GITHUB_REPO_NAME: ${{ env.github_repo_name }}
GITHUB_ORG: "ministryofjustice"
GITHUB_REPO_DESCRIPTION: "${{ env.github_repo_description }}"
QUAYIO_ORG: "hmpps"
QUAYIO_TOKEN: "${{ env.quayio_token }}"
CIRCLECI_TOKEN: "${{ env.circleci_token }}"
59 changes: 48 additions & 11 deletions .github/workflows/bootstrap-actions.yml
Original file line number Diff line number Diff line change
@@ -1,30 +1,67 @@
# Test workflow
# This is intended to be the main workflow from which actions are run to bootstrap a new project
#
# Requires
#
# Secrets
# SERVICE_CATALOGUE_API_KEY
# QUAYIO_TOKEN
# CIRCLECI_TOKEN
#
# Steps
# Prompt for the component name (must match service catalogue)
# Gather information from Service Catalogue fo rthis component
# Optional bits:
# Create the github repository based on the template
# Configure CircleCI
# Configure QuayIO
# Configue kubectl namespace secrets and things
#
# Maybe some options to exclude / only include some elements like the bootstrap.sh
# - k specify whether to only run the circleci kubectl changes
# - s specify whether to only run the service catalogue changes
# - r specify whether to only run the github and service catalogue changes

name: Bootstrap Actions Workflow Dispatch

on:
workflow_dispatch:
inputs:
component:
description: 'The component to bootstrap (needs to be in the Service Catalogue)'
required: true
options:
type: choice
description: 'How many minutes to run for'
description: 'Bootstrap options (default: full bootstrap, including github repo)'
required: true
default: '10'
default: 'full'
options:
- '1'
- '10'
- '30'
- 'full'
- 'kubectl only'
- 'github only'

jobs:
deploy:
runs-on: [self-hosted, Linux, X64, hmpps-github-actions-runner]
runs-on: ubuntu-latest
steps:
- run: echo "Running a script for ${{ github.event.inputs.options }} 10 minutes"
- run: echo "Running ${{ github.event.inputs.options }} component ${{ github.event.inputs.component }}"
- name: Install jq
run: sudo apt-get install -y jq httpie
- name: Checkout code
uses: actions/checkout@v4
- id: get_sc_data
name: Run a script
uses: ./.github/actions/run-script
name: Get service catalogue data
uses: ./.github/actions/get-sc-data
env:
options: ${{ github.event.inputs.options }}
github_repo_name: ${{ github.event.inputs.component }}
service_catalogue_api_key: "${{ secrets.SERVICE_CATALOGUE_API_KEY }}"
- id: update_quayio
name: Updates quay.io with component information
uses: ./.github/actions/update-quayio
if: ${{ github.event.inputs.options == 'full' || github.event.inputs.options == 'kubectl only' }}
env:
github_repo_name: ${{ github.event.inputs.component }}
github_repo_description: "${{ steps.get_sc_data.outputs.component_description }}"
quay_io_token: "${{ secrets.QUAYIO_TOKEN }}"
circle_ci_token: "${{ secrets.CIRCLECI_TOKEN }}"


85 changes: 85 additions & 0 deletions scripts/get-sc-data.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
#!/usr/bin/env bash

set -e

# Requires:
# COMPONENT_NAME
# SERVICE_CATALOGUE_API_KEY

# Outputs (all need to be populated in the Service Catalogue)
# component_description
# component_github_template_repo
# component_github_project_teams_write
# component_github_project_teams_admin
# component_github_project_branch_protection_restricted_teams
# component_circleci_project_k8s_namespace
# component_circleci_context_k8s_namespaces
# component_jira_project_keys
# product_hmpps_product_id

# Setup SC session
SC_API_ENDPOINT="https://service-catalogue.hmpps.service.justice.gov.uk/v1"

SC_HTTPIE_SESSION="./.httpie_session_sc.json"
SC_HTTPIE_OPTS=("--check-status" "--timeout=4.5" "--session-read-only=${SC_HTTPIE_SESSION}")

# echo "Service catalogue API_KEY is ${SERVICE_CATALOGUE_API_KEY:0:5}..${SERVICE_CATALOGUE_API_KEY:250:255}" >&2

# Setup httpie session, enable preview API features
if ! OUTPUT=$(http --check-status --ignore-stdin --session=${SC_HTTPIE_SESSION} "${SC_API_ENDPOINT}/components" "Authorization: Bearer ${SERVICE_CATALOGUE_API_KEY}"); then
echo "Unable to talk to Service Catalogue API, check connectivity and API token value set correctly." >&2
echo "$OUTPUT" >&2
# exit 1
fi

http_sc() {
http "${SC_HTTPIE_OPTS[@]}" "${SC_API_ENDPOINT}/$@"
}

project_name=$COMPONENT_NAME

#COMPONENT_SETTINGS=$(http_sc "components?filters[name][\$eq]=${COMPONENT_NAME}&populate=*")
COMPONENT_SETTINGS=$(http_sc "components?filters[name][\$eq]=${COMPONENT_NAME}&populate[0]=product&populate[1]=environments")

if [ $(echo $COMPONENT_SETTINGS | jq ".meta.pagination.total") -eq 0 ]
then
echo "${COMPONENT_NAME} could not be found in the Service Catalogue - please add it first."
exit 1
else
component_description="$(echo $COMPONENT_SETTINGS | jq '.data[0].attributes.description' | tr -d '\"')"
component_github_template_repo="$(echo $COMPONENT_SETTINGS | jq '.data[0].attributes.github_template_repo' | tr -d '\"')"
component_github_project_teams_write="$(echo $COMPONENT_SETTINGS | jq '.data[0].attributes.github_project_teams_write // []' | tr -d '\n')"
component_github_project_teams_admin="$(echo $COMPONENT_SETTINGS | jq '.data[0].attributes.github_project_teams_admin // []' | tr -d '\n')"
component_github_project_teams_maintain="$(echo $COMPONENT_SETTINGS | jq '.data[0].attributes.github_project_teams_maintain' | tr -d '\n')"
component_github_project_branch_protection_restricted_teams="$(echo $COMPONENT_SETTINGS | jq '.data[0].attributes.github_project_branch_protection_restricted_teams // []' | tr -d '\n')"
component_github_project_visibility="$(echo $COMPONENT_SETTINGS | jq '.data[0].attributes.github_project_visibility // "public"' | tr -d '\"')"
component_jira_project_keys="$(echo $COMPONENT_SETTINGS | jq '.data[0].attributes.jira_project_keys // []' | tr -d '\n')"
product_hmpps_product_id="$(echo $COMPONENT_SETTINGS | jq '.data[0].attributes.product.data.attributes.p_id' | tr -d '\"')"
namespace_details="$(echo $COMPONENT_SETTINGS | jq '.data[0].attributes.environments' )"
component_circleci_project_k8s_namespace="$(echo $namespace_details | jq '.[] | select ( .name=="dev").namespace' | tr -d '\"')"
if [ $(echo $namespace_details | jq '.[] | select ( .name!="dev").namespace' | wc -l) -gt 0 ]
then
component_circleci_context_k8s_namespaces="["
for each_namespace in $(echo $namespace_details | jq '.[] | select ( .name!="dev").namespace' | sed "s/${COMPONENT_NAME}-//g")
do
component_circleci_context_k8s_namespaces="${component_circleci_context_k8s_namespaces} { \"env_name\" : ${each_namespace} },"
done
component_circleci_context_k8s_namespaces=$(echo $component_circleci_context_k8s_namespaces | sed 's/,$/\]/g')
else
component_circleci_context_k8s_namespaces="[]"
fi


# Generate the outputs of the action
echo "component_description=${component_description}"
echo "component_github_template_repo=${component_github_template_repo}"
echo "component_github_project_teams_write=${component_github_project_teams_write}"
echo "component_github_project_teams_admin=${component_github_project_teams_admin}"
echo "component_github_project_teams_maintain=${component_github_project_teams_maintain}"
echo "component_github_project_branch_protection_restricted_teams=${component_github_project_branch_protection_restricted_teams}"
echo "component_github_project_visibility=${component_github_project_visibility}"
echo "component_jira_project_keys=${component_jira_project_keys}"
echo "product_hmpps_product_id=${product_hmpps_product_id}"
echo "component_circleci_project_k8s_namespace=${component_circleci_project_k8s_namespace}"
echo "component_circleci_context_k8s_namespaces=${component_circleci_context_k8s_namespaces}"
fi
72 changes: 72 additions & 0 deletions scripts/update-quayio.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
#!/usr/bin/env bash
# Modification of quayio.sh to be standalone as part of github actions
# Made by jamesH July 2024
# Version 0.0.1 - initial commit

set -e

echo -e "\n### QUAY.IO REPO SETUP ###"
# Required env vars, set by calling action
#GITHUB_REPO_NAME=""
#QUAYIO_ORG="hmpps"
#GITHUB_REPO_DESCRIPTION=""
#GITHUB_ORG="ministryofjustice"
#CIRCLECI_TOKEN=""

#QUAY.IO parameters
QUAYIO_HTTPIE_SESSION="./.httpie_session_quayio.json"
QUAYIO_HTTPIE_OPTS=("--body" "--check-status" "--ignore-stdin" "--timeout=4.5" "--session-read-only=${QUAYIO_HTTPIE_SESSION}")
QUAYIO_API_ENDPOINT="https://quay.io/api/v1"

#CIRCLECI parameters
CIRCLECI_API_ENDPOINT="https://circleci.com/api/v2"
CIRCLECI_HTTPIE_SESSION="./.httpie_session_circleci.json"
CIRCLECI_HTTPIE_OPTS=("-b" "--check-status" "--ignore-stdin" "--timeout=60" "--session-read-only=${CIRCLECI_HTTPIE_SESSION}")
PROJECT_SLUG="gh/${GITHUB_ORG}/${GITHUB_REPO_NAME}"

function http_quayio() {
http "${QUAYIO_HTTPIE_OPTS[@]}" "$@"
}

function setup_quayio_session() {
# Setup httpie quay.io session
if ! OUTPUT=$(http --check-status --ignore-stdin --session=${QUAYIO_HTTPIE_SESSION} "${QUAYIO_API_ENDPOINT}/organization/$QUAYIO_ORG" "Authorization: Bearer ${QUAYIO_TOKEN}"); then
echo "Unable to talk to Quay.io API - check that the QUAYIO_TOKEN value is set correctly and permissions granted."
echo "$OUTPUT"
exit 1
fi
if [[ $(echo "$OUTPUT" | jq -r .is_admin) != 'true' ]]; then
echo "QUAYIO_TOKEN is not an administrator of the $QUAYIO_ORG organisation"
echo "$OUTPUT"
exit 1
fi
}

function http_circleci() {
http "${CIRCLECI_HTTPIE_OPTS[@]}" "$@"
}

function setup_circleci_session() {
#setup httpie circleci session
if ! OUTPUT=$(http -b --check-status --session=${CIRCLECI_HTTPIE_SESSION} ${CIRCLECI_API_ENDPOINT}/me/collaborations "Circle-Token: ${CIRCLECI_TOKEN}"); then
echo "Unable to talk to circleci API - check that the CIRCLECI_TOKEN value is set correctly and permissions granted."
echo "$OUTPUT"
exit 1
fi
}

function set_circleci_env_var {
VAR_NAME=$1
VAR_VALUE=$2
echo "Setting env var on project ${PROJECT_SLUG}:"
http_circleci POST "${CIRCLECI_API_ENDPOINT}/project/${PROJECT_SLUG}/envvar" \
name="${VAR_NAME}" \
value="${VAR_VALUE}"
}


echo "Entering update-quayio.sh - the description is: ${github_repo_description}"

# Set up the sessions
setup_quayio_session
setup_circleci_session

0 comments on commit 778f4e2

Please sign in to comment.