ic-code 1.2.9__tar.gz → 1.3.1__tar.gz

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.
Files changed (256) hide show
  1. {ic_code-1.2.9/src/ic_code.egg-info → ic_code-1.3.1}/PKG-INFO +3 -2
  2. {ic_code-1.2.9 → ic_code-1.3.1}/README.md +2 -1
  3. {ic_code-1.2.9 → ic_code-1.3.1}/docs/cloudflare_configuration_example.md +1 -1
  4. {ic_code-1.2.9 → ic_code-1.3.1}/docs/user_guide.md +1 -1
  5. {ic_code-1.2.9 → ic_code-1.3.1}/pyproject.toml +1 -1
  6. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/__init__.py +1 -1
  7. ic_code-1.3.1/src/ic/platforms/aws/healthdashboard/__init__.py +1 -0
  8. ic_code-1.3.1/src/ic/platforms/aws/healthdashboard/reboot.py +350 -0
  9. {ic_code-1.2.9 → ic_code-1.3.1/src/ic_code.egg-info}/PKG-INFO +3 -2
  10. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic_code.egg-info/SOURCES.txt +2 -0
  11. {ic_code-1.2.9 → ic_code-1.3.1}/LICENSE +0 -0
  12. {ic_code-1.2.9 → ic_code-1.3.1}/MANIFEST.in +0 -0
  13. {ic_code-1.2.9 → ic_code-1.3.1}/SECURITY.md +0 -0
  14. {ic_code-1.2.9 → ic_code-1.3.1}/config/default.yaml +0 -0
  15. {ic_code-1.2.9 → ic_code-1.3.1}/docs/README.md +0 -0
  16. {ic_code-1.2.9 → ic_code-1.3.1}/docs/_templates/configuration.md +0 -0
  17. {ic_code-1.2.9 → ic_code-1.3.1}/docs/_templates/installation.md +0 -0
  18. {ic_code-1.2.9 → ic_code-1.3.1}/docs/_templates/troubleshooting.md +0 -0
  19. {ic_code-1.2.9 → ic_code-1.3.1}/docs/_templates/usage.md +0 -0
  20. {ic_code-1.2.9 → ic_code-1.3.1}/docs/aws/README.md +0 -0
  21. {ic_code-1.2.9 → ic_code-1.3.1}/docs/aws/aws_cli_prd.md +0 -0
  22. {ic_code-1.2.9 → ic_code-1.3.1}/docs/aws/installation.md +0 -0
  23. {ic_code-1.2.9 → ic_code-1.3.1}/docs/ci-workflow-guide.md +0 -0
  24. {ic_code-1.2.9 → ic_code-1.3.1}/docs/config_migration.md +0 -0
  25. {ic_code-1.2.9 → ic_code-1.3.1}/docs/deployment.md +0 -0
  26. {ic_code-1.2.9 → ic_code-1.3.1}/docs/development/README.md +0 -0
  27. {ic_code-1.2.9 → ic_code-1.3.1}/docs/development/cleanup_summary.md +0 -0
  28. {ic_code-1.2.9 → ic_code-1.3.1}/docs/development/development_guide.md +0 -0
  29. {ic_code-1.2.9 → ic_code-1.3.1}/docs/development/import_patterns.md +0 -0
  30. {ic_code-1.2.9 → ic_code-1.3.1}/docs/development/migration_guide.md +0 -0
  31. {ic_code-1.2.9 → ic_code-1.3.1}/docs/gcp/GCP_CONFIGURATION_GUIDE.md +0 -0
  32. {ic_code-1.2.9 → ic_code-1.3.1}/docs/gcp/GCP_SECURITY_BEST_PRACTICES.md +0 -0
  33. {ic_code-1.2.9 → ic_code-1.3.1}/docs/gcp/README.md +0 -0
  34. {ic_code-1.2.9 → ic_code-1.3.1}/docs/general/configuration.md +0 -0
  35. {ic_code-1.2.9 → ic_code-1.3.1}/docs/installation.md +0 -0
  36. {ic_code-1.2.9 → ic_code-1.3.1}/docs/migration.md +0 -0
  37. {ic_code-1.2.9 → ic_code-1.3.1}/docs/migration_guide.md +0 -0
  38. {ic_code-1.2.9 → ic_code-1.3.1}/docs/oci/README.md +0 -0
  39. {ic_code-1.2.9 → ic_code-1.3.1}/docs/oci/installation.md +0 -0
  40. {ic_code-1.2.9 → ic_code-1.3.1}/docs/release-guide.md +0 -0
  41. {ic_code-1.2.9 → ic_code-1.3.1}/docs/security.md +0 -0
  42. {ic_code-1.2.9 → ic_code-1.3.1}/docs/ssh/configuration.md +0 -0
  43. {ic_code-1.2.9 → ic_code-1.3.1}/docs/troubleshooting.md +0 -0
  44. {ic_code-1.2.9 → ic_code-1.3.1}/requirements.txt +0 -0
  45. {ic_code-1.2.9 → ic_code-1.3.1}/scripts/analysis_summary.py +0 -0
  46. {ic_code-1.2.9 → ic_code-1.3.1}/scripts/bump-version.sh +0 -0
  47. {ic_code-1.2.9 → ic_code-1.3.1}/scripts/cf_edge_nsg_make/cf_edge_nsg_make.py +0 -0
  48. {ic_code-1.2.9 → ic_code-1.3.1}/scripts/ci-detect-platforms.py +0 -0
  49. {ic_code-1.2.9 → ic_code-1.3.1}/scripts/ci-generate-matrix.py +0 -0
  50. {ic_code-1.2.9 → ic_code-1.3.1}/scripts/cli_usage_analysis.py +0 -0
  51. {ic_code-1.2.9 → ic_code-1.3.1}/scripts/dependency_mapper.py +0 -0
  52. {ic_code-1.2.9 → ic_code-1.3.1}/scripts/deploy.sh +0 -0
  53. {ic_code-1.2.9 → ic_code-1.3.1}/scripts/final_validation_and_documentation.py +0 -0
  54. {ic_code-1.2.9 → ic_code-1.3.1}/scripts/fix_consolidated_imports.py +0 -0
  55. {ic_code-1.2.9 → ic_code-1.3.1}/scripts/migration_execution_and_validation.py +0 -0
  56. {ic_code-1.2.9 → ic_code-1.3.1}/scripts/oracle-policy/user_policy.py +0 -0
  57. {ic_code-1.2.9 → ic_code-1.3.1}/scripts/performance_optimization.py +0 -0
  58. {ic_code-1.2.9 → ic_code-1.3.1}/scripts/setup_venv.py +0 -0
  59. {ic_code-1.2.9 → ic_code-1.3.1}/scripts/test-ci-detection.sh +0 -0
  60. {ic_code-1.2.9 → ic_code-1.3.1}/scripts/unset_env.sh +0 -0
  61. {ic_code-1.2.9 → ic_code-1.3.1}/scripts/validate_config.py +0 -0
  62. {ic_code-1.2.9 → ic_code-1.3.1}/scripts/validate_dependencies.py +0 -0
  63. {ic_code-1.2.9 → ic_code-1.3.1}/setup.cfg +0 -0
  64. {ic_code-1.2.9 → ic_code-1.3.1}/setup.py +0 -0
  65. {ic_code-1.2.9 → ic_code-1.3.1}/src/common/__init__.py +0 -0
  66. {ic_code-1.2.9 → ic_code-1.3.1}/src/common/gather_env.py +0 -0
  67. {ic_code-1.2.9 → ic_code-1.3.1}/src/common/gcp_config_validator.py +0 -0
  68. {ic_code-1.2.9 → ic_code-1.3.1}/src/common/gcp_monitoring.py +0 -0
  69. {ic_code-1.2.9 → ic_code-1.3.1}/src/common/gcp_utils.py +0 -0
  70. {ic_code-1.2.9 → ic_code-1.3.1}/src/common/log.py +0 -0
  71. {ic_code-1.2.9 → ic_code-1.3.1}/src/common/progress_decorator.py +0 -0
  72. {ic_code-1.2.9 → ic_code-1.3.1}/src/common/slack.py +0 -0
  73. {ic_code-1.2.9 → ic_code-1.3.1}/src/common/utils.py +0 -0
  74. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/cli.py +0 -0
  75. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/commands/__init__.py +0 -0
  76. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/commands/config.py +0 -0
  77. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/commands/security.py +0 -0
  78. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/compat/__init__.py +0 -0
  79. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/compat/cli.py +0 -0
  80. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/compat/common.py +0 -0
  81. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/config/__init__.py +0 -0
  82. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/config/cleanup.py +0 -0
  83. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/config/docs_organizer.py +0 -0
  84. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/config/external.py +0 -0
  85. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/config/installer.py +0 -0
  86. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/config/manager.py +0 -0
  87. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/config/migration.py +0 -0
  88. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/config/migration_utils.py +0 -0
  89. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/config/path_manager.py +0 -0
  90. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/config/schema.py +0 -0
  91. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/config/secrets.py +0 -0
  92. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/config/security.py +0 -0
  93. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/core/__init__.py +0 -0
  94. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/core/dependency_validator.py +0 -0
  95. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/core/logging.py +0 -0
  96. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/core/platform_discovery.py +0 -0
  97. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/core/session.py +0 -0
  98. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/core/silence_logging.py +0 -0
  99. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/__init__.py +0 -0
  100. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/aws/__init__.py +0 -0
  101. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/aws/cloudfront/__init__.py +0 -0
  102. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/aws/cloudfront/info.py +0 -0
  103. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/aws/codepipeline/__init__.py +0 -0
  104. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/aws/codepipeline/build.py +0 -0
  105. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/aws/codepipeline/deploy.py +0 -0
  106. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/aws/ec2/__init__.py +0 -0
  107. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/aws/ec2/info.py +0 -0
  108. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/aws/ec2/list_tags.py +0 -0
  109. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/aws/ec2/tag_check.py +0 -0
  110. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/aws/ecs/__init__.py +0 -0
  111. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/aws/ecs/info.py +0 -0
  112. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/aws/ecs/service.py +0 -0
  113. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/aws/ecs/task.py +0 -0
  114. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/aws/eks/__init__.py +0 -0
  115. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/aws/eks/addons.py +0 -0
  116. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/aws/eks/fargate.py +0 -0
  117. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/aws/eks/info.py +0 -0
  118. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/aws/eks/nodes.py +0 -0
  119. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/aws/eks/pods.py +0 -0
  120. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/aws/eks/update_config.py +0 -0
  121. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/aws/fargate/__init__.py +0 -0
  122. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/aws/fargate/info.py +0 -0
  123. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/aws/lb/__init__.py +0 -0
  124. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/aws/lb/info.py +0 -0
  125. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/aws/lb/list_tags.py +0 -0
  126. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/aws/lb/tag_check.py +0 -0
  127. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/aws/msk/__init__.py +0 -0
  128. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/aws/msk/broker.py +0 -0
  129. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/aws/msk/info.py +0 -0
  130. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/aws/nat/__init__.py +0 -0
  131. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/aws/nat/list_tags.py +0 -0
  132. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/aws/nat/tag_check.py +0 -0
  133. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/aws/profile/__init__.py +0 -0
  134. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/aws/profile/info.py +0 -0
  135. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/aws/rds/__init__.py +0 -0
  136. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/aws/rds/info.py +0 -0
  137. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/aws/rds/list_tags.py +0 -0
  138. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/aws/rds/tag_check.py +0 -0
  139. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/aws/s3/__init__.py +0 -0
  140. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/aws/s3/info.py +0 -0
  141. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/aws/s3/list_tags.py +0 -0
  142. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/aws/s3/tag_check.py +0 -0
  143. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/aws/sg/__init__.py +0 -0
  144. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/aws/sg/info.py +0 -0
  145. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/aws/vpc/__init__.py +0 -0
  146. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/aws/vpc/info.py +0 -0
  147. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/aws/vpc/list_tags.py +0 -0
  148. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/aws/vpc/tag_check.py +0 -0
  149. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/aws/vpn/__init__.py +0 -0
  150. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/aws/vpn/info.py +0 -0
  151. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/cloudflare/README.md +0 -0
  152. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/cloudflare/__init__.py +0 -0
  153. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/cloudflare/account/__init__.py +0 -0
  154. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/cloudflare/account/info.py +0 -0
  155. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/cloudflare/client.py +0 -0
  156. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/cloudflare/dns/__init__.py +0 -0
  157. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/cloudflare/dns/info.py +0 -0
  158. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/cloudflare/dns/list_info.py +0 -0
  159. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/cloudflare/rules/__init__.py +0 -0
  160. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/cloudflare/rules/info.py +0 -0
  161. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/cloudflare/traffic/__init__.py +0 -0
  162. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/cloudflare/traffic/info.py +0 -0
  163. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/cloudflare/waf/__init__.py +0 -0
  164. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/cloudflare/waf/info.py +0 -0
  165. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/cloudflare/zone/__init__.py +0 -0
  166. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/cloudflare/zone/info.py +0 -0
  167. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/gcp/README.md +0 -0
  168. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/gcp/__init__.py +0 -0
  169. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/gcp/billing/__init__.py +0 -0
  170. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/gcp/billing/info.py +0 -0
  171. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/gcp/billing/mock_data.json +0 -0
  172. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/gcp/compute/__init__.py +0 -0
  173. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/gcp/compute/info.py +0 -0
  174. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/gcp/compute/mock_data.json +0 -0
  175. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/gcp/firewall/__init__.py +0 -0
  176. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/gcp/firewall/info.py +0 -0
  177. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/gcp/functions/__init__.py +0 -0
  178. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/gcp/functions/info.py +0 -0
  179. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/gcp/gke/__init__.py +0 -0
  180. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/gcp/gke/info.py +0 -0
  181. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/gcp/gke/mock_data.json +0 -0
  182. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/gcp/lb/__init__.py +0 -0
  183. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/gcp/lb/info.py +0 -0
  184. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/gcp/run/__init__.py +0 -0
  185. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/gcp/run/info.py +0 -0
  186. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/gcp/sql/__init__.py +0 -0
  187. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/gcp/sql/info.py +0 -0
  188. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/gcp/storage/__init__.py +0 -0
  189. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/gcp/storage/info.py +0 -0
  190. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/gcp/vpc/__init__.py +0 -0
  191. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/gcp/vpc/info.py +0 -0
  192. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/gcp/vpc/mock_data.json +0 -0
  193. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/oci/README.md +0 -0
  194. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/oci/__init__.py +0 -0
  195. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/oci/common/__init__.py +0 -0
  196. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/oci/common/utils.py +0 -0
  197. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/oci/compartment/__init__.py +0 -0
  198. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/oci/compartment/info.py +0 -0
  199. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/oci/cost/__init__.py +0 -0
  200. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/oci/cost/credit.py +0 -0
  201. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/oci/cost/usage.py +0 -0
  202. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/oci/info/__init__.py +0 -0
  203. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/oci/info/oci_info.py +0 -0
  204. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/oci/lb/__init__.py +0 -0
  205. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/oci/lb/info.py +0 -0
  206. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/oci/nsg/__init__.py +0 -0
  207. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/oci/nsg/info.py +0 -0
  208. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/oci/obj/__init__.py +0 -0
  209. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/oci/obj/info.py +0 -0
  210. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/oci/policy/__init__.py +0 -0
  211. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/oci/policy/info.py +0 -0
  212. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/oci/policy/search.py +0 -0
  213. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/oci/vcn/__init__.py +0 -0
  214. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/oci/vcn/info.py +0 -0
  215. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/oci/vm/__init__.py +0 -0
  216. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/oci/vm/info.py +0 -0
  217. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/oci/volume/__init__.py +0 -0
  218. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/oci/volume/info.py +0 -0
  219. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/ssh/README.md +0 -0
  220. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/ssh/__init__.py +0 -0
  221. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/ssh/auto/__init__.py +0 -0
  222. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/ssh/auto/scan.py +0 -0
  223. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/ssh/auto_ssh.py +0 -0
  224. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/ssh/server/__init__.py +0 -0
  225. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/ssh/server/info.py +0 -0
  226. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/ssh/server_info.py +0 -0
  227. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/tencent/__init__.py +0 -0
  228. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/tencent/clb/__init__.py +0 -0
  229. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/tencent/clb/info.py +0 -0
  230. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/tencent/client.py +0 -0
  231. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/tencent/cvm/__init__.py +0 -0
  232. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/tencent/cvm/info.py +0 -0
  233. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/tencent/lighthouse/__init__.py +0 -0
  234. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/tencent/lighthouse/info.py +0 -0
  235. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/tencent/nat/__init__.py +0 -0
  236. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/tencent/nat/info.py +0 -0
  237. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/tencent/profile/__init__.py +0 -0
  238. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/tencent/profile/info.py +0 -0
  239. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/tencent/sg/__init__.py +0 -0
  240. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/tencent/sg/info.py +0 -0
  241. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/tencent/tke/__init__.py +0 -0
  242. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/tencent/tke/info.py +0 -0
  243. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/tencent/vpc/__init__.py +0 -0
  244. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/platforms/tencent/vpc/info.py +0 -0
  245. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/security/README.md +0 -0
  246. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/security/__init__.py +0 -0
  247. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/security/config.py +0 -0
  248. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/security/detector.py +0 -0
  249. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/security/guidance.py +0 -0
  250. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/security/hooks.py +0 -0
  251. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/security/patterns.py +0 -0
  252. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic/security/scanner.py +0 -0
  253. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic_code.egg-info/dependency_links.txt +0 -0
  254. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic_code.egg-info/entry_points.txt +0 -0
  255. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic_code.egg-info/requires.txt +0 -0
  256. {ic_code-1.2.9 → ic_code-1.3.1}/src/ic_code.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ic-code
3
- Version: 1.2.9
3
+ Version: 1.3.1
4
4
  Summary: Infrastructure CLI tool for managing AWS, GCP, OCI, CloudFlare, SSH, and more
5
5
  Home-page: https://github.com/dgr009/ic
6
6
  Author: SangYun Kim
@@ -104,6 +104,7 @@ A comprehensive, production-grade Infrastructure Command Line Interface tool for
104
104
  - **Compute**: EC2 instances, ECS services/tasks, EKS clusters/nodes/pods, Fargate profiles
105
105
  - **Storage & DB**: S3 buckets (with tagging compliance checks), RDS instances & clusters
106
106
  - **Networking**: VPC, Subnets, Gateways, Load Balancers (ALB/NLB with listener rules, health check path & target health analysis), Security Groups (with Ingress & Egress rule analysis & tree view), VPN connections
107
+ - **Health & Maintenance**: AWS Health Dashboard EC2 scheduled reboot maintenance check (`ic aws healthdashboard reboot`)
107
108
  - **Integrations**: CloudFront distributions, MSK Kafka brokers, CodePipeline build/deploy status, Profile management
108
109
 
109
110
  ### 2. 🟦 Tencent Cloud Services (Production Ready)
@@ -138,7 +139,7 @@ A comprehensive, production-grade Infrastructure Command Line Interface tool for
138
139
  ### From PyPI (Recommended)
139
140
 
140
141
  ```bash
141
- # Install the latest stable version (v1.2.9+)
142
+ # Install the latest stable version (v1.3.1+)
142
143
  pip install ic-code
143
144
 
144
145
  # Verify installation
@@ -26,6 +26,7 @@ A comprehensive, production-grade Infrastructure Command Line Interface tool for
26
26
  - **Compute**: EC2 instances, ECS services/tasks, EKS clusters/nodes/pods, Fargate profiles
27
27
  - **Storage & DB**: S3 buckets (with tagging compliance checks), RDS instances & clusters
28
28
  - **Networking**: VPC, Subnets, Gateways, Load Balancers (ALB/NLB with listener rules, health check path & target health analysis), Security Groups (with Ingress & Egress rule analysis & tree view), VPN connections
29
+ - **Health & Maintenance**: AWS Health Dashboard EC2 scheduled reboot maintenance check (`ic aws healthdashboard reboot`)
29
30
  - **Integrations**: CloudFront distributions, MSK Kafka brokers, CodePipeline build/deploy status, Profile management
30
31
 
31
32
  ### 2. 🟦 Tencent Cloud Services (Production Ready)
@@ -60,7 +61,7 @@ A comprehensive, production-grade Infrastructure Command Line Interface tool for
60
61
  ### From PyPI (Recommended)
61
62
 
62
63
  ```bash
63
- # Install the latest stable version (v1.2.9+)
64
+ # Install the latest stable version (v1.3.1+)
64
65
  pip install ic-code
65
66
 
66
67
  # Verify installation
@@ -496,5 +496,5 @@ cloudflare:
496
496
  ---
497
497
 
498
498
  **Last Updated:** November 2024
499
- **IC CLI Version:** 1.2.x+
499
+ **IC CLI Version:** 1.3.x+
500
500
  **CloudFlare API Version:** v4
@@ -4,7 +4,7 @@
4
4
 
5
5
  IC는 통합 클라우드 인프라 관리 CLI 도구로, **AWS**, **GCP**, **OCI**, **CloudFlare**, **SSH** 등 다양한 멀티 클라우드 및 서버 리소스를 단일 CLI 환경에서 손쉽게 조회하고 관리할 수 있습니다.
6
6
 
7
- ## 주요 특징 (v1.2.6+)
7
+ ## 주요 특징 (v1.3.1+)
8
8
 
9
9
  - **YAML 기반 보안 설정 시스템**: 민감한 자격 증명(`secrets.yaml`)과 일반 설정(`default.yaml`)의 명확한 분리
10
10
  - **실시간 프로그레스 바**: 리전 및 계정별 리소스 수집 진행 상황 시각화
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "ic-code"
7
- version = "1.2.9"
7
+ version = "1.3.1"
8
8
  authors = [
9
9
  {name = "sykim", email = "cruiser594@gmail.com"},
10
10
  ]
@@ -4,7 +4,7 @@ IC (Infra Resource Management CLI) - A comprehensive tool for managing cloud inf
4
4
  This package provides CLI tools and libraries for managing AWS, GCP, OCI, CloudFlare, and SSH resources.
5
5
  """
6
6
 
7
- __version__ = "1.2.9"
7
+ __version__ = "1.3.1"
8
8
  __author__ = "SangYun"
9
9
  __email__ = "cruiser594@gmail.com"
10
10
 
@@ -0,0 +1 @@
1
+ # AWS Health Dashboard Service Package
@@ -0,0 +1,350 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ AWS Health Dashboard EC2 Reboot Maintenance Schedule Command
4
+ `ic aws healthdashboard reboot`
5
+
6
+ AWS Health API를 사용하여 EC2 인스턴스의 예정된 재부팅 유지보수 일정
7
+ ("EC2 instance reboot maintenance scheduled")을 조회합니다.
8
+ """
9
+
10
+ import sys
11
+ import argparse
12
+ from datetime import datetime, timezone
13
+ from concurrent.futures import ThreadPoolExecutor, as_completed
14
+
15
+ import boto3
16
+ from botocore.exceptions import BotoCoreError, ClientError
17
+ from rich.console import Console
18
+ from rich.table import Table
19
+ from rich.panel import Panel
20
+ from rich.text import Text
21
+ from rich import box
22
+
23
+ from common.log import log_info_non_console
24
+ from common.progress_decorator import ManualProgress
25
+ from common.utils import get_valid_accounts, get_profiles, DEFINED_REGIONS
26
+
27
+ console = Console()
28
+
29
+ # 대상 타겟 이벤트 코드 정의 (EC2 인스턴스 예정된 재부팅 유지보수)
30
+ TARGET_EVENT_CODES = [
31
+ "AWS_EC2_INSTANCE_REBOOT_MAINTENANCE_SCHEDULED",
32
+ "AWS_EC2_PERSISTENT_INSTANCE_REBOOT_SCHEDULED",
33
+ "AWS_EC2_SCHEDULED_REBOOT"
34
+ ]
35
+
36
+ TARGET_DESCRIPTION_KEYWORD = "ec2 instance reboot maintenance scheduled"
37
+
38
+ def format_datetime_short(dt):
39
+ """datetime 객체를 YY-MM-DD HH:MM UTC 형태로 압축하여 표 가로폭을 최적화합니다."""
40
+ if not dt:
41
+ return "-"
42
+ if isinstance(dt, str):
43
+ return dt
44
+ if dt.tzinfo is None:
45
+ dt = dt.replace(tzinfo=timezone.utc)
46
+
47
+ try:
48
+ return dt.strftime("%Y-%m-%d %H:%M UTC")
49
+ except Exception:
50
+ return str(dt)
51
+
52
+ def get_instance_details(session, instance_id, region):
53
+ """
54
+ EC2 API를 호출하여 인스턴스의 Name 태그, 현재 상태(State), 실제 리전을 조회합니다.
55
+ """
56
+ if not instance_id or not instance_id.startswith("i-"):
57
+ return "-", "unknown", region
58
+
59
+ regions_to_try = [region] if region and region != "global" else DEFINED_REGIONS
60
+
61
+ for reg in regions_to_try:
62
+ try:
63
+ ec2_client = session.client("ec2", region_name=reg)
64
+ response = ec2_client.describe_instances(InstanceIds=[instance_id])
65
+ for reservation in response.get("Reservations", []):
66
+ for instance in reservation.get("Instances", []):
67
+ state = instance.get("State", {}).get("Name", "unknown")
68
+ name = "-"
69
+ for tag in instance.get("Tags", []):
70
+ if tag.get("Key") == "Name":
71
+ name = tag.get("Value", "-")
72
+ break
73
+ return name, state, reg
74
+ except ClientError:
75
+ continue
76
+ except Exception as e:
77
+ log_info_non_console(f"EC2 인스턴스 세부 정보 조회 오류 ({instance_id}/{reg}): {e}")
78
+ continue
79
+
80
+ return "-", "unknown", region
81
+
82
+ def parse_region_from_arn_or_event(event, entity):
83
+ """이벤트 또는 엔티티 ARN에서 AWS Region 정보를 추출합니다."""
84
+ event_region = event.get("region")
85
+ if event_region and event_region != "global":
86
+ return event_region
87
+
88
+ entity_arn = entity.get("entityArn", "")
89
+ if entity_arn and entity_arn.startswith("arn:aws:"):
90
+ parts = entity_arn.split(":")
91
+ if len(parts) >= 4 and parts[3]:
92
+ return parts[3]
93
+
94
+ return "global"
95
+
96
+ def fetch_reboot_events_for_account(account_id, profile_name, include_closed=False):
97
+ """단일 계정에 대해 AWS Health API(us-east-1)를 사용하여 EC2 재부팅 유지보수 이벤트를 수집합니다."""
98
+ log_info_non_console(f"AWS Health API 조회 시작: Account={account_id}, Profile={profile_name}")
99
+
100
+ events_found = []
101
+ error_message = None
102
+
103
+ try:
104
+ session = boto3.Session(profile_name=profile_name, region_name="us-east-1")
105
+ health_client = session.client("health", region_name="us-east-1")
106
+
107
+ status_codes = ["open", "upcoming"]
108
+ if include_closed:
109
+ status_codes.append("closed")
110
+
111
+ filter_params = {
112
+ "services": ["EC2"],
113
+ "eventStatusCodes": status_codes
114
+ }
115
+
116
+ paginator = health_client.get_paginator("describe_events")
117
+ raw_events = []
118
+ for page in paginator.paginate(filter=filter_params):
119
+ for event in page.get("events", []):
120
+ raw_events.append(event)
121
+
122
+ if not raw_events:
123
+ return account_id, profile_name, [], None
124
+
125
+ for event in raw_events:
126
+ event_arn = event.get("arn")
127
+ event_code = event.get("eventTypeCode", "")
128
+ event_status = event.get("statusCode", "unknown")
129
+ start_time = format_datetime_short(event.get("startTime"))
130
+ end_time = format_datetime_short(event.get("endTime"))
131
+ event_region = event.get("region", "global")
132
+
133
+ # 이벤트 설명 상세 조회
134
+ description_text = ""
135
+ try:
136
+ details_res = health_client.describe_event_details(eventArns=[event_arn])
137
+ successful_set = details_res.get("successfulSet", [])
138
+ if successful_set:
139
+ event_desc_obj = successful_set[0].get("eventDescription", {})
140
+ description_text = event_desc_obj.get("latestDescription", "")
141
+ except Exception as de:
142
+ log_info_non_console(f"이벤트 상세 정보 조회 실패 ({event_arn}): {de}")
143
+
144
+ # 정확한 EC2 인스턴스 재부팅 유지보수 일정 필터링
145
+ is_target_code = event_code in TARGET_EVENT_CODES
146
+ is_target_desc = TARGET_DESCRIPTION_KEYWORD in description_text.lower()
147
+
148
+ if not (is_target_code or is_target_desc):
149
+ continue
150
+
151
+ # 영향받는 엔티티(인스턴스) 수집
152
+ affected_entities = []
153
+ try:
154
+ ent_paginator = health_client.get_paginator("describe_affected_entities")
155
+ for ent_page in ent_paginator.paginate(filter={"eventArns": [event_arn]}):
156
+ for entity in ent_page.get("entities", []):
157
+ affected_entities.append(entity)
158
+ except Exception as ee:
159
+ log_info_non_console(f"영향받는 엔티티 조회 실패 ({event_arn}): {ee}")
160
+
161
+ if affected_entities:
162
+ for entity in affected_entities:
163
+ entity_value = entity.get("entityValue", "-") # 인스턴스 ID
164
+ entity_status = entity.get("statusCode", "UNKNOWN") # IMPAIRED, RESOLVED 등
165
+
166
+ parsed_region = parse_region_from_arn_or_event(event, entity)
167
+ inst_name, inst_state, final_region = get_instance_details(session, entity_value, parsed_region)
168
+
169
+ events_found.append({
170
+ "account_id": account_id,
171
+ "profile_name": profile_name,
172
+ "event_code": event_code,
173
+ "event_status": event_status,
174
+ "entity_status": entity_status,
175
+ "start_time": start_time,
176
+ "end_time": end_time,
177
+ "instance_id": entity_value,
178
+ "instance_name": inst_name,
179
+ "instance_state": inst_state,
180
+ "region": final_region,
181
+ "description": description_text
182
+ })
183
+ else:
184
+ events_found.append({
185
+ "account_id": account_id,
186
+ "profile_name": profile_name,
187
+ "event_code": event_code,
188
+ "event_status": event_status,
189
+ "entity_status": "-",
190
+ "start_time": start_time,
191
+ "end_time": end_time,
192
+ "instance_id": "-",
193
+ "instance_name": "-",
194
+ "instance_state": "-",
195
+ "region": event_region,
196
+ "description": description_text
197
+ })
198
+
199
+ except ClientError as e:
200
+ error_code = e.response.get("Error", {}).get("Code", "")
201
+ if error_code == "SubscriptionRequiredException":
202
+ error_message = "AWS Business 또는 Enterprise Support 플랜이 필요합니다."
203
+ elif error_code == "AccessDeniedException":
204
+ error_message = "AWS Health API 접근 권한(health:DescribeEvents 등)이 부족합니다."
205
+ else:
206
+ error_message = f"AWS Health API 오류: {e.response.get('Error', {}).get('Message', str(e))}"
207
+ log_info_non_console(f"Account {account_id} Health API ClientError: {e}")
208
+ except Exception as e:
209
+ error_message = f"오류 발생: {e}"
210
+ log_info_non_console(f"Account {account_id} Health API 예외: {e}")
211
+
212
+ return account_id, profile_name, events_found, error_message
213
+
214
+ def print_results(all_events, account_errors, verbose=False):
215
+ """결과 데이터를 rich 표 및 안내 패널로 출력합니다."""
216
+ console.print()
217
+
218
+ if verbose and account_errors:
219
+ for acct, prof, err in account_errors:
220
+ console.print(f"[bold yellow]⚠️ [{prof} ({acct})][/bold yellow] {err}")
221
+ console.print()
222
+
223
+ if not all_events:
224
+ panel_content = Text()
225
+ panel_content.append("✅ 예정된 EC2 인스턴스 재부팅 일정이 없습니다.\n", style="bold green")
226
+ panel_content.append(" (EC2 instance reboot maintenance scheduled)", style="dim")
227
+ console.print(Panel(panel_content, title="AWS Health Dashboard", border_style="green", box=box.ROUNDED))
228
+ console.print()
229
+ return
230
+
231
+ table = Table(
232
+ title="🚨 EC2 Instance Reboot Maintenance Schedule",
233
+ box=box.ROUNDED,
234
+ header_style="bold cyan",
235
+ show_lines=True,
236
+ expand=True
237
+ )
238
+
239
+ table.add_column("Account", style="cyan", min_width=15, ratio=2)
240
+ table.add_column("Region", style="magenta", min_width=12, ratio=1)
241
+ table.add_column("Instance ID", style="bold yellow", min_width=19, ratio=2)
242
+ table.add_column("Instance Name", style="bold white", min_width=20, ratio=3)
243
+ table.add_column("EC2 State", style="green", min_width=8, ratio=1)
244
+ table.add_column("Entity Status", style="bold white", min_width=10, ratio=1)
245
+ table.add_column("Event Status", style="dim", min_width=9, ratio=1)
246
+ table.add_column("Scheduled Start", style="yellow", min_width=16, ratio=2)
247
+ table.add_column("Scheduled End", style="dim", min_width=16, ratio=2)
248
+
249
+ for item in all_events:
250
+ event_status_display = item["event_status"]
251
+ if item["event_status"].lower() in ["open", "upcoming"]:
252
+ event_status_display = f"[yellow]{item['event_status']}[/yellow]"
253
+ elif item["event_status"].lower() == "closed":
254
+ event_status_display = f"[dim]{item['event_status']}[/dim]"
255
+
256
+ entity_status_str = str(item["entity_status"]).upper()
257
+ if entity_status_str == "RESOLVED":
258
+ entity_status_display = "[bold green]RESOLVED[/bold green]"
259
+ elif entity_status_str in ["IMPAIRED", "IMPACTED"]:
260
+ entity_status_display = "[bold red]IMPAIRED[/bold red]"
261
+ else:
262
+ entity_status_display = entity_status_str
263
+
264
+ state_str = str(item["instance_state"]).lower()
265
+ if state_str == "running":
266
+ state_display = f"[bold green]{item['instance_state']}[/bold green]"
267
+ elif state_str in ["stopped", "stopping"]:
268
+ state_display = f"[bold yellow]{item['instance_state']}[/bold yellow]"
269
+ elif state_str == "terminated":
270
+ state_display = f"[bold red]{item['instance_state']}[/bold red]"
271
+ else:
272
+ state_display = item["instance_state"]
273
+
274
+ table.add_row(
275
+ f"{item['profile_name']}\n({item['account_id']})",
276
+ item["region"],
277
+ item["instance_id"],
278
+ item["instance_name"],
279
+ state_display,
280
+ entity_status_display,
281
+ event_status_display,
282
+ item["start_time"],
283
+ item["end_time"]
284
+ )
285
+
286
+ console.print(table)
287
+ console.print(f"\n총 [bold yellow]{len(all_events)}[/bold yellow]건의 유지보수 일정이 확인되었습니다.")
288
+ console.print()
289
+
290
+ def main(args, config=None):
291
+ """ic aws healthdashboard reboot 실행 엔트리 포인트"""
292
+ all_accounts_flag = getattr(args, 'all_accounts', False)
293
+ account_input = args.account if hasattr(args, 'account') and args.account else None
294
+
295
+ # --all-accounts 플래그가 지정되었거나 계정이 지정되지 않은 경우, 로컬 AWS 프로파일 전체 수집
296
+ if all_accounts_flag or not account_input:
297
+ profiles_dict = get_profiles()
298
+ valid_accounts = []
299
+ if profiles_dict:
300
+ for acct_id, prof_name in profiles_dict.items():
301
+ # 'default' 제외하고 추가하거나 default도 활성화된 프로필이면 유지
302
+ valid_accounts.append((acct_id, prof_name))
303
+ else:
304
+ valid_accounts = get_valid_accounts(None)
305
+ else:
306
+ valid_accounts = get_valid_accounts(account_input)
307
+
308
+ if not valid_accounts:
309
+ console.print("❌ 조회를 진행할 AWS 계정을 찾을 수 없습니다. (.env 또는 AWS 프로파일 설정을 확인하세요)")
310
+ sys.exit(1)
311
+
312
+ include_closed = getattr(args, 'all_status', False)
313
+ all_events = []
314
+ account_errors = []
315
+
316
+ total_ops = len(valid_accounts)
317
+ with ManualProgress("Checking AWS Health Dashboard for EC2 reboot schedules across all profiles...", total=total_ops) as progress:
318
+ with ThreadPoolExecutor(max_workers=min(len(valid_accounts), 15)) as executor:
319
+ futures = {
320
+ executor.submit(fetch_reboot_events_for_account, acct, prof, include_closed): (acct, prof)
321
+ for acct, prof in valid_accounts
322
+ }
323
+
324
+ for future in as_completed(futures):
325
+ acct, prof = futures[future]
326
+ try:
327
+ acct_id, prof_name, events, error_msg = future.result()
328
+ if error_msg:
329
+ account_errors.append((acct_id, prof_name, error_msg))
330
+ if events:
331
+ all_events.extend(events)
332
+ progress.update(f"Completed {prof_name} ({acct_id})", advance=1)
333
+ except Exception as e:
334
+ account_errors.append((acct, prof, f"조회 중 예외 발생: {e}"))
335
+ progress.update(f"Failed {prof} ({acct})", advance=1)
336
+
337
+ print_results(all_events, account_errors, verbose=getattr(args, 'verbose', False))
338
+
339
+ def add_arguments(parser):
340
+ """Command line arguments definition"""
341
+ parser.add_argument('-a', '--account', help='특정 AWS 계정 ID 또는 프로파일 지정 (구분자: ,)')
342
+ parser.add_argument('-A', '--all-accounts', '--all-profiles', action='store_true', help='로컬 AWS 프로필에 등록된 모든 계정 전체 조회')
343
+ parser.add_argument('--all-status', action='store_true', help='이미 종료된(closed) 과거 일정까지 포함하여 조회')
344
+ parser.add_argument('-v', '--verbose', action='store_true', help='상세 에러 로그 및 정보 출력')
345
+
346
+ if __name__ == "__main__":
347
+ parser = argparse.ArgumentParser(description="AWS Health Dashboard EC2 Reboot Schedule Check")
348
+ add_arguments(parser)
349
+ args = parser.parse_args()
350
+ main(args)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ic-code
3
- Version: 1.2.9
3
+ Version: 1.3.1
4
4
  Summary: Infrastructure CLI tool for managing AWS, GCP, OCI, CloudFlare, SSH, and more
5
5
  Home-page: https://github.com/dgr009/ic
6
6
  Author: SangYun Kim
@@ -104,6 +104,7 @@ A comprehensive, production-grade Infrastructure Command Line Interface tool for
104
104
  - **Compute**: EC2 instances, ECS services/tasks, EKS clusters/nodes/pods, Fargate profiles
105
105
  - **Storage & DB**: S3 buckets (with tagging compliance checks), RDS instances & clusters
106
106
  - **Networking**: VPC, Subnets, Gateways, Load Balancers (ALB/NLB with listener rules, health check path & target health analysis), Security Groups (with Ingress & Egress rule analysis & tree view), VPN connections
107
+ - **Health & Maintenance**: AWS Health Dashboard EC2 scheduled reboot maintenance check (`ic aws healthdashboard reboot`)
107
108
  - **Integrations**: CloudFront distributions, MSK Kafka brokers, CodePipeline build/deploy status, Profile management
108
109
 
109
110
  ### 2. 🟦 Tencent Cloud Services (Production Ready)
@@ -138,7 +139,7 @@ A comprehensive, production-grade Infrastructure Command Line Interface tool for
138
139
  ### From PyPI (Recommended)
139
140
 
140
141
  ```bash
141
- # Install the latest stable version (v1.2.9+)
142
+ # Install the latest stable version (v1.3.1+)
142
143
  pip install ic-code
143
144
 
144
145
  # Verify installation
@@ -114,6 +114,8 @@ src/ic/platforms/aws/eks/pods.py
114
114
  src/ic/platforms/aws/eks/update_config.py
115
115
  src/ic/platforms/aws/fargate/__init__.py
116
116
  src/ic/platforms/aws/fargate/info.py
117
+ src/ic/platforms/aws/healthdashboard/__init__.py
118
+ src/ic/platforms/aws/healthdashboard/reboot.py
117
119
  src/ic/platforms/aws/lb/__init__.py
118
120
  src/ic/platforms/aws/lb/info.py
119
121
  src/ic/platforms/aws/lb/list_tags.py
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes