ic-code 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.
- ic/__init__.py +29 -0
- ic/cli.py +769 -0
- ic/commands/__init__.py +10 -0
- ic/commands/config.py +699 -0
- ic/compat/__init__.py +241 -0
- ic/compat/cli.py +289 -0
- ic/compat/common.py +243 -0
- ic/config/__init__.py +10 -0
- ic/config/cleanup.py +382 -0
- ic/config/docs_organizer.py +587 -0
- ic/config/external.py +456 -0
- ic/config/manager.py +898 -0
- ic/config/migration.py +628 -0
- ic/config/schema.py +595 -0
- ic/config/secrets.py +437 -0
- ic/config/security.py +462 -0
- ic/core/__init__.py +16 -0
- ic/core/logging.py +311 -0
- ic/core/mcp_manager.py +856 -0
- ic/core/session.py +392 -0
- ic/core/silence_logging.py +67 -0
- ic_code-1.0.0.dist-info/METADATA +354 -0
- ic_code-1.0.0.dist-info/RECORD +27 -0
- ic_code-1.0.0.dist-info/WHEEL +5 -0
- ic_code-1.0.0.dist-info/entry_points.txt +2 -0
- ic_code-1.0.0.dist-info/licenses/LICENSE +21 -0
- ic_code-1.0.0.dist-info/top_level.txt +1 -0
ic/cli.py
ADDED
|
@@ -0,0 +1,769 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
|
|
3
|
+
import argparse
|
|
4
|
+
import sys
|
|
5
|
+
import warnings
|
|
6
|
+
|
|
7
|
+
# Silence all logging except ERROR messages
|
|
8
|
+
from .core.silence_logging import silence_all_logging
|
|
9
|
+
silence_all_logging()
|
|
10
|
+
|
|
11
|
+
# Set up compatibility layer first
|
|
12
|
+
from .compat.cli import setup_cli_compatibility, wrap_command_function, ensure_env_compatibility
|
|
13
|
+
from .compat.common import log_error, log_env_short, log_args_short, gather_env_for_command
|
|
14
|
+
|
|
15
|
+
# Initialize compatibility layer
|
|
16
|
+
setup_cli_compatibility()
|
|
17
|
+
|
|
18
|
+
# Initialize new configuration system
|
|
19
|
+
from .config.manager import ConfigManager
|
|
20
|
+
from .config.security import SecurityManager
|
|
21
|
+
from .core.logging import init_logger
|
|
22
|
+
|
|
23
|
+
# Global configuration manager instance
|
|
24
|
+
_config_manager = None
|
|
25
|
+
_ic_logger = None
|
|
26
|
+
|
|
27
|
+
def get_config_manager():
|
|
28
|
+
"""Get or create global configuration manager."""
|
|
29
|
+
global _config_manager, _ic_logger
|
|
30
|
+
if _config_manager is None:
|
|
31
|
+
# Suppress all logging during initialization
|
|
32
|
+
import logging
|
|
33
|
+
logging.getLogger().setLevel(logging.CRITICAL)
|
|
34
|
+
|
|
35
|
+
security_manager = SecurityManager()
|
|
36
|
+
_config_manager = ConfigManager(security_manager)
|
|
37
|
+
|
|
38
|
+
# Load all configurations
|
|
39
|
+
config = _config_manager.load_all_configs()
|
|
40
|
+
|
|
41
|
+
# Initialize logging with new configuration
|
|
42
|
+
_ic_logger = init_logger(config)
|
|
43
|
+
|
|
44
|
+
# Log .env file usage to file only (no console output)
|
|
45
|
+
from pathlib import Path
|
|
46
|
+
if Path('.env').exists() and _ic_logger:
|
|
47
|
+
_ic_logger.log_info_file_only("Using .env file for configuration. Consider migrating to YAML configuration with 'ic config migrate'")
|
|
48
|
+
|
|
49
|
+
return _config_manager
|
|
50
|
+
|
|
51
|
+
# Legacy dotenv support (silent loading)
|
|
52
|
+
try:
|
|
53
|
+
from dotenv import load_dotenv
|
|
54
|
+
from pathlib import Path
|
|
55
|
+
if Path('.env').exists():
|
|
56
|
+
load_dotenv()
|
|
57
|
+
except ImportError:
|
|
58
|
+
pass
|
|
59
|
+
from aws.ec2 import list_tags as ec2_list_tags
|
|
60
|
+
from aws.ec2 import tag_check as ec2_tag_check
|
|
61
|
+
from aws.ec2 import info as ec2_info
|
|
62
|
+
from aws.lb import list_tags as lb_list_tags
|
|
63
|
+
from aws.lb import tag_check as lb_tag_check
|
|
64
|
+
from aws.vpc import tag_check as vpc_tag_check
|
|
65
|
+
from aws.vpc import list_tags as vpc_list_tags
|
|
66
|
+
from aws.rds import list_tags as rds_list_tags
|
|
67
|
+
from aws.rds import tag_check as rds_tag_check
|
|
68
|
+
from aws.s3 import list_tags as s3_list_tags
|
|
69
|
+
from aws.s3 import tag_check as s3_tag_check
|
|
70
|
+
from aws.sg import info as sg_info
|
|
71
|
+
from aws.eks import info as eks_info
|
|
72
|
+
from aws.eks import nodes as eks_nodes
|
|
73
|
+
from aws.eks import pods as eks_pods
|
|
74
|
+
from aws.eks import fargate as eks_fargate
|
|
75
|
+
from aws.eks import addons as eks_addons
|
|
76
|
+
from aws.eks import update_config as eks_update_config
|
|
77
|
+
from aws.fargate import info as fargate_info
|
|
78
|
+
from aws.codepipeline import build as codepipeline_build
|
|
79
|
+
from aws.codepipeline import deploy as codepipeline_deploy
|
|
80
|
+
from aws.ecs import info as ecs_info
|
|
81
|
+
from aws.ecs import service as ecs_service
|
|
82
|
+
from aws.ecs import task as ecs_task
|
|
83
|
+
from aws.msk import info as msk_info
|
|
84
|
+
from aws.msk import broker as msk_broker
|
|
85
|
+
from cf.dns import list_info as dns_info
|
|
86
|
+
from oci_module.info import oci_info as oci_info # Deprecated. 통합 oci info
|
|
87
|
+
from oci_module.vm import add_arguments as vm_add_args, main as vm_main
|
|
88
|
+
from oci_module.lb import add_arguments as lb_add_args, main as lb_main
|
|
89
|
+
from oci_module.nsg import add_arguments as nsg_add_args, main as nsg_main
|
|
90
|
+
from oci_module.volume import add_arguments as volume_add_args, main as volume_main
|
|
91
|
+
from oci_module.policy import add_arguments as policy_add_args, main as policy_main
|
|
92
|
+
from oci_module.policy import search as oci_policy_search
|
|
93
|
+
from oci_module.obj import add_arguments as obj_add_args, main as obj_main
|
|
94
|
+
from oci_module.cost import usage_add_arguments as cost_usage_add_args, usage_main as cost_usage_main
|
|
95
|
+
from oci_module.cost import credit_add_arguments as cost_credit_add_args, credit_main as cost_credit_main
|
|
96
|
+
from oci_module.vcn import info as vcn_info
|
|
97
|
+
from ssh import auto_ssh, server_info
|
|
98
|
+
import concurrent.futures
|
|
99
|
+
from threading import Lock
|
|
100
|
+
|
|
101
|
+
load_dotenv()
|
|
102
|
+
|
|
103
|
+
# Global lock for thread-safe output formatting
|
|
104
|
+
output_lock = Lock()
|
|
105
|
+
|
|
106
|
+
def oci_info_deprecated(args):
|
|
107
|
+
from rich.console import Console
|
|
108
|
+
console = Console()
|
|
109
|
+
console.print("\n[bold yellow]⚠️ 'ic oci info' 명령어는 더 이상 사용되지 않습니다.[/bold yellow]")
|
|
110
|
+
console.print("대신 각 서비스별 `info` 명령어를 사용해주세요. 예시:\n")
|
|
111
|
+
console.print(" - `ic oci vm info`")
|
|
112
|
+
console.print(" - `ic oci lb info`")
|
|
113
|
+
console.print(" - `ic oci nsg info`")
|
|
114
|
+
console.print(" - `ic oci volume info`")
|
|
115
|
+
console.print(" - `ic oci obj info`")
|
|
116
|
+
console.print(" - `ic oci policy info`\n")
|
|
117
|
+
console.print(" - 여러 서비스 : `ic oci vm,lb,nsg,volume,obj,policy info`\n")
|
|
118
|
+
console.print("전체 OCI 명령어는 `ic oci --help`로 확인하실 수 있습니다.")
|
|
119
|
+
|
|
120
|
+
def execute_gcp_multi_service(services, command_and_options, parser):
|
|
121
|
+
"""GCP 다중 서비스 명령을 병렬로 실행합니다."""
|
|
122
|
+
from rich.console import Console
|
|
123
|
+
console = Console()
|
|
124
|
+
|
|
125
|
+
def execute_service(service):
|
|
126
|
+
"""단일 GCP 서비스를 실행하고 결과를 반환합니다."""
|
|
127
|
+
try:
|
|
128
|
+
current_argv = ['gcp', service] + command_and_options
|
|
129
|
+
args = parser.parse_args(current_argv)
|
|
130
|
+
|
|
131
|
+
# Capture output for thread-safe display
|
|
132
|
+
import io
|
|
133
|
+
import contextlib
|
|
134
|
+
|
|
135
|
+
output_buffer = io.StringIO()
|
|
136
|
+
with contextlib.redirect_stdout(output_buffer):
|
|
137
|
+
execute_single_command(args)
|
|
138
|
+
|
|
139
|
+
return {
|
|
140
|
+
'service': service,
|
|
141
|
+
'success': True,
|
|
142
|
+
'output': output_buffer.getvalue(),
|
|
143
|
+
'error': None
|
|
144
|
+
}
|
|
145
|
+
except SystemExit as e:
|
|
146
|
+
# SystemExit with code 0 is normal (e.g., help command)
|
|
147
|
+
if e.code == 0:
|
|
148
|
+
return {
|
|
149
|
+
'service': service,
|
|
150
|
+
'success': True,
|
|
151
|
+
'output': output_buffer.getvalue(),
|
|
152
|
+
'error': None
|
|
153
|
+
}
|
|
154
|
+
else:
|
|
155
|
+
return {
|
|
156
|
+
'service': service,
|
|
157
|
+
'success': False,
|
|
158
|
+
'output': '',
|
|
159
|
+
'error': f"Command failed with exit code: {e.code}"
|
|
160
|
+
}
|
|
161
|
+
except Exception as e:
|
|
162
|
+
return {
|
|
163
|
+
'service': service,
|
|
164
|
+
'success': False,
|
|
165
|
+
'output': '',
|
|
166
|
+
'error': str(e)
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
# Execute services in parallel
|
|
170
|
+
console.print(f"\n[bold cyan]Executing GCP services in parallel: {', '.join(services)}[/bold cyan]")
|
|
171
|
+
|
|
172
|
+
with concurrent.futures.ThreadPoolExecutor(max_workers=min(len(services), 5)) as executor:
|
|
173
|
+
future_to_service = {executor.submit(execute_service, service): service for service in services}
|
|
174
|
+
results = []
|
|
175
|
+
|
|
176
|
+
for future in concurrent.futures.as_completed(future_to_service):
|
|
177
|
+
result = future.result()
|
|
178
|
+
results.append(result)
|
|
179
|
+
|
|
180
|
+
# Sort results by original service order
|
|
181
|
+
service_order = {service: i for i, service in enumerate(services)}
|
|
182
|
+
results.sort(key=lambda x: service_order[x['service']])
|
|
183
|
+
|
|
184
|
+
# Display results with thread-safe output
|
|
185
|
+
with output_lock:
|
|
186
|
+
has_error = False
|
|
187
|
+
for result in results:
|
|
188
|
+
service = result['service']
|
|
189
|
+
if result['success']:
|
|
190
|
+
console.print(f"\n[bold green]✓ GCP {service.upper()} Results:[/bold green]")
|
|
191
|
+
if result['output'].strip():
|
|
192
|
+
print(result['output'])
|
|
193
|
+
else:
|
|
194
|
+
console.print(f"[dim]No output from {service} service[/dim]")
|
|
195
|
+
else:
|
|
196
|
+
console.print(f"\n[bold red]✗ GCP {service.upper()} Failed:[/bold red]")
|
|
197
|
+
console.print(f"[red]Error: {result['error']}[/red]")
|
|
198
|
+
has_error = True
|
|
199
|
+
|
|
200
|
+
if has_error:
|
|
201
|
+
console.print(f"\n[bold yellow]⚠️ Some GCP services failed. Check individual service configurations.[/bold yellow]")
|
|
202
|
+
sys.exit(1)
|
|
203
|
+
else:
|
|
204
|
+
console.print(f"\n[bold green]✓ All GCP services completed successfully[/bold green]")
|
|
205
|
+
|
|
206
|
+
def gcp_monitor_performance_command(args):
|
|
207
|
+
"""GCP 성능 메트릭을 표시하는 명령어"""
|
|
208
|
+
try:
|
|
209
|
+
from common.gcp_monitoring import log_gcp_performance_summary
|
|
210
|
+
log_gcp_performance_summary()
|
|
211
|
+
except ImportError:
|
|
212
|
+
from rich.console import Console
|
|
213
|
+
console = Console()
|
|
214
|
+
console.print("[bold red]GCP monitoring module not available[/bold red]")
|
|
215
|
+
|
|
216
|
+
def gcp_monitor_health_command(args):
|
|
217
|
+
"""GCP 서비스 헬스 상태를 표시하는 명령어"""
|
|
218
|
+
try:
|
|
219
|
+
from common.gcp_monitoring import gcp_monitor
|
|
220
|
+
from rich.console import Console
|
|
221
|
+
from rich.panel import Panel
|
|
222
|
+
|
|
223
|
+
console = Console()
|
|
224
|
+
health_status = gcp_monitor.get_health_status()
|
|
225
|
+
|
|
226
|
+
health_text = f"MCP Connected: {'✓' if health_status['mcp_connected'] else '✗'}\n"
|
|
227
|
+
health_text += f"Uptime: {health_status['uptime_minutes']:.1f} minutes\n"
|
|
228
|
+
health_text += f"Total API Calls: {health_status['total_api_calls']}\n"
|
|
229
|
+
|
|
230
|
+
if health_status['service_health']:
|
|
231
|
+
health_text += "\nService Health:\n"
|
|
232
|
+
for service, is_healthy in health_status['service_health'].items():
|
|
233
|
+
status = '✓' if is_healthy else '✗'
|
|
234
|
+
health_text += f" {service}: {status}\n"
|
|
235
|
+
else:
|
|
236
|
+
health_text += "\nNo service health data available"
|
|
237
|
+
|
|
238
|
+
console.print(Panel(
|
|
239
|
+
health_text,
|
|
240
|
+
title="GCP System Health",
|
|
241
|
+
border_style="green" if health_status['mcp_connected'] else "yellow"
|
|
242
|
+
))
|
|
243
|
+
|
|
244
|
+
except ImportError:
|
|
245
|
+
from rich.console import Console
|
|
246
|
+
console = Console()
|
|
247
|
+
console.print("[bold red]GCP monitoring module not available[/bold red]")
|
|
248
|
+
|
|
249
|
+
def main():
|
|
250
|
+
"""IC CLI 엔트리 포인트"""
|
|
251
|
+
# Initialize configuration system early
|
|
252
|
+
try:
|
|
253
|
+
config_manager = get_config_manager()
|
|
254
|
+
except Exception as e:
|
|
255
|
+
print(f"Warning: Failed to initialize configuration system: {e}")
|
|
256
|
+
print("Falling back to legacy configuration...")
|
|
257
|
+
|
|
258
|
+
parser = argparse.ArgumentParser(
|
|
259
|
+
description="Infra CLI: Platform Resource CLI Tool",
|
|
260
|
+
usage="ic <platform|config> <service> <command> [options]"
|
|
261
|
+
)
|
|
262
|
+
platform_subparsers = parser.add_subparsers(
|
|
263
|
+
dest="platform",
|
|
264
|
+
required=True,
|
|
265
|
+
help="클라우드 플랫폼 (aws, oci, cf, ssh, azure, gcp) 또는 config 관리"
|
|
266
|
+
)
|
|
267
|
+
|
|
268
|
+
# Add config commands
|
|
269
|
+
from .commands.config import ConfigCommands
|
|
270
|
+
config_commands = ConfigCommands()
|
|
271
|
+
config_commands.add_subparsers(platform_subparsers)
|
|
272
|
+
|
|
273
|
+
aws_parser = platform_subparsers.add_parser("aws", help="AWS 관련 명령어")
|
|
274
|
+
oci_parser = platform_subparsers.add_parser("oci", help="OCI 관련 명령어")
|
|
275
|
+
azure_parser = platform_subparsers.add_parser("azure", help="Azure 관련 명령어")
|
|
276
|
+
gcp_parser = platform_subparsers.add_parser("gcp", help="GCP 관련 명령어")
|
|
277
|
+
cf_parser = platform_subparsers.add_parser("cf", help="CloudFlare 관련 명령어")
|
|
278
|
+
ssh_parser = platform_subparsers.add_parser("ssh", help="SSH 관련 명령어")
|
|
279
|
+
|
|
280
|
+
aws_subparsers = aws_parser.add_subparsers(dest="service",required=True,help="AWS 리소스 관리 서비스")
|
|
281
|
+
oci_subparsers = oci_parser.add_subparsers(dest="service",required=True,help="OCI 리소스 관리 서비스")
|
|
282
|
+
azure_subparsers = azure_parser.add_subparsers(dest="service", required=True, help="Azure 리소스 관리 서비스")
|
|
283
|
+
gcp_subparsers = gcp_parser.add_subparsers(dest="service", required=True, help="GCP 리소스 관리 서비스")
|
|
284
|
+
cf_subparsers = cf_parser.add_subparsers(dest="service",required=True,help="CloudFlare 리소스 관리 서비스")
|
|
285
|
+
ssh_subparsers = ssh_parser.add_subparsers(dest="service",required=True,help="SSH 관리 서비스")
|
|
286
|
+
|
|
287
|
+
# ---------------- AWS ----------------
|
|
288
|
+
ec2_parser = aws_subparsers.add_parser("ec2", help="EC2 관련 명령어")
|
|
289
|
+
ec2_subparsers = ec2_parser.add_subparsers(dest="command", required=True)
|
|
290
|
+
ec2_list_tags_parser = ec2_subparsers.add_parser("list_tags", help="EC2 인스턴스 태그 나열")
|
|
291
|
+
ec2_list_tags.add_arguments(ec2_list_tags_parser)
|
|
292
|
+
ec2_list_tags_parser.set_defaults(func=ec2_list_tags.main)
|
|
293
|
+
ec2_tag_check_parser = ec2_subparsers.add_parser("tag_check", help="EC2 태그 유효성 검사")
|
|
294
|
+
ec2_tag_check.add_arguments(ec2_tag_check_parser)
|
|
295
|
+
ec2_tag_check_parser.set_defaults(func=ec2_tag_check.main)
|
|
296
|
+
ec2_info_parser = ec2_subparsers.add_parser("info", help="EC2 인스턴스 정보 나열")
|
|
297
|
+
ec2_info.add_arguments(ec2_info_parser)
|
|
298
|
+
ec2_info_parser.set_defaults(func=ec2_info.main)
|
|
299
|
+
|
|
300
|
+
lb_parser = aws_subparsers.add_parser("lb", help="LB 관련 명령어")
|
|
301
|
+
lb_subparsers = lb_parser.add_subparsers(dest="command", required=True)
|
|
302
|
+
lb_list_parser = lb_subparsers.add_parser("list_tags", help="LB 태그 조회")
|
|
303
|
+
lb_list_tags.add_arguments(lb_list_parser)
|
|
304
|
+
lb_list_parser.set_defaults(func=lb_list_tags.main)
|
|
305
|
+
lb_check_parser = lb_subparsers.add_parser("tag_check", help="LB 태그 유효성 검사")
|
|
306
|
+
lb_tag_check.add_arguments(lb_check_parser)
|
|
307
|
+
lb_check_parser.set_defaults(func=lb_tag_check.main)
|
|
308
|
+
|
|
309
|
+
lb_info_parser = lb_subparsers.add_parser("info", help="LB 상세 정보 조회")
|
|
310
|
+
from aws.lb import info as lb_info
|
|
311
|
+
lb_info.add_arguments(lb_info_parser)
|
|
312
|
+
lb_info_parser.set_defaults(func=lb_info.main)
|
|
313
|
+
|
|
314
|
+
vpc_parser = aws_subparsers.add_parser("vpc", help="VPC + Gateway + VPN 관련 명령어")
|
|
315
|
+
vpc_subparsers = vpc_parser.add_subparsers(dest="command", required=True)
|
|
316
|
+
vpc_check_parser = vpc_subparsers.add_parser("tag_check", help="VPC + Gateway + VPN 태그 유효성 검사")
|
|
317
|
+
vpc_tag_check.add_arguments(vpc_check_parser)
|
|
318
|
+
vpc_check_parser.set_defaults(func=vpc_tag_check.main)
|
|
319
|
+
vpc_list_parser = vpc_subparsers.add_parser("list_tags", help="VPC + Gateway + VPN 태그 조회")
|
|
320
|
+
vpc_tag_check.add_arguments(vpc_list_parser)
|
|
321
|
+
vpc_list_parser.set_defaults(func=vpc_list_tags.main)
|
|
322
|
+
|
|
323
|
+
vpc_info_parser = vpc_subparsers.add_parser("info", help="VPC 상세 정보 조회")
|
|
324
|
+
from aws.vpc import info as vpc_info
|
|
325
|
+
vpc_info.add_arguments(vpc_info_parser)
|
|
326
|
+
vpc_info_parser.set_defaults(func=vpc_info.main)
|
|
327
|
+
|
|
328
|
+
vpn_parser = aws_subparsers.add_parser("vpn", help="TGW, VGW, VPN Connection, Endpoint 관련 명령어")
|
|
329
|
+
vpn_subparsers = vpn_parser.add_subparsers(dest="command", required=True)
|
|
330
|
+
vpn_info_parser = vpn_subparsers.add_parser("info", help="VPN 관련 상세 정보 조회")
|
|
331
|
+
from aws.vpn import info as vpn_info
|
|
332
|
+
vpn_info.add_arguments(vpn_info_parser)
|
|
333
|
+
vpn_info_parser.set_defaults(func=vpn_info.main)
|
|
334
|
+
|
|
335
|
+
|
|
336
|
+
rds_parser = aws_subparsers.add_parser("rds", help="RDS 관련 명령어")
|
|
337
|
+
rds_subparsers = rds_parser.add_subparsers(dest="command", required=True)
|
|
338
|
+
rds_list_cmd = rds_subparsers.add_parser("list_tags", help="RDS 태그 조회")
|
|
339
|
+
rds_list_tags.add_arguments(rds_list_cmd)
|
|
340
|
+
rds_list_cmd.set_defaults(func=rds_list_tags.main)
|
|
341
|
+
rds_check_cmd = rds_subparsers.add_parser("tag_check", help="RDS 태그 유효성 검사")
|
|
342
|
+
rds_tag_check.add_arguments(rds_check_cmd)
|
|
343
|
+
rds_check_cmd.set_defaults(func=rds_tag_check.main)
|
|
344
|
+
|
|
345
|
+
rds_info_parser = rds_subparsers.add_parser("info", help="RDS 상세 정보 조회")
|
|
346
|
+
from aws.rds import info as rds_info
|
|
347
|
+
rds_info.add_arguments(rds_info_parser)
|
|
348
|
+
rds_info_parser.set_defaults(func=rds_info.main)
|
|
349
|
+
|
|
350
|
+
s3_parser = aws_subparsers.add_parser("s3", help="S3 관련 명령어")
|
|
351
|
+
s3_subparsers = s3_parser.add_subparsers(dest="command", required=True)
|
|
352
|
+
s3_list_cmd = s3_subparsers.add_parser("list_tags", help="S3 버킷 태그 조회")
|
|
353
|
+
s3_list_tags.add_arguments(s3_list_cmd)
|
|
354
|
+
s3_list_cmd.set_defaults(func=s3_list_tags.main)
|
|
355
|
+
s3_check_cmd = s3_subparsers.add_parser("tag_check", help="S3 태그 유효성 검사")
|
|
356
|
+
s3_tag_check.add_arguments(s3_check_cmd)
|
|
357
|
+
s3_check_cmd.set_defaults(func=s3_tag_check.main)
|
|
358
|
+
|
|
359
|
+
s3_info_parser = s3_subparsers.add_parser("info", help="S3 상세 정보 조회")
|
|
360
|
+
from aws.s3 import info as s3_info
|
|
361
|
+
s3_info.add_arguments(s3_info_parser)
|
|
362
|
+
s3_info_parser.set_defaults(func=s3_info.main)
|
|
363
|
+
|
|
364
|
+
sg_parser = aws_subparsers.add_parser("sg", help="Security Group 관련 명령어")
|
|
365
|
+
sg_subparsers = sg_parser.add_subparsers(dest="command", required=True)
|
|
366
|
+
sg_info_parser = sg_subparsers.add_parser("info", help="Security Group 상세 정보 조회")
|
|
367
|
+
sg_info.add_arguments(sg_info_parser)
|
|
368
|
+
sg_info_parser.set_defaults(func=sg_info.main)
|
|
369
|
+
|
|
370
|
+
# EKS 관련 명령어
|
|
371
|
+
eks_parser = aws_subparsers.add_parser("eks", help="EKS 관련 명령어")
|
|
372
|
+
eks_subparsers = eks_parser.add_subparsers(dest="command", required=True)
|
|
373
|
+
|
|
374
|
+
eks_info_parser = eks_subparsers.add_parser("info", help="EKS 클러스터 정보 조회")
|
|
375
|
+
eks_info.add_arguments(eks_info_parser)
|
|
376
|
+
eks_info_parser.set_defaults(func=eks_info.main)
|
|
377
|
+
|
|
378
|
+
eks_nodes_parser = eks_subparsers.add_parser("nodes", help="EKS 노드 정보 조회")
|
|
379
|
+
eks_nodes.add_arguments(eks_nodes_parser)
|
|
380
|
+
eks_nodes_parser.set_defaults(func=eks_nodes.main)
|
|
381
|
+
|
|
382
|
+
eks_pods_parser = eks_subparsers.add_parser("pods", help="EKS 파드 정보 조회")
|
|
383
|
+
eks_pods.add_arguments(eks_pods_parser)
|
|
384
|
+
eks_pods_parser.set_defaults(func=eks_pods.main)
|
|
385
|
+
|
|
386
|
+
eks_fargate_parser = eks_subparsers.add_parser("fargate", help="EKS Fargate 프로파일 정보 조회")
|
|
387
|
+
eks_fargate.add_arguments(eks_fargate_parser)
|
|
388
|
+
eks_fargate_parser.set_defaults(func=eks_fargate.main)
|
|
389
|
+
|
|
390
|
+
eks_addons_parser = eks_subparsers.add_parser("addons", help="EKS 애드온 정보 조회")
|
|
391
|
+
eks_addons.add_arguments(eks_addons_parser)
|
|
392
|
+
eks_addons_parser.set_defaults(func=eks_addons.main)
|
|
393
|
+
|
|
394
|
+
eks_update_config_parser = eks_subparsers.add_parser("update-config", help="EKS kubeconfig 업데이트")
|
|
395
|
+
eks_update_config.add_arguments(eks_update_config_parser)
|
|
396
|
+
eks_update_config_parser.set_defaults(func=eks_update_config.main)
|
|
397
|
+
|
|
398
|
+
# Fargate 관련 명령어 (DEPRECATED - EKS로 완전 통합됨)
|
|
399
|
+
def fargate_deprecated_handler(args):
|
|
400
|
+
from rich.console import Console
|
|
401
|
+
console = Console()
|
|
402
|
+
console.print("\n[bold red]⚠️ 'ic aws fargate' 명령어는 더 이상 사용되지 않습니다.[/bold red]")
|
|
403
|
+
console.print("EKS Fargate 기능이 EKS 서비스로 완전히 통합되었습니다.\n")
|
|
404
|
+
console.print("[bold yellow]새로운 명령어를 사용해주세요:[/bold yellow]")
|
|
405
|
+
console.print(" • EKS Fargate 프로파일: [bold cyan]ic aws eks fargate[/bold cyan]")
|
|
406
|
+
console.print(" • EKS 파드 정보: [bold cyan]ic aws eks pods[/bold cyan]")
|
|
407
|
+
console.print(" • EKS 전체 정보: [bold cyan]ic aws eks --help[/bold cyan]\n")
|
|
408
|
+
console.print("ECS Fargate는 [bold cyan]ic aws ecs task[/bold cyan] 명령어를 사용하세요.")
|
|
409
|
+
return
|
|
410
|
+
|
|
411
|
+
fargate_parser = aws_subparsers.add_parser("fargate", help="[DEPRECATED] Fargate 관련 명령어 - 'ic aws eks' 사용 권장")
|
|
412
|
+
fargate_subparsers = fargate_parser.add_subparsers(dest="command", required=False)
|
|
413
|
+
fargate_parser.set_defaults(func=fargate_deprecated_handler)
|
|
414
|
+
|
|
415
|
+
# CodePipeline 관련 명령어 (code 서비스 하위)
|
|
416
|
+
code_parser = aws_subparsers.add_parser("code", help="CodePipeline 관련 명령어")
|
|
417
|
+
code_subparsers = code_parser.add_subparsers(dest="command", required=True)
|
|
418
|
+
|
|
419
|
+
code_build_parser = code_subparsers.add_parser("build", help="CodePipeline 빌드 스테이지 상태 조회")
|
|
420
|
+
codepipeline_build.add_arguments(code_build_parser)
|
|
421
|
+
code_build_parser.set_defaults(func=codepipeline_build.main)
|
|
422
|
+
|
|
423
|
+
code_deploy_parser = code_subparsers.add_parser("deploy", help="CodePipeline 배포 스테이지 상태 조회")
|
|
424
|
+
codepipeline_deploy.add_arguments(code_deploy_parser)
|
|
425
|
+
code_deploy_parser.set_defaults(func=codepipeline_deploy.main)
|
|
426
|
+
|
|
427
|
+
# ECS 관련 명령어
|
|
428
|
+
ecs_parser = aws_subparsers.add_parser("ecs", help="ECS 관련 명령어")
|
|
429
|
+
ecs_subparsers = ecs_parser.add_subparsers(dest="command", required=True)
|
|
430
|
+
|
|
431
|
+
ecs_info_parser = ecs_subparsers.add_parser("info", help="ECS 클러스터 정보 조회")
|
|
432
|
+
ecs_info.add_arguments(ecs_info_parser)
|
|
433
|
+
ecs_info_parser.set_defaults(func=ecs_info.main)
|
|
434
|
+
|
|
435
|
+
ecs_service_parser = ecs_subparsers.add_parser("service", help="ECS 서비스 정보 조회")
|
|
436
|
+
ecs_service.add_arguments(ecs_service_parser)
|
|
437
|
+
ecs_service_parser.set_defaults(func=ecs_service.main)
|
|
438
|
+
|
|
439
|
+
ecs_task_parser = ecs_subparsers.add_parser("task", help="ECS 태스크 정보 조회")
|
|
440
|
+
ecs_task.add_arguments(ecs_task_parser)
|
|
441
|
+
ecs_task_parser.set_defaults(func=ecs_task.main)
|
|
442
|
+
|
|
443
|
+
# MSK 관련 명령어
|
|
444
|
+
msk_parser = aws_subparsers.add_parser("msk", help="MSK (Managed Streaming for Apache Kafka) 관련 명령어")
|
|
445
|
+
msk_subparsers = msk_parser.add_subparsers(dest="command", required=True)
|
|
446
|
+
|
|
447
|
+
msk_info_parser = msk_subparsers.add_parser("info", help="MSK 클러스터 정보 조회")
|
|
448
|
+
msk_info.add_arguments(msk_info_parser)
|
|
449
|
+
msk_info_parser.set_defaults(func=msk_info.main)
|
|
450
|
+
|
|
451
|
+
msk_broker_parser = msk_subparsers.add_parser("broker", help="MSK 브로커 엔드포인트 정보 조회")
|
|
452
|
+
msk_broker.add_arguments(msk_broker_parser)
|
|
453
|
+
msk_broker_parser.set_defaults(func=msk_broker.main)
|
|
454
|
+
|
|
455
|
+
# ---------------- Azure ----------------
|
|
456
|
+
# Azure VM 관련 명령어
|
|
457
|
+
azure_vm_parser = azure_subparsers.add_parser("vm", help="Azure Virtual Machine 관련 명령어")
|
|
458
|
+
azure_vm_subparsers = azure_vm_parser.add_subparsers(dest="command", required=True)
|
|
459
|
+
azure_vm_info_parser = azure_vm_subparsers.add_parser("info", help="Azure VM 정보 조회")
|
|
460
|
+
try:
|
|
461
|
+
from azure_module.vm import info as azure_vm_info
|
|
462
|
+
azure_vm_info.add_arguments(azure_vm_info_parser)
|
|
463
|
+
azure_vm_info_parser.set_defaults(func=azure_vm_info.main)
|
|
464
|
+
except ImportError:
|
|
465
|
+
azure_vm_info_parser.set_defaults(func=lambda args: print("Azure 모듈이 설치되지 않았습니다. pip install azure-mgmt-compute를 실행하세요."))
|
|
466
|
+
|
|
467
|
+
# Azure VNet 관련 명령어
|
|
468
|
+
azure_vnet_parser = azure_subparsers.add_parser("vnet", help="Azure Virtual Network 관련 명령어")
|
|
469
|
+
azure_vnet_subparsers = azure_vnet_parser.add_subparsers(dest="command", required=True)
|
|
470
|
+
azure_vnet_info_parser = azure_vnet_subparsers.add_parser("info", help="Azure VNet 정보 조회")
|
|
471
|
+
try:
|
|
472
|
+
from azure_module.vnet import info as azure_vnet_info
|
|
473
|
+
azure_vnet_info.add_arguments(azure_vnet_info_parser)
|
|
474
|
+
azure_vnet_info_parser.set_defaults(func=azure_vnet_info.main)
|
|
475
|
+
except ImportError:
|
|
476
|
+
azure_vnet_info_parser.set_defaults(func=lambda args: print("Azure 모듈이 설치되지 않았습니다."))
|
|
477
|
+
|
|
478
|
+
# Azure AKS 관련 명령어
|
|
479
|
+
azure_aks_parser = azure_subparsers.add_parser("aks", help="Azure Kubernetes Service 관련 명령어")
|
|
480
|
+
azure_aks_subparsers = azure_aks_parser.add_subparsers(dest="command", required=True)
|
|
481
|
+
azure_aks_info_parser = azure_aks_subparsers.add_parser("info", help="Azure AKS 클러스터 정보 조회")
|
|
482
|
+
try:
|
|
483
|
+
from azure_module.aks import info as azure_aks_info
|
|
484
|
+
azure_aks_info.add_arguments(azure_aks_info_parser)
|
|
485
|
+
azure_aks_info_parser.set_defaults(func=azure_aks_info.main)
|
|
486
|
+
except ImportError:
|
|
487
|
+
azure_aks_info_parser.set_defaults(func=lambda args: print("Azure 모듈이 설치되지 않았습니다."))
|
|
488
|
+
|
|
489
|
+
# Azure Storage 관련 명령어
|
|
490
|
+
azure_storage_parser = azure_subparsers.add_parser("storage", help="Azure Storage Account 관련 명령어")
|
|
491
|
+
azure_storage_subparsers = azure_storage_parser.add_subparsers(dest="command", required=True)
|
|
492
|
+
azure_storage_info_parser = azure_storage_subparsers.add_parser("info", help="Azure Storage Account 정보 조회")
|
|
493
|
+
try:
|
|
494
|
+
from azure_module.storage import info as azure_storage_info
|
|
495
|
+
azure_storage_info.add_arguments(azure_storage_info_parser)
|
|
496
|
+
azure_storage_info_parser.set_defaults(func=azure_storage_info.main)
|
|
497
|
+
except ImportError:
|
|
498
|
+
azure_storage_info_parser.set_defaults(func=lambda args: print("Azure 모듈이 설치되지 않았습니다."))
|
|
499
|
+
|
|
500
|
+
# Azure NSG 관련 명령어
|
|
501
|
+
azure_nsg_parser = azure_subparsers.add_parser("nsg", help="Azure Network Security Group 관련 명령어")
|
|
502
|
+
azure_nsg_subparsers = azure_nsg_parser.add_subparsers(dest="command", required=True)
|
|
503
|
+
azure_nsg_info_parser = azure_nsg_subparsers.add_parser("info", help="Azure NSG 정보 조회")
|
|
504
|
+
try:
|
|
505
|
+
from azure_module.nsg import info as azure_nsg_info
|
|
506
|
+
azure_nsg_info.add_arguments(azure_nsg_info_parser)
|
|
507
|
+
azure_nsg_info_parser.set_defaults(func=azure_nsg_info.main)
|
|
508
|
+
except ImportError:
|
|
509
|
+
azure_nsg_info_parser.set_defaults(func=lambda args: print("Azure 모듈이 설치되지 않았습니다."))
|
|
510
|
+
|
|
511
|
+
# Azure Load Balancer 관련 명령어
|
|
512
|
+
azure_lb_parser = azure_subparsers.add_parser("lb", help="Azure Load Balancer 관련 명령어")
|
|
513
|
+
azure_lb_subparsers = azure_lb_parser.add_subparsers(dest="command", required=True)
|
|
514
|
+
azure_lb_info_parser = azure_lb_subparsers.add_parser("info", help="Azure Load Balancer 정보 조회")
|
|
515
|
+
try:
|
|
516
|
+
from azure_module.lb import info as azure_lb_info
|
|
517
|
+
azure_lb_info.add_arguments(azure_lb_info_parser)
|
|
518
|
+
azure_lb_info_parser.set_defaults(func=azure_lb_info.main)
|
|
519
|
+
except ImportError:
|
|
520
|
+
azure_lb_info_parser.set_defaults(func=lambda args: print("Azure 모듈이 설치되지 않았습니다."))
|
|
521
|
+
|
|
522
|
+
# Azure Container Instances 관련 명령어
|
|
523
|
+
azure_aci_parser = azure_subparsers.add_parser("aci", help="Azure Container Instances 관련 명령어")
|
|
524
|
+
azure_aci_subparsers = azure_aci_parser.add_subparsers(dest="command", required=True)
|
|
525
|
+
azure_aci_info_parser = azure_aci_subparsers.add_parser("info", help="Azure Container Instances 정보 조회")
|
|
526
|
+
try:
|
|
527
|
+
from azure_module.aci import info as azure_aci_info
|
|
528
|
+
azure_aci_info.add_arguments(azure_aci_info_parser)
|
|
529
|
+
azure_aci_info_parser.set_defaults(func=azure_aci_info.main)
|
|
530
|
+
except ImportError:
|
|
531
|
+
azure_aci_info_parser.set_defaults(func=lambda args: print("Azure 모듈이 설치되지 않았습니다."))
|
|
532
|
+
|
|
533
|
+
# ---------------- GCP ----------------
|
|
534
|
+
gcp_compute_parser = gcp_subparsers.add_parser("compute", help="GCP Compute Engine 관련 명령어")
|
|
535
|
+
gcp_compute_subparsers = gcp_compute_parser.add_subparsers(dest="command", required=True)
|
|
536
|
+
gcp_compute_info_parser = gcp_compute_subparsers.add_parser("info", help="GCP Compute Engine 정보 조회 (Mock)")
|
|
537
|
+
from gcp.compute import info as gcp_compute_info
|
|
538
|
+
gcp_compute_info.add_arguments(gcp_compute_info_parser)
|
|
539
|
+
gcp_compute_info_parser.set_defaults(func=gcp_compute_info.main)
|
|
540
|
+
|
|
541
|
+
gcp_vpc_parser = gcp_subparsers.add_parser("vpc", help="GCP VPC 관련 명령어")
|
|
542
|
+
gcp_vpc_subparsers = gcp_vpc_parser.add_subparsers(dest="command", required=True)
|
|
543
|
+
gcp_vpc_info_parser = gcp_vpc_subparsers.add_parser("info", help="GCP VPC 정보 조회 (Mock)")
|
|
544
|
+
from gcp.vpc import info as gcp_vpc_info
|
|
545
|
+
gcp_vpc_info.add_arguments(gcp_vpc_info_parser)
|
|
546
|
+
gcp_vpc_info_parser.set_defaults(func=gcp_vpc_info.main)
|
|
547
|
+
|
|
548
|
+
gcp_gke_parser = gcp_subparsers.add_parser("gke", help="GCP Google Kubernetes Engine 관련 명령어")
|
|
549
|
+
gcp_gke_subparsers = gcp_gke_parser.add_subparsers(dest="command", required=True)
|
|
550
|
+
gcp_gke_info_parser = gcp_gke_subparsers.add_parser("info", help="GCP GKE 클러스터 정보 조회")
|
|
551
|
+
from gcp.gke import info as gcp_gke_info
|
|
552
|
+
gcp_gke_info.add_arguments(gcp_gke_info_parser)
|
|
553
|
+
gcp_gke_info_parser.set_defaults(func=gcp_gke_info.main)
|
|
554
|
+
|
|
555
|
+
gcp_storage_parser = gcp_subparsers.add_parser("storage", help="GCP Cloud Storage 관련 명령어")
|
|
556
|
+
gcp_storage_subparsers = gcp_storage_parser.add_subparsers(dest="command", required=True)
|
|
557
|
+
gcp_storage_info_parser = gcp_storage_subparsers.add_parser("info", help="GCP Cloud Storage 버킷 정보 조회")
|
|
558
|
+
from gcp.storage import info as gcp_storage_info
|
|
559
|
+
gcp_storage_info.add_arguments(gcp_storage_info_parser)
|
|
560
|
+
gcp_storage_info_parser.set_defaults(func=gcp_storage_info.main)
|
|
561
|
+
|
|
562
|
+
gcp_sql_parser = gcp_subparsers.add_parser("sql", help="GCP Cloud SQL 관련 명령어")
|
|
563
|
+
gcp_sql_subparsers = gcp_sql_parser.add_subparsers(dest="command", required=True)
|
|
564
|
+
gcp_sql_info_parser = gcp_sql_subparsers.add_parser("info", help="GCP Cloud SQL 인스턴스 정보 조회")
|
|
565
|
+
from gcp.sql import info as gcp_sql_info
|
|
566
|
+
gcp_sql_info.add_arguments(gcp_sql_info_parser)
|
|
567
|
+
gcp_sql_info_parser.set_defaults(func=gcp_sql_info.main)
|
|
568
|
+
|
|
569
|
+
gcp_functions_parser = gcp_subparsers.add_parser("functions", help="GCP Cloud Functions 관련 명령어")
|
|
570
|
+
gcp_functions_subparsers = gcp_functions_parser.add_subparsers(dest="command", required=True)
|
|
571
|
+
gcp_functions_info_parser = gcp_functions_subparsers.add_parser("info", help="GCP Cloud Functions 정보 조회")
|
|
572
|
+
from gcp.functions import info as gcp_functions_info
|
|
573
|
+
gcp_functions_info.add_arguments(gcp_functions_info_parser)
|
|
574
|
+
gcp_functions_info_parser.set_defaults(func=gcp_functions_info.main)
|
|
575
|
+
|
|
576
|
+
gcp_run_parser = gcp_subparsers.add_parser("run", help="GCP Cloud Run 관련 명령어")
|
|
577
|
+
gcp_run_subparsers = gcp_run_parser.add_subparsers(dest="command", required=True)
|
|
578
|
+
gcp_run_info_parser = gcp_run_subparsers.add_parser("info", help="GCP Cloud Run 서비스 정보 조회")
|
|
579
|
+
from gcp.run import info as gcp_run_info
|
|
580
|
+
gcp_run_info.add_arguments(gcp_run_info_parser)
|
|
581
|
+
gcp_run_info_parser.set_defaults(func=gcp_run_info.main)
|
|
582
|
+
|
|
583
|
+
gcp_lb_parser = gcp_subparsers.add_parser("lb", help="GCP Load Balancing 관련 명령어")
|
|
584
|
+
gcp_lb_subparsers = gcp_lb_parser.add_subparsers(dest="command", required=True)
|
|
585
|
+
gcp_lb_info_parser = gcp_lb_subparsers.add_parser("info", help="GCP Load Balancer 정보 조회")
|
|
586
|
+
from gcp.lb import info as gcp_lb_info
|
|
587
|
+
gcp_lb_info.add_arguments(gcp_lb_info_parser)
|
|
588
|
+
gcp_lb_info_parser.set_defaults(func=gcp_lb_info.main)
|
|
589
|
+
|
|
590
|
+
gcp_firewall_parser = gcp_subparsers.add_parser("firewall", help="GCP 방화벽 규칙 관련 명령어")
|
|
591
|
+
gcp_firewall_subparsers = gcp_firewall_parser.add_subparsers(dest="command", required=True)
|
|
592
|
+
gcp_firewall_info_parser = gcp_firewall_subparsers.add_parser("info", help="GCP 방화벽 규칙 정보 조회")
|
|
593
|
+
from gcp.firewall import info as gcp_firewall_info
|
|
594
|
+
gcp_firewall_info.add_arguments(gcp_firewall_info_parser)
|
|
595
|
+
gcp_firewall_info_parser.set_defaults(func=gcp_firewall_info.main)
|
|
596
|
+
|
|
597
|
+
gcp_billing_parser = gcp_subparsers.add_parser("billing", help="GCP Billing 및 비용 관련 명령어")
|
|
598
|
+
gcp_billing_subparsers = gcp_billing_parser.add_subparsers(dest="command", required=True)
|
|
599
|
+
gcp_billing_info_parser = gcp_billing_subparsers.add_parser("info", help="GCP Billing 정보 및 비용 조회")
|
|
600
|
+
from gcp.billing import info as gcp_billing_info
|
|
601
|
+
gcp_billing_info.add_arguments(gcp_billing_info_parser)
|
|
602
|
+
gcp_billing_info_parser.set_defaults(func=gcp_billing_info.main)
|
|
603
|
+
|
|
604
|
+
# GCP 모니터링 및 성능 메트릭
|
|
605
|
+
gcp_monitor_parser = gcp_subparsers.add_parser("monitor", help="GCP 모니터링 및 성능 메트릭")
|
|
606
|
+
gcp_monitor_subparsers = gcp_monitor_parser.add_subparsers(dest="command", required=True)
|
|
607
|
+
gcp_monitor_perf_parser = gcp_monitor_subparsers.add_parser("performance", help="GCP 성능 메트릭 조회")
|
|
608
|
+
gcp_monitor_perf_parser.add_argument("--time-window", type=int, default=60,
|
|
609
|
+
help="메트릭 조회 시간 창 (분, 기본값: 60)")
|
|
610
|
+
gcp_monitor_perf_parser.set_defaults(func=gcp_monitor_performance_command)
|
|
611
|
+
|
|
612
|
+
gcp_monitor_health_parser = gcp_monitor_subparsers.add_parser("health", help="GCP 서비스 헬스 체크")
|
|
613
|
+
gcp_monitor_health_parser.set_defaults(func=gcp_monitor_health_command)
|
|
614
|
+
|
|
615
|
+
# ---------------- CloudFlare ----------------
|
|
616
|
+
cf_dns_parser = cf_subparsers.add_parser("dns", help="DNS Record 관련 명령어")
|
|
617
|
+
dns_subparsers = cf_dns_parser.add_subparsers(dest="command", required=True)
|
|
618
|
+
dns_info_cmd = dns_subparsers.add_parser("info", help="DNS Record 정보 조회")
|
|
619
|
+
dns_info.add_arguments(dns_info_cmd)
|
|
620
|
+
dns_info_cmd.set_defaults(func=dns_info.info)
|
|
621
|
+
|
|
622
|
+
# ---------------- SSH ----------------
|
|
623
|
+
ssh_info_parser = ssh_subparsers.add_parser("info", help="등록된 SSH 서버의 상세 정보(CPU/Mem/Disk)를 스캔합니다.")
|
|
624
|
+
ssh_info_parser.add_argument("--host", help="특정 호스트 문자열을 포함하는 서버만 필터링합니다.")
|
|
625
|
+
ssh_info_parser.add_argument("--key", help="사용할 특정 프라이빗 키 파일을 지정합니다. (config 파일 우선)")
|
|
626
|
+
ssh_info_parser.set_defaults(func=server_info.main)
|
|
627
|
+
|
|
628
|
+
ssh_reg_parser = ssh_subparsers.add_parser("reg", help="네트워크를 스캔하여 새로운 SSH 서버를 찾아 .ssh/config에 등록합니다.")
|
|
629
|
+
ssh_reg_parser.set_defaults(func=lambda args: auto_ssh.main())
|
|
630
|
+
|
|
631
|
+
# ---------------- OCI ----------------
|
|
632
|
+
oci_info_parser = oci_subparsers.add_parser("info", help="[DEPRECATED] OCI 리소스 통합 조회. 각 서비스별 명령어를 사용하세요.")
|
|
633
|
+
oci_info_parser.set_defaults(func=oci_info_deprecated)
|
|
634
|
+
|
|
635
|
+
# ---- new structured services ----
|
|
636
|
+
vm_parser = oci_subparsers.add_parser("vm", help="OCI VM(Instance) 관련")
|
|
637
|
+
vm_sub = vm_parser.add_subparsers(dest="command", required=True)
|
|
638
|
+
vm_info_p = vm_sub.add_parser("info", help="VM 정보 조회")
|
|
639
|
+
vm_add_args(vm_info_p)
|
|
640
|
+
vm_info_p.set_defaults(func=vm_main)
|
|
641
|
+
|
|
642
|
+
lb_parser = oci_subparsers.add_parser("lb", help="OCI LoadBalancer 관련")
|
|
643
|
+
lb_sub = lb_parser.add_subparsers(dest="command", required=True)
|
|
644
|
+
lb_info_p = lb_sub.add_parser("info", help="LB 정보 조회")
|
|
645
|
+
lb_add_args(lb_info_p)
|
|
646
|
+
lb_info_p.set_defaults(func=lb_main)
|
|
647
|
+
|
|
648
|
+
nsg_parser = oci_subparsers.add_parser("nsg", help="OCI NSG 관련")
|
|
649
|
+
nsg_sub = nsg_parser.add_subparsers(dest="command", required=True)
|
|
650
|
+
nsg_info_p = nsg_sub.add_parser("info", help="NSG 정보 조회")
|
|
651
|
+
nsg_add_args(nsg_info_p)
|
|
652
|
+
nsg_info_p.set_defaults(func=nsg_main)
|
|
653
|
+
|
|
654
|
+
vcn_parser = oci_subparsers.add_parser("vcn", help="OCI VCN 관련")
|
|
655
|
+
vcn_sub = vcn_parser.add_subparsers(dest="command", required=True)
|
|
656
|
+
vcn_info_p = vcn_sub.add_parser("info", help="VCN, Subnet, Route Table 정보 조회")
|
|
657
|
+
vcn_info.add_arguments(vcn_info_p)
|
|
658
|
+
vcn_info_p.set_defaults(func=vcn_info.main)
|
|
659
|
+
|
|
660
|
+
vol_parser = oci_subparsers.add_parser("volume", help="OCI Block/Boot Volume 관련")
|
|
661
|
+
vol_sub = vol_parser.add_subparsers(dest="command", required=True)
|
|
662
|
+
vol_info_p = vol_sub.add_parser("info", help="Volume 정보 조회")
|
|
663
|
+
volume_add_args(vol_info_p)
|
|
664
|
+
vol_info_p.set_defaults(func=volume_main)
|
|
665
|
+
|
|
666
|
+
obj_parser = oci_subparsers.add_parser("obj", help="OCI Object Storage 관련")
|
|
667
|
+
obj_sub = obj_parser.add_subparsers(dest="command", required=True)
|
|
668
|
+
obj_info_p = obj_sub.add_parser("info", help="Bucket 정보 조회")
|
|
669
|
+
obj_add_args(obj_info_p)
|
|
670
|
+
obj_info_p.set_defaults(func=obj_main)
|
|
671
|
+
|
|
672
|
+
pol_parser = oci_subparsers.add_parser("policy", help="OCI Policy 관련")
|
|
673
|
+
pol_sub = pol_parser.add_subparsers(dest="command", required=True)
|
|
674
|
+
pol_info_p = pol_sub.add_parser("info", help="Policy 목록/구문 조회")
|
|
675
|
+
policy_add_args(pol_info_p)
|
|
676
|
+
pol_info_p.set_defaults(func=policy_main)
|
|
677
|
+
pol_search_p = pol_sub.add_parser("search", help="Policy 구문 검색")
|
|
678
|
+
oci_policy_search.add_arguments(pol_search_p)
|
|
679
|
+
pol_search_p.set_defaults(func=oci_policy_search.main)
|
|
680
|
+
|
|
681
|
+
cost_parser = oci_subparsers.add_parser("cost", help="OCI 비용/크레딧 관련")
|
|
682
|
+
cost_sub = cost_parser.add_subparsers(dest="command", required=True)
|
|
683
|
+
cost_usage_p = cost_sub.add_parser("usage", help="비용 조회")
|
|
684
|
+
cost_usage_add_args(cost_usage_p)
|
|
685
|
+
cost_usage_p.set_defaults(func=cost_usage_main)
|
|
686
|
+
cost_credit_p = cost_sub.add_parser("credit", help="크레딧 사용 조회")
|
|
687
|
+
cost_credit_add_args(cost_credit_p)
|
|
688
|
+
cost_credit_p.set_defaults(func=cost_credit_main)
|
|
689
|
+
|
|
690
|
+
# 인수 처리
|
|
691
|
+
process_and_execute_commands(parser)
|
|
692
|
+
|
|
693
|
+
def process_and_execute_commands(parser):
|
|
694
|
+
"""명령행 인수를 파싱하고 각 서비스에 대해 명령을 실행합니다."""
|
|
695
|
+
if len(sys.argv) > 2 and sys.argv[1] == 'oci' and sys.argv[2] == 'info':
|
|
696
|
+
oci_info_deprecated(None)
|
|
697
|
+
sys.exit(0)
|
|
698
|
+
|
|
699
|
+
if len(sys.argv) > 2 and ',' in sys.argv[2]:
|
|
700
|
+
platform = sys.argv[1]
|
|
701
|
+
services = [s.strip() for s in sys.argv[2].split(',')]
|
|
702
|
+
command_and_options = sys.argv[3:]
|
|
703
|
+
|
|
704
|
+
# For GCP multi-service commands, use parallel execution
|
|
705
|
+
if platform == 'gcp':
|
|
706
|
+
execute_gcp_multi_service(services, command_and_options, parser)
|
|
707
|
+
else:
|
|
708
|
+
# Sequential execution for other platforms
|
|
709
|
+
has_error = False
|
|
710
|
+
for service in services:
|
|
711
|
+
print(f"--- Executing: ic {platform} {service} {' '.join(command_and_options)} ---")
|
|
712
|
+
current_argv = [platform, service] + command_and_options
|
|
713
|
+
try:
|
|
714
|
+
args = parser.parse_args(current_argv)
|
|
715
|
+
execute_single_command(args)
|
|
716
|
+
except SystemExit:
|
|
717
|
+
print(f"--- Skipping service '{service}' due to an error or invalid arguments ---")
|
|
718
|
+
has_error = True
|
|
719
|
+
except Exception as e:
|
|
720
|
+
log_error(f"Error processing service '{service}': {e}")
|
|
721
|
+
has_error = True
|
|
722
|
+
|
|
723
|
+
if has_error:
|
|
724
|
+
sys.exit(1)
|
|
725
|
+
|
|
726
|
+
else:
|
|
727
|
+
try:
|
|
728
|
+
args = parser.parse_args()
|
|
729
|
+
execute_single_command(args)
|
|
730
|
+
except SystemExit:
|
|
731
|
+
sys.exit(0)
|
|
732
|
+
except Exception as e:
|
|
733
|
+
log_error(f"명령어 실행 중 오류 발생: {e}")
|
|
734
|
+
sys.exit(1)
|
|
735
|
+
|
|
736
|
+
def execute_single_command(args):
|
|
737
|
+
"""파싱된 인수를 기반으로 실제 단일 명령을 실행합니다."""
|
|
738
|
+
if not hasattr(args, 'service') or not args.service:
|
|
739
|
+
return
|
|
740
|
+
|
|
741
|
+
if args.platform == "ssh" and args.service == "info":
|
|
742
|
+
args.command = "none"
|
|
743
|
+
elif args.platform == "oci" and args.service == "info":
|
|
744
|
+
args.command = "none"
|
|
745
|
+
|
|
746
|
+
log_args_short(args)
|
|
747
|
+
env_used = gather_env_for_command(args.platform, args.service, args.command)
|
|
748
|
+
if env_used:
|
|
749
|
+
log_env_short(env_used)
|
|
750
|
+
|
|
751
|
+
if hasattr(args, 'func'):
|
|
752
|
+
# Add consistent error handling for GCP services
|
|
753
|
+
if args.platform == 'gcp':
|
|
754
|
+
try:
|
|
755
|
+
args.func(args)
|
|
756
|
+
except ImportError as e:
|
|
757
|
+
log_error(f"GCP service '{args.service}' dependencies not available: {e}")
|
|
758
|
+
raise
|
|
759
|
+
except Exception as e:
|
|
760
|
+
log_error(f"GCP service '{args.service}' execution failed: {e}")
|
|
761
|
+
raise
|
|
762
|
+
else:
|
|
763
|
+
args.func(args)
|
|
764
|
+
else:
|
|
765
|
+
log_error(f"'{args.service}' 서비스에 대해 실행할 명령어가 지정되지 않았습니다. 'ic {args.platform} {args.service} --help'를 확인하세요.")
|
|
766
|
+
raise ValueError("No function to execute")
|
|
767
|
+
|
|
768
|
+
if __name__ == "__main__":
|
|
769
|
+
main()
|