forked from mautic/Community-Portal
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
ci: scripts to redeploy in developments
- Loading branch information
Hadrien Froger
committed
Feb 7, 2024
1 parent
1399db3
commit eb588d7
Showing
2 changed files
with
337 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,310 @@ | ||
jpsType: update | ||
jpsVersion: '1.7.4' | ||
|
||
name: Scripts/DailyTask | ||
id: daily-task | ||
description: | ||
short: Sysadmin Actions for jelastic account | ||
categories: | ||
- apps/platforms | ||
ssl: true | ||
ha: false | ||
settings: | ||
fields: | ||
- name: RESTIC_REPOSITORY | ||
type: string | ||
caption: Host+bucket+region for the S3 | ||
- name: AWS_ACCESS_KEY_ID | ||
type: string | ||
caption: Key ID for S3 | ||
- name: AWS_SECRET_ACCESS_KEY | ||
type: string | ||
caption: Secret for S3 | ||
- name: RESTIC_PASSWORD | ||
type: string | ||
caption: Key used for restic encryption | ||
- name: AWS_DEFAULT_REGION | ||
type: string | ||
caption: Default Region | ||
default: 'ch-dk-2' | ||
- name: TAG | ||
type: string | ||
caption: Tag the backup | ||
default: 'daily' | ||
|
||
onInstall: | ||
- type: "javascript" | ||
script: | ||
- 'var resp = jelastic.environment.control.GetEnvs(appid, session);' | ||
- 'if(resp.result != 0) return {"result": 1, "message": "ERROR"};' | ||
- 'var nodes = (resp.infos || []).filter(function(env) { | ||
return (env.env.status || 0) === 1; | ||
}).reduce(function(acc, curr) { | ||
acc[curr.env.envName] = { | ||
raw: curr, | ||
nodes: curr.nodes.filter(function(nd) { | ||
if(nd.nodeGroup === "cp" && curr.nodes.find(function(nd2) { return nd2.nodeGroup === "storage"; })) { | ||
return false; | ||
} | ||
return (typeof nd.customitem !== "undefined") && | ||
(typeof nd.customitem.dockerVolumes !== "undefined") && | ||
(nd.customitem.dockerVolumes.length > 0) && | ||
["cp", "bl", "sqldb", "storage"].includes(nd.nodeGroup); | ||
}).map(function(nd) { | ||
return { | ||
nodeGroup: nd.nodeGroup, | ||
volumes: nd.customitem.dockerVolumes, | ||
id: nd.id, | ||
ip: nd.intIP, | ||
port: nd.port | ||
}; | ||
}) | ||
}; | ||
return acc; | ||
}, {})' | ||
- 'var result = Object.keys(nodes).map(function(envName) { | ||
var nd = nodes[envName]; | ||
nd.envName = envName; | ||
return nd; | ||
})' | ||
- 'return {"result": 0,"environments": JSON.stringify(result)}' | ||
|
||
- setGlobals: | ||
- ENVIRONMENTS: ${response.environments} | ||
|
||
- type: javascript | ||
environments: ${globals.ENVIRONMENTS} | ||
script: | ||
- 'var installRestic = function(envName, nodeGroups){ | ||
var results = nodeGroups.map(function(nodeGroup) { | ||
var resp = jelastic.environment.control.ExecCmdByGroup( | ||
envName, | ||
session, | ||
nodeGroup, | ||
JSON.stringify([ | ||
{ | ||
"command": "which restic >/dev/null || { which dnf >/dev/null && { dnf install -y epel-release; dnf install -y restic; } || { which apk >/dev/null && apk add restic; } || { which yum >/dev/null && { yum-config-manager --add-repo https://copr.fedorainfracloud.org/coprs/copart/restic/repo/epel-7/copart-restic-epel-7.repo; yum-config-manager --enable copr:copr.fedorainfracloud.org:copart:restic; yum -y install restic; yum-config-manager --disable copr:copr.fedorainfracloud.org:copart:restic; } ; } ; }" | ||
} | ||
]) | ||
); | ||
return resp.result === 0; | ||
}); | ||
return results.filter(Boolean).length === results.length; | ||
}' | ||
- 'var environments = JSON.parse(getParam("environments"))' | ||
- 'var failedInstall = environments.filter(function(environment) { | ||
var nodes = environment.nodes; | ||
var nodeGroups = nodes.map(function(nd) { return nd.nodeGroup }); | ||
return !installRestic(environment.envName, nodeGroups) | ||
})' | ||
- 'var outputMessage = failedInstall.length > 0 ? | ||
( | ||
"Fail to install Restic. Check environments " + failedInstall.map(function(environment) { | ||
return "`" + environment.envName + "`"; | ||
}).join(", ") | ||
) : "OK"' | ||
- 'return {result: 0, outputMessage: outputMessage }' | ||
- setGlobals: | ||
- OUTPUT_RESTIC_INSTALL: ${response.outputMessage} | ||
- type: javascript | ||
environments: ${globals.ENVIRONMENTS} | ||
script: | ||
- 'var backupContainer = function(envName, nodeGroup, directories, topology){ | ||
var tag = "${settings.TAG}"; | ||
var repo = "s3:${settings.RESTIC_REPOSITORY}/" + envName + "-" + nodeGroup; | ||
var keyId = "${settings.AWS_ACCESS_KEY_ID}"; | ||
var keySecret = "${settings.AWS_SECRET_ACCESS_KEY}"; | ||
var resticPassword = "${settings.RESTIC_PASSWORD}"; | ||
var defaultRegion = "${settings.AWS_DEFAULT_REGION}"; | ||
if(topology) { | ||
jelastic.environment.control.ExecCmdByGroup( | ||
envName, | ||
session, | ||
nodeGroup, | ||
JSON.stringify([ | ||
{ | ||
"command": "mkdir -p /tmp/topology", | ||
"params": "" | ||
} | ||
]) | ||
); | ||
directories.push("/tmp/topology"); | ||
jelastic.environment.file.write( | ||
envName, | ||
session, | ||
"/tmp/topology/topology.json", | ||
JSON.stringify(topology), | ||
undefined, | ||
nodeGroup | ||
); | ||
} | ||
var resp = jelastic.environment.control.ExecCmdByGroup( | ||
envName, | ||
session, | ||
nodeGroup, | ||
JSON.stringify([ | ||
{ | ||
"command": "export RESTIC_REPOSITORY=\""+repo+"\"", | ||
"params": "" | ||
}, | ||
{ | ||
"command": "export AWS_ACCESS_KEY_ID=\""+keyId+"\"", | ||
"params": "" | ||
}, | ||
{ | ||
"command": "export AWS_SECRET_ACCESS_KEY=\""+keySecret+"\"", | ||
"params": "" | ||
}, | ||
{ | ||
"command": "export RESTIC_PASSWORD=\""+resticPassword+"\"", | ||
"params": "" | ||
}, | ||
{ | ||
"command": "export AWS_DEFAULT_REGION=\""+defaultRegion+"\"", | ||
"params": "" | ||
}, | ||
{ | ||
"command": "if ! restic snapshots >/dev/null 2>&1; then restic init; fi", | ||
"params": "" | ||
}, | ||
{ | ||
"command": "restic backup --tag "+ tag +" " + directories.filter(function(dir) { | ||
return !dir.endsWith("vendor") && !dir.endsWith("node_modules"); | ||
}).join(" "), | ||
"params": "" | ||
} | ||
]) | ||
); | ||
return resp.result === 0; | ||
}' | ||
- 'var backupDatabase = function(envName){ | ||
var resp = jelastic.environment.control.ExecCmdByGroup( | ||
envName, | ||
session, | ||
"sqldb", | ||
JSON.stringify([ | ||
{ | ||
"command": "mkdir -p /root/dump", | ||
"params": "" | ||
}, | ||
{ | ||
"command": "cd /root/dump", | ||
"params": "" | ||
}, | ||
{ | ||
"command": "databases=$(psql --username $POSTGRES_USER postgres -qAt -c \"SELECT datname FROM pg_database WHERE NOT datistemplate\")", | ||
"params": "" | ||
}, | ||
{ | ||
"command": "for db in $databases; do pg_dump --username $POSTGRES_USER -Fp $db > /root/dump/$db.sql; done", | ||
"params": "" | ||
} | ||
]) | ||
); | ||
return resp.result == 0; | ||
}' | ||
- 'var environments = JSON.parse(getParam("environments"))' | ||
- 'var backups = environments.map(function(environment) { | ||
var nodes = environment.nodes; | ||
var raw = environment.raw; | ||
var envName = environment.envName; | ||
var nodeGroups = nodes.map(function(nd) { return nd.nodeGroup }); | ||
var backupProcess = []; | ||
var hasStorage = nodeGroups.includes("storage"); | ||
if(nodeGroups.includes("sqldb")) { | ||
var matchNode = nodes.find(function(nd) { return nd.nodeGroup == "sqldb";}); | ||
backupProcess.push(backupContainer(envName, "sqldb", ["/root/dump"], undefined)); | ||
} | ||
if(nodeGroups.includes("cp")) { | ||
var matchNode = nodes.find(function(nd) { return nd.nodeGroup == "cp";}); | ||
backupProcess.push(backupContainer(envName, "cp", matchNode.volumes, hasStorage ? undefined : raw)); | ||
} | ||
if(hasStorage) { | ||
var matchNode = nodes.find(function(nd) { return nd.nodeGroup == "storage";}); | ||
backupProcess.push(backupContainer(envName, "storage", matchNode.volumes, raw)); | ||
} | ||
if(nodeGroups.includes("bl")) { | ||
var matchNode = nodes.find(function(nd) { return nd.nodeGroup == "bl";}); | ||
backupProcess.push(backupContainer(envName, "bl", matchNode.volumes, undefined)); | ||
} | ||
return [ | ||
envName, | ||
backupProcess.length > 0 && backupProcess.filter(Boolean).length === backupProcess.length | ||
]; | ||
})' | ||
- 'var outputMessage = backups.map(function(backupInfo) { | ||
return " * " + backupInfo[0] + ": " + (backupInfo[1] ? "✅" : "⚠️") | ||
}).join("\n")' | ||
- 'return {"result": 0, outputMessage: outputMessage}' | ||
|
||
- setGlobals: | ||
- OUTPUT_BACKUP: ${response.outputMessage} | ||
|
||
- type: javascript | ||
environments: ${globals.ENVIRONMENTS} | ||
script: | ||
- 'var fetchBilling = function(targetAppId, envName) { | ||
var yesterdayStart = new Date(); | ||
yesterdayStart.setDate(yesterdayStart.getDate() - 1); | ||
yesterdayStart.setUTCHours(0,0,0,0); | ||
yesterdayStart = yesterdayStart.toISOString(); | ||
var yesterdayEnd = new Date(); | ||
yesterdayEnd.setDate(yesterdayEnd.getDate() - 1); | ||
yesterdayEnd.setUTCHours(23,59,59,999); | ||
yesterdayEnd = yesterdayEnd.toISOString(); | ||
var billingHistory = jelastic.billing.account.GetExtendedAccountBillingHistoryByPeriod( | ||
appid, | ||
session, | ||
yesterdayStart, | ||
yesterdayEnd, | ||
targetAppId | ||
); | ||
if(!billingHistory || billingHistory.result !== 0 || billingHistory.object.envs.length === 0) { | ||
return null; | ||
} | ||
var envBillingHistory = billingHistory.object.envs[0][envName]; | ||
var cloudlets = (envBillingHistory.cloudlets.flexible.cost || 0) + (envBillingHistory.cloudlets.fixed.cost || 0); | ||
var storage = envBillingHistory.storage.total.cost || 0; | ||
var ips = envBillingHistory.ips.cost || 0; | ||
var ssl = envBillingHistory.ssl.cost || 0; | ||
return { | ||
"total": (cloudlets + storage + ips + ssl).toFixed(2), | ||
"ips": ips.toFixed(2), | ||
"cloudlets": cloudlets.toFixed(2), | ||
"storage": storage.toFixed(2), | ||
"ssl": ssl.toFixed(2) | ||
}; | ||
}' | ||
- 'var environments = JSON.parse(getParam("environments"))' | ||
- 'var billings = environments.map(function(environment) { | ||
var billingHistory = fetchBilling(environment.raw.env.appid, envName); | ||
return [ | ||
"Yesterday Billing " + (billingHistory ? billingHistory.total + "CHF" : "unknown"), | ||
"_Yesterday Billing Details_", | ||
(billingHistory ? Object.keys(billingHistory).filter(function(k) { return k !== "total"}).map(function(k) { | ||
var value = billingHistory[k]; | ||
return " * __"+ k + "__: " + (value === "0" ? "free" : value + "CHF") | ||
}).join("\n") : "unknown") | ||
].join("\n\n"); | ||
}' | ||
- 'var outputMessage = billings.join("\n")' | ||
- 'return {"result": 0, outputMessage: outputMessage}' | ||
- setGlobals: | ||
- OUTPUT_BILLING: ${response.outputMessage} | ||
|
||
- return: | ||
type: success | ||
message: | | ||
# Jelastic Daily Review | ||
## Backup Status | ||
**▪️ Backup are installed** | ||
${globals.OUTPUT_RESTIC_INSTALL} | ||
**▪️ Backup are done** | ||
${globals.OUTPUT_BACKUP} | ||
## Billing status | ||
${globals.OUTPUT_BILLING} | ||
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
name: Redploy Decidim Image in Jelastic Infra | ||
|
||
on: | ||
workflow_dispatch: | ||
|
||
jobs: | ||
deploy: | ||
runs-on: ubuntu-latest | ||
container: | ||
image: mwienk/jelastic-cli | ||
|
||
steps: | ||
- name: Checkout code | ||
uses: actions/checkout@v2 | ||
|
||
- name: Redeploy container in Jelastic | ||
env: | ||
JELASTIC_LOGIN: ${{ secrets.JELASTIC_LOGIN }} | ||
JELASTIC_PASSWORD: ${{ secrets.JELASTIC_PASSWORD }} | ||
JELASTIC_HOSTER: ${{ secrets.JELASTIC_HOSTER }} | ||
ENVNAME: ${{ secrets.ENVNAME }} | ||
NODE_GROUP: ${{ secrets.NODE_GROUP }} # Default to cp if not set | ||
TAG: ${{ secrets.TAG }} # Default to latest if not set | ||
USE_EXISTING_VOLUME: ${{ secrets.USE_EXISTING_VOLUME }} # Default to true if not set | ||
run: | | ||
/root/jelastic/users/authentication/signin --login $JELASTIC_LOGIN --password $JELASTIC_PASSWORD --platformUrl $JELASTIC_HOSTER | ||
/root/jelastic/environment/control/redeploycontainersbygroup --envName $ENVNAME --nodeGroup ${NODE_GROUP:-cp} --tag ${TAG:-latest} --useExistingVolumes ${USE_EXISTING_VOLUME:-true} |