Skip to content

Commit 95e8622

Browse files
authored
Merge pull request #7 from stack-spot/feat/unified-action
Feat/unified action
2 parents 13386d0 + 6a5987d commit 95e8622

File tree

6 files changed

+343
-2
lines changed

6 files changed

+343
-2
lines changed

runtime-unified-action/.stkignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# Este arquivo pode ser usado para ignorar arquivos e pastas ao publicar um artefato.

runtime-unified-action/action.yaml

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
schema-version: v3
2+
kind: action
3+
metadata:
4+
name: runtime-unified-action
5+
display-name: runtime-unified-action
6+
description: Descreva sua action explicando o propósito.
7+
version: 0.0.1
8+
spec:
9+
type: python
10+
docs:
11+
pt-br: docs/pt-br/docs.md
12+
en-us: docs/en-us/docs.md
13+
repository: https://github.com/stack-spot/workflow-stackspot-actions-runtime-selfhosted.git
14+
inputs:
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
63+
type: text
64+
required: false
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+
97+
python:
98+
workdir: .
99+
script: script.py
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
<!--
2+
******************************************
3+
4+
- THIS IS AN EXAMPLE OF HOW TO FILL OUT YOUR DOCUMENTATION OF CONTENT.
5+
6+
- FILL OUT THE TEMPLATE BELOW WITH YOUR INFORMATION SO OTHER PEOPLE CAN USE IT. THIS DOCUMENTATION WILL APPEAR ON THE SECTION OF THE STACKSPOT PORTAL.
7+
8+
******************************************
9+
-->
10+
## Action name
11+
12+
<!-- Write concisely describing your Action. -->
13+
14+
## Requirements
15+
16+
<!--
17+
[This is a guideline; delete this content and write your information outside this markup. <!-- ]
18+
19+
- Describe the requirements that the user needs to know before using the Action.
20+
-->
21+
22+
## Usage
23+
24+
<!--
25+
[This is a guideline; delete this content and write your information outside this markup. <!-- ]
26+
27+
Add the steps for the user to use your Action:
28+
29+
- What are the inputs?
30+
- Which methods should we know?
31+
- What are the resources?
32+
- Add the Action dependencies, if necessary.
33+
34+
Example:
35+
On your application’s folder, run the **action-doc-template** action and follow the instructions:
36+
1. Execute the command:
37+
`
38+
stk run action /Users/Home/action-doc-template
39+
`
40+
-->
41+
42+
## Release Notes
43+
44+
<!--
45+
[This is a guideline; delete this content and write your information outside this markup. <!-- ]
46+
47+
This section is only necessary if you publish a new Action version. Add what was changed, fixed, and the new features.
48+
49+
Example:
50+
### action-doc-template v1.0.0
51+
52+
#### Features
53+
Added new templates
54+
-->
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
<!--
2+
******************************************
3+
4+
- ESTE É APENAS UM EXEMPLO DE COMO PREENCHER A DOCUMENTAÇÃO DO SEU CONTEUDO.
5+
6+
- PREENCHA O TEMPLATE COM AS INFORMAÇÕES DO SEU CONTEUDO PARA QUE OUTROS USUÁRIO CONSIGAM UTILIZÁ-LO. ESSA DOCUMENTAÇÃO SERÁ EXPOSTA NA PÁGINA DO CONTEUDO NO PORTAL DA STACKSPOT.
7+
8+
******************************************
9+
-->
10+
## Nome Action
11+
12+
<!-- Escreva uma descrição clara e breve sobre a sua Action. -->
13+
14+
## Pré-requisitos
15+
16+
<!--
17+
[Isto é uma orientação, apague essa o conteúdo e escreva suas informações fora desta marcação <!-- ]
18+
19+
- Descreva quais os requisitos que o usuário precisa saber antes de usar a Action.
20+
-->
21+
22+
## Uso
23+
24+
<!--
25+
[Isto é uma orientação, apague essa o conteúdo e escreva suas informações fora desta marcação <!-- ]
26+
27+
Descreva as etapas para o usuário utilizar esta Action:
28+
29+
- Quais as entradas
30+
- Quais os métodos usar
31+
- Quais os recursos
32+
- E se necessário, adicione as dependências de sua Action.
33+
34+
Exemplo:
35+
Na pasta do seu aplicativo, execute a **action-doc-template** para preencher os arquivos abaixo:
36+
1. Execute o comando:
37+
`
38+
stk run action /Users/Home/action-doc-template
39+
`
40+
-->
41+
42+
## Release Notes
43+
44+
<!--
45+
[Isto é uma orientação, apague essa o conteúdo e escreva suas informações fora desta marcação <!-- ]
46+
47+
Esta seção só é necessária se você publicar uma nova versão da Action. Apenas adicione o que foi modificado ou adicionado.
48+
49+
Exemplo:
50+
### action-doc-template v1.0.0
51+
52+
#### Features
53+
Novos templates foram adicionados.
54+
-->

runtime-unified-action/script.py

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
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+
flags = []
100+
for k, v in docker_flags.items():
101+
flags += ["-e", f"{k}={v}"]
102+
103+
return flags
104+
105+
106+
def run(metadata):
107+
inputs: dict = metadata.inputs
108+
run_id: str = inputs["run_id"]
109+
base_path_output: str = inputs.get("base_path_output") or "."
110+
path_to_mount: str = inputs.get("path_to_mount") or "."
111+
path_to_mount = f"{path_to_mount}:/app-volume"
112+
113+
flags = build_flags(inputs)
114+
cmd = (
115+
["docker", "run", "--rm", "-v", path_to_mount]
116+
+ flags
117+
+ [
118+
"--entrypoint=/app/stackspot-runtime-job",
119+
CONTAINER_UNIFIED_URL,
120+
"start",
121+
f"--run-id={run_id}",
122+
f"--base-path-output={base_path_output}",
123+
]
124+
)
125+
126+
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)