From ebce6d3c1600bccf9084ba08005b9f36fc9aead7 Mon Sep 17 00:00:00 2001 From: pedrohrfz Date: Mon, 7 Oct 2024 16:48:43 -0300 Subject: [PATCH 01/14] docs --- README.md | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index c934a72..06a1264 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,14 @@ -# workflow-stackspot-actions-runtime-selfhosted -workflow-stackspot-actions-runtime-selfhosted +# StackSpot actions runtimes repository + +This repository contains various StackSpot Actions that can be used to automate processes in CI/CD pipelines. Additionally, there is a main action that orchestrates the execution of the other actions, simplifying the integration and management of multiple tasks in a single workflow. + +## Repository Structure + + +## Requirements + +Before using the actions in this repository, ensure that you have the following requirements: + +* StackSpot CLI installed and configured. + + From 661cb38d4972de08ba15371f2dc3ff96f7856ea5 Mon Sep 17 00:00:00 2001 From: pedrohrfz Date: Mon, 7 Oct 2024 16:48:50 -0300 Subject: [PATCH 02/14] ... --- .github/workflows/stk-quality-check.yaml | 46 ++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 .github/workflows/stk-quality-check.yaml diff --git a/.github/workflows/stk-quality-check.yaml b/.github/workflows/stk-quality-check.yaml new file mode 100644 index 0000000..bb41b1c --- /dev/null +++ b/.github/workflows/stk-quality-check.yaml @@ -0,0 +1,46 @@ +name: STK actions quality-check + +on: + workflow_call: + inputs: + realm: + description: The realm of the account. + required: false + type: string + default: "stackspot" + secrets: + stk-client-id: + required: true + stk-client-secret: + required: true + +jobs: + stackspot-runtime-v2: + name: StackSpot Runtime (v2) + runs-on: ubuntu-latest + env: + LANG: C.UTF-8 + LANGUAGE: C.UTF-8 + LC_ALL: C.UTF-8 + PYTHONIOENCODING: utf-8 + steps: + - run: sudo apt update && sudo apt install -y curl unzip git jq + name: install dependencies + - name: Setup STK CLI + run: | + curl \ + --fail \ + --http2-prior-knowledge \ + --location \ + --output /tmp/stk.deb \ + --silent \ + --show-error \ + --tlsv1.3 \ + https://stk.stackspot.com/installer/linux/stk.deb + sudo dpkg --install /tmp/stk.deb || echo installed + rm --force /tmp/stk.deb + - name: Show STK CLI version + run: $HOME/.stk/bin/stk --version + - name: Login StackSpot + run: | + $HOME/.stk/bin/stk login -id ${{ secrets.stk-client-id }} -key ${{ secrets.stk-client-secret }} -r ${{ inputs.realm }} \ No newline at end of file From eaa5fe3d05a1a3e37e4f5e1c8c0a818aa56bda4e Mon Sep 17 00:00:00 2001 From: pedrohrfz Date: Mon, 7 Oct 2024 22:34:25 -0300 Subject: [PATCH 03/14] add readme and stk validate action to pipe --- .github/workflows/stk-quality-check.yaml | 26 ++++++++++---------- README.md | 31 +++++++++++++++++++++++- action.yaml | 5 +++- script.py | 2 +- 4 files changed, 48 insertions(+), 16 deletions(-) diff --git a/.github/workflows/stk-quality-check.yaml b/.github/workflows/stk-quality-check.yaml index bb41b1c..28b3dcc 100644 --- a/.github/workflows/stk-quality-check.yaml +++ b/.github/workflows/stk-quality-check.yaml @@ -1,18 +1,7 @@ name: STK actions quality-check on: - workflow_call: - inputs: - realm: - description: The realm of the account. - required: false - type: string - default: "stackspot" - secrets: - stk-client-id: - required: true - stk-client-secret: - required: true + pull_request: jobs: stackspot-runtime-v2: @@ -24,8 +13,13 @@ jobs: LC_ALL: C.UTF-8 PYTHONIOENCODING: utf-8 steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + - run: sudo apt update && sudo apt install -y curl unzip git jq name: install dependencies + - name: Setup STK CLI run: | curl \ @@ -39,8 +33,14 @@ jobs: https://stk.stackspot.com/installer/linux/stk.deb sudo dpkg --install /tmp/stk.deb || echo installed rm --force /tmp/stk.deb + - name: Show STK CLI version run: $HOME/.stk/bin/stk --version + - name: Login StackSpot run: | - $HOME/.stk/bin/stk login -id ${{ secrets.stk-client-id }} -key ${{ secrets.stk-client-secret }} -r ${{ inputs.realm }} \ No newline at end of file + $HOME/.stk/bin/stk login -id ${{ secrets.IDP_STK_CLIENT_ID }} -key ${{ secrets.IDP_STK_CLIENT_SECRET }} -r stackspot + + - name: Validate main action + run: | + $HOME/.stk/bin/stk validate action \ No newline at end of file diff --git a/README.md b/README.md index 06a1264..6d62b44 100644 --- a/README.md +++ b/README.md @@ -11,4 +11,33 @@ Before using the actions in this repository, ensure that you have the following * StackSpot CLI installed and configured. - +## How to Use + +### Deploy + +```bash +stk run action \ + --workflow_type deploy \ + --environment "" \ + --version_tag "" \ + --repository_name "" \ + --client_id "" \ + --client_key "" \ + --client_realm "" \ + --aws_access_key_id "" \ + --aws_secret_access_key "" \ + --aws_session_token "" \ + --tf_state_bucket_name "" \ + --iac_bucket_name "" \ + --tf_state_region "" \ + --iac_region "" \ + --aws_region "" +``` + +### Cancel + +```bash +stk run action \ + --workflow_type cancel \ + --run_id "" +``` \ No newline at end of file diff --git a/action.yaml b/action.yaml index eb93a87..878e20b 100644 --- a/action.yaml +++ b/action.yaml @@ -13,7 +13,10 @@ spec: inputs: - label: Workflow type name: workflow_type - type: text + type: select + items: + - deploy + - cancel required: true python: workdir: . diff --git a/script.py b/script.py index 8144d9d..b88f983 100644 --- a/script.py +++ b/script.py @@ -42,7 +42,7 @@ def cancel_deploy_run(run_action: RunAction): def run(metadata): - workflows = dict(deploy=deploy_workflow, cancel_deploy=cancel_deploy_run) + workflows = dict(deploy=deploy_workflow, cancel=cancel_deploy_run) run_action = RunAction(metadata) workflow_runner = workflows.get(metadata.inputs["workflow_type"]) workflow_runner and workflow_runner(run_action=run_action) From 57b9867da2093322e28bcdc2957d73260126f100 Mon Sep 17 00:00:00 2001 From: pedrohrfz Date: Mon, 7 Oct 2024 22:44:18 -0300 Subject: [PATCH 04/14] lint --- runtime-cancel-run-action/script.py | 18 ++--- runtime-create-manifest-action/script.py | 36 ++++++---- runtime-deploy-action/script.py | 58 ++++++++++------- runtime-iac-action/script.py | 48 ++++++++------ runtime-manager-action/script.py | 64 ++++++++++-------- runtime-rollback-action/script.py | 83 ++++++++++++++---------- script.py | 25 ++++--- 7 files changed, 195 insertions(+), 137 deletions(-) diff --git a/runtime-cancel-run-action/script.py b/runtime-cancel-run-action/script.py index 24d5c80..ba53925 100644 --- a/runtime-cancel-run-action/script.py +++ b/runtime-cancel-run-action/script.py @@ -2,7 +2,9 @@ from oscli.core.http import post_with_authorization -STK_RUNTIME_MANAGER_DOMAIN = os.getenv("STK_RUNTIME_MANAGER_DOMAIN", "https://runtime-manager.v1.stackspot.com") +STK_RUNTIME_MANAGER_DOMAIN = os.getenv( + "STK_RUNTIME_MANAGER_DOMAIN", "https://runtime-manager.v1.stackspot.com" +) def run(metadata): @@ -40,17 +42,17 @@ def run(metadata): print the error details and exit the program. """ - + # Extract the RUN_ID from the metadata inputs - RUN_ID = metadata.inputs['run_id'] + RUN_ID = metadata.inputs["run_id"] print(f"> Requesting Run {RUN_ID} to be cancelled") - + # Send a POST request to cancel the run cancel_request = post_with_authorization( - url=f"{STK_RUNTIME_MANAGER_DOMAIN}/v1/run/cancel/{RUN_ID}?force=true", - headers={'Content-Type': 'application/json'}, + url=f"{STK_RUNTIME_MANAGER_DOMAIN}/v1/run/cancel/{RUN_ID}?force=true", + headers={"Content-Type": "application/json"}, body=None, - timeout=20 + timeout=20, ) # Handle the response based on the status code @@ -66,4 +68,4 @@ def run(metadata): print("- Status:", cancel_request.status_code) print("- Error:", cancel_request.reason) print("- Response:", cancel_request.text) - exit(1) \ No newline at end of file + exit(1) diff --git a/runtime-create-manifest-action/script.py b/runtime-create-manifest-action/script.py index 26cc479..984f176 100644 --- a/runtime-create-manifest-action/script.py +++ b/runtime-create-manifest-action/script.py @@ -4,12 +4,14 @@ from typing import List, Optional # Configure logging -logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') +logging.basicConfig( + level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s" +) def check(result: subprocess.Popen) -> None: """ - Checks the result of a subprocess execution. If the return code is non-zero, + Checks the result of a subprocess execution. If the return code is non-zero, it logs an error message and exits the program. Args: @@ -35,12 +37,14 @@ def run_command(command: List[str]) -> subprocess.Popen: try: logging.info(f"Running command: {' '.join(command)}") # Start the process - process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) - + process = subprocess.Popen( + command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True + ) + # Read and print output in real-time for line in process.stdout: print(line, end="") # Print each line as it is produced - + # Check the result after the process completes check(process) return process @@ -49,7 +53,7 @@ def run_command(command: List[str]) -> subprocess.Popen: logging.error(str(e)) sys.exit(1) - + def run(metadata) -> None: """ Executes a cmd of StackSpot CLI to deploy a plan. @@ -58,10 +62,10 @@ def run(metadata) -> None: metadata (object): An object containing the inputs required for the execution. """ stk = sys.argv[0] - environment = metadata.inputs['environment'] - version_tag = metadata.inputs['version_tag'] - open_api_path: Optional[str] = metadata.inputs.get('open_api_path') - dynamic_inputs: Optional[str] = metadata.inputs.get('dynamic_inputs') + environment = metadata.inputs["environment"] + version_tag = metadata.inputs["version_tag"] + open_api_path: Optional[str] = metadata.inputs.get("open_api_path") + dynamic_inputs: Optional[str] = metadata.inputs.get("dynamic_inputs") # Prepare optional parameters for the deploy command optional_params = [] @@ -71,7 +75,15 @@ def run(metadata) -> None: optional_params += dynamic_inputs.split() # Prepare the StackSpot CLI commands - stk_deploy_plan = [stk, "deploy", "plan", "--env", environment, "--version", version_tag] + optional_params + stk_deploy_plan = [ + stk, + "deploy", + "plan", + "--env", + environment, + "--version", + version_tag, + ] + optional_params # Execute the commands - run_command(stk_deploy_plan) \ No newline at end of file + run_command(stk_deploy_plan) diff --git a/runtime-deploy-action/script.py b/runtime-deploy-action/script.py index 98fe743..1288421 100644 --- a/runtime-deploy-action/script.py +++ b/runtime-deploy-action/script.py @@ -5,12 +5,18 @@ from typing import List # Configure logging -logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') +logging.basicConfig( + level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s" +) STK_IAM_DOMAIN = os.getenv("STK_IAM_DOMAIN", "https://idm.stackspot.com") -STK_RUNTIME_MANAGER_DOMAIN = os.getenv("STK_RUNTIME_MANAGER_DOMAIN", "https://runtime-manager.v1.stackspot.com") -CONTAINER_DEPLOY_URL = os.getenv("CONTAINER_DEPLOY_URL", "stackspot/runtime-job-deploy:latest") +STK_RUNTIME_MANAGER_DOMAIN = os.getenv( + "STK_RUNTIME_MANAGER_DOMAIN", "https://runtime-manager.v1.stackspot.com" +) +CONTAINER_DEPLOY_URL = os.getenv( + "CONTAINER_DEPLOY_URL", "stackspot/runtime-job-deploy:latest" +) FEATURES_BASEPATH_TMP = "/tmp/runtime/deploys" FEATURES_BASEPATH_EBS = "/opt/runtime" @@ -20,7 +26,7 @@ def check(result: subprocess.Popen) -> None: """ - Checks the result of a subprocess execution. If the return code is non-zero, + Checks the result of a subprocess execution. If the return code is non-zero, it logs an error message and exits the program. Args: @@ -46,12 +52,14 @@ def run_command(command: List[str]) -> subprocess.Popen: try: logging.info(f"Running command: {' '.join(command)}") # Start the process - process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) - + process = subprocess.Popen( + command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True + ) + # Read and print output in real-time for line in process.stdout: print(line, end="") # Print each line as it is produced - + # Check the result after the process completes check(process) return process @@ -62,33 +70,31 @@ def run_command(command: List[str]) -> subprocess.Popen: def build_flags(inputs: dict) -> list: - + docker_flags: dict = dict( FEATURES_LEVEL_LOG=inputs.get("features_level_log") or "info", FEATURES_TERRAFORM_LOGPROVIDER=inputs.get("tf_log_provider") or "info", FEATURES_RELEASE_LOCALEXEC=inputs.get("localexec_enabled") or "False", - FEATURES_TERRAFORM_MODULES=inputs.get("features_terraform_modules") or '[]', - - AWS_ACCESS_KEY_ID=inputs['aws_access_key_id'], - AWS_SECRET_ACCESS_KEY=inputs['aws_secret_access_key'], - AWS_SESSION_TOKEN=inputs['aws_session_token'], + FEATURES_TERRAFORM_MODULES=inputs.get("features_terraform_modules") or "[]", + AWS_ACCESS_KEY_ID=inputs["aws_access_key_id"], + AWS_SECRET_ACCESS_KEY=inputs["aws_secret_access_key"], + AWS_SESSION_TOKEN=inputs["aws_session_token"], AUTHENTICATE_CLIENT_ID=inputs["client_id"], AUTHENTICATE_CLIENT_SECRET=inputs["client_key"], AUTHENTICATE_CLIENT_REALMS=inputs["client_realm"], REPOSITORY_NAME=inputs["repository_name"], AWS_REGION=inputs["aws_region"], - AUTHENTICATE_URL=STK_IAM_DOMAIN, FEATURES_API_MANAGER=STK_RUNTIME_MANAGER_DOMAIN, FEATURES_BASEPATH_TMP=FEATURES_BASEPATH_TMP, FEATURES_BASEPATH_EBS=FEATURES_BASEPATH_EBS, FEATURES_TEMPLATES_FILEPATH=FEATURES_TEMPLATES_FILEPATH, - FEATURES_BASEPATH_TERRAFORM=FEATURES_BASEPATH_TERRAFORM + FEATURES_BASEPATH_TERRAFORM=FEATURES_BASEPATH_TERRAFORM, ) flags = [] for k, v in docker_flags.items(): flags += ["-e", f"{k}={v}"] - + return flags @@ -97,15 +103,19 @@ def run(metadata): run_task_id: str = inputs["run_task_id"] output_file: str = inputs.get("output_file") or "deploy-output.json" path_to_mount: str = inputs.get("path_to_mount") or "." - path_to_mount = f"{path_to_mount}:/app-volume" + path_to_mount = f"{path_to_mount}:/app-volume" flags = build_flags(inputs) - cmd = ["docker", "run", "--rm", "-v", path_to_mount] + flags + [ - "--entrypoint=/app/stackspot-runtime-job-deploy", - CONTAINER_DEPLOY_URL, - "start", - f"--run-task-id={run_task_id}", - f"--output-file={output_file}", - ] + cmd = ( + ["docker", "run", "--rm", "-v", path_to_mount] + + flags + + [ + "--entrypoint=/app/stackspot-runtime-job-deploy", + CONTAINER_DEPLOY_URL, + "start", + f"--run-task-id={run_task_id}", + f"--output-file={output_file}", + ] + ) run_command(cmd) diff --git a/runtime-iac-action/script.py b/runtime-iac-action/script.py index 5f29708..80a524c 100644 --- a/runtime-iac-action/script.py +++ b/runtime-iac-action/script.py @@ -5,17 +5,21 @@ from typing import List # Configure logging -logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') +logging.basicConfig( + level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s" +) STK_IAM_DOMAIN = os.getenv("STK_IAM_DOMAIN", "https://idm.stackspot.com") -STK_RUNTIME_MANAGER_DOMAIN = os.getenv("STK_RUNTIME_MANAGER_DOMAIN", "https://runtime-manager.v1.stackspot.com") +STK_RUNTIME_MANAGER_DOMAIN = os.getenv( + "STK_RUNTIME_MANAGER_DOMAIN", "https://runtime-manager.v1.stackspot.com" +) CONTAINER_IAC_URL = os.getenv("CONTAINER_IAC_URL", "stackspot/runtime-job-iac:latest") def check(result: subprocess.Popen) -> None: """ - Checks the result of a subprocess execution. If the return code is non-zero, + Checks the result of a subprocess execution. If the return code is non-zero, it logs an error message and exits the program. Args: @@ -41,12 +45,14 @@ def run_command(command: List[str]) -> subprocess.Popen: try: logging.info(f"Running command: {' '.join(command)}") # Start the process - process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) - + process = subprocess.Popen( + command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True + ) + # Read and print output in real-time for line in process.stdout: print(line, end="") # Print each line as it is produced - + # Check the result after the process completes check(process) return process @@ -59,23 +65,21 @@ def run_command(command: List[str]) -> subprocess.Popen: def build_flags(inputs: dict) -> list: docker_flags: dict = dict( FEATURES_LEVEL_LOG=inputs.get("features_level_log") or "info", - REPOSITORY_NAME=inputs["repository_name"], AUTHENTICATE_CLIENT_ID=inputs["client_id"], AUTHENTICATE_CLIENT_SECRET=inputs["client_key"], AUTHENTICATE_CLIENT_REALMS=inputs["client_realm"], - AWS_ACCESS_KEY_ID=inputs['aws_access_key_id'], - AWS_SECRET_ACCESS_KEY=inputs['aws_secret_access_key'], - AWS_SESSION_TOKEN=inputs['aws_session_token'], + AWS_ACCESS_KEY_ID=inputs["aws_access_key_id"], + AWS_SECRET_ACCESS_KEY=inputs["aws_secret_access_key"], + AWS_SESSION_TOKEN=inputs["aws_session_token"], AWS_REGION=inputs["aws_region"], - AUTHENTICATE_URL=STK_IAM_DOMAIN, FEATURES_API_MANAGER=STK_RUNTIME_MANAGER_DOMAIN, ) flags = [] for k, v in docker_flags.items(): flags += ["-e", f"{k}={v}"] - + return flags @@ -84,15 +88,19 @@ def run(metadata): run_task_id: str = inputs["run_task_id"] base_path_output: str = inputs.get("base_path_output") or "." path_to_mount: str = inputs.get("path_to_mount") or "." - path_to_mount = f"{path_to_mount}:/app-volume" + path_to_mount = f"{path_to_mount}:/app-volume" flags = build_flags(inputs) - cmd = ["docker", "run", "--rm", "-v", path_to_mount] + flags + [ - "--entrypoint=/app/stackspot-runtime-job-iac", - CONTAINER_IAC_URL, - "start", - f"--run-task-id={run_task_id}", - f"--base-path-output={base_path_output}", - ] + cmd = ( + ["docker", "run", "--rm", "-v", path_to_mount] + + flags + + [ + "--entrypoint=/app/stackspot-runtime-job-iac", + CONTAINER_IAC_URL, + "start", + f"--run-task-id={run_task_id}", + f"--base-path-output={base_path_output}", + ] + ) run_command(cmd) diff --git a/runtime-manager-action/script.py b/runtime-manager-action/script.py index f0f02e5..dd8df93 100644 --- a/runtime-manager-action/script.py +++ b/runtime-manager-action/script.py @@ -7,18 +7,20 @@ from oscli.core.http import post_with_authorization # Constants -STK_RUNTIME_MANAGER_DOMAIN = os.getenv("STK_RUNTIME_MANAGER_DOMAIN", "https://runtime-manager.v1.stackspot.com") +STK_RUNTIME_MANAGER_DOMAIN = os.getenv( + "STK_RUNTIME_MANAGER_DOMAIN", "https://runtime-manager.v1.stackspot.com" +) TYPE_PARSER = {"application": "app", "shared-infrastructure": "infra"} -MANIFEST_FILE = 'manifest.yaml' -OUTPUT_FILE = 'manager-output.log' -HEADERS = {'Content-Type': 'application/json'} +MANIFEST_FILE = "manifest.yaml" +OUTPUT_FILE = "manager-output.log" +HEADERS = {"Content-Type": "application/json"} TIMEOUT = 20 def yaml() -> YAML: """ Initializes and returns a YAML parser with specific configurations. - + Returns: YAML: A configured YAML parser. """ @@ -33,10 +35,10 @@ def yaml() -> YAML: def safe_load(content: str) -> dict: """ Safely loads a YAML string into a Python dictionary. - + Args: content (str): The YAML content as a string. - + Returns: dict: The parsed YAML content as a dictionary. """ @@ -47,15 +49,15 @@ def safe_load(content: str) -> dict: def get_manifest() -> dict: """ Reads and parses the 'manifest.yaml' file into a dictionary. - + Returns: dict: The parsed manifest content. - + Raises: FileNotFoundError: If the 'manifest.yaml' file is not found. """ try: - with open(Path(MANIFEST_FILE), 'r') as file: + with open(Path(MANIFEST_FILE), "r") as file: manifesto_yaml = file.read() manifest = safe_load(manifesto_yaml) return manifest @@ -70,23 +72,23 @@ def get_manifest() -> dict: def save_output(value: dict): """ Saves the provided value to the 'manager-output.log' file. - + Args: value (dict): The content to be saved in the log file. """ - with open(OUTPUT_FILE, 'w') as output_file: + with open(OUTPUT_FILE, "w") as output_file: json.dump(value, output_file, indent=4) print(f"> Output saved to {OUTPUT_FILE}") - + def build_request(action_inputs: dict, app_infra_manifest: dict) -> dict: """ Builds the request data for the self-hosted deployment by merging the action inputs and manifest data. - + Args: action_inputs (dict): The inputs provided for the action (e.g., bucket names, regions). app_infra_manifest (dict): The parsed manifest data. - + Returns: dict: The complete request data for the deployment. """ @@ -95,18 +97,20 @@ def build_request(action_inputs: dict, app_infra_manifest: dict) -> dict: "config": { "tfstate": { "bucket": action_inputs["tf_state_bucket_name"], - "region": action_inputs["tf_state_region"] + "region": action_inputs["tf_state_region"], }, "iac": { "bucket": action_inputs["iac_bucket_name"], - "region": action_inputs["iac_region"] - } + "region": action_inputs["iac_region"], + }, }, "pipelineUrl": "http://stackspot.com", } # Merge the manifest data with the configuration data request_data = {**app_infra_manifest, **config_data} - print(f"> Runtime manager run self hosted deploy request data:\n{json.dumps(request_data, indent=4)}") + print( + f"> Runtime manager run self hosted deploy request data:\n{json.dumps(request_data, indent=4)}" + ) return request_data except KeyError as e: print(f"> Error: Missing required input {e}") @@ -116,29 +120,33 @@ def build_request(action_inputs: dict, app_infra_manifest: dict) -> dict: def runtime_manager_run_self_hosted_deploy(request_data: dict, manifest: dict): """ Sends a request to the StackSpot Runtime Manager to start a self-hosted deployment. - + Args: request_data (dict): The request data for the deployment. manifest (dict): The parsed manifest data. - + Raises: SystemExit: If the deployment request fails. """ manifest_type = manifest["manifesto"]["kind"] url = f"{STK_RUNTIME_MANAGER_DOMAIN}/v1/run/self-hosted/deploy/{TYPE_PARSER[manifest_type]}" - + print("> Calling runtime manager to define tasks...") - response = post_with_authorization(url=url, body=request_data, headers=HEADERS, timeout=TIMEOUT) + response = post_with_authorization( + url=url, body=request_data, headers=HEADERS, timeout=TIMEOUT + ) if response.ok: # Parse the response and extract relevant data response_data = response.json() print(f"> Deploy successfully started:\n{json.dumps(response_data, indent=4)}") - + # Save the response to the output log save_output(response_data) else: - print(f"> Error: Failed to start self-hosted deploy run. Status: {response.status_code}") + print( + f"> Error: Failed to start self-hosted deploy run. Status: {response.status_code}" + ) print(f"> Response: {response.text}") exit(1) @@ -146,9 +154,9 @@ def runtime_manager_run_self_hosted_deploy(request_data: dict, manifest: dict): def run(metadata): # Load the manifest file manifest = get_manifest() - + # Build the request data request = build_request(metadata.inputs, manifest) - + # Execute the deployment request - runtime_manager_run_self_hosted_deploy(request, manifest) \ No newline at end of file + runtime_manager_run_self_hosted_deploy(request, manifest) diff --git a/runtime-rollback-action/script.py b/runtime-rollback-action/script.py index 1bf2ee8..d4ca85b 100644 --- a/runtime-rollback-action/script.py +++ b/runtime-rollback-action/script.py @@ -6,6 +6,7 @@ from oscli.core.http import post_with_authorization from oscli.core.http import get_with_authorization + def yaml() -> YAML: yml = YAML() yml.indent(mapping=2, sequence=4, offset=2) @@ -21,15 +22,17 @@ def safe_load(content: str) -> dict: def save_output(name: str, value: str): - with open("rollback-output.log", 'a') as output_file: - print(f'{name}={value}', file=output_file) + with open("rollback-output.log", "a") as output_file: + print(f"{name}={value}", file=output_file) def get_env_id(slug): - - env_request = get_with_authorization(url=f"https://workspace-workspace-api.stg.stackspot.com/v1/environments", - headers={'Content-Type': 'application/json' }, - timeout=20) + + env_request = get_with_authorization( + url=f"https://workspace-workspace-api.stg.stackspot.com/v1/environments", + headers={"Content-Type": "application/json"}, + timeout=20, + ) if env_request.status_code != 200: print("Unable to fetch Environments data") @@ -37,13 +40,13 @@ def get_env_id(slug): print("- Error:", env_request.reason) print("- Response:", env_request.text) exit(1) - + env_list = env_request.json() - + for env in env_list: if env["name"] == slug: return env["id"] - + print(f"Unable to find environment: {slug}") exit(1) @@ -58,13 +61,20 @@ def run(metadata): VERSION_TAG = metadata.inputs.get("version_tag") ENVIRONMENT = metadata.inputs.get("environment") - inputs_list = [ENVIRONMENT, VERSION_TAG, TF_STATE_BUCKET_NAME, TF_STATE_REGION, IAC_BUCKET_NAME, IAC_REGION] + inputs_list = [ + ENVIRONMENT, + VERSION_TAG, + TF_STATE_BUCKET_NAME, + TF_STATE_REGION, + IAC_BUCKET_NAME, + IAC_REGION, + ] if None in inputs_list: print("- Some mandatory input is empty. Please, check the input list.") exit(1) - with open(Path('.stk/stk.yaml'), 'r') as file: + with open(Path(".stk/stk.yaml"), "r") as file: stk_yaml = file.read() stk_dict = safe_load(stk_yaml) @@ -73,45 +83,46 @@ def run(metadata): print("- stk.yaml:", stk_dict) stk_yaml_type = stk_dict["spec"]["type"] - app_or_infra_id = stk_dict["spec"]["infra-id"] if stk_yaml_type == "infra" else stk_dict["spec"]["app-id"] + app_or_infra_id = ( + stk_dict["spec"]["infra-id"] + if stk_yaml_type == "infra" + else stk_dict["spec"]["app-id"] + ) print(f"{stk_yaml_type} project identified, with ID: {app_or_infra_id}") - - stk_id = { - "appId": app_or_infra_id, - } if stk_yaml_type != "infra" else { - "infraId": app_or_infra_id, - } + stk_id = ( + { + "appId": app_or_infra_id, + } + if stk_yaml_type != "infra" + else { + "infraId": app_or_infra_id, + } + ) request_data = { **stk_id, "envId": get_env_id(ENVIRONMENT), "tag": VERSION_TAG, "config": { - "tfstate": { - "bucket": TF_STATE_BUCKET_NAME, - "region": TF_STATE_REGION - }, - "iac": { - "bucket": IAC_BUCKET_NAME, - "region": IAC_REGION - } + "tfstate": {"bucket": TF_STATE_BUCKET_NAME, "region": TF_STATE_REGION}, + "iac": {"bucket": IAC_BUCKET_NAME, "region": IAC_REGION}, }, - "pipelineUrl": "http://stackspot.com" + "pipelineUrl": "http://stackspot.com", } if VERBOSE is not None: print("- ROLLBACK RUN REQUEST DATA:", request_data) - print("Deploying Self-Hosted Rollback..") - rollback_request = post_with_authorization(url=f"https://runtime-manager.v1.stackspot.com/v1/run/self-hosted/rollback/{stk_yaml_type}", - body=request_data, - headers={'Content-Type': 'application/json' }, - timeout=20) - + rollback_request = post_with_authorization( + url=f"https://runtime-manager.v1.stackspot.com/v1/run/self-hosted/rollback/{stk_yaml_type}", + body=request_data, + headers={"Content-Type": "application/json"}, + timeout=20, + ) if rollback_request.status_code == 201: d2 = rollback_request.json() @@ -119,8 +130,8 @@ def run(metadata): runType = d2["runType"] tasks = d2["tasks"] - save_output('tasks', tasks) - save_output('run_id', runId) + save_output("tasks", tasks) + save_output("run_id", runId) print(f"- Rollback RUN {runType} successfully started with ID: {runId}") print(f"- Rollback RUN TASKS LIST: {tasks}") @@ -130,4 +141,4 @@ def run(metadata): print("- Status:", rollback_request.status_code) print("- Error:", rollback_request.reason) print("- Response:", rollback_request.text) - exit(1) \ No newline at end of file + exit(1) diff --git a/script.py b/script.py index b88f983..aea8192 100644 --- a/script.py +++ b/script.py @@ -13,11 +13,19 @@ def __init__(self, metadata): self.inputs = {k: v for k, v in metadata.inputs.items() if v is not None} def __call__(self, action_name: str, **inputs): - action_path = f'{self.action_base_path}/{action_name}' - cmd = [self.stk, 'run', 'action', action_path, '--inputs-json', json.dumps({**self.inputs, **inputs}),'--non-interactive'] + action_path = f"{self.action_base_path}/{action_name}" + cmd = [ + self.stk, + "run", + "action", + action_path, + "--inputs-json", + json.dumps({**self.inputs, **inputs}), + "--non-interactive", + ] result = subprocess.run(cmd) - if (result.returncode == 1): - print(f"Fail to execute {result.args}...") + if result.returncode == 1: + print(f"Fail to execute {result.args}...") exit(1) @@ -25,14 +33,14 @@ def deploy_workflow(run_action: RunAction): run_action("runtime-create-manifest-action") run_action("runtime-manager-action") - with open('manager-output.log', 'r') as file: - data = json.loads(file.read().replace("\'", "\"")) - + with open("manager-output.log", "r") as file: + data = json.loads(file.read().replace("'", '"')) + task_runners = dict( IAC_SELF_HOSTED=lambda **i: run_action("runtime-iac-action", **i), DEPLOY_SELF_HOSTED=lambda **i: run_action("runtime-deploy-action", **i), ) - for t in data['tasks']: + for t in data["tasks"]: runner = task_runners.get(t["taskType"]) runner and runner(run_task_id=t["runTaskId"]) @@ -46,4 +54,3 @@ def run(metadata): run_action = RunAction(metadata) workflow_runner = workflows.get(metadata.inputs["workflow_type"]) workflow_runner and workflow_runner(run_action=run_action) - \ No newline at end of file From 6118d46286fad423f03a2e7b2f1f01fd5c4b4c0e Mon Sep 17 00:00:00 2001 From: pedrohrfz Date: Mon, 7 Oct 2024 22:45:21 -0300 Subject: [PATCH 05/14] lint pipeline --- .github/workflows/lint-quality-check.yml | 30 ++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 .github/workflows/lint-quality-check.yml diff --git a/.github/workflows/lint-quality-check.yml b/.github/workflows/lint-quality-check.yml new file mode 100644 index 0000000..90e9052 --- /dev/null +++ b/.github/workflows/lint-quality-check.yml @@ -0,0 +1,30 @@ +name: Quality Check +on: + workflow_call: + secrets: + git-org-token: + required: true + pull_request: +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true +jobs: + static_tests: + runs-on: ubuntu-latest + steps: + + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - uses: actions/setup-python@v4 + with: + python-version: '3.11' + + - name: Install linters + run: | + pip install black + + - name: Perform lint + run: | + black . --check From 22be4900ae9cbb893926e8e2b30662917080bd89 Mon Sep 17 00:00:00 2001 From: pedrohrfz Date: Tue, 8 Oct 2024 11:14:05 -0300 Subject: [PATCH 06/14] ... --- .github/workflows/stk-quality-check.yaml | 2 +- docs/en-us/docs.md | 1 + runtime-deploy-action/docs/en-us/docs.md | 1 + runtime-iac-action/docs/en-us/docs.md | 1 + runtime-matrix/action.yaml | 98 +++++++++++++ runtime-matrix/en-us/docs.md | 1 + runtime-matrix/script.py | 175 +++++++++++++++++++++++ 7 files changed, 278 insertions(+), 1 deletion(-) create mode 100644 runtime-matrix/action.yaml create mode 100644 runtime-matrix/en-us/docs.md create mode 100644 runtime-matrix/script.py diff --git a/.github/workflows/stk-quality-check.yaml b/.github/workflows/stk-quality-check.yaml index 28b3dcc..d1ab608 100644 --- a/.github/workflows/stk-quality-check.yaml +++ b/.github/workflows/stk-quality-check.yaml @@ -39,7 +39,7 @@ jobs: - name: Login StackSpot run: | - $HOME/.stk/bin/stk login -id ${{ secrets.IDP_STK_CLIENT_ID }} -key ${{ secrets.IDP_STK_CLIENT_SECRET }} -r stackspot + $HOME/.stk/bin/stk login -id ${{ secrets.STK_CLIENT_ID }} -key ${{ secrets.STK_CLIENT_SECRET }} -r ${{ secrets.STK_REALM }} - name: Validate main action run: | diff --git a/docs/en-us/docs.md b/docs/en-us/docs.md index e69de29..4287ca8 100644 --- a/docs/en-us/docs.md +++ b/docs/en-us/docs.md @@ -0,0 +1 @@ +# \ No newline at end of file diff --git a/runtime-deploy-action/docs/en-us/docs.md b/runtime-deploy-action/docs/en-us/docs.md index e69de29..792d600 100644 --- a/runtime-deploy-action/docs/en-us/docs.md +++ b/runtime-deploy-action/docs/en-us/docs.md @@ -0,0 +1 @@ +# diff --git a/runtime-iac-action/docs/en-us/docs.md b/runtime-iac-action/docs/en-us/docs.md index e69de29..792d600 100644 --- a/runtime-iac-action/docs/en-us/docs.md +++ b/runtime-iac-action/docs/en-us/docs.md @@ -0,0 +1 @@ +# diff --git a/runtime-matrix/action.yaml b/runtime-matrix/action.yaml new file mode 100644 index 0000000..5842355 --- /dev/null +++ b/runtime-matrix/action.yaml @@ -0,0 +1,98 @@ +schema-version: v3 +kind: action +metadata: + name: runtime-iac-action + display-name: runtime-iac-action + description: runtime-iac-action + version: 1.0.0 +spec: + type: python + docs: + en-us: docs/en-us/docs.md + repository: https://github.com/stack-spot/workflow-stackspot-actions-runtime-selfhosted.git + inputs: + + - label: "CLIENT ID" + name: client_id + type: text + required: true + + - label: "CLIENT KEY" + name: client_key + type: text + required: true + + - label: "CLIENT REALM" + name: client_realm + type: text + required: true + + - label: "Git Repository Name" + name: repository_name + type: text + required: true + + - label: "AWS ACCESS KEY ID from console" + name: aws_access_key_id + type: text + required: true + + - label: "AWS SECRET ACCESS KEY from console" + name: aws_secret_access_key + type: text + required: true + + - label: "AWS SESSION TOKEN from console" + name: aws_session_token + type: text + required: true + + - label: "AWS REGION" + name: aws_region + type: text + required: true + + - label: "Runtime Run Task Id" + name: run_task_id + type: text + required: true + + - label: "Path to mount inside the docker" + name: path_to_mount + type: text + required: false + + - label: "Base Path Output" + name: base_path_output + type: text + required: false + + - label: "Features Log Level" + name: features_level_log + type: text + required: false + + - label: "Features Terraform Modules" + name: features_terraform_modules + type: text + required: false + + - label: "File name to save outputs" + name: output_file + type: text + required: false + + - label: "If Runtimes will allow execution of the local-exec command within terraform" + name: localexec_enabled + type: bool + required: false + + - label: "Level tf log provider - info, debug, warn or trace" + name: tf_log_provider + type: text + required: false + + python: + workdir: . + script: script.py + \ No newline at end of file diff --git a/runtime-matrix/en-us/docs.md b/runtime-matrix/en-us/docs.md new file mode 100644 index 0000000..792d600 --- /dev/null +++ b/runtime-matrix/en-us/docs.md @@ -0,0 +1 @@ +# diff --git a/runtime-matrix/script.py b/runtime-matrix/script.py new file mode 100644 index 0000000..e88d41c --- /dev/null +++ b/runtime-matrix/script.py @@ -0,0 +1,175 @@ +import os +import sys +import subprocess +import logging +import json +from typing import List + +# Configure logging +logging.basicConfig( + level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s" +) + + +STK_IAM_DOMAIN = os.getenv("STK_IAM_DOMAIN", "https://idm.stackspot.com") +STK_RUNTIME_MANAGER_DOMAIN = os.getenv( + "STK_RUNTIME_MANAGER_DOMAIN", "https://runtime-manager.v1.stackspot.com" +) +CONTAINER_IAC_URL = os.getenv("CONTAINER_IAC_URL", "stackspot/runtime-job-iac:latest") +CONTAINER_DEPLOY_URL = os.getenv( + "CONTAINER_DEPLOY_URL", "stackspot/runtime-job-deploy:latest" +) + +FEATURES_BASEPATH_TMP = "/tmp/runtime/deploys" +FEATURES_BASEPATH_EBS = "/opt/runtime" +FEATURES_TEMPLATES_FILEPATH = "/app/" +FEATURES_BASEPATH_TERRAFORM = "/root/.asdf/shims/terraform" + + +def check(result: subprocess.Popen) -> None: + """ + Checks the result of a subprocess execution. If the return code is non-zero, + it logs an error message and exits the program. + + Args: + result (subprocess.Popen): The result of the subprocess execution. + """ + result.wait() # Wait for the process to complete + if result.returncode != 0: + logging.error(f"Failed to execute: {result.args}") + logging.error(f"Error output: {result.stderr.read()}") + sys.exit(1) + + +def run_command(command: List[str]) -> subprocess.Popen: + """ + Runs a command using subprocess.Popen and returns the result. + + Args: + command (List[str]): The command to be executed as a list of strings. + + Returns: + subprocess.Popen: The result of the command execution. + """ + try: + logging.info(f"Running command: {' '.join(command)}") + # Start the process + process = subprocess.Popen( + command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True + ) + + # Read and print output in real-time + for line in process.stdout: + print(line, end="") # Print each line as it is produced + + # Check the result after the process completes + check(process) + return process + except Exception as e: + logging.error(f"Exception occurred while running command: {command}") + logging.error(str(e)) + sys.exit(1) + + +def build_iac_flags(inputs: dict) -> list: + docker_flags: dict = dict( + FEATURES_LEVEL_LOG=inputs.get("features_level_log") or "info", + REPOSITORY_NAME=inputs["repository_name"], + AUTHENTICATE_CLIENT_ID=inputs["client_id"], + AUTHENTICATE_CLIENT_SECRET=inputs["client_key"], + AUTHENTICATE_CLIENT_REALMS=inputs["client_realm"], + AWS_ACCESS_KEY_ID=inputs["aws_access_key_id"], + AWS_SECRET_ACCESS_KEY=inputs["aws_secret_access_key"], + AWS_SESSION_TOKEN=inputs["aws_session_token"], + AWS_REGION=inputs["aws_region"], + AUTHENTICATE_URL=STK_IAM_DOMAIN, + FEATURES_API_MANAGER=STK_RUNTIME_MANAGER_DOMAIN, + ) + flags = [] + for k, v in docker_flags.items(): + flags += ["-e", f"{k}={v}"] + + return flags + + +def run_iac(inputs: dict): + run_task_id: str = inputs["run_task_id"] + base_path_output: str = inputs.get("base_path_output") or "." + path_to_mount: str = inputs.get("path_to_mount") or "." + path_to_mount = f"{path_to_mount}:/app-volume" + + flags = build_iac_flags(inputs) + cmd = ( + ["docker", "run", "--rm", "-v", path_to_mount] + + flags + + [ + "--entrypoint=/app/stackspot-runtime-job-iac", + CONTAINER_IAC_URL, + "start", + f"--run-task-id={run_task_id}", + f"--base-path-output={base_path_output}", + ] + ) + + run_command(cmd) + + +def build_deploy_flags(inputs: dict) -> list: + + docker_flags: dict = dict( + FEATURES_LEVEL_LOG=inputs.get("features_level_log") or "info", + FEATURES_TERRAFORM_LOGPROVIDER=inputs.get("tf_log_provider") or "info", + FEATURES_RELEASE_LOCALEXEC=inputs.get("localexec_enabled") or "False", + FEATURES_TERRAFORM_MODULES=inputs.get("features_terraform_modules") or "[]", + AWS_ACCESS_KEY_ID=inputs["aws_access_key_id"], + AWS_SECRET_ACCESS_KEY=inputs["aws_secret_access_key"], + AWS_SESSION_TOKEN=inputs["aws_session_token"], + AUTHENTICATE_CLIENT_ID=inputs["client_id"], + AUTHENTICATE_CLIENT_SECRET=inputs["client_key"], + AUTHENTICATE_CLIENT_REALMS=inputs["client_realm"], + REPOSITORY_NAME=inputs["repository_name"], + AWS_REGION=inputs["aws_region"], + AUTHENTICATE_URL=STK_IAM_DOMAIN, + FEATURES_API_MANAGER=STK_RUNTIME_MANAGER_DOMAIN, + FEATURES_BASEPATH_TMP=FEATURES_BASEPATH_TMP, + FEATURES_BASEPATH_EBS=FEATURES_BASEPATH_EBS, + FEATURES_TEMPLATES_FILEPATH=FEATURES_TEMPLATES_FILEPATH, + FEATURES_BASEPATH_TERRAFORM=FEATURES_BASEPATH_TERRAFORM, + ) + flags = [] + for k, v in docker_flags.items(): + flags += ["-e", f"{k}={v}"] + + return flags + + +def run_deploy(inputs: dict): + run_task_id: str = inputs["run_task_id"] + output_file: str = inputs.get("output_file") or "deploy-output.json" + path_to_mount: str = inputs.get("path_to_mount") or "." + path_to_mount = f"{path_to_mount}:/app-volume" + + flags = build_deploy_flags(inputs) + cmd = ( + ["docker", "run", "--rm", "-v", path_to_mount] + + flags + + [ + "--entrypoint=/app/stackspot-runtime-job-deploy", + CONTAINER_DEPLOY_URL, + "start", + f"--run-task-id={run_task_id}", + f"--output-file={output_file}", + ] + ) + + run_command(cmd) + + +def run(metadata): + with open("manager-output.log", "r") as file: + data = json.loads(file.read().replace("'", '"')) + + task_runners = dict(IAC_SELF_HOSTED=run_iac, DEPLOY_SELF_HOSTED=run_deploy) + for t in data["tasks"]: + runner = task_runners.get(t["taskType"]) + runner and runner(run_task_id=t["runTaskId"], **metadata.inputs) \ No newline at end of file From 197dec7273b95b362204e6cbd06734d2f3a3e8ac Mon Sep 17 00:00:00 2001 From: pedrohrfz Date: Tue, 8 Oct 2024 11:18:50 -0300 Subject: [PATCH 07/14] lint --- runtime-matrix/script.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime-matrix/script.py b/runtime-matrix/script.py index e88d41c..eeca6e4 100644 --- a/runtime-matrix/script.py +++ b/runtime-matrix/script.py @@ -172,4 +172,4 @@ def run(metadata): task_runners = dict(IAC_SELF_HOSTED=run_iac, DEPLOY_SELF_HOSTED=run_deploy) for t in data["tasks"]: runner = task_runners.get(t["taskType"]) - runner and runner(run_task_id=t["runTaskId"], **metadata.inputs) \ No newline at end of file + runner and runner(run_task_id=t["runTaskId"], **metadata.inputs) From c730a698318ed6abf7c2c88cdbe428f302204a0b Mon Sep 17 00:00:00 2001 From: pedrohrfz Date: Tue, 8 Oct 2024 11:28:59 -0300 Subject: [PATCH 08/14] add validates --- .github/workflows/stk-quality-check.yaml | 44 +++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/.github/workflows/stk-quality-check.yaml b/.github/workflows/stk-quality-check.yaml index d1ab608..16b31e3 100644 --- a/.github/workflows/stk-quality-check.yaml +++ b/.github/workflows/stk-quality-check.yaml @@ -43,4 +43,46 @@ jobs: - name: Validate main action run: | - $HOME/.stk/bin/stk validate action \ No newline at end of file + $HOME/.stk/bin/stk validate action + + - name: Validate runtime-cancel-run-action action + run: | + cd runtime-cancel-run-action + $HOME/.stk/bin/stk validate action + + - name: Validate runtime-create-manifest-action action + run: | + cd runtime-create-manifest-action + $HOME/.stk/bin/stk validate action + + - name: Validate runtime-deploy-action action + run: | + cd runtime-deploy-action + $HOME/.stk/bin/stk validate action + + - name: Validate runtime-destroy-action action + run: | + cd runtime-destroy-action + $HOME/.stk/bin/stk validate action + + - name: Validate runtime-iac-action action + run: | + cd runtime-iac-action + $HOME/.stk/bin/stk validate action + + - name: Validate runtime-manager-action action + run: | + cd runtime-manager-action + $HOME/.stk/bin/stk validate action + + - name: Validate runtime-rollback-action action + run: | + cd runtime-rollback-action + $HOME/.stk/bin/stk validate action + + - name: Validate runtime-matrix action + run: | + cd runtime-matrix + $HOME/.stk/bin/stk validate action + + \ No newline at end of file From 3c1bf4380c414dcdadaa0a047489b842aa656830 Mon Sep 17 00:00:00 2001 From: pedrohrfz Date: Tue, 8 Oct 2024 11:32:07 -0300 Subject: [PATCH 09/14] fix matrix action --- .github/workflows/stk-quality-check.yaml | 2 +- runtime-matrix/en-us/docs.md | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) delete mode 100644 runtime-matrix/en-us/docs.md diff --git a/.github/workflows/stk-quality-check.yaml b/.github/workflows/stk-quality-check.yaml index 16b31e3..6b9190f 100644 --- a/.github/workflows/stk-quality-check.yaml +++ b/.github/workflows/stk-quality-check.yaml @@ -4,7 +4,7 @@ on: pull_request: jobs: - stackspot-runtime-v2: + validate-actions: name: StackSpot Runtime (v2) runs-on: ubuntu-latest env: diff --git a/runtime-matrix/en-us/docs.md b/runtime-matrix/en-us/docs.md deleted file mode 100644 index 792d600..0000000 --- a/runtime-matrix/en-us/docs.md +++ /dev/null @@ -1 +0,0 @@ -# From e2846e8e7fbd77531ef89d908860e8634714f654 Mon Sep 17 00:00:00 2001 From: pedrohrfz Date: Tue, 8 Oct 2024 11:32:13 -0300 Subject: [PATCH 10/14] fix matrix action --- runtime-matrix/docs/en-us/docs.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 runtime-matrix/docs/en-us/docs.md diff --git a/runtime-matrix/docs/en-us/docs.md b/runtime-matrix/docs/en-us/docs.md new file mode 100644 index 0000000..792d600 --- /dev/null +++ b/runtime-matrix/docs/en-us/docs.md @@ -0,0 +1 @@ +# From d78dbfd3ed1e3406b82c86811fc4169e9ca3f43e Mon Sep 17 00:00:00 2001 From: pedrohrfz Date: Wed, 9 Oct 2024 11:28:19 -0300 Subject: [PATCH 11/14] lint --- runtime-destroy-action/script.py | 60 ++++++++++++--------- runtime-rollback-action/script.py | 89 +++++++++++++++++++------------ script.py | 21 +++++--- 3 files changed, 104 insertions(+), 66 deletions(-) diff --git a/runtime-destroy-action/script.py b/runtime-destroy-action/script.py index 6f9d631..e82696c 100644 --- a/runtime-destroy-action/script.py +++ b/runtime-destroy-action/script.py @@ -5,12 +5,18 @@ from typing import List # Configure logging -logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') +logging.basicConfig( + level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s" +) STK_IAM_DOMAIN = os.getenv("STK_IAM_DOMAIN", "https://idm.stackspot.com") -STK_RUNTIME_MANAGER_DOMAIN = os.getenv("STK_RUNTIME_MANAGER_DOMAIN", "https://runtime-manager.v1.stackspot.com") -CONTAINER_DESTROY_URL = os.getenv("CONTAINER_DESTROY_URL", "stackspot/runtime-job-destroy:latest") +STK_RUNTIME_MANAGER_DOMAIN = os.getenv( + "STK_RUNTIME_MANAGER_DOMAIN", "https://runtime-manager.v1.stackspot.com" +) +CONTAINER_DESTROY_URL = os.getenv( + "CONTAINER_DESTROY_URL", "stackspot/runtime-job-destroy:latest" +) FEATURES_BASEPATH_TMP = "/tmp/runtime/deploys" FEATURES_BASEPATH_EBS = "/opt/runtime" @@ -20,7 +26,7 @@ def check(result: subprocess.Popen) -> None: """ - Checks the result of a subprocess execution. If the return code is non-zero, + Checks the result of a subprocess execution. If the return code is non-zero, it logs an error message and exits the program. Args: @@ -46,12 +52,14 @@ def run_command(command: List[str]) -> subprocess.Popen: try: logging.info(f"Running command: {' '.join(command)}") # Start the process - process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) - + process = subprocess.Popen( + command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True + ) + # Read and print output in real-time for line in process.stdout: print(line, end="") # Print each line as it is produced - + # Check the result after the process completes check(process) return process @@ -62,33 +70,31 @@ def run_command(command: List[str]) -> subprocess.Popen: def build_flags(inputs: dict) -> list: - + docker_flags: dict = dict( FEATURES_LEVEL_LOG=inputs.get("features_level_log") or "info", FEATURES_TERRAFORM_LOGPROVIDER=inputs.get("tf_log_provider") or "info", FEATURES_RELEASE_LOCALEXEC=inputs.get("localexec_enabled") or "False", - FEATURES_TERRAFORM_MODULES=inputs.get("features_terraform_modules") or '[]', - - AWS_ACCESS_KEY_ID=inputs['aws_access_key_id'], - AWS_SECRET_ACCESS_KEY=inputs['aws_secret_access_key'], - AWS_SESSION_TOKEN=inputs['aws_session_token'], + FEATURES_TERRAFORM_MODULES=inputs.get("features_terraform_modules") or "[]", + AWS_ACCESS_KEY_ID=inputs["aws_access_key_id"], + AWS_SECRET_ACCESS_KEY=inputs["aws_secret_access_key"], + AWS_SESSION_TOKEN=inputs["aws_session_token"], AUTHENTICATE_CLIENT_ID=inputs["client_id"], AUTHENTICATE_CLIENT_SECRET=inputs["client_key"], AUTHENTICATE_CLIENT_REALMS=inputs["client_realm"], REPOSITORY_NAME=inputs["repository_name"], AWS_REGION=inputs["aws_region"], - AUTHENTICATE_URL=STK_IAM_DOMAIN, FEATURES_API_MANAGER=STK_RUNTIME_MANAGER_DOMAIN, FEATURES_BASEPATH_TMP=FEATURES_BASEPATH_TMP, FEATURES_BASEPATH_EBS=FEATURES_BASEPATH_EBS, FEATURES_TEMPLATES_FILEPATH=FEATURES_TEMPLATES_FILEPATH, - FEATURES_BASEPATH_TERRAFORM=FEATURES_BASEPATH_TERRAFORM + FEATURES_BASEPATH_TERRAFORM=FEATURES_BASEPATH_TERRAFORM, ) flags = [] for k, v in docker_flags.items(): flags += ["-e", f"{k}={v}"] - + return flags @@ -96,14 +102,18 @@ def run(metadata): inputs: dict = metadata.inputs run_task_id: str = inputs["run_task_id"] path_to_mount: str = inputs.get("path_to_mount") or "." - path_to_mount = f"{path_to_mount}:/app-volume" + path_to_mount = f"{path_to_mount}:/app-volume" flags = build_flags(inputs) - cmd = ["docker", "run", "--rm", "-v", path_to_mount] + flags + [ - "--entrypoint=/app/stackspot-runtime-job-destroy", - CONTAINER_DESTROY_URL, - "start", - f"--run-task-id={run_task_id}", - ] - - run_command(cmd) \ No newline at end of file + cmd = ( + ["docker", "run", "--rm", "-v", path_to_mount] + + flags + + [ + "--entrypoint=/app/stackspot-runtime-job-destroy", + CONTAINER_DESTROY_URL, + "start", + f"--run-task-id={run_task_id}", + ] + ) + + run_command(cmd) diff --git a/runtime-rollback-action/script.py b/runtime-rollback-action/script.py index 19a6534..b92ef0e 100644 --- a/runtime-rollback-action/script.py +++ b/runtime-rollback-action/script.py @@ -9,11 +9,15 @@ from sys import exit # Constants -STK_RUNTIME_MANAGER_DOMAIN = os.getenv("STK_RUNTIME_MANAGER_DOMAIN", "https://runtime-manager.v1.stackspot.com") -STK_WORKSPACE_DOMAIN = os.getenv("STK_WORKSPACE_DOMAIN", "https://runtime-manager.v1.stackspot.com") -STK_FILE = '.stk/stk.yaml' -OUTPUT_FILE = 'rollback-output.log' -HEADERS = {'Content-Type': 'application/json'} +STK_RUNTIME_MANAGER_DOMAIN = os.getenv( + "STK_RUNTIME_MANAGER_DOMAIN", "https://runtime-manager.v1.stackspot.com" +) +STK_WORKSPACE_DOMAIN = os.getenv( + "STK_WORKSPACE_DOMAIN", "https://runtime-manager.v1.stackspot.com" +) +STK_FILE = ".stk/stk.yaml" +OUTPUT_FILE = "rollback-output.log" +HEADERS = {"Content-Type": "application/json"} TIMEOUT = 20 @@ -25,6 +29,7 @@ def yaml() -> YAML: yml.preserve_quotes = True return yml + def safe_load(content: str) -> dict: yml = yaml() return yml.load(StringIO(content)) @@ -32,7 +37,7 @@ def safe_load(content: str) -> dict: def get_stk_yaml() -> dict: try: - with open(Path(STK_FILE), 'r') as file: + with open(Path(STK_FILE), "r") as file: stk_yaml = file.read() stk_yaml = safe_load(stk_yaml) return stk_yaml @@ -46,82 +51,96 @@ def get_stk_yaml() -> dict: def save_output(value: dict): - with open(OUTPUT_FILE, 'w') as output_file: + with open(OUTPUT_FILE, "w") as output_file: json.dump(value, output_file, indent=4) print(f"> Output saved to {OUTPUT_FILE}") - + def build_request(action_inputs: dict, env_id: str, stk_yaml: dict) -> dict: try: # Extract the type of deployment (app or infra) from the stack YAML configuration type = get_type(stk_yaml) - + # Define a parser to map the type to the appropriate key and value for the request payload type_parser = { "app": {"key": "appId", "value": stk_yaml["spec"].get("app-id")}, - "infra": {"key": "infraId", "value": stk_yaml["spec"].get("infra-id")} - } - + "infra": {"key": "infraId", "value": stk_yaml["spec"].get("infra-id")}, + } + # Build the request payload using the provided inputs and the parsed type information request_data = { - f"{type_parser[type]['key']}": type_parser[type]['value'], + f"{type_parser[type]['key']}": type_parser[type]["value"], "envId": env_id, "tag": action_inputs["version_tag"], "config": { "tfstate": { "bucket": action_inputs["tf_state_bucket_name"], - "region": action_inputs["tf_state_region"] + "region": action_inputs["tf_state_region"], }, "iac": { "bucket": action_inputs["iac_bucket_name"], - "region": action_inputs["iac_region"] - } + "region": action_inputs["iac_region"], + }, }, "pipelineUrl": "http://stackspot.com", } - - print(f"> Runtime manager run self hosted rollback request data:\n{json.dumps(request_data, indent=4)}") + + print( + f"> Runtime manager run self hosted rollback request data:\n{json.dumps(request_data, indent=4)}" + ) return request_data except KeyError as e: print(f"> Error: Missing required input {e}") exit(1) + def get_type(stk_yaml: dict) -> str: return stk_yaml["spec"]["type"] -def runtime_manager_run_self_hosted_rollback(request_data: dict, stk_yaml: dict, version_tag: str): + +def runtime_manager_run_self_hosted_rollback( + request_data: dict, stk_yaml: dict, version_tag: str +): type = get_type(stk_yaml) url = f"{STK_RUNTIME_MANAGER_DOMAIN}/v1/run/self-hosted/rollback/{type}" - + print("> Calling runtime manager to rollback tasks...") - response = post_with_authorization(url=url, body=request_data, headers=HEADERS, timeout=TIMEOUT) + response = post_with_authorization( + url=url, body=request_data, headers=HEADERS, timeout=TIMEOUT + ) if response.ok: - if(response.status_code == 201): + if response.status_code == 201: response_data = response.json() - print(f"> Rollback successfully started:\n{json.dumps(response_data, indent=4)}") + print( + f"> Rollback successfully started:\n{json.dumps(response_data, indent=4)}" + ) else: - print(f"> Rollback successfully but no modifications detected for tag {version_tag}") + print( + f"> Rollback successfully but no modifications detected for tag {version_tag}" + ) response_data = {} save_output(response_data) - + else: - print(f"> Error: Failed to start self-hosted rollback run. Status: {response.status_code}") + print( + f"> Error: Failed to start self-hosted rollback run. Status: {response.status_code}" + ) print(f"> Response: {response.text}") exit(1) def get_environment_id(environment_slug): - + url = f"{STK_WORKSPACE_DOMAIN}/v1/environments" print("> Calling workspace to load environments...") - response = get_with_authorization(url=url,headers=HEADERS,timeout=TIMEOUT) - - if response.ok: + response = get_with_authorization(url=url, headers=HEADERS, timeout=TIMEOUT) + + if response.ok: env_list = response.json() for env in env_list: if env["name"] == environment_slug: @@ -131,7 +150,7 @@ def get_environment_id(environment_slug): print(f"> Error: Failed to load environments. Status: {response.status_code}") print(f"> Response: {response.text}") exit(1) - + def run(metadata): # Load the manifest file @@ -139,9 +158,11 @@ def run(metadata): # Load environment Id env_id = get_environment_id(metadata.inputs.get("environment")) - + # Build the request data request = build_request(metadata.inputs, env_id, stk_yaml) - + # Execute the rollback request - runtime_manager_run_self_hosted_rollback(request, stk_yaml, metadata.inputs['version_tag']) \ No newline at end of file + runtime_manager_run_self_hosted_rollback( + request, stk_yaml, metadata.inputs["version_tag"] + ) diff --git a/script.py b/script.py index 8398c6b..fa70af6 100644 --- a/script.py +++ b/script.py @@ -35,30 +35,37 @@ def deploy_workflow(run_action: RunAction): run_tasks("manager-output.log", run_action) + def cancel_deploy_run(run_action: RunAction): run_action("runtime-cancel-run-action") + def rollback_deploy_run(run_action: RunAction): run_action("runtime-rollback-action") run_tasks("rollback-output.log", run_action) - + def run_tasks(file_tasks: str, run_action: RunAction): - with open(file_tasks, 'r') as file: - data = json.loads(file.read().replace("\'", "\"")) - + with open(file_tasks, "r") as file: + data = json.loads(file.read().replace("'", '"')) + task_runners = dict( IAC_SELF_HOSTED=lambda **i: run_action("runtime-iac-action", **i), DEPLOY_SELF_HOSTED=lambda **i: run_action("runtime-deploy-action", **i), DESTROY_SELF_HOSTED=lambda **i: run_action("runtime-destroy-action", **i), ) - - for t in data.get('tasks') or []: + + for t in data.get("tasks") or []: runner = task_runners.get(t["taskType"]) runner and runner(run_task_id=t["runTaskId"]) + def run(metadata): - workflows = dict(deploy=deploy_workflow, cancel_deploy=cancel_deploy_run, rollback_deploy=rollback_deploy_run) + workflows = dict( + deploy=deploy_workflow, + cancel_deploy=cancel_deploy_run, + rollback_deploy=rollback_deploy_run, + ) run_action = RunAction(metadata) workflow_runner = workflows.get(metadata.inputs["workflow_type"]) workflow_runner and workflow_runner(run_action=run_action) From 8aa952dd6ea2ffd2df71bb077af12f74a59e59aa Mon Sep 17 00:00:00 2001 From: pedrohrfz Date: Wed, 9 Oct 2024 11:40:20 -0300 Subject: [PATCH 12/14] remove pt br doc from rollback --- runtime-rollback-action/action.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/runtime-rollback-action/action.yaml b/runtime-rollback-action/action.yaml index 98aa4b9..eb8bc83 100644 --- a/runtime-rollback-action/action.yaml +++ b/runtime-rollback-action/action.yaml @@ -8,7 +8,6 @@ metadata: spec: type: python docs: - pt-br: docs/pt-br/docs.md en-us: docs/en-us/docs.md repository: https://github.com/stack-spot/workflow-stackspot-actions-runtime-selfhosted.git inputs: From 104fffc46a8c86d7a3fd45326666373028bb56ad Mon Sep 17 00:00:00 2001 From: pedrohrfz Date: Wed, 9 Oct 2024 16:10:53 -0300 Subject: [PATCH 13/14] general fixes --- .github/workflows/lint-quality-check.yml | 4 - examples/gitlab/stackspot-deploy.yml | 24 ++-- runtime-matrix/action.yaml | 98 ------------- runtime-matrix/docs/en-us/docs.md | 1 - runtime-matrix/script.py | 175 ----------------------- script.py | 2 +- 6 files changed, 15 insertions(+), 289 deletions(-) delete mode 100644 runtime-matrix/action.yaml delete mode 100644 runtime-matrix/docs/en-us/docs.md delete mode 100644 runtime-matrix/script.py diff --git a/.github/workflows/lint-quality-check.yml b/.github/workflows/lint-quality-check.yml index 90e9052..94e4842 100644 --- a/.github/workflows/lint-quality-check.yml +++ b/.github/workflows/lint-quality-check.yml @@ -1,9 +1,5 @@ name: Quality Check on: - workflow_call: - secrets: - git-org-token: - required: true pull_request: concurrency: group: ${{ github.workflow }}-${{ github.ref }} diff --git a/examples/gitlab/stackspot-deploy.yml b/examples/gitlab/stackspot-deploy.yml index 3dc52c1..1c1d5ef 100644 --- a/examples/gitlab/stackspot-deploy.yml +++ b/examples/gitlab/stackspot-deploy.yml @@ -1,9 +1,8 @@ -image: ubuntu:latest +image: # Define global variables variables: - ENVIRONMENT: "staging" - WORKFLOW_REPO_URL: "https://$GITHUB_PAT@github.com/stack-spot/workflow-stackspot-actions-runtime-selfhosted.git" + WORKFLOW_REPO_URL: "https://@github.com/stack-spot/workflow-stackspot-actions-runtime-selfhosted.git" stages: - run_stackspot @@ -27,6 +26,15 @@ before_script: stk: stage: run_stackspot script: + # You can use this clone directly on the workflow as implemented here, or, + # you checkout this repository locally and publish in your stackspot studio and share it to your app workspace + # in this way you will need to use the action qualifier name (/@/) when running the action in the end of this script + # Clone the workflow repository + - git clone $WORKFLOW_REPO_URL + - cd workflow-stackspot-actions-runtime-selfhosted + - run_action_path=$(pwd) + - cd .. + # Export environment variables for StackSpot - export INPUTS_CLIENT_ID=$STK_CLIENT_ID - export INPUTS_CLIENT_KEY=$STK_CLIENT_SECRET @@ -40,6 +48,8 @@ stk: - export INPUTS_AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY - export INPUTS_AWS_SESSION_TOKEN=$AWS_SESSION_TOKEN - export INPUTS_ENVIRONMENT=$ENVIRONMENT + - export INPUTS_REPOSITORY_NAME=$CI_PROJECT_NAME + - export INPUTS_VERSION_TAG=$CI_JOB_ID # Change this logic as you wish # Authenticate with StackSpot - $STK login --client-id $INPUTS_CLIENT_ID --client-key $INPUTS_CLIENT_KEY --realm $INPUTS_CLIENT_REALM @@ -47,11 +57,5 @@ stk: # Use the specified workspace - $STK use workspace $STK_WORKSPACE - # Clone the workflow repository - - git clone $WORKFLOW_REPO_URL - - cd workflow-stackspot-actions-runtime-selfhosted - - run_action_path=$(pwd) - - cd .. - # Run the StackSpot action - - $STK run action $run_action_path --workflow_type deploy --version_tag $CI_JOB_ID --repository_name $CI_PROJECT_NAME --non-interactive + - $STK run action $run_action_path --workflow_type deploy --non-interactive diff --git a/runtime-matrix/action.yaml b/runtime-matrix/action.yaml deleted file mode 100644 index 5842355..0000000 --- a/runtime-matrix/action.yaml +++ /dev/null @@ -1,98 +0,0 @@ -schema-version: v3 -kind: action -metadata: - name: runtime-iac-action - display-name: runtime-iac-action - description: runtime-iac-action - version: 1.0.0 -spec: - type: python - docs: - en-us: docs/en-us/docs.md - repository: https://github.com/stack-spot/workflow-stackspot-actions-runtime-selfhosted.git - inputs: - - - label: "CLIENT ID" - name: client_id - type: text - required: true - - - label: "CLIENT KEY" - name: client_key - type: text - required: true - - - label: "CLIENT REALM" - name: client_realm - type: text - required: true - - - label: "Git Repository Name" - name: repository_name - type: text - required: true - - - label: "AWS ACCESS KEY ID from console" - name: aws_access_key_id - type: text - required: true - - - label: "AWS SECRET ACCESS KEY from console" - name: aws_secret_access_key - type: text - required: true - - - label: "AWS SESSION TOKEN from console" - name: aws_session_token - type: text - required: true - - - label: "AWS REGION" - name: aws_region - type: text - required: true - - - label: "Runtime Run Task Id" - name: run_task_id - type: text - required: true - - - label: "Path to mount inside the docker" - name: path_to_mount - type: text - required: false - - - label: "Base Path Output" - name: base_path_output - type: text - required: false - - - label: "Features Log Level" - name: features_level_log - type: text - required: false - - - label: "Features Terraform Modules" - name: features_terraform_modules - type: text - required: false - - - label: "File name to save outputs" - name: output_file - type: text - required: false - - - label: "If Runtimes will allow execution of the local-exec command within terraform" - name: localexec_enabled - type: bool - required: false - - - label: "Level tf log provider - info, debug, warn or trace" - name: tf_log_provider - type: text - required: false - - python: - workdir: . - script: script.py - \ No newline at end of file diff --git a/runtime-matrix/docs/en-us/docs.md b/runtime-matrix/docs/en-us/docs.md deleted file mode 100644 index 792d600..0000000 --- a/runtime-matrix/docs/en-us/docs.md +++ /dev/null @@ -1 +0,0 @@ -# diff --git a/runtime-matrix/script.py b/runtime-matrix/script.py deleted file mode 100644 index eeca6e4..0000000 --- a/runtime-matrix/script.py +++ /dev/null @@ -1,175 +0,0 @@ -import os -import sys -import subprocess -import logging -import json -from typing import List - -# Configure logging -logging.basicConfig( - level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s" -) - - -STK_IAM_DOMAIN = os.getenv("STK_IAM_DOMAIN", "https://idm.stackspot.com") -STK_RUNTIME_MANAGER_DOMAIN = os.getenv( - "STK_RUNTIME_MANAGER_DOMAIN", "https://runtime-manager.v1.stackspot.com" -) -CONTAINER_IAC_URL = os.getenv("CONTAINER_IAC_URL", "stackspot/runtime-job-iac:latest") -CONTAINER_DEPLOY_URL = os.getenv( - "CONTAINER_DEPLOY_URL", "stackspot/runtime-job-deploy:latest" -) - -FEATURES_BASEPATH_TMP = "/tmp/runtime/deploys" -FEATURES_BASEPATH_EBS = "/opt/runtime" -FEATURES_TEMPLATES_FILEPATH = "/app/" -FEATURES_BASEPATH_TERRAFORM = "/root/.asdf/shims/terraform" - - -def check(result: subprocess.Popen) -> None: - """ - Checks the result of a subprocess execution. If the return code is non-zero, - it logs an error message and exits the program. - - Args: - result (subprocess.Popen): The result of the subprocess execution. - """ - result.wait() # Wait for the process to complete - if result.returncode != 0: - logging.error(f"Failed to execute: {result.args}") - logging.error(f"Error output: {result.stderr.read()}") - sys.exit(1) - - -def run_command(command: List[str]) -> subprocess.Popen: - """ - Runs a command using subprocess.Popen and returns the result. - - Args: - command (List[str]): The command to be executed as a list of strings. - - Returns: - subprocess.Popen: The result of the command execution. - """ - try: - logging.info(f"Running command: {' '.join(command)}") - # Start the process - process = subprocess.Popen( - command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True - ) - - # Read and print output in real-time - for line in process.stdout: - print(line, end="") # Print each line as it is produced - - # Check the result after the process completes - check(process) - return process - except Exception as e: - logging.error(f"Exception occurred while running command: {command}") - logging.error(str(e)) - sys.exit(1) - - -def build_iac_flags(inputs: dict) -> list: - docker_flags: dict = dict( - FEATURES_LEVEL_LOG=inputs.get("features_level_log") or "info", - REPOSITORY_NAME=inputs["repository_name"], - AUTHENTICATE_CLIENT_ID=inputs["client_id"], - AUTHENTICATE_CLIENT_SECRET=inputs["client_key"], - AUTHENTICATE_CLIENT_REALMS=inputs["client_realm"], - AWS_ACCESS_KEY_ID=inputs["aws_access_key_id"], - AWS_SECRET_ACCESS_KEY=inputs["aws_secret_access_key"], - AWS_SESSION_TOKEN=inputs["aws_session_token"], - AWS_REGION=inputs["aws_region"], - AUTHENTICATE_URL=STK_IAM_DOMAIN, - FEATURES_API_MANAGER=STK_RUNTIME_MANAGER_DOMAIN, - ) - flags = [] - for k, v in docker_flags.items(): - flags += ["-e", f"{k}={v}"] - - return flags - - -def run_iac(inputs: dict): - run_task_id: str = inputs["run_task_id"] - base_path_output: str = inputs.get("base_path_output") or "." - path_to_mount: str = inputs.get("path_to_mount") or "." - path_to_mount = f"{path_to_mount}:/app-volume" - - flags = build_iac_flags(inputs) - cmd = ( - ["docker", "run", "--rm", "-v", path_to_mount] - + flags - + [ - "--entrypoint=/app/stackspot-runtime-job-iac", - CONTAINER_IAC_URL, - "start", - f"--run-task-id={run_task_id}", - f"--base-path-output={base_path_output}", - ] - ) - - run_command(cmd) - - -def build_deploy_flags(inputs: dict) -> list: - - docker_flags: dict = dict( - FEATURES_LEVEL_LOG=inputs.get("features_level_log") or "info", - FEATURES_TERRAFORM_LOGPROVIDER=inputs.get("tf_log_provider") or "info", - FEATURES_RELEASE_LOCALEXEC=inputs.get("localexec_enabled") or "False", - FEATURES_TERRAFORM_MODULES=inputs.get("features_terraform_modules") or "[]", - AWS_ACCESS_KEY_ID=inputs["aws_access_key_id"], - AWS_SECRET_ACCESS_KEY=inputs["aws_secret_access_key"], - AWS_SESSION_TOKEN=inputs["aws_session_token"], - AUTHENTICATE_CLIENT_ID=inputs["client_id"], - AUTHENTICATE_CLIENT_SECRET=inputs["client_key"], - AUTHENTICATE_CLIENT_REALMS=inputs["client_realm"], - REPOSITORY_NAME=inputs["repository_name"], - AWS_REGION=inputs["aws_region"], - AUTHENTICATE_URL=STK_IAM_DOMAIN, - FEATURES_API_MANAGER=STK_RUNTIME_MANAGER_DOMAIN, - FEATURES_BASEPATH_TMP=FEATURES_BASEPATH_TMP, - FEATURES_BASEPATH_EBS=FEATURES_BASEPATH_EBS, - FEATURES_TEMPLATES_FILEPATH=FEATURES_TEMPLATES_FILEPATH, - FEATURES_BASEPATH_TERRAFORM=FEATURES_BASEPATH_TERRAFORM, - ) - flags = [] - for k, v in docker_flags.items(): - flags += ["-e", f"{k}={v}"] - - return flags - - -def run_deploy(inputs: dict): - run_task_id: str = inputs["run_task_id"] - output_file: str = inputs.get("output_file") or "deploy-output.json" - path_to_mount: str = inputs.get("path_to_mount") or "." - path_to_mount = f"{path_to_mount}:/app-volume" - - flags = build_deploy_flags(inputs) - cmd = ( - ["docker", "run", "--rm", "-v", path_to_mount] - + flags - + [ - "--entrypoint=/app/stackspot-runtime-job-deploy", - CONTAINER_DEPLOY_URL, - "start", - f"--run-task-id={run_task_id}", - f"--output-file={output_file}", - ] - ) - - run_command(cmd) - - -def run(metadata): - with open("manager-output.log", "r") as file: - data = json.loads(file.read().replace("'", '"')) - - task_runners = dict(IAC_SELF_HOSTED=run_iac, DEPLOY_SELF_HOSTED=run_deploy) - for t in data["tasks"]: - runner = task_runners.get(t["taskType"]) - runner and runner(run_task_id=t["runTaskId"], **metadata.inputs) diff --git a/script.py b/script.py index fa70af6..1aea4cd 100644 --- a/script.py +++ b/script.py @@ -63,7 +63,7 @@ def run_tasks(file_tasks: str, run_action: RunAction): def run(metadata): workflows = dict( deploy=deploy_workflow, - cancel_deploy=cancel_deploy_run, + cancel=cancel_deploy_run, rollback_deploy=rollback_deploy_run, ) run_action = RunAction(metadata) From 3b0f713eacea9525deb25034eee5956a942d474b Mon Sep 17 00:00:00 2001 From: pedrohrfz Date: Wed, 9 Oct 2024 16:13:58 -0300 Subject: [PATCH 14/14] fixes --- .github/workflows/stk-quality-check.yaml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/.github/workflows/stk-quality-check.yaml b/.github/workflows/stk-quality-check.yaml index 6b9190f..71acf3e 100644 --- a/.github/workflows/stk-quality-check.yaml +++ b/.github/workflows/stk-quality-check.yaml @@ -80,9 +80,4 @@ jobs: cd runtime-rollback-action $HOME/.stk/bin/stk validate action - - name: Validate runtime-matrix action - run: | - cd runtime-matrix - $HOME/.stk/bin/stk validate action - \ No newline at end of file