Create deployment script
Some checks failed
continuous-integration/drone/push Build is failing

This commit is contained in:
2023-10-02 20:34:40 -05:00
parent ec4abaae1f
commit bac592b5b0
7 changed files with 128 additions and 38 deletions

8
deploy/portainer/.env Normal file
View File

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

100
deploy/portainer/deploy.py Normal file
View File

@@ -0,0 +1,100 @@
#!/usr/bin/env python3
import os
import sys
import argparse
import requests
import json
from dotenv import load_dotenv
from string import Template
load_dotenv()
required_env_vars = {
'PORTAINER': 'The portainer instance to deploy to',
'API_KEY': 'API-Key to access portainer instance',
'PORTAINER_EP': 'Portainer Environment EndPoint to deploy to',
'DEPLOY_REPO_URL': 'The repository URL to deploy',
'DEPLOY_REF': 'The git ref to deploy',
'DEPLOY_HOST': 'The host name under which the deployment will be reachable',
'DEPLOY_NAME': 'Custom name to use as the deployment name',
}
# Try getting all arguments from (in order): 1 command line, 2 .env file, 3 Environment
parser = argparse.ArgumentParser(description='Deploys a docker compose application to portainer.')
for var, usage in required_env_vars.items():
parser.add_argument(f'--{var}', default=os.getenv(var, None), help=usage)
args = parser.parse_args()
# Check if all were parsed
not_parsed = []
for var, usage in required_env_vars.items():
if not getattr(args, var):
not_parsed.append(var)
else:
print(f'--{var}: {getattr(args, var)}')
if not_parsed:
print(f"Error: The following required environment variables were not provided: {', '.join(not_parsed)}")
parser.print_help()
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 = {key: getattr(args, key) for key in
['DEPLOY_REPO_URL', 'DEPLOY_HOST', 'DEPLOY_PROJECT', 'DEPLOY_NAME', 'DEPLOY_REF']
}
### Find CICD-runner portainer environment endpointId ###
headers = {
'Content-Type': 'application/json',
'X-API-Key': api_key,
}
url = f'{portainer}/api/endpoints'
json_endpoints = None
try:
response = requests.get(url, headers=headers)
response.raise_for_status() # Raise HTTPError for bad requests
json_endpoints = response.json()
except requests.exceptions.RequestException as err:
raise Exception(f'Could not retrieve portainer endpoints: {err}')
endpoint_id = None
for endpoint in json_endpoints:
if endpoint["Name"] == portainer_ep:
endpoint_id = endpoint["Id"]
break
if endpoint_id is None:
raise Exception(f'Portainer endpoint \'{portainer_ep}\' not found.')
else:
print(f'Found portainer endpoint \'{portainer_ep}\' has id: \'{endpoint_id}\'.')
### Template substitution for the portainer stack deployment ###
portainer_deploy_json = None
with open('portainer_deploy.template.json', 'r') as file:
portainer_template = Template(file.read())
# Perform variable substitution
portainer_deploy_json = portainer_template.substitute(**deploy_variables)
### Deploy to portainer ###
headers = {
'Content-Type': 'application/json',
'X-API-Key': api_key,
}
url = f'{portainer}/api/stacks/create/standalone/repository?endpointId={endpoint_id}'
try:
response = requests.post(url, headers=headers, json=json.loads(portainer_deploy_json))
response.raise_for_status() # Raise HTTPError for bad requests
response_data = response.json() # Parse response JSON
except requests.exceptions.RequestException as err:
raise Exception(f'Could not deploy portainer stack: {err}')
print(f'Successfully deployed project')

View File

@@ -0,0 +1,11 @@
version: '3.4'
services:
http-echo:
networks:
- cicd
networks:
cicd:
driver: bridge
external: true

View File

@@ -0,0 +1,31 @@
{
"additionalFiles": [
"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
}