ic-code 1.3.4__tar.gz → 1.3.5__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 (231) hide show
  1. {ic_code-1.3.4/src/ic_code.egg-info → ic_code-1.3.5}/PKG-INFO +45 -20
  2. {ic_code-1.3.4 → ic_code-1.3.5}/pyproject.toml +56 -32
  3. {ic_code-1.3.4 → ic_code-1.3.5}/scripts/ci-detect-platforms.py +17 -11
  4. ic_code-1.3.5/scripts/ci-smoke-test.sh +83 -0
  5. {ic_code-1.3.4 → ic_code-1.3.5}/src/common/progress_decorator.py +24 -7
  6. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/__init__.py +1 -1
  7. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/core/dependency_validator.py +7 -5
  8. ic_code-1.3.5/src/ic/core/desc_helper.py +221 -0
  9. ic_code-1.3.5/src/ic/core/interfaces/__init__.py +9 -0
  10. ic_code-1.3.5/src/ic/core/interfaces/command.py +69 -0
  11. ic_code-1.3.5/src/ic/core/interfaces/formatter.py +97 -0
  12. ic_code-1.3.5/src/ic/core/interfaces/result.py +81 -0
  13. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/core/platform_discovery.py +76 -11
  14. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/core/session.py +28 -10
  15. ic_code-1.3.5/src/ic/platforms/aws/ec2/desc.py +196 -0
  16. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/aws/ec2/info.py +33 -10
  17. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/aws/ec2/list_tags.py +12 -23
  18. ic_code-1.3.5/src/ic/platforms/aws/lb/desc.py +281 -0
  19. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/aws/lb/info.py +123 -41
  20. ic_code-1.3.5/src/ic/platforms/tencent/clb/desc.py +281 -0
  21. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/tencent/clb/info.py +32 -11
  22. ic_code-1.3.5/src/ic/platforms/tencent/cvm/desc.py +232 -0
  23. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/tencent/cvm/info.py +35 -16
  24. {ic_code-1.3.4 → ic_code-1.3.5/src/ic_code.egg-info}/PKG-INFO +45 -20
  25. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic_code.egg-info/SOURCES.txt +10 -0
  26. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic_code.egg-info/requires.txt +50 -18
  27. {ic_code-1.3.4 → ic_code-1.3.5}/LICENSE +0 -0
  28. {ic_code-1.3.4 → ic_code-1.3.5}/MANIFEST.in +0 -0
  29. {ic_code-1.3.4 → ic_code-1.3.5}/README.md +0 -0
  30. {ic_code-1.3.4 → ic_code-1.3.5}/SECURITY.md +0 -0
  31. {ic_code-1.3.4 → ic_code-1.3.5}/config/default.yaml +0 -0
  32. {ic_code-1.3.4 → ic_code-1.3.5}/docs/README.md +0 -0
  33. {ic_code-1.3.4 → ic_code-1.3.5}/docs/aws/README.md +0 -0
  34. {ic_code-1.3.4 → ic_code-1.3.5}/docs/cloudflare/README.md +0 -0
  35. {ic_code-1.3.4 → ic_code-1.3.5}/docs/gcp/README.md +0 -0
  36. {ic_code-1.3.4 → ic_code-1.3.5}/docs/installation.md +0 -0
  37. {ic_code-1.3.4 → ic_code-1.3.5}/docs/oci/README.md +0 -0
  38. {ic_code-1.3.4 → ic_code-1.3.5}/docs/release-guide.md +0 -0
  39. {ic_code-1.3.4 → ic_code-1.3.5}/docs/security.md +0 -0
  40. {ic_code-1.3.4 → ic_code-1.3.5}/docs/ssh/README.md +0 -0
  41. {ic_code-1.3.4 → ic_code-1.3.5}/docs/tencent/README.md +0 -0
  42. {ic_code-1.3.4 → ic_code-1.3.5}/docs/troubleshooting.md +0 -0
  43. {ic_code-1.3.4 → ic_code-1.3.5}/docs/user_guide.md +0 -0
  44. {ic_code-1.3.4 → ic_code-1.3.5}/requirements.txt +0 -0
  45. {ic_code-1.3.4 → ic_code-1.3.5}/scripts/bump-version.sh +0 -0
  46. {ic_code-1.3.4 → ic_code-1.3.5}/scripts/cf_edge_nsg_make/cf_edge_nsg_make.py +0 -0
  47. {ic_code-1.3.4 → ic_code-1.3.5}/scripts/ci-generate-matrix.py +0 -0
  48. {ic_code-1.3.4 → ic_code-1.3.5}/scripts/deploy.sh +0 -0
  49. {ic_code-1.3.4 → ic_code-1.3.5}/scripts/oracle-policy/user_policy.py +0 -0
  50. {ic_code-1.3.4 → ic_code-1.3.5}/setup.cfg +0 -0
  51. {ic_code-1.3.4 → ic_code-1.3.5}/setup.py +0 -0
  52. {ic_code-1.3.4 → ic_code-1.3.5}/src/common/__init__.py +0 -0
  53. {ic_code-1.3.4 → ic_code-1.3.5}/src/common/gather_env.py +0 -0
  54. {ic_code-1.3.4 → ic_code-1.3.5}/src/common/gcp_config_validator.py +0 -0
  55. {ic_code-1.3.4 → ic_code-1.3.5}/src/common/gcp_monitoring.py +0 -0
  56. {ic_code-1.3.4 → ic_code-1.3.5}/src/common/gcp_utils.py +0 -0
  57. {ic_code-1.3.4 → ic_code-1.3.5}/src/common/log.py +0 -0
  58. {ic_code-1.3.4 → ic_code-1.3.5}/src/common/slack.py +0 -0
  59. {ic_code-1.3.4 → ic_code-1.3.5}/src/common/utils.py +0 -0
  60. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/cli.py +0 -0
  61. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/commands/__init__.py +0 -0
  62. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/commands/config.py +0 -0
  63. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/commands/security.py +0 -0
  64. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/compat/__init__.py +0 -0
  65. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/compat/cli.py +0 -0
  66. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/compat/common.py +0 -0
  67. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/config/__init__.py +0 -0
  68. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/config/cleanup.py +0 -0
  69. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/config/docs_organizer.py +0 -0
  70. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/config/external.py +0 -0
  71. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/config/installer.py +0 -0
  72. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/config/manager.py +0 -0
  73. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/config/migration.py +0 -0
  74. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/config/migration_utils.py +0 -0
  75. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/config/path_manager.py +0 -0
  76. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/config/schema.py +0 -0
  77. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/config/secrets.py +0 -0
  78. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/config/security.py +0 -0
  79. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/core/__init__.py +0 -0
  80. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/core/logging.py +0 -0
  81. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/core/silence_logging.py +0 -0
  82. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/__init__.py +0 -0
  83. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/aws/__init__.py +0 -0
  84. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/aws/cloudfront/__init__.py +0 -0
  85. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/aws/cloudfront/info.py +0 -0
  86. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/aws/codepipeline/__init__.py +0 -0
  87. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/aws/codepipeline/build.py +0 -0
  88. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/aws/codepipeline/deploy.py +0 -0
  89. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/aws/ec2/__init__.py +0 -0
  90. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/aws/ec2/tag_check.py +0 -0
  91. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/aws/ecs/__init__.py +0 -0
  92. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/aws/ecs/info.py +0 -0
  93. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/aws/ecs/service.py +0 -0
  94. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/aws/ecs/task.py +0 -0
  95. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/aws/eks/__init__.py +0 -0
  96. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/aws/eks/addons.py +0 -0
  97. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/aws/eks/fargate.py +0 -0
  98. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/aws/eks/info.py +0 -0
  99. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/aws/eks/nodes.py +0 -0
  100. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/aws/eks/pods.py +0 -0
  101. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/aws/eks/update_config.py +0 -0
  102. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/aws/fargate/__init__.py +0 -0
  103. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/aws/fargate/info.py +0 -0
  104. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/aws/healthdashboard/__init__.py +0 -0
  105. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/aws/healthdashboard/reboot.py +0 -0
  106. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/aws/lb/__init__.py +0 -0
  107. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/aws/lb/list_tags.py +0 -0
  108. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/aws/lb/tag_check.py +0 -0
  109. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/aws/msk/__init__.py +0 -0
  110. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/aws/msk/broker.py +0 -0
  111. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/aws/msk/info.py +0 -0
  112. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/aws/nat/__init__.py +0 -0
  113. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/aws/nat/list_tags.py +0 -0
  114. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/aws/nat/tag_check.py +0 -0
  115. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/aws/profile/__init__.py +0 -0
  116. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/aws/profile/info.py +0 -0
  117. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/aws/rds/__init__.py +0 -0
  118. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/aws/rds/info.py +0 -0
  119. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/aws/rds/list_tags.py +0 -0
  120. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/aws/rds/tag_check.py +0 -0
  121. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/aws/s3/__init__.py +0 -0
  122. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/aws/s3/info.py +0 -0
  123. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/aws/s3/list_tags.py +0 -0
  124. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/aws/s3/tag_check.py +0 -0
  125. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/aws/sg/__init__.py +0 -0
  126. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/aws/sg/info.py +0 -0
  127. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/aws/vpc/__init__.py +0 -0
  128. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/aws/vpc/info.py +0 -0
  129. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/aws/vpc/list_tags.py +0 -0
  130. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/aws/vpc/tag_check.py +0 -0
  131. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/aws/vpn/__init__.py +0 -0
  132. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/aws/vpn/info.py +0 -0
  133. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/cloudflare/__init__.py +0 -0
  134. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/cloudflare/account/__init__.py +0 -0
  135. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/cloudflare/account/info.py +0 -0
  136. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/cloudflare/client.py +0 -0
  137. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/cloudflare/dns/__init__.py +0 -0
  138. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/cloudflare/dns/info.py +0 -0
  139. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/cloudflare/dns/list_info.py +0 -0
  140. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/cloudflare/rules/__init__.py +0 -0
  141. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/cloudflare/rules/info.py +0 -0
  142. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/cloudflare/traffic/__init__.py +0 -0
  143. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/cloudflare/traffic/info.py +0 -0
  144. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/cloudflare/waf/__init__.py +0 -0
  145. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/cloudflare/waf/info.py +0 -0
  146. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/cloudflare/zone/__init__.py +0 -0
  147. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/cloudflare/zone/info.py +0 -0
  148. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/gcp/__init__.py +0 -0
  149. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/gcp/billing/__init__.py +0 -0
  150. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/gcp/billing/info.py +0 -0
  151. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/gcp/billing/mock_data.json +0 -0
  152. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/gcp/compute/__init__.py +0 -0
  153. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/gcp/compute/info.py +0 -0
  154. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/gcp/compute/mock_data.json +0 -0
  155. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/gcp/firewall/__init__.py +0 -0
  156. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/gcp/firewall/info.py +0 -0
  157. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/gcp/functions/__init__.py +0 -0
  158. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/gcp/functions/info.py +0 -0
  159. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/gcp/gke/__init__.py +0 -0
  160. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/gcp/gke/info.py +0 -0
  161. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/gcp/gke/mock_data.json +0 -0
  162. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/gcp/lb/__init__.py +0 -0
  163. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/gcp/lb/info.py +0 -0
  164. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/gcp/run/__init__.py +0 -0
  165. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/gcp/run/info.py +0 -0
  166. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/gcp/sql/__init__.py +0 -0
  167. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/gcp/sql/info.py +0 -0
  168. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/gcp/storage/__init__.py +0 -0
  169. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/gcp/storage/info.py +0 -0
  170. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/gcp/vpc/__init__.py +0 -0
  171. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/gcp/vpc/info.py +0 -0
  172. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/gcp/vpc/mock_data.json +0 -0
  173. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/oci/__init__.py +0 -0
  174. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/oci/common/__init__.py +0 -0
  175. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/oci/common/utils.py +0 -0
  176. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/oci/compartment/__init__.py +0 -0
  177. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/oci/compartment/info.py +0 -0
  178. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/oci/cost/__init__.py +0 -0
  179. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/oci/cost/credit.py +0 -0
  180. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/oci/cost/usage.py +0 -0
  181. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/oci/info/__init__.py +0 -0
  182. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/oci/info/oci_info.py +0 -0
  183. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/oci/lb/__init__.py +0 -0
  184. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/oci/lb/info.py +0 -0
  185. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/oci/nsg/__init__.py +0 -0
  186. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/oci/nsg/info.py +0 -0
  187. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/oci/obj/__init__.py +0 -0
  188. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/oci/obj/info.py +0 -0
  189. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/oci/policy/__init__.py +0 -0
  190. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/oci/policy/info.py +0 -0
  191. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/oci/policy/search.py +0 -0
  192. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/oci/vcn/__init__.py +0 -0
  193. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/oci/vcn/info.py +0 -0
  194. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/oci/vm/__init__.py +0 -0
  195. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/oci/vm/info.py +0 -0
  196. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/oci/volume/__init__.py +0 -0
  197. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/oci/volume/info.py +0 -0
  198. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/ssh/__init__.py +0 -0
  199. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/ssh/auto/__init__.py +0 -0
  200. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/ssh/auto/scan.py +0 -0
  201. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/ssh/auto_ssh.py +0 -0
  202. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/ssh/server/__init__.py +0 -0
  203. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/ssh/server/info.py +0 -0
  204. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/ssh/server_info.py +0 -0
  205. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/tencent/__init__.py +0 -0
  206. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/tencent/clb/__init__.py +0 -0
  207. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/tencent/clb/traffic.py +0 -0
  208. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/tencent/client.py +0 -0
  209. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/tencent/cvm/__init__.py +0 -0
  210. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/tencent/lighthouse/__init__.py +0 -0
  211. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/tencent/lighthouse/info.py +0 -0
  212. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/tencent/nat/__init__.py +0 -0
  213. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/tencent/nat/info.py +0 -0
  214. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/tencent/profile/__init__.py +0 -0
  215. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/tencent/profile/info.py +0 -0
  216. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/tencent/sg/__init__.py +0 -0
  217. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/tencent/sg/info.py +0 -0
  218. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/tencent/tke/__init__.py +0 -0
  219. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/tencent/tke/info.py +0 -0
  220. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/tencent/vpc/__init__.py +0 -0
  221. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/platforms/tencent/vpc/info.py +0 -0
  222. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/security/__init__.py +0 -0
  223. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/security/config.py +0 -0
  224. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/security/detector.py +0 -0
  225. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/security/guidance.py +0 -0
  226. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/security/hooks.py +0 -0
  227. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/security/patterns.py +0 -0
  228. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic/security/scanner.py +0 -0
  229. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic_code.egg-info/dependency_links.txt +0 -0
  230. {ic_code-1.3.4 → ic_code-1.3.5}/src/ic_code.egg-info/entry_points.txt +0 -0
  231. {ic_code-1.3.4 → ic_code-1.3.5}/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.3.4
3
+ Version: 1.3.5
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
@@ -28,24 +28,8 @@ Classifier: Environment :: Console
28
28
  Requires-Python: >=3.9,<3.15
29
29
  Description-Content-Type: text/markdown
30
30
  License-File: LICENSE
31
- Requires-Dist: boto3<2.0.0,>=1.34.0
32
- Requires-Dist: botocore<2.0.0,>=1.34.0
33
- Requires-Dist: oci<3.0.0,>=2.149.0
34
31
  Requires-Dist: requests<3.0.0,>=2.31.0
35
- Requires-Dist: kubernetes<32.0.0,>=29.0.0
36
- Requires-Dist: awscli<2.0.0,>=1.32.0
37
- Requires-Dist: google-cloud-compute<2.0.0,>=1.36.0
38
- Requires-Dist: google-cloud-container<3.0.0,>=2.44.0
39
- Requires-Dist: google-cloud-storage<3.0.0,>=2.18.0
40
- Requires-Dist: google-cloud-functions<2.0.0,>=1.16.0
41
- Requires-Dist: google-cloud-run<1.0.0,>=0.11.0
42
- Requires-Dist: google-cloud-billing<2.0.0,>=1.13.0
43
- Requires-Dist: google-cloud-resource-manager<2.0.0,>=1.12.0
44
- Requires-Dist: google-auth<3.0.0,>=2.29.0
45
- Requires-Dist: google-auth-oauthlib<2.0.0,>=1.2.0
46
- Requires-Dist: google-auth-httplib2<1.0.0,>=0.2.0
47
- Requires-Dist: paramiko<5.0.0,>=3.4.0
48
- Requires-Dist: netifaces<1.0.0,>=0.11.0
32
+ Requires-Dist: cryptography<50.0.0,>=42.0.0
49
33
  Requires-Dist: rich<15.0.0,>=13.0.0
50
34
  Requires-Dist: InquirerPy<1.0.0,>=0.3.4
51
35
  Requires-Dist: tqdm<5.0.0,>=4.67.0
@@ -56,13 +40,54 @@ Requires-Dist: click<9.0.0,>=8.1.0
56
40
  Requires-Dist: docutils<1.0.0,>=0.19
57
41
  Requires-Dist: invoke<3.0.0,>=2.2.0
58
42
  Requires-Dist: jsonschema<5.0.0,>=4.23.0
59
- Requires-Dist: cryptography<50.0.0,>=42.0.0
60
43
  Requires-Dist: watchdog<6.0.0,>=4.0.0
61
44
  Requires-Dist: cerberus<2.0.0,>=1.3.5
62
45
  Requires-Dist: pydantic<3.0.0,>=2.7.0
63
46
  Requires-Dist: packaging<25.0,>=24.0
64
47
  Requires-Dist: setuptools<76.0.0,>=69.0.0
65
- Requires-Dist: tencentcloud-sdk-python<4.0.0,>=3.0.0
48
+ Provides-Extra: aws
49
+ Requires-Dist: boto3<2.0.0,>=1.34.0; extra == "aws"
50
+ Requires-Dist: botocore<2.0.0,>=1.34.0; extra == "aws"
51
+ Requires-Dist: awscli<2.0.0,>=1.32.0; extra == "aws"
52
+ Provides-Extra: tencent
53
+ Requires-Dist: tencentcloud-sdk-python<4.0.0,>=3.0.0; extra == "tencent"
54
+ Provides-Extra: oci
55
+ Requires-Dist: oci<3.0.0,>=2.149.0; extra == "oci"
56
+ Provides-Extra: gcp
57
+ Requires-Dist: google-cloud-compute<2.0.0,>=1.36.0; extra == "gcp"
58
+ Requires-Dist: google-cloud-container<3.0.0,>=2.44.0; extra == "gcp"
59
+ Requires-Dist: google-cloud-storage<3.0.0,>=2.18.0; extra == "gcp"
60
+ Requires-Dist: google-cloud-functions<2.0.0,>=1.16.0; extra == "gcp"
61
+ Requires-Dist: google-cloud-run<1.0.0,>=0.11.0; extra == "gcp"
62
+ Requires-Dist: google-cloud-billing<2.0.0,>=1.13.0; extra == "gcp"
63
+ Requires-Dist: google-cloud-resource-manager<2.0.0,>=1.12.0; extra == "gcp"
64
+ Requires-Dist: google-auth<3.0.0,>=2.29.0; extra == "gcp"
65
+ Requires-Dist: google-auth-oauthlib<2.0.0,>=1.2.0; extra == "gcp"
66
+ Requires-Dist: google-auth-httplib2<1.0.0,>=0.2.0; extra == "gcp"
67
+ Provides-Extra: ssh
68
+ Requires-Dist: paramiko<5.0.0,>=3.4.0; extra == "ssh"
69
+ Requires-Dist: netifaces<1.0.0,>=0.11.0; extra == "ssh"
70
+ Provides-Extra: k8s
71
+ Requires-Dist: kubernetes<32.0.0,>=29.0.0; extra == "k8s"
72
+ Provides-Extra: all
73
+ Requires-Dist: boto3<2.0.0,>=1.34.0; extra == "all"
74
+ Requires-Dist: botocore<2.0.0,>=1.34.0; extra == "all"
75
+ Requires-Dist: awscli<2.0.0,>=1.32.0; extra == "all"
76
+ Requires-Dist: tencentcloud-sdk-python<4.0.0,>=3.0.0; extra == "all"
77
+ Requires-Dist: oci<3.0.0,>=2.149.0; extra == "all"
78
+ Requires-Dist: google-cloud-compute<2.0.0,>=1.36.0; extra == "all"
79
+ Requires-Dist: google-cloud-container<3.0.0,>=2.44.0; extra == "all"
80
+ Requires-Dist: google-cloud-storage<3.0.0,>=2.18.0; extra == "all"
81
+ Requires-Dist: google-cloud-functions<2.0.0,>=1.16.0; extra == "all"
82
+ Requires-Dist: google-cloud-run<1.0.0,>=0.11.0; extra == "all"
83
+ Requires-Dist: google-cloud-billing<2.0.0,>=1.13.0; extra == "all"
84
+ Requires-Dist: google-cloud-resource-manager<2.0.0,>=1.12.0; extra == "all"
85
+ Requires-Dist: google-auth<3.0.0,>=2.29.0; extra == "all"
86
+ Requires-Dist: google-auth-oauthlib<2.0.0,>=1.2.0; extra == "all"
87
+ Requires-Dist: google-auth-httplib2<1.0.0,>=0.2.0; extra == "all"
88
+ Requires-Dist: paramiko<5.0.0,>=3.4.0; extra == "all"
89
+ Requires-Dist: netifaces<1.0.0,>=0.11.0; extra == "all"
90
+ Requires-Dist: kubernetes<32.0.0,>=29.0.0; extra == "all"
66
91
  Provides-Extra: dev
67
92
  Requires-Dist: pytest<9.0.0,>=8.0.0; extra == "dev"
68
93
  Requires-Dist: pytest-cov<8.0.0,>=5.0.0; extra == "dev"
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "ic-code"
7
- version = "1.3.4"
7
+ version = "1.3.5"
8
8
  authors = [
9
9
  {name = "sykim", email = "cruiser594@gmail.com"},
10
10
  ]
@@ -30,36 +30,16 @@ classifiers = [
30
30
  ]
31
31
  keywords = ["cli", "infrastructure", "aws", "oci", "gcp", "cloudflare", "ssh", "devops", "multi-cloud"]
32
32
  dependencies = [
33
- # Core Cloud SDKs - Compatible with Python 3.9-3.13
34
- "boto3>=1.34.0,<2.0.0", # AWS SDK for Python
35
- "botocore>=1.34.0,<2.0.0", # AWS SDK core library
36
- "oci>=2.149.0,<3.0.0", # Oracle Cloud Infrastructure SDK
33
+ # Core HTTP & Cryptography (NCP native REST & general communication)
37
34
  "requests>=2.31.0,<3.0.0", # HTTP library for API calls
38
- "kubernetes>=29.0.0,<32.0.0", # Kubernetes Python client
39
- "awscli>=1.32.0,<2.0.0", # AWS CLI for additional functionality
35
+ "cryptography>=42.0.0,<50.0.0", # Cryptographic primitives (NCP HMAC signing, security)
40
36
 
41
- # Google Cloud SDKs - Compatible with Python 3.9-3.13
42
- "google-cloud-compute>=1.36.0,<2.0.0", # Google Compute Engine API
43
- "google-cloud-container>=2.44.0,<3.0.0", # Google Kubernetes Engine API
44
- "google-cloud-storage>=2.18.0,<3.0.0", # Google Cloud Storage API
45
- "google-cloud-functions>=1.16.0,<2.0.0", # Google Cloud Functions API
46
- "google-cloud-run>=0.11.0,<1.0.0", # Google Cloud Run API
47
- "google-cloud-billing>=1.13.0,<2.0.0", # Google Cloud Billing API
48
- "google-cloud-resource-manager>=1.12.0,<2.0.0", # Google Cloud Resource Manager API
49
- "google-auth>=2.29.0,<3.0.0", # Google authentication library
50
- "google-auth-oauthlib>=1.2.0,<2.0.0", # Google OAuth2 authentication
51
- "google-auth-httplib2>=0.2.0,<1.0.0", # Google HTTP transport for authentication
52
-
53
- # SSH and Network - Compatible with Python 3.9-3.13
54
- "paramiko>=3.4.0,<5.0.0", # SSH client library
55
- "netifaces>=0.11.0,<1.0.0", # Network interface information
56
-
57
- # CLI User Interface and Output - Compatible with Python 3.9-3.13
37
+ # CLI User Interface and Output
58
38
  "rich>=13.0.0,<15.0.0", # Rich text and beautiful formatting
59
39
  "InquirerPy>=0.3.4,<1.0.0", # Interactive command line prompts
60
40
  "tqdm>=4.67.0,<5.0.0", # Progress bars
61
41
 
62
- # Configuration and Utilities - Compatible with Python 3.9-3.13
42
+ # Configuration and Utilities
63
43
  "python-dotenv>=1.0.0,<2.0.0", # Environment variable loading
64
44
  "python-dateutil>=2.9.0,<3.0.0", # Date/time utilities
65
45
  "PyYAML>=6.0.1,<7.0.0", # YAML parser
@@ -67,11 +47,8 @@ dependencies = [
67
47
  "docutils>=0.19,<1.0.0", # Documentation utilities
68
48
  "invoke>=2.2.0,<3.0.0", # Task execution library
69
49
 
70
- # Security and Validation - Compatible with Python 3.9-3.13
50
+ # Security and Validation
71
51
  "jsonschema>=4.23.0,<5.0.0", # JSON schema validation
72
- "cryptography>=42.0.0,<50.0.0", # Cryptographic recipes and primitives
73
-
74
- # Additional dependencies for config system (v2.0) - Compatible with Python 3.9-3.13
75
52
  "watchdog>=4.0.0,<6.0.0", # File change monitoring
76
53
  "cerberus>=1.3.5,<2.0.0", # Schema validation
77
54
  "pydantic>=2.7.0,<3.0.0", # Data validation and settings management
@@ -79,12 +56,59 @@ dependencies = [
79
56
  # Package management and compatibility
80
57
  "packaging>=24.0,<25.0", # Version parsing and comparison
81
58
  "setuptools>=69.0.0,<76.0.0", # Package building tools
82
-
83
- # Tencent Cloud SDK
84
- "tencentcloud-sdk-python>=3.0.0,<4.0.0", # Tencent Cloud SDK (CVM, CLB, VPC, TKE, Lighthouse, STS)
85
59
  ]
86
60
 
87
61
  [project.optional-dependencies]
62
+ aws = [
63
+ "boto3>=1.34.0,<2.0.0",
64
+ "botocore>=1.34.0,<2.0.0",
65
+ "awscli>=1.32.0,<2.0.0",
66
+ ]
67
+ tencent = [
68
+ "tencentcloud-sdk-python>=3.0.0,<4.0.0",
69
+ ]
70
+ oci = [
71
+ "oci>=2.149.0,<3.0.0",
72
+ ]
73
+ gcp = [
74
+ "google-cloud-compute>=1.36.0,<2.0.0",
75
+ "google-cloud-container>=2.44.0,<3.0.0",
76
+ "google-cloud-storage>=2.18.0,<3.0.0",
77
+ "google-cloud-functions>=1.16.0,<2.0.0",
78
+ "google-cloud-run>=0.11.0,<1.0.0",
79
+ "google-cloud-billing>=1.13.0,<2.0.0",
80
+ "google-cloud-resource-manager>=1.12.0,<2.0.0",
81
+ "google-auth>=2.29.0,<3.0.0",
82
+ "google-auth-oauthlib>=1.2.0,<2.0.0",
83
+ "google-auth-httplib2>=0.2.0,<1.0.0",
84
+ ]
85
+ ssh = [
86
+ "paramiko>=3.4.0,<5.0.0",
87
+ "netifaces>=0.11.0,<1.0.0",
88
+ ]
89
+ k8s = [
90
+ "kubernetes>=29.0.0,<32.0.0",
91
+ ]
92
+ all = [
93
+ "boto3>=1.34.0,<2.0.0",
94
+ "botocore>=1.34.0,<2.0.0",
95
+ "awscli>=1.32.0,<2.0.0",
96
+ "tencentcloud-sdk-python>=3.0.0,<4.0.0",
97
+ "oci>=2.149.0,<3.0.0",
98
+ "google-cloud-compute>=1.36.0,<2.0.0",
99
+ "google-cloud-container>=2.44.0,<3.0.0",
100
+ "google-cloud-storage>=2.18.0,<3.0.0",
101
+ "google-cloud-functions>=1.16.0,<2.0.0",
102
+ "google-cloud-run>=0.11.0,<1.0.0",
103
+ "google-cloud-billing>=1.13.0,<2.0.0",
104
+ "google-cloud-resource-manager>=1.12.0,<2.0.0",
105
+ "google-auth>=2.29.0,<3.0.0",
106
+ "google-auth-oauthlib>=1.2.0,<2.0.0",
107
+ "google-auth-httplib2>=0.2.0,<1.0.0",
108
+ "paramiko>=3.4.0,<5.0.0",
109
+ "netifaces>=0.11.0,<1.0.0",
110
+ "kubernetes>=29.0.0,<32.0.0",
111
+ ]
88
112
  dev = [
89
113
  "pytest>=8.0.0,<9.0.0",
90
114
  "pytest-cov>=5.0.0,<8.0.0",
@@ -64,7 +64,9 @@ def detect_platforms_from_files(changed_files, all_platforms):
64
64
  for file_path in changed_files:
65
65
  for platform in all_platforms:
66
66
  if f"src/ic/platforms/{platform}/" in file_path or \
67
- f"tests/platforms/{platform}/" in file_path:
67
+ f"tests/platforms/{platform}/" in file_path or \
68
+ f"test_{platform}" in file_path or \
69
+ f"_{platform}_" in file_path:
68
70
  detected.add(platform)
69
71
 
70
72
  return list(detected)
@@ -76,16 +78,15 @@ def filter_platforms_with_tests(platforms):
76
78
 
77
79
  for platform in platforms:
78
80
  test_dir = Path(f"tests/platforms/{platform}")
79
- if test_dir.exists():
80
- # Check if there are any test files
81
- test_files = list(test_dir.rglob("test_*.py"))
82
- if test_files:
83
- platforms_with_tests.append(platform)
84
- print(f"✓ Platform {platform} has {len(test_files)} test files")
85
- else:
86
- print(f"⚠ Platform {platform} directory exists but has no test files")
81
+ platform_tests = list(test_dir.rglob("test_*.py")) if test_dir.exists() else []
82
+ unit_tests = list(Path("tests").rglob(f"test_*{platform}*.py"))
83
+
84
+ all_tests = set(platform_tests + unit_tests)
85
+ if all_tests:
86
+ platforms_with_tests.append(platform)
87
+ print(f"✓ Platform {platform} has {len(all_tests)} test files")
87
88
  else:
88
- print(f"⚠ Platform {platform} has no test directory")
89
+ print(f"⚠ Platform {platform} has no test files")
89
90
 
90
91
  return platforms_with_tests
91
92
 
@@ -129,6 +130,11 @@ def main():
129
130
  # Remove duplicates and sort
130
131
  platforms_with_tests = sorted(set(platforms_with_tests))
131
132
 
133
+ # If no platforms with tests detected, fallback to aws
134
+ if not platforms_with_tests:
135
+ print("⚠ No platforms with tests detected, falling back to: aws")
136
+ platforms_with_tests = ["aws"]
137
+
132
138
  # Output as JSON (compact, single line)
133
139
  platforms_json = json.dumps(platforms_with_tests, separators=(',', ':'))
134
140
  print(f"\nFinal platforms to test: {platforms_json}")
@@ -144,7 +150,7 @@ def main():
144
150
  print(f"platforms={platforms_json}")
145
151
  print(f"should-run-tests={'true' if platforms_with_tests else 'false'}")
146
152
 
147
- return 0 if platforms_with_tests else 1
153
+ return 0
148
154
 
149
155
 
150
156
  if __name__ == "__main__":
@@ -0,0 +1,83 @@
1
+ #!/usr/bin/env bash
2
+ # CI Clean Environment Smoke Test Script
3
+ # Verifies that built wheel packages install and run without runtime crashes in a clean environment.
4
+
5
+ set -euo pipefail
6
+
7
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
8
+ REPO_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"
9
+
10
+ echo "=================================================="
11
+ echo "🚀 Running IC CLI Clean Environment Smoke Test"
12
+ echo "=================================================="
13
+
14
+ # Check if dist/ contains a wheel
15
+ DIST_DIR="${REPO_ROOT}/dist"
16
+ WHEEL_FILE=$(find "${DIST_DIR}" -name "ic_code-*.whl" 2>/dev/null | sort -V | tail -n 1 || true)
17
+
18
+ if [ -z "${WHEEL_FILE}" ] || [ ! -f "${WHEEL_FILE}" ]; then
19
+ echo "⚠️ No built wheel found in ${DIST_DIR}. Building package..."
20
+ python3 -m pip install --quiet build
21
+ python3 -m build --wheel "${REPO_ROOT}"
22
+ WHEEL_FILE=$(find "${DIST_DIR}" -name "ic_code-*.whl" | sort -V | tail -n 1)
23
+ fi
24
+
25
+ echo "📦 Target wheel: ${WHEEL_FILE}"
26
+
27
+ # Create isolated temporary virtual environment
28
+ TEMP_VENV=$(mktemp -d -t ic-smoke-venv-XXXXXX)
29
+ echo "📁 Creating temporary virtualenv in ${TEMP_VENV}..."
30
+ python3 -m venv "${TEMP_VENV}"
31
+
32
+ cleanup() {
33
+ echo "🧹 Cleaning up temporary test environment..."
34
+ rm -rf "${TEMP_VENV}"
35
+ }
36
+ trap cleanup EXIT
37
+
38
+ # Activate clean environment
39
+ source "${TEMP_VENV}/bin/activate"
40
+ pip install --upgrade --quiet pip
41
+
42
+ # 1. Test Core Installation (NO cloud extras)
43
+ echo "--------------------------------------------------"
44
+ echo "1️⃣ Testing Minimal Core Installation (No extras)..."
45
+ pip install --quiet "${WHEEL_FILE}"
46
+
47
+ echo " ✓ Checking 'ic --help'..."
48
+ ic --help > /dev/null
49
+
50
+ echo " ✓ Checking 'ic version'..."
51
+ ic version > /dev/null || ic --version > /dev/null
52
+
53
+ echo " ✓ Checking lazy platform help without cloud SDKs (e.g., 'ic tencent --help')..."
54
+ ic tencent --help > /dev/null
55
+ ic aws --help > /dev/null
56
+
57
+ # 2. Test Output formatting in core
58
+ echo "--------------------------------------------------"
59
+ echo "2️⃣ Testing Core Output Formatting & Stderr Separation..."
60
+ HELP_OUTPUT=$(ic --help)
61
+ if [[ -z "${HELP_OUTPUT}" ]]; then
62
+ echo "❌ ERROR: 'ic --help' produced empty output"
63
+ exit 1
64
+ fi
65
+
66
+ # Verify no python traceback in standard help
67
+ if echo "${HELP_OUTPUT}" | grep -i "traceback"; then
68
+ echo "❌ ERROR: Traceback detected in 'ic --help' output"
69
+ exit 1
70
+ fi
71
+
72
+ echo " ✓ Zero-crash parser & lazy-loading validated in isolated venv."
73
+
74
+ # 3. Test Extras Installation syntax
75
+ echo "--------------------------------------------------"
76
+ echo "3️⃣ Testing Extras Resolution (dry-run/compatibility check)..."
77
+ pip install --dry-run "${WHEEL_FILE}[aws]" > /dev/null 2>&1 || {
78
+ echo "⚠️ Warning: pip dry-run not fully supported on this pip version, skipping dry-run."
79
+ }
80
+
81
+ echo "=================================================="
82
+ echo "✅ All Clean Environment Smoke Tests PASSED!"
83
+ echo "=================================================="
@@ -16,6 +16,8 @@ Features:
16
16
 
17
17
  import functools
18
18
  import inspect
19
+ import os
20
+ import sys
19
21
  import threading
20
22
  import time
21
23
  from concurrent.futures import ThreadPoolExecutor, as_completed
@@ -83,13 +85,18 @@ class ProgressBarDecorator:
83
85
  self.show_spinner = show_spinner
84
86
  self.auto_detect = auto_detect
85
87
  self.max_workers = max_workers or 4
86
- self.console = Console() if RICH_AVAILABLE else None
88
+ # Route progress bars to stderr so stdout remains clean for piping (JSON, YAML, jq, etc.)
89
+ self.console = Console(stderr=True) if RICH_AVAILABLE else None
87
90
 
88
91
  def __call__(self, func: Callable) -> Callable:
89
92
  """Apply the progress bar decorator to a function."""
90
93
 
91
94
  @functools.wraps(func)
92
95
  def wrapper(*args, **kwargs):
96
+ # Check if progress bars should be suppressed
97
+ if os.environ.get("IC_DISABLE_PROGRESS_BARS", "").lower() in ("true", "1", "yes"):
98
+ return func(*args, **kwargs)
99
+
93
100
  # Extract function name for default description
94
101
  func_name = getattr(func, '__name__', 'Operation')
95
102
  display_name = self.description or f"Running {func_name.replace('_', ' ').title()}"
@@ -328,17 +335,19 @@ class ProgressBarDecorator:
328
335
 
329
336
  def _fallback_execution(self, func: Callable, description: str, *args, **kwargs) -> Any:
330
337
  """Fallback execution when Rich is not available."""
331
- print(f"Starting: {description}")
338
+ if os.environ.get("IC_DISABLE_PROGRESS_BARS", "").lower() in ("true", "1", "yes"):
339
+ return func(*args, **kwargs)
340
+ print(f"Starting: {description}", file=sys.stderr)
332
341
  start_time = time.time()
333
342
 
334
343
  try:
335
344
  result = func(*args, **kwargs)
336
345
  elapsed = time.time() - start_time
337
- print(f"Completed: {description} (took {elapsed:.2f}s)")
346
+ print(f"Completed: {description} (took {elapsed:.2f}s)", file=sys.stderr)
338
347
  return result
339
348
  except Exception as e:
340
349
  elapsed = time.time() - start_time
341
- print(f"Failed: {description} (took {elapsed:.2f}s) - {str(e)}")
350
+ print(f"Failed: {description} (took {elapsed:.2f}s) - {str(e)}", file=sys.stderr)
342
351
  raise
343
352
 
344
353
 
@@ -416,15 +425,22 @@ class ManualProgress:
416
425
  """
417
426
 
418
427
  def __init__(self, description: str, total: Optional[int] = None, **kwargs):
428
+ import os
419
429
  self.description = description
420
430
  self.total = total
421
431
  self.kwargs = kwargs
422
432
  self.progress = None
423
433
  self.task_id = None
424
- self.console = Console() if RICH_AVAILABLE else None
434
+
435
+ # Check if progress bars should be suppressed
436
+ is_disabled = os.environ.get("IC_DISABLE_PROGRESS_BARS", "").lower() in ("true", "1", "yes")
437
+ self.disabled = is_disabled or kwargs.get("disable", False)
438
+
439
+ # Route progress bars to stderr so stdout remains clean for piping (JSON, YAML, jq, etc.)
440
+ self.console = Console(stderr=True) if (RICH_AVAILABLE and not self.disabled) else None
425
441
 
426
442
  def __enter__(self):
427
- if RICH_AVAILABLE:
443
+ if RICH_AVAILABLE and not self.disabled:
428
444
  columns = [
429
445
  SpinnerColumn(),
430
446
  TextColumn("[progress.description]{task.description}"),
@@ -465,7 +481,8 @@ class ManualProgress:
465
481
  if update_kwargs:
466
482
  self.progress.update(self.task_id, **update_kwargs)
467
483
  elif not RICH_AVAILABLE and description:
468
- print(f"Progress: {description}")
484
+ if not self.disabled:
485
+ print(f"Progress: {description}", file=sys.stderr)
469
486
 
470
487
  def advance(self, amount: int = 1):
471
488
  """Advance progress by specified amount."""
@@ -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.3.4"
7
+ __version__ = "1.3.5"
8
8
  __author__ = "SangYun"
9
9
  __email__ = "cruiser594@gmail.com"
10
10
 
@@ -43,11 +43,9 @@ class DependencyValidator:
43
43
 
44
44
  # Core dependencies required for basic functionality
45
45
  CORE_DEPENDENCIES = {
46
- "boto3": ">=1.26.0",
47
46
  "requests": ">=2.28.0",
48
47
  "rich": ">=12.0.0",
49
48
  "PyYAML": ">=6.0",
50
- "paramiko": ">=2.11.0",
51
49
  "python-dotenv": ">=0.19.0",
52
50
  "cryptography": ">=3.4.8",
53
51
  "tqdm": ">=4.67.0",
@@ -56,9 +54,13 @@ class DependencyValidator:
56
54
  # Optional dependencies for specific cloud platforms
57
55
  OPTIONAL_DEPENDENCIES = {
58
56
  "aws": {
57
+ "boto3": ">=1.26.0",
59
58
  "awscli": ">=1.42.0",
60
59
  "kubernetes": ">=29.0.0",
61
60
  },
61
+ "tencent": {
62
+ "tencentcloud-sdk-python": ">=3.0.0",
63
+ },
62
64
  "oci": {
63
65
  "oci": ">=2.149.0",
64
66
  },
@@ -205,7 +207,7 @@ class DependencyValidator:
205
207
 
206
208
  return all_satisfied
207
209
 
208
- def validate_optional_dependencies(self, platforms: List[str] = None) -> Dict[str, bool]:
210
+ def validate_optional_dependencies(self, platforms: Optional[List[str]] = None) -> Dict[str, bool]:
209
211
  """
210
212
  Validate optional dependencies for specific platforms.
211
213
 
@@ -330,7 +332,7 @@ class DependencyValidator:
330
332
 
331
333
  print("\n" + "="*60)
332
334
 
333
- def validate_all(self, platforms: List[str] = None) -> bool:
335
+ def validate_all(self, platforms: Optional[List[str]] = None) -> bool:
334
336
  """
335
337
  Run complete dependency validation.
336
338
 
@@ -352,7 +354,7 @@ class DependencyValidator:
352
354
  return python_ok and core_ok
353
355
 
354
356
 
355
- def validate_dependencies(platforms: List[str] = None, verbose: bool = True) -> bool:
357
+ def validate_dependencies(platforms: Optional[List[str]] = None, verbose: bool = True) -> bool:
356
358
  """
357
359
  Convenience function to validate dependencies.
358
360