Add Gitea webhook

pull/1/head
lars 2023-10-03 14:29:22 -05:00
parent 7e0f34b9af
commit 39a5f5e006
4 changed files with 94 additions and 64 deletions

View File

@ -12,13 +12,16 @@ steps:
- pip3 install requests python-dotenv --quiet - pip3 install requests python-dotenv --quiet
- python3 deploy/portainer/deploy.py - python3 deploy/portainer/deploy.py
--PORTAINER https://dvportainer.privatedns.org --PORTAINER https://dvportainer.privatedns.org
--API_KEY=ptr_RwxH2Cd+htdD2FoFiG46erT9beyvj9VoF3BrQPtDH3Q= --PORTAINER_API_KEY=ptr_RwxH2Cd+htdD2FoFiG46erT9beyvj9VoF3BrQPtDH3Q=
--PORTAINER_EP=CICD-runner --PORTAINER_EP=CICD-runner
--GITEA_API_KEY=f449c74ec7f04e54fe1e481eae43492b34cea406
--DEPLOY_REPO_URL=${DRONE_REPO_LINK} --DEPLOY_REPO_URL=${DRONE_REPO_LINK}
--DEPLOY_REF=${DRONE_COMMIT_REF} --DEPLOY_REF=${DRONE_COMMIT_REF}
--DEPLOY_HOST=dvdemo.privatedns.org --DEPLOY_HOST=dvdemo.privatedns.org
--DEPLOY_NAME=${DRONE_COMMIT_SHA} --DEPLOY_NAME=${DRONE_COMMIT_SHA}
trigger: trigger:
branch: event:
- main - pull_request
action:
- opened

View File

@ -1,8 +1,9 @@
PORTAINER=https://dvportainer.privatedns.org PORTAINER=https://dvportainer.privatedns.org
API_KEY=ptr_RwxH2Cd+htdD2FoFiG46erT9beyvj9VoF3BrQPtDH3Q= PORTAINER_API_KEY=ptr_RwxH2Cd+htdD2FoFiG46erT9beyvj9VoF3BrQPtDH3Q=
PORTAINER_EP=CICD-runner PORTAINER_EP=CICD-runner
DEPLOY_REPO_URL=https://dvgit.privatedns.org/lars/DeployTests GITEA_API_KEY=f449c74ec7f04e54fe1e481eae43492b34cea406
DEPLOY_REF=refs/heads/main DEPLOY_REPO_URL=https://dvgit.privatedns.org/lars/DeployTests
DEPLOY_HOST=dvdemo.privatedns.org DEPLOY_REF=refs/heads/main
DEPLOY_PROJECT=ManualDeployTests DEPLOY_HOST=dvdemo.privatedns.org
DEPLOY_PROJECT=ManualDeployTests
DEPLOY_NAME=ManualDeploy DEPLOY_NAME=ManualDeploy

View File

@ -5,16 +5,19 @@ import sys
import argparse import argparse
import requests import requests
import json import json
import uuid
from dotenv import load_dotenv from dotenv import load_dotenv
from string import Template from string import Template
from pathlib import Path from pathlib import Path
from urllib.parse import urlparse
load_dotenv() load_dotenv()
required_env_vars = { required_env_vars = {
'PORTAINER': 'The portainer instance to deploy to', 'PORTAINER': 'The portainer instance to deploy to',
'API_KEY': 'API-Key to access portainer instance', 'PORTAINER_API_KEY': 'API-Key to access portainer instance',
'PORTAINER_EP': 'Portainer Environment EndPoint to deploy to', 'PORTAINER_EP': 'Portainer Environment EndPoint to deploy to',
'GITEA_API_KEY': 'API-Key to access Gitea instance',
'DEPLOY_REPO_URL': 'The repository URL to deploy', 'DEPLOY_REPO_URL': 'The repository URL to deploy',
'DEPLOY_REF': 'The git ref to deploy', 'DEPLOY_REF': 'The git ref to deploy',
'DEPLOY_HOST': 'The host name under which the deployment will be reachable', 'DEPLOY_HOST': 'The host name under which the deployment will be reachable',
@ -41,24 +44,29 @@ if not_parsed:
parser.print_help() parser.print_help()
sys.exit(1) sys.exit(1)
portainer=args.PORTAINER
api_key=args.API_KEY
portainer_ep=args.PORTAINER_EP
# Deploy variables to substitute in portainer deploy template # Deploy variables to substitute in portainer deploy template
deploy_variables = {key: getattr(args, key) for key in deploy_variables = {key: getattr(args, key) for key in
['DEPLOY_REPO_URL', 'DEPLOY_HOST', 'DEPLOY_NAME', 'DEPLOY_REF'] ['DEPLOY_REPO_URL', 'DEPLOY_HOST', 'DEPLOY_NAME', 'DEPLOY_REF']
} }
deploy_variables['DEPLOY_WEBHOOK'] = str(uuid.uuid4())
portainer=args.PORTAINER
portainer_api_key=args.PORTAINER_API_KEY
portainer_ep=args.PORTAINER_EP
gitea_api_key=args.GITEA_API_KEY
deploy_repo=deploy_variables['DEPLOY_REPO_URL']
deploy_webhook=deploy_variables['DEPLOY_WEBHOOK']
deploy_ref=deploy_variables['DEPLOY_REF']
### Find CICD-runner portainer environment endpointId ### ### Find CICD-runner portainer environment endpointId ###
headers = { portainer_headers = {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
'X-API-Key': api_key, 'X-API-Key': portainer_api_key,
} }
url = f'{portainer}/api/endpoints' endpoint_url = f'{portainer}/api/endpoints'
json_endpoints = None json_endpoints = None
try: try:
response = requests.get(url, headers=headers) response = requests.get(endpoint_url, headers=portainer_headers)
response.raise_for_status() # Raise HTTPError for bad requests response.raise_for_status() # Raise HTTPError for bad requests
json_endpoints = response.json() json_endpoints = response.json()
@ -77,26 +85,75 @@ else:
### Template substitution for the portainer stack deployment ### ### Template substitution for the portainer stack deployment ###
portainer_deploy_json = None portainer_deploy_payload = {
template_file = f'{Path( __file__ ).parent.absolute()}/portainer_deploy.template.json' "additionalFiles": [
with open(template_file, 'r') as file: "deploy/portainer/portainer_deploy.docker-compose.yml"
portainer_template = Template(file.read()) ],
"autoUpdate": {
# Perform variable substitution "webhook": f"{deploy_variables['DEPLOY_WEBHOOK']}"
portainer_deploy_json = portainer_template.substitute(**deploy_variables) },
"composeFile": "docker-compose.yml",
"env": [
{
"name": "HOST",
"value": f"{deploy_variables['DEPLOY_HOST']}"
},
{
"name": "COMPOSE_PROJECT_NAME",
"value": f"{deploy_variables['DEPLOY_NAME']}"
}
],
"fromAppTemplate": False,
"name": f"{deploy_variables['DEPLOY_NAME']}",
"repositoryAuthentication": True,
"repositoryUsername": "cicd",
"repositoryPassword": "gJ6@$7ZjWGyV4%i",
"repositoryReferenceName": f"{deploy_variables['DEPLOY_REF']}",
"repositoryURL": f"{deploy_variables['DEPLOY_REPO_URL']}",
"tlsskipVerify": False
}
### Deploy to portainer ### ### Deploy to portainer ###
headers = { deploy_url = f'{portainer}/api/stacks/create/standalone/repository?endpointId={endpoint_id}'
'Content-Type': 'application/json',
'X-API-Key': api_key,
}
url = f'{portainer}/api/stacks/create/standalone/repository?endpointId={endpoint_id}'
try: try:
response = requests.post(url, headers=headers, json=json.loads(portainer_deploy_json)) response = requests.post(deploy_url, headers=portainer_headers, json=portainer_deploy_payload)
response.raise_for_status() # Raise HTTPError for bad requests response.raise_for_status() # Raise HTTPError for bad requests
response_data = response.json() # Parse response JSON deploy_response = response.json()
except requests.exceptions.RequestException as err: except requests.exceptions.RequestException as err:
raise Exception(f'Could not deploy portainer stack: {err}') raise Exception(f'Could not deploy portainer stack: {err}')
### Add Webhook to Gitea ###
repo_url = urlparse(deploy_repo)
gitea = f"{repo_url.scheme}://{repo_url.netloc}"
repo_path = repo_url.path
repo_parts = repo_path.strip('/').split('/')
owner = repo_parts[0]
repo = repo_parts[1]
ref_parts = deploy_ref.strip('/').split('/')
branch = ref_parts[2]
webhook_payload = {
"type": "gitea",
"branch_filter": f"{branch}",
"config": {
"url": f"{portainer}/api/stacks/webhooks/{deploy_webhook}",
"content_type": "json"
},
"events": ["push"], # You can specify other events as needed
"active": True
}
webhook_url = f'{gitea}/api/v1/repos/{owner}/{repo}/hooks'
webhook_headers = {
"Authorization": f"token {gitea_api_key}"
}
try:
response = requests.post(webhook_url, headers=webhook_headers, json=webhook_payload)
response.raise_for_status() # Raise HTTPError for bad requests
webhook_response = response.json()
except requests.exceptions.RequestException as err:
raise Exception(f'Could not add webhook to Gitea: {err}')
print(f'Successfully deployed project') print(f'Successfully deployed project')

View File

@ -1,31 +0,0 @@
{
"additionalFiles": [
"deploy/portainer/portainer_deploy.docker-compose.yml"
],
"autoUpdate": {
"forcePullImage": false,
"forceUpdate": false,
"interval": "1m30s",
"jobID": "15",
"webhook": "05de31a2-79fa-4644-9c12-faa67e5c49f0"
},
"composeFile": "docker-compose.yml",
"env": [
{
"name": "HOST",
"value": "${DEPLOY_HOST}"
},
{
"name": "COMPOSE_PROJECT_NAME",
"value": "${DEPLOY_NAME}"
}
],
"fromAppTemplate": false,
"name": "${DEPLOY_NAME}",
"repositoryAuthentication": true,
"repositoryUsername": "cicd",
"repositoryPassword": "gJ6@$$7ZjWGyV4%i",
"repositoryReferenceName": "${DEPLOY_REF}",
"repositoryURL": "${DEPLOY_REPO_URL}",
"tlsskipVerify": false
}