-
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.
- Loading branch information
Showing
3 changed files
with
213 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,149 @@ | ||
""" | ||
This file connects with CloudMyDC Jelastic API and adds/updates application manifests defined in the repository. | ||
""" | ||
|
||
import os | ||
import requests | ||
import yaml | ||
import logging | ||
from urllib.parse import urlencode | ||
|
||
# Initialize logging | ||
logging.basicConfig(level=logging.INFO) | ||
|
||
# Constants and Environment Variables | ||
JELASTIC_TOKEN = os.environ.get("JELASTIC_TOKEN") | ||
if not JELASTIC_TOKEN: | ||
logging.error("JELASTIC_TOKEN not set.") | ||
exit(1) | ||
|
||
JELASTIC_BASE_URL = "https://jca.xapp.cloudmydc.com/1.0/marketplace/admin/rest" | ||
|
||
|
||
def url(path, params=None, add_session=True): | ||
""" | ||
Generate a full URL for a given API path and parameters. | ||
""" | ||
if params is None: | ||
params = {} | ||
|
||
if add_session: | ||
params["session"] = JELASTIC_TOKEN | ||
|
||
query_string = urlencode(params) | ||
return f"{JELASTIC_BASE_URL}/{path}?{query_string}" | ||
|
||
|
||
def get_apps(): | ||
""" | ||
Get all applications from the Jelastic account. | ||
""" | ||
try: | ||
response = requests.get(url("getapps", {"appid": "cluster"})) | ||
response.raise_for_status() | ||
logging.info("Fetched apps from Jelastic.") | ||
return response.json().get("apps", []) | ||
except requests.RequestException as e: | ||
logging.error(f"Error fetching apps: {e}") | ||
return [] | ||
|
||
|
||
def get_local_manifests(): | ||
""" | ||
Get all the application manifests from the repository. | ||
""" | ||
manifests = [] | ||
for root, dirs, files in os.walk("."): | ||
if ".git" in dirs: | ||
dirs.remove(".git") # ignore git directory | ||
for file in files: | ||
if file.endswith(".jps"): | ||
manifests.append(os.path.join(root, file)) | ||
|
||
logging.info(f"Found {len(manifests)} manifests in the repository.") | ||
return manifests | ||
|
||
|
||
def add_app(app_id, app_manifest, publish=True, id=None): | ||
""" | ||
Add or update an application in the Jelastic account. | ||
:param app_id: ID of the application. | ||
:param app_manifest: Path to the manifest file. | ||
:param publish: Whether to publish the application. | ||
:param id: ID of the application if updating. | ||
:return: None | ||
""" | ||
if not publish and not id: | ||
raise ValueError("ID must be provided when updating an application.") | ||
|
||
if id and not isinstance(id, int): | ||
raise TypeError("ID must be an integer.") | ||
|
||
logging.info(f"{'Adding' if publish else 'Updating'} application [{app_id}]") | ||
|
||
data = open(app_manifest).read() | ||
|
||
payload = { | ||
"appid": "cluster", | ||
"manifest": data, | ||
"session": JELASTIC_TOKEN, | ||
} | ||
|
||
if publish: | ||
api_path = "addapp" | ||
else: | ||
payload["id"] = id | ||
api_path = "editapp" | ||
|
||
try: | ||
response = requests.post(url(api_path, add_session=False), data=payload) | ||
if response.json().get("result") != 0: | ||
raise Exception(response.json().get("error")) | ||
|
||
if publish: | ||
# Fetch the ID of the newly added application | ||
for app in get_apps(): | ||
if app["app_id"] == app_id: | ||
id = app["id"] | ||
break | ||
|
||
logging.info(f"Publishing [{app_id}] application...") | ||
publish_response = requests.post( | ||
url("publishapp", {"id": id, "appid": "cluster"}) | ||
) | ||
if publish_response.json().get("result") != 0: | ||
raise Exception(publish_response.json().get("error")) | ||
except requests.RequestException as e: | ||
logging.error(f"Error in {'adding' if publish else 'updating'} app: {e}") | ||
|
||
|
||
def process_manifest(manifest, remote_apps): | ||
""" | ||
Process each manifest file. | ||
""" | ||
with open(manifest) as f: | ||
data = yaml.safe_load(f) | ||
|
||
app_id = data["id"] | ||
app_exists = False | ||
id = None | ||
|
||
for app in remote_apps: | ||
if app["app_id"] == app_id: | ||
app_exists = True | ||
id = app["id"] | ||
break | ||
|
||
add_app(app_id, manifest, publish=not app_exists, id=id) | ||
|
||
|
||
# Main Script Execution | ||
try: | ||
remote_apps = get_apps() | ||
local_manifests = get_local_manifests() | ||
|
||
for manifest in local_manifests: | ||
process_manifest(manifest, remote_apps) | ||
except Exception as e: | ||
logging.error(f"An error occurred: {e}") |
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,25 @@ | ||
name: JPS Manifest | ||
|
||
on: | ||
push: | ||
branches: | ||
- master | ||
|
||
jobs: | ||
update-manifest: | ||
runs-on: ubuntu-latest | ||
|
||
steps: | ||
- name: Checkout Repository | ||
uses: actions/checkout@v4 | ||
|
||
- name: Set up Python | ||
uses: actions/setup-python@v5 | ||
|
||
- name: Install Python Dependencies | ||
run: pip install requests | ||
|
||
- name: Run Update Script | ||
env: | ||
JELASTIC_TOKEN: ${{ secrets.JELASTIC_TOKEN }} | ||
run: python .github/jca.py |
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,39 @@ | ||
name: PR Check | ||
|
||
on: | ||
pull_request: | ||
branches: [ master ] | ||
|
||
jobs: | ||
check-manifest: | ||
runs-on: ubuntu-latest | ||
|
||
steps: | ||
- name: Checkout code | ||
uses: actions/checkout@v2 | ||
|
||
- name: Find manifest.jps files | ||
id: find-manifest | ||
run: | | ||
files=$(find . -name 'manifest.jps') | ||
echo "::set-output name=files::$(echo "$files" | sed ':a;N;$!ba;s/\n/ /g')" | ||
- name: Validate baseUrl in manifest files | ||
run: | | ||
repo_owner="${{ github.repository_owner }}" | ||
repo_name=$(echo "${{ github.repository }}" | cut -d'/' -f2) | ||
expected_base_url="https://raw.githubusercontent.com/${repo_owner}/${repo_name}/master" | ||
IFS=' ' read -r -a file_array <<< "${{ steps.find-manifest.outputs.files }}" | ||
for file in "${file_array[@]}" | ||
do | ||
if [ ! -f "$file" ]; then | ||
echo "File not found: $file" | ||
continue | ||
fi | ||
baseUrl=$(yq eval '.baseUrl' "$file") | ||
if [[ "$baseUrl" != "$expected_base_url" ]]; then | ||
echo "Invalid baseUrl format in $file. Expected ${expected_base_url}, but found ${baseUrl}" | ||
exit 1 | ||
fi | ||
done |