Skip to content

Commit b8f4f79

Browse files
committed
add new action unified
1 parent 4a8ca6e commit b8f4f79

File tree

3 files changed

+213
-7
lines changed

3 files changed

+213
-7
lines changed

runtime-unified-action/action.yaml

Lines changed: 80 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,88 @@ spec:
1212
en-us: docs/en-us/docs.md
1313
repository: https://github.com/stack-spot/workflow-stackspot-actions-runtime-selfhosted.git
1414
inputs:
15-
- label: What is your name?
16-
name: user_name
15+
- label: "CLIENT ID"
16+
name: client_id
17+
type: text
18+
required: true
19+
20+
- label: "CLIENT KEY"
21+
name: client_key
22+
type: text
23+
required: true
24+
25+
- label: "CLIENT REALM"
26+
name: client_realm
27+
type: text
28+
required: true
29+
30+
- label: "Git Repository Name"
31+
name: repository_name
32+
type: text
33+
required: true
34+
35+
- label: "AWS ACCESS KEY ID from console"
36+
name: aws_access_key_id
37+
type: text
38+
required: true
39+
40+
- label: "AWS SECRET ACCESS KEY from console"
41+
name: aws_secret_access_key
42+
type: text
43+
required: true
44+
45+
- label: "AWS SESSION TOKEN from console"
46+
name: aws_session_token
47+
type: text
48+
required: true
49+
50+
- label: "AWS REGION"
51+
name: aws_region
52+
type: text
53+
required: true
54+
55+
- label: "Terraform parallelism order"
56+
name: tf_parallelism
57+
type: text
58+
default: "10"
59+
required: false
60+
61+
- label: "Terraform Modules"
62+
name: features_terraform_modules
1763
type: text
1864
required: false
19-
pattern: '^[A-Za-z]+(?:\s[A-Za-z]+)*$'
20-
help: 'Inform your name'
65+
66+
- label: "Path to mount inside the docker"
67+
name: path_to_mount
68+
type: text
69+
default: "."
70+
required: false
71+
72+
- label: "If Runtimes will allow execution of the local-exec command within terraform"
73+
name: localexec_enabled
74+
type: bool
75+
required: false
76+
77+
- label: "Level tf log provider - info, debug, warn or trace"
78+
name: tf_log_provider
79+
type: text
80+
required: false
81+
82+
- label: "Features Log Level"
83+
name: features_level_log
84+
type: text
85+
required: false
86+
87+
- label: "Base Path Output"
88+
name: base_path_output
89+
type: text
90+
required: false
91+
92+
- label: "Run ID that contains its tasks"
93+
name: run_id
94+
type: text
95+
required: true
96+
2197
python:
2298
workdir: .
2399
script: script.py

runtime-unified-action/script.py

Lines changed: 124 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,127 @@
1+
import os
2+
import sys
3+
import subprocess
4+
import logging
5+
from typing import List
6+
7+
# Configure logging
8+
logging.basicConfig(
9+
level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s"
10+
)
11+
12+
13+
STK_IAM_DOMAIN = os.getenv("STK_IAM_DOMAIN", "https://idm.stackspot.com")
14+
STK_RUNTIME_MANAGER_DOMAIN = os.getenv(
15+
"STK_RUNTIME_MANAGER_DOMAIN", "https://runtime-manager.v1.stackspot.com"
16+
)
17+
CONTAINER_UNIFIED_URL = os.getenv(
18+
"CONTAINER_UNIFIED_URL", "stackspot/runtime-job-unified:latest"
19+
)
20+
21+
FEATURES_BASEPATH_TMP = "/tmp/runtime/deploys"
22+
FEATURES_BASEPATH_EBS = "/opt/runtime"
23+
FEATURES_TEMPLATES_FILEPATH = "/app/"
24+
FEATURES_BASEPATH_TERRAFORM = "/root/.asdf/shims/terraform"
25+
26+
27+
def check(result: subprocess.Popen) -> None:
28+
"""
29+
Checks the result of a subprocess execution. If the return code is non-zero,
30+
it logs an error message and exits the program.
31+
32+
Args:
33+
result (subprocess.Popen): The result of the subprocess execution.
34+
"""
35+
result.wait() # Wait for the process to complete
36+
if result.returncode != 0:
37+
logging.error(f"Failed to execute: {result.args}")
38+
logging.error(f"Error output: {result.stderr.read()}")
39+
sys.exit(1)
40+
41+
42+
def run_command(command: List[str]) -> subprocess.Popen:
43+
"""
44+
Runs a command using subprocess.Popen and returns the result.
45+
46+
Args:
47+
command (List[str]): The command to be executed as a list of strings.
48+
49+
Returns:
50+
subprocess.Popen: The result of the command execution.
51+
"""
52+
try:
53+
logging.info(f"Running command: {' '.join(command)}")
54+
# Start the process
55+
process = subprocess.Popen(
56+
command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True
57+
)
58+
59+
# Read and print output in real-time
60+
for line in process.stdout:
61+
print(line, end="") # Print each line as it is produced
62+
63+
# Check the result after the process completes
64+
check(process)
65+
return process
66+
except Exception as e:
67+
logging.error(f"Exception occurred while running command: {command}")
68+
logging.error(str(e))
69+
sys.exit(1)
70+
71+
72+
def build_flags(inputs: dict) -> list:
73+
74+
TF_PARALLELISM=f"-parallelism={inputs.get('tf_parallelism') or '10'}"
75+
76+
docker_flags: dict = dict(
77+
FEATURES_LEVEL_LOG=inputs.get("features_level_log") or "info",
78+
FEATURES_TERRAFORM_LOGPROVIDER=inputs.get("tf_log_provider") or "info",
79+
FEATURES_RELEASE_LOCALEXEC=inputs.get("localexec_enabled") or "False",
80+
FEATURES_TERRAFORM_MODULES=inputs.get("features_terraform_modules") or "[]",
81+
AWS_ACCESS_KEY_ID=inputs["aws_access_key_id"],
82+
AWS_SECRET_ACCESS_KEY=inputs["aws_secret_access_key"],
83+
AWS_SESSION_TOKEN=inputs["aws_session_token"],
84+
AUTHENTICATE_CLIENT_ID=inputs["client_id"],
85+
AUTHENTICATE_CLIENT_SECRET=inputs["client_key"],
86+
AUTHENTICATE_CLIENT_REALMS=inputs["client_realm"],
87+
REPOSITORY_NAME=inputs["repository_name"],
88+
AWS_REGION=inputs["aws_region"],
89+
AUTHENTICATE_URL=STK_IAM_DOMAIN,
90+
FEATURES_API_MANAGER=STK_RUNTIME_MANAGER_DOMAIN,
91+
FEATURES_BASEPATH_TMP=FEATURES_BASEPATH_TMP,
92+
FEATURES_BASEPATH_EBS=FEATURES_BASEPATH_EBS,
93+
FEATURES_TEMPLATES_FILEPATH=FEATURES_TEMPLATES_FILEPATH,
94+
FEATURES_BASEPATH_TERRAFORM=FEATURES_BASEPATH_TERRAFORM,
95+
TF_CLI_ARGS_apply=TF_PARALLELISM,
96+
TF_CLI_ARGS_plan=TF_PARALLELISM,
97+
TF_CLI_ARGS_destroy=TF_PARALLELISM
98+
99+
)
100+
flags = []
101+
for k, v in docker_flags.items():
102+
flags += ["-e", f"{k}={v}"]
103+
104+
return flags
1105

2106

3107
def run(metadata):
4-
print(f"Hello {metadata.inputs.get('user_name')}!")
108+
inputs: dict = metadata.inputs
109+
run_id: str = inputs["run_id"]
110+
base_path_output: str = inputs.get("base_path_output") or "."
111+
path_to_mount: str = inputs.get("path_to_mount") or "."
112+
path_to_mount = f"{path_to_mount}:/app-volume"
113+
114+
flags = build_flags(inputs)
115+
cmd = (
116+
["docker", "run", "--rm", "-v", path_to_mount]
117+
+ flags
118+
+ [
119+
"--entrypoint=/app/stackspot-runtime-job",
120+
CONTAINER_UNIFIED_URL,
121+
"start",
122+
f"--run-id={run_id}",
123+
f"--base-path-output={base_path_output}",
124+
]
125+
)
126+
127+
run_command(cmd)

script.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,11 +53,18 @@ def run_tasks(file_tasks: str, run_action: RunAction):
5353
IAC_SELF_HOSTED=lambda **i: run_action("runtime-iac-action", **i),
5454
DEPLOY_SELF_HOSTED=lambda **i: run_action("runtime-deploy-action", **i),
5555
DESTROY_SELF_HOSTED=lambda **i: run_action("runtime-destroy-action", **i),
56+
UNIFIED_IAC=lambda **i: run_action("runtime-unified-action", **i),
57+
UNIFIED_DEPLOY=lambda **i: run_action("runtime-unified-action", **i),
58+
UNIFIED_DESTROY=lambda **i: run_action("runtime-unified-action", **i)
5659
)
5760

5861
for t in data.get("tasks") or []:
59-
runner = task_runners.get(t["taskType"])
60-
runner and runner(run_task_id=t["runTaskId"])
62+
task_type = t["taskType"]
63+
runner = task_runners.get(task_type)
64+
if "UNIFIED" in task_type:
65+
runner and runner(run_id=data.get("runId"))
66+
else:
67+
runner and runner(run_task_id=t["runTaskId"])
6168

6269

6370
def run(metadata):

0 commit comments

Comments
 (0)