paramsx 1.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of paramsx might be problematic. Click here for more details.
- paramsx/__init__.py +0 -0
- paramsx/funcions.py +254 -0
- paramsx/main.py +206 -0
- paramsx/paramsx_config.py +12 -0
- paramsx/text.py +12 -0
- paramsx-1.0.0.dist-info/LICENSE +21 -0
- paramsx-1.0.0.dist-info/METADATA +9 -0
- paramsx-1.0.0.dist-info/RECORD +11 -0
- paramsx-1.0.0.dist-info/WHEEL +5 -0
- paramsx-1.0.0.dist-info/entry_points.txt +2 -0
- paramsx-1.0.0.dist-info/top_level.txt +1 -0
paramsx/__init__.py
ADDED
|
File without changes
|
paramsx/funcions.py
ADDED
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
import time
|
|
2
|
+
import os
|
|
3
|
+
from .text import HEADER_ASCII, FOOTER_TEXT
|
|
4
|
+
import curses
|
|
5
|
+
|
|
6
|
+
# Función para obtener parámetros con un entorno específico
|
|
7
|
+
def get_parameters_by_prefix(ssm, prefix):
|
|
8
|
+
parameters = []
|
|
9
|
+
next_token = None
|
|
10
|
+
|
|
11
|
+
while True:
|
|
12
|
+
request_args = {
|
|
13
|
+
"Path": prefix,
|
|
14
|
+
"WithDecryption": True,
|
|
15
|
+
"Recursive": True,
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
if next_token:
|
|
19
|
+
request_args["NextToken"] = next_token
|
|
20
|
+
|
|
21
|
+
try:
|
|
22
|
+
response = ssm.get_parameters_by_path(**request_args)
|
|
23
|
+
except Exception as e:
|
|
24
|
+
raise RuntimeError(f"Error al obtener parámetros: {e}")
|
|
25
|
+
|
|
26
|
+
for param in response.get('Parameters', []):
|
|
27
|
+
parameters.append({
|
|
28
|
+
"parameter_name": param['Name'],
|
|
29
|
+
"parameter_value": param['Value']
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
next_token = response.get('NextToken')
|
|
33
|
+
if not next_token:
|
|
34
|
+
break
|
|
35
|
+
|
|
36
|
+
if not parameters:
|
|
37
|
+
raise ValueError(f"No se encontraron parámetros con el prefijo: {prefix}")
|
|
38
|
+
|
|
39
|
+
return parameters
|
|
40
|
+
|
|
41
|
+
# Función para borrar los parámetros
|
|
42
|
+
def delete_parameter(ssm_client, parameter_name):
|
|
43
|
+
try:
|
|
44
|
+
ssm_client.delete_parameter(Name=parameter_name)
|
|
45
|
+
print(f"Parámetro eliminado: {parameter_name}")
|
|
46
|
+
except Exception as e:
|
|
47
|
+
print(f"Error al eliminar el parámetro {parameter_name}: {e}")
|
|
48
|
+
|
|
49
|
+
# Función para exportar parámetros a un archivo
|
|
50
|
+
def export_parameters_to_file(parameters, file_path):
|
|
51
|
+
with open(file_path, 'w') as f:
|
|
52
|
+
f.write("# PARAMS exportados\n")
|
|
53
|
+
f.write("parametros = [\n")
|
|
54
|
+
for param in parameters:
|
|
55
|
+
parameter_name = param['parameter_name']
|
|
56
|
+
parameter_value = param['parameter_value']
|
|
57
|
+
# Usar triple comillas para valores largos
|
|
58
|
+
f.write(f" {{'parameter_name': '{parameter_name}',\n")
|
|
59
|
+
f.write(f" 'parameter_value': \"\"\"{parameter_value}\"\"\"}},\n\n")
|
|
60
|
+
f.write("]\n")
|
|
61
|
+
|
|
62
|
+
# Función para comparar parámetros y mostrar las diferencias
|
|
63
|
+
def compare_parameters(file_path, backup_file_path, stdscr):
|
|
64
|
+
if not os.path.exists(file_path) or not os.path.exists(backup_file_path):
|
|
65
|
+
return None
|
|
66
|
+
|
|
67
|
+
# Usar diccionarios específicos para cargar los archivos
|
|
68
|
+
current_scope = {}
|
|
69
|
+
backup_scope = {}
|
|
70
|
+
|
|
71
|
+
with open(file_path, 'r') as f:
|
|
72
|
+
exec(f.read(), current_scope)
|
|
73
|
+
|
|
74
|
+
with open(backup_file_path, 'r') as f:
|
|
75
|
+
exec(f.read(), backup_scope)
|
|
76
|
+
|
|
77
|
+
# Extraer los parámetros de cada archivo
|
|
78
|
+
current_params = current_scope.get('parametros', [])
|
|
79
|
+
backup_params = backup_scope.get('parametros', [])
|
|
80
|
+
|
|
81
|
+
# Comparar parámetros
|
|
82
|
+
changes = []
|
|
83
|
+
current_dict = {p['parameter_name']: p['parameter_value'] for p in current_params}
|
|
84
|
+
backup_dict = {p['parameter_name']: p['parameter_value'] for p in backup_params}
|
|
85
|
+
|
|
86
|
+
for key in current_dict:
|
|
87
|
+
if key not in backup_dict:
|
|
88
|
+
changes.append((key, "Nuevo", f"{key} - Nuevo"))
|
|
89
|
+
elif current_dict[key] != backup_dict[key]:
|
|
90
|
+
changes.append((key, "Modificado", f"{key} - Modificado"))
|
|
91
|
+
|
|
92
|
+
for key in backup_dict:
|
|
93
|
+
if key not in current_dict:
|
|
94
|
+
changes.append((key, "Eliminado", f"{key} - Eliminado"))
|
|
95
|
+
|
|
96
|
+
return changes
|
|
97
|
+
|
|
98
|
+
# Mostrar contenido comparado
|
|
99
|
+
def show_comparison_results(stdscr, changes):
|
|
100
|
+
stdscr.clear()
|
|
101
|
+
draw_header(stdscr)
|
|
102
|
+
|
|
103
|
+
max_y, max_x = stdscr.getmaxyx() # Tamaño del terminal
|
|
104
|
+
start_line = HEADER_ASCII.count("\n") + 1 # Reservar espacio para el header
|
|
105
|
+
visible_height = max_y - start_line - 3 # Espacio visible en el terminal (sin header/footer)
|
|
106
|
+
scroll_offset = 0 # Controlar desde qué línea se empieza a mostrar
|
|
107
|
+
buffer_lines = 2 # Número de líneas adicionales para mostrar al final
|
|
108
|
+
|
|
109
|
+
while True:
|
|
110
|
+
stdscr.clear()
|
|
111
|
+
draw_header(stdscr)
|
|
112
|
+
|
|
113
|
+
# Mostrar encabezado de la lista con cantidad y guía de navegación
|
|
114
|
+
title = f"Cambios detectados ({len(changes)}) - Usa ↑ y ↓ para navegar - Intro confirmar y Esc para salir"
|
|
115
|
+
stdscr.addstr(start_line, 0, title.center(max_x, "-"))
|
|
116
|
+
|
|
117
|
+
# Calcular el rango visible incluyendo el buffer
|
|
118
|
+
visible_changes = changes[scroll_offset:scroll_offset + visible_height]
|
|
119
|
+
|
|
120
|
+
for i, change in enumerate(visible_changes, start=1 + scroll_offset):
|
|
121
|
+
comment = f"{i}. {change[0]} - {change[1]}"
|
|
122
|
+
truncated_comment = comment[:max_x - 1] # Truncar si excede el ancho
|
|
123
|
+
stdscr.addstr(start_line + i - scroll_offset, 0, truncated_comment)
|
|
124
|
+
|
|
125
|
+
# Mostrar footer vacío o decorativo
|
|
126
|
+
draw_footer(stdscr)
|
|
127
|
+
|
|
128
|
+
# Actualizar pantalla
|
|
129
|
+
stdscr.refresh()
|
|
130
|
+
|
|
131
|
+
# Capturar entrada del usuario
|
|
132
|
+
key = stdscr.getkey()
|
|
133
|
+
|
|
134
|
+
# Manejar teclas de desplazamiento
|
|
135
|
+
if key == "KEY_UP" and scroll_offset > 0:
|
|
136
|
+
scroll_offset -= 1
|
|
137
|
+
elif key == "KEY_DOWN" and scroll_offset + visible_height < len(changes) + buffer_lines:
|
|
138
|
+
scroll_offset += 1
|
|
139
|
+
elif key == '\x1b': # Presionar Esc para salir
|
|
140
|
+
return False
|
|
141
|
+
elif key == '\n': # Presionar Enter para confirmar
|
|
142
|
+
return True
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
# Función para mostrar el header personalizado
|
|
146
|
+
def draw_header(stdscr):
|
|
147
|
+
max_y, max_x = stdscr.getmaxyx()
|
|
148
|
+
separator = "=" * max_x
|
|
149
|
+
stdscr.addstr(0, 0, separator) # Línea superior del header
|
|
150
|
+
|
|
151
|
+
# Mostrar HEADER_ASCII línea por línea sin strip
|
|
152
|
+
header_lines = HEADER_ASCII.split("\n") # No eliminar espacios ni líneas vacías
|
|
153
|
+
last_line_index = 0 # Guardar el índice de la última línea válida
|
|
154
|
+
|
|
155
|
+
for i, line in enumerate(header_lines, start=1):
|
|
156
|
+
if line.strip(): # Solo imprimir líneas no vacías
|
|
157
|
+
stdscr.addstr(i, 0, line)
|
|
158
|
+
last_line_index = i # Actualizar la posición de la última línea visible
|
|
159
|
+
|
|
160
|
+
stdscr.addstr(last_line_index + 1, 0, separator) # Línea inferior después de la última línea del header
|
|
161
|
+
|
|
162
|
+
# Función para mostrar el footer personalizado
|
|
163
|
+
def draw_footer(stdscr):
|
|
164
|
+
rows, cols = stdscr.getmaxyx() # Tamaño del terminal
|
|
165
|
+
exit_text = "Pulsa 'Esc' para volver o salir" # Mensaje adicional
|
|
166
|
+
footer_text = FOOTER_TEXT[:cols - 1] # Recortar el texto si es más ancho que el terminal
|
|
167
|
+
separator = "-" * cols # Separador completo ajustado al ancho
|
|
168
|
+
|
|
169
|
+
# Asegurarse de que hay espacio suficiente para el footer
|
|
170
|
+
if rows > 2: # Verifica que haya espacio mínimo para el footer
|
|
171
|
+
try:
|
|
172
|
+
stdscr.addstr(rows - 3, 0, exit_text.center(cols, " ")) # Centrar el texto de salida
|
|
173
|
+
stdscr.addstr(rows - 2, 0, separator) # Línea separadora
|
|
174
|
+
stdscr.addstr(rows - 1, 0, footer_text.center(cols - 1, " ")) # Centrar el texto
|
|
175
|
+
except curses.error:
|
|
176
|
+
pass # Ignorar errores si no hay espacio suficiente
|
|
177
|
+
|
|
178
|
+
# Mostrar contenido principal del menú
|
|
179
|
+
def show_main_menu(stdscr):
|
|
180
|
+
start_line = HEADER_ASCII.count("\n") + 1 # Calcula dónde termina el header
|
|
181
|
+
stdscr.addstr(start_line, 0, "1. Leer parámetros".ljust(60))
|
|
182
|
+
stdscr.addstr(start_line + 1, 0, "2. Cargar parámetros desde archivo".ljust(60))
|
|
183
|
+
stdscr.addstr(start_line + 2, 0, "3. Crear Backup de parámetros".ljust(60))
|
|
184
|
+
stdscr.addstr(start_line + 3, 0, "Elija una opción (1/2): ")
|
|
185
|
+
|
|
186
|
+
# Mostrar selección de parámetros
|
|
187
|
+
def show_parameter_selection(stdscr, options):
|
|
188
|
+
stdscr.clear()
|
|
189
|
+
draw_header(stdscr)
|
|
190
|
+
start_line = HEADER_ASCII.count("\n") + 1 # Calcula el inicio después del header
|
|
191
|
+
stdscr.addstr(start_line, 0, "Seleccione un parámetro para leer:".center(60, "-"))
|
|
192
|
+
for idx, option in enumerate(options, start=1):
|
|
193
|
+
stdscr.addstr(start_line + idx, 0, f"{idx}. {option}")
|
|
194
|
+
draw_footer(stdscr)
|
|
195
|
+
stdscr.refresh()
|
|
196
|
+
|
|
197
|
+
while True:
|
|
198
|
+
key = stdscr.getkey()
|
|
199
|
+
if key == '\x1b': # Si se presiona Esc
|
|
200
|
+
return None # Cancelar selección
|
|
201
|
+
try:
|
|
202
|
+
choice = int(key) - 1
|
|
203
|
+
if 0 <= choice < len(options):
|
|
204
|
+
return choice
|
|
205
|
+
except ValueError:
|
|
206
|
+
pass # Ignorar entradas inválidas
|
|
207
|
+
|
|
208
|
+
# Mostrar selección de entorno
|
|
209
|
+
def show_environment_selection(stdscr, environments):
|
|
210
|
+
stdscr.clear()
|
|
211
|
+
draw_header(stdscr)
|
|
212
|
+
start_line = HEADER_ASCII.count("\n") + 1
|
|
213
|
+
stdscr.addstr(start_line, 0, "Seleccione el entorno:".center(60, "-"))
|
|
214
|
+
for idx, env in enumerate(environments, start=1):
|
|
215
|
+
stdscr.addstr(start_line + idx, 0, f"{idx}. {env}")
|
|
216
|
+
draw_footer(stdscr)
|
|
217
|
+
stdscr.refresh()
|
|
218
|
+
|
|
219
|
+
while True:
|
|
220
|
+
key = stdscr.getkey()
|
|
221
|
+
if key == '\x1b': # Si se presiona Esc
|
|
222
|
+
return None # Cancelar selección
|
|
223
|
+
try:
|
|
224
|
+
choice = int(key) - 1
|
|
225
|
+
if 0 <= choice < len(environments):
|
|
226
|
+
return choice
|
|
227
|
+
except ValueError:
|
|
228
|
+
pass # Ignorar entradas inválidas
|
|
229
|
+
|
|
230
|
+
# Pantalla de confirmación o resultados
|
|
231
|
+
def show_message(stdscr, message, color_pair=1):
|
|
232
|
+
stdscr.clear()
|
|
233
|
+
draw_header(stdscr)
|
|
234
|
+
start_line = HEADER_ASCII.count("\n") + 1
|
|
235
|
+
stdscr.addstr(start_line, 0, message.center(60, " "), curses.color_pair(color_pair))
|
|
236
|
+
draw_footer(stdscr)
|
|
237
|
+
stdscr.refresh()
|
|
238
|
+
time.sleep(3)
|
|
239
|
+
|
|
240
|
+
# Errores varios
|
|
241
|
+
def load_parameters(file_path):
|
|
242
|
+
if not os.path.exists(file_path):
|
|
243
|
+
raise FileNotFoundError(f"El archivo {file_path} no existe.")
|
|
244
|
+
|
|
245
|
+
param_scope = {}
|
|
246
|
+
try:
|
|
247
|
+
with open(file_path, 'r') as f:
|
|
248
|
+
exec(f.read(), param_scope) # Ejecuta el archivo en el contexto de param_scope
|
|
249
|
+
except SyntaxError as e:
|
|
250
|
+
raise SyntaxError(
|
|
251
|
+
f"Error de sintaxis en {file_path}.\nRevisa las comillas o el formato del archivo."
|
|
252
|
+
)
|
|
253
|
+
|
|
254
|
+
return param_scope.get('parametros', [])
|
paramsx/main.py
ADDED
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import boto3
|
|
3
|
+
import curses
|
|
4
|
+
import importlib.util
|
|
5
|
+
from .funcions import (
|
|
6
|
+
draw_header, draw_footer, show_main_menu, show_comparison_results,
|
|
7
|
+
show_environment_selection, show_message, show_parameter_selection,
|
|
8
|
+
get_parameters_by_prefix, delete_parameter, export_parameters_to_file,
|
|
9
|
+
compare_parameters, load_parameters
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
# Ruta de la configuración personalizada
|
|
14
|
+
CONFIG_PATH = os.path.expanduser("~/.xsoft/paramsx_config.py")
|
|
15
|
+
|
|
16
|
+
# Cargar configuraciones desde el archivo de usuario
|
|
17
|
+
def load_config():
|
|
18
|
+
if not os.path.exists(CONFIG_PATH):
|
|
19
|
+
raise FileNotFoundError(f"No se encontró el archivo de configuración en {CONFIG_PATH}")
|
|
20
|
+
spec = importlib.util.spec_from_file_location("config", CONFIG_PATH)
|
|
21
|
+
config = importlib.util.module_from_spec(spec)
|
|
22
|
+
spec.loader.exec_module(config)
|
|
23
|
+
return config.configuraciones
|
|
24
|
+
|
|
25
|
+
# Función principal
|
|
26
|
+
def main(stdscr):
|
|
27
|
+
|
|
28
|
+
## Cargando configuración
|
|
29
|
+
config = load_config()
|
|
30
|
+
# Configurar boto3 con el perfil y región del usuario
|
|
31
|
+
boto3.setup_default_session(profile_name=config["profile_name"])
|
|
32
|
+
ssm = boto3.client("ssm", region_name=config["region_name"])
|
|
33
|
+
|
|
34
|
+
curses.start_color()
|
|
35
|
+
curses.init_pair(1, curses.COLOR_WHITE, curses.COLOR_BLUE)
|
|
36
|
+
curses.init_pair(2, curses.COLOR_RED, curses.COLOR_BLACK)
|
|
37
|
+
curses.init_pair(3, curses.COLOR_GREEN, curses.COLOR_BLACK)
|
|
38
|
+
|
|
39
|
+
environments = config['entornos']
|
|
40
|
+
PARAMETER_LIST = config['parameter_list']
|
|
41
|
+
|
|
42
|
+
while True:
|
|
43
|
+
stdscr.clear()
|
|
44
|
+
draw_header(stdscr)
|
|
45
|
+
show_main_menu(stdscr)
|
|
46
|
+
draw_footer(stdscr)
|
|
47
|
+
stdscr.refresh()
|
|
48
|
+
|
|
49
|
+
choice = stdscr.getkey()
|
|
50
|
+
|
|
51
|
+
if choice == '\x1b': # Código ASCII para 'Esc'
|
|
52
|
+
break # Salir del programa
|
|
53
|
+
|
|
54
|
+
elif choice == '1':
|
|
55
|
+
# Leer parámetros
|
|
56
|
+
param_choice = show_parameter_selection(stdscr, PARAMETER_LIST)
|
|
57
|
+
if param_choice is None: # Si se presionó Esc
|
|
58
|
+
continue # Regresar al menú principal
|
|
59
|
+
|
|
60
|
+
selected_param = PARAMETER_LIST[param_choice]
|
|
61
|
+
|
|
62
|
+
env_choice = show_environment_selection(stdscr, environments)
|
|
63
|
+
if env_choice is None: # Si se presionó Esc
|
|
64
|
+
continue # Regresar al menú principal
|
|
65
|
+
|
|
66
|
+
selected_env = environments[env_choice]
|
|
67
|
+
|
|
68
|
+
# Crear el prefijo completo
|
|
69
|
+
full_path = f"{selected_param}/{selected_env}"
|
|
70
|
+
show_message(stdscr, f"Buscando parámetros en: {full_path}...", 3) # Mensaje inicial
|
|
71
|
+
|
|
72
|
+
try:
|
|
73
|
+
# Obtener parámetros desde AWS SSM
|
|
74
|
+
parameters = get_parameters_by_prefix(ssm, full_path)
|
|
75
|
+
except ValueError as e:
|
|
76
|
+
show_message(stdscr, f"ERROR: {e}", 2) # Error por prefijo vacío
|
|
77
|
+
continue # Regresar al menú principal
|
|
78
|
+
except Exception as e:
|
|
79
|
+
show_message(stdscr, f"Error inesperado: {e}", 2) # Error genérico
|
|
80
|
+
continue # Regresar al menú principal
|
|
81
|
+
|
|
82
|
+
# Validar si se encontraron parámetros antes de continuar
|
|
83
|
+
if not parameters:
|
|
84
|
+
show_message(stdscr, f"No se encontraron parámetros en: {full_path}.", 2)
|
|
85
|
+
continue # Regresar al menú principal
|
|
86
|
+
|
|
87
|
+
# Crear archivos si se encontraron parámetros
|
|
88
|
+
file_name = f"parameters_{selected_env}.py"
|
|
89
|
+
backup_file_name = f"parameters_{selected_env}_backup.py"
|
|
90
|
+
|
|
91
|
+
# Exportar parámetros al archivo principal
|
|
92
|
+
export_parameters_to_file(parameters, file_name)
|
|
93
|
+
|
|
94
|
+
# Crear un respaldo exacto del archivo principal
|
|
95
|
+
export_parameters_to_file(parameters, backup_file_name)
|
|
96
|
+
|
|
97
|
+
# Confirmación de archivos creados
|
|
98
|
+
show_message(stdscr, f"Archivos creados:\n- {file_name}\n- {backup_file_name}", 3)
|
|
99
|
+
|
|
100
|
+
elif choice == '2':
|
|
101
|
+
# Cargar parámetros desde archivo
|
|
102
|
+
env_choice = show_environment_selection(stdscr, environments)
|
|
103
|
+
if env_choice is None: # Si se presionó Esc
|
|
104
|
+
continue # Regresar al menú principal
|
|
105
|
+
|
|
106
|
+
selected_env = environments[env_choice]
|
|
107
|
+
file_name = f"parameters_{selected_env}.py"
|
|
108
|
+
backup_file_name = f"parameters_{selected_env}_backup.py"
|
|
109
|
+
|
|
110
|
+
if not os.path.exists(file_name) or not os.path.exists(backup_file_name):
|
|
111
|
+
show_message(stdscr, f"Archivos {file_name} o {backup_file_name} no encontrados.", 2)
|
|
112
|
+
continue
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
try:
|
|
116
|
+
# Cargar parámetros del archivo principal
|
|
117
|
+
parametros = load_parameters(file_name)
|
|
118
|
+
except SyntaxError as e:
|
|
119
|
+
show_message(stdscr, f"ERROR: {e}", 2)
|
|
120
|
+
continue # Regresar al menú principal
|
|
121
|
+
except Exception as e:
|
|
122
|
+
show_message(stdscr, f"Error inesperado: {e}", 2)
|
|
123
|
+
continue # Regresar al menú principal
|
|
124
|
+
|
|
125
|
+
# Comparar los parámetros
|
|
126
|
+
changes = compare_parameters(file_name, backup_file_name, stdscr)
|
|
127
|
+
|
|
128
|
+
if changes:
|
|
129
|
+
# Mostrar resultados de la comparación
|
|
130
|
+
confirmed = show_comparison_results(stdscr, changes)
|
|
131
|
+
|
|
132
|
+
if not confirmed: # Si el usuario cancela
|
|
133
|
+
show_message(stdscr, "Operación cancelada volvemos a menú principal.", 2)
|
|
134
|
+
continue
|
|
135
|
+
|
|
136
|
+
# Subir parámetros si se confirman los cambios
|
|
137
|
+
with open(file_name, 'r') as f:
|
|
138
|
+
param_scope = {}
|
|
139
|
+
exec(f.read(), param_scope)
|
|
140
|
+
|
|
141
|
+
parametros = param_scope.get('parametros', [])
|
|
142
|
+
current_dict = {p['parameter_name']: p['parameter_value'] for p in parametros}
|
|
143
|
+
|
|
144
|
+
for change in changes:
|
|
145
|
+
param_name, change_type, _ = change
|
|
146
|
+
if change_type == "Nuevo" or change_type == "Modificado":
|
|
147
|
+
# Subir o actualizar parámetros
|
|
148
|
+
ssm.put_parameter(
|
|
149
|
+
Name=param_name,
|
|
150
|
+
Value=current_dict[param_name],
|
|
151
|
+
Type='SecureString',
|
|
152
|
+
Overwrite=True
|
|
153
|
+
)
|
|
154
|
+
elif change_type == "Eliminado":
|
|
155
|
+
# Borrar parámetros eliminados
|
|
156
|
+
delete_parameter(ssm, param_name)
|
|
157
|
+
|
|
158
|
+
# Eliminar los archivos una vez procesados
|
|
159
|
+
os.remove(file_name)
|
|
160
|
+
os.remove(backup_file_name)
|
|
161
|
+
show_message(stdscr, "¡Cambios aplicados y archivos eliminados!", 3)
|
|
162
|
+
else:
|
|
163
|
+
show_message(stdscr, "No se encontraron cambios entre los archivos.", 3)
|
|
164
|
+
|
|
165
|
+
elif choice == '3':
|
|
166
|
+
# Crear backup
|
|
167
|
+
param_choice = show_parameter_selection(stdscr, PARAMETER_LIST)
|
|
168
|
+
if param_choice is None: # Si se presionó Esc
|
|
169
|
+
continue # Regresar al menú principal
|
|
170
|
+
|
|
171
|
+
selected_param = PARAMETER_LIST[param_choice]
|
|
172
|
+
|
|
173
|
+
env_choice = show_environment_selection(stdscr, environments)
|
|
174
|
+
if env_choice is None: # Si se presionó Esc
|
|
175
|
+
continue # Regresar al menú principal
|
|
176
|
+
|
|
177
|
+
selected_env = environments[env_choice]
|
|
178
|
+
|
|
179
|
+
# Crear el prefijo completo
|
|
180
|
+
full_path = f"{selected_param}/{selected_env}"
|
|
181
|
+
try:
|
|
182
|
+
# Obtener parámetros desde AWS SSM
|
|
183
|
+
parameters = get_parameters_by_prefix(ssm, full_path)
|
|
184
|
+
except ValueError as e:
|
|
185
|
+
show_message(stdscr, f"ERROR: {e}", 2)
|
|
186
|
+
continue # Regresar al menú principal
|
|
187
|
+
except Exception as e:
|
|
188
|
+
show_message(stdscr, f"Error inesperado: {e}", 2)
|
|
189
|
+
continue # Regresar al menú principal
|
|
190
|
+
|
|
191
|
+
# Crear archivo de backup con nombre claro
|
|
192
|
+
backup_file_name = f"{selected_param.replace('/', '_')}_{selected_env}_backup.py"
|
|
193
|
+
export_parameters_to_file(parameters, backup_file_name)
|
|
194
|
+
|
|
195
|
+
# Confirmación de backup creado
|
|
196
|
+
show_message(stdscr, f"Backup creado:\n- {backup_file_name}", 3)
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
else:
|
|
200
|
+
show_message(stdscr, "Opción inválida. Inténtalo de nuevo.", 2)
|
|
201
|
+
|
|
202
|
+
def entry_point():
|
|
203
|
+
curses.wrapper(main)
|
|
204
|
+
|
|
205
|
+
if __name__ == "__main__":
|
|
206
|
+
curses.wrapper(main)
|
paramsx/text.py
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
HEADER_ASCII = """
|
|
2
|
+
_____ __ __
|
|
3
|
+
| __ \ \ \ / /
|
|
4
|
+
| |__) |_ _ _ __ __ _ _ __ ___ ___ \ V /
|
|
5
|
+
| ___/ _` | '__/ _` | '_ ` _ \/ __| > <
|
|
6
|
+
| | | (_| | | | (_| | | | | | \__ \/ . \
|
|
7
|
+
|_| \__,_|_| \__,_|_| |_| |_|___/_/ \_\
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
FOOTER_TEXT = "By Mariox"
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Mario x
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: paramsx
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Librería para gestionar y respaldar parámetros de AWS SSM de manera sencilla y eficiente.
|
|
5
|
+
Home-page: https://github.com/pistatxos/paramsx
|
|
6
|
+
Author: Mariox
|
|
7
|
+
Author-email: info@tomonota.net
|
|
8
|
+
License-File: LICENSE
|
|
9
|
+
Requires-Dist: boto3
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
paramsx/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
+
paramsx/funcions.py,sha256=1053brCERgadfA1lB31U8VbnYksCbfttQ5HnxhDlZ2Q,9629
|
|
3
|
+
paramsx/main.py,sha256=Wgh-8bibDIGhdeoTcRCZr39ph_D0AYnQeODCjmScAjQ,8356
|
|
4
|
+
paramsx/paramsx_config.py,sha256=uBKYtCLiPfuCw58nzMCc-kKx2yXJLXA4ytaXHOneP74,213
|
|
5
|
+
paramsx/text.py,sha256=nJf5wJ0dZNiuBrp8zFacu-mWe1FbIEcslWRokR9SPS4,315
|
|
6
|
+
paramsx-1.0.0.dist-info/LICENSE,sha256=GrUwVxQBOoDjqiy-ts0ms4stmdZjDEZZlkjUgCaGcCQ,1064
|
|
7
|
+
paramsx-1.0.0.dist-info/METADATA,sha256=rYC2-6_DBNiyupV-D8vl8ZYF5vxYqkhusUeSEVanH0s,290
|
|
8
|
+
paramsx-1.0.0.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
|
|
9
|
+
paramsx-1.0.0.dist-info/entry_points.txt,sha256=DaoL0NejfYIz3DaYsnAZzB3pWhtqydt-T5K2rE4iQ1k,53
|
|
10
|
+
paramsx-1.0.0.dist-info/top_level.txt,sha256=LiSJIPKNZVfaJcRHqKr0YoBl7cHS_IolBI6cYB-aBbE,8
|
|
11
|
+
paramsx-1.0.0.dist-info/RECORD,,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
paramsx
|