tccli 3.0.1215.1__py2.py3-none-any.whl → 3.0.1217.1__py2.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.
Files changed (282) hide show
  1. tccli/__init__.py +1 -1
  2. tccli/argparser.py +1 -1
  3. tccli/command.py +2 -2
  4. tccli/configure.py +46 -1
  5. tccli/credentials.py +25 -0
  6. tccli/main.py +6 -2
  7. tccli/plugins/sso/__init__.py +61 -0
  8. tccli/plugins/sso/configs.py +4 -0
  9. tccli/plugins/sso/configure.py +45 -0
  10. tccli/plugins/sso/login.py +144 -0
  11. tccli/plugins/sso/logout.py +21 -0
  12. tccli/plugins/sso/terminal.py +161 -0
  13. tccli/plugins/sso/texts.py +40 -0
  14. tccli/services/__init__.py +6 -3
  15. tccli/services/acp/v20220105/api.json +7 -7
  16. tccli/services/acp/v20220105/examples.json +2 -2
  17. tccli/services/aiart/v20221229/api.json +29 -29
  18. tccli/services/aiart/v20221229/examples.json +8 -8
  19. tccli/services/apigateway/v20180808/api.json +18 -17
  20. tccli/services/apigateway/v20180808/examples.json +12 -12
  21. tccli/services/apm/v20210622/api.json +118 -4
  22. tccli/services/asr/v20190614/api.json +21 -20
  23. tccli/services/asr/v20190614/examples.json +13 -13
  24. tccli/services/autoscaling/v20180419/api.json +371 -309
  25. tccli/services/autoscaling/v20180419/examples.json +17 -17
  26. tccli/services/batch/v20170312/api.json +7 -7
  27. tccli/services/bda/v20200324/api.json +39 -31
  28. tccli/services/bda/v20200324/examples.json +9 -9
  29. tccli/services/bh/__init__.py +4 -0
  30. tccli/services/bh/bh_client.py +3428 -0
  31. tccli/services/bh/v20230418/api.json +8180 -0
  32. tccli/services/bh/v20230418/examples.json +519 -0
  33. tccli/services/bi/v20220105/api.json +80 -4
  34. tccli/services/bi/v20220105/examples.json +1 -1
  35. tccli/services/billing/billing_client.py +53 -0
  36. tccli/services/billing/v20180709/api.json +330 -24
  37. tccli/services/billing/v20180709/examples.json +8 -0
  38. tccli/services/bsca/v20210811/api.json +223 -18
  39. tccli/services/bsca/v20210811/examples.json +4 -4
  40. tccli/services/btoe/v20210514/api.json +4 -4
  41. tccli/services/btoe/v20210514/examples.json +2 -2
  42. tccli/services/ca/v20230228/api.json +60 -0
  43. tccli/services/cam/v20190116/api.json +11 -11
  44. tccli/services/cat/v20180409/api.json +9 -0
  45. tccli/services/cbs/v20170312/api.json +200 -188
  46. tccli/services/cbs/v20170312/examples.json +4 -4
  47. tccli/services/ccc/ccc_client.py +53 -0
  48. tccli/services/ccc/v20200210/api.json +541 -325
  49. tccli/services/ccc/v20200210/examples.json +26 -18
  50. tccli/services/cdb/cdb_client.py +13 -13
  51. tccli/services/cdb/v20170320/api.json +308 -274
  52. tccli/services/cdb/v20170320/examples.json +38 -38
  53. tccli/services/cdc/v20201214/api.json +283 -270
  54. tccli/services/cdc/v20201214/examples.json +26 -26
  55. tccli/services/cdn/v20180606/api.json +5 -3
  56. tccli/services/cds/v20180420/api.json +82 -76
  57. tccli/services/cds/v20180420/examples.json +1 -1
  58. tccli/services/cdwch/v20200915/api.json +1 -1
  59. tccli/services/cdwdoris/v20211228/api.json +54 -4
  60. tccli/services/cdz/v20221123/api.json +41 -5
  61. tccli/services/cfg/v20210820/api.json +31 -0
  62. tccli/services/cfs/v20190719/api.json +89 -1
  63. tccli/services/cfs/v20190719/examples.json +1 -1
  64. tccli/services/cfw/cfw_client.py +0 -53
  65. tccli/services/cfw/v20190904/api.json +1895 -2011
  66. tccli/services/cfw/v20190904/examples.json +175 -171
  67. tccli/services/ciam/v20220331/api.json +316 -315
  68. tccli/services/ciam/v20220331/examples.json +49 -49
  69. tccli/services/ckafka/v20190819/api.json +104 -75
  70. tccli/services/clb/v20180317/api.json +48 -26
  71. tccli/services/clb/v20180317/examples.json +1 -1
  72. tccli/services/cloudapp/v20220530/api.json +5 -1
  73. tccli/services/cloudaudit/cloudaudit_client.py +30 -30
  74. tccli/services/cloudaudit/v20190319/api.json +254 -211
  75. tccli/services/cloudaudit/v20190319/examples.json +19 -19
  76. tccli/services/cloudstudio/v20230508/api.json +38 -37
  77. tccli/services/cloudstudio/v20230508/examples.json +4 -4
  78. tccli/services/cls/cls_client.py +216 -4
  79. tccli/services/cls/v20201016/api.json +935 -147
  80. tccli/services/cls/v20201016/examples.json +43 -5
  81. tccli/services/csip/v20221121/api.json +2566 -2386
  82. tccli/services/csip/v20221121/examples.json +108 -108
  83. tccli/services/cvm/v20170312/api.json +191 -112
  84. tccli/services/cvm/v20170312/examples.json +2 -2
  85. tccli/services/cwp/cwp_client.py +4 -110
  86. tccli/services/cwp/v20180228/api.json +6498 -6252
  87. tccli/services/cwp/v20180228/examples.json +372 -412
  88. tccli/services/cynosdb/v20190107/api.json +170 -110
  89. tccli/services/cynosdb/v20190107/examples.json +91 -91
  90. tccli/services/dasb/v20191018/api.json +859 -637
  91. tccli/services/dasb/v20191018/examples.json +101 -101
  92. tccli/services/dcdb/dcdb_client.py +114 -61
  93. tccli/services/dcdb/v20180411/api.json +141 -7
  94. tccli/services/dcdb/v20180411/examples.json +32 -0
  95. tccli/services/dlc/v20210125/api.json +21 -11
  96. tccli/services/dnspod/dnspod_client.py +417 -46
  97. tccli/services/dnspod/v20210323/api.json +751 -30
  98. tccli/services/dnspod/v20210323/examples.json +62 -0
  99. tccli/services/domain/v20180808/api.json +3 -3
  100. tccli/services/domain/v20180808/examples.json +3 -3
  101. tccli/services/dts/v20211206/api.json +4 -4
  102. tccli/services/eb/v20210416/api.json +15 -15
  103. tccli/services/eb/v20210416/examples.json +1 -1
  104. tccli/services/ecm/v20190719/api.json +2 -2
  105. tccli/services/emr/v20190103/api.json +339 -114
  106. tccli/services/emr/v20190103/examples.json +64 -82
  107. tccli/services/es/es_client.py +249 -37
  108. tccli/services/es/v20180416/api.json +550 -0
  109. tccli/services/es/v20180416/examples.json +33 -1
  110. tccli/services/ess/ess_client.py +53 -0
  111. tccli/services/ess/v20201111/api.json +192 -38
  112. tccli/services/ess/v20201111/examples.json +35 -9
  113. tccli/services/essbasic/essbasic_client.py +106 -0
  114. tccli/services/essbasic/v20210526/api.json +287 -60
  115. tccli/services/essbasic/v20210526/examples.json +58 -18
  116. tccli/services/facefusion/v20181201/api.json +47 -45
  117. tccli/services/facefusion/v20181201/examples.json +2 -2
  118. tccli/services/facefusion/v20220927/api.json +54 -48
  119. tccli/services/facefusion/v20220927/examples.json +5 -5
  120. tccli/services/faceid/v20180301/api.json +497 -496
  121. tccli/services/faceid/v20180301/examples.json +219 -101
  122. tccli/services/fmu/v20191213/api.json +59 -67
  123. tccli/services/fmu/v20191213/examples.json +22 -22
  124. tccli/services/ft/v20200304/api.json +53 -57
  125. tccli/services/ft/v20200304/examples.json +14 -14
  126. tccli/services/gaap/v20180529/api.json +44 -26
  127. tccli/services/gaap/v20180529/examples.json +24 -30
  128. tccli/services/gme/v20180711/api.json +21 -11
  129. tccli/services/gme/v20180711/examples.json +1 -1
  130. tccli/services/hai/v20230812/api.json +116 -9
  131. tccli/services/hai/v20230812/examples.json +4 -4
  132. tccli/services/hunyuan/hunyuan_client.py +436 -12
  133. tccli/services/hunyuan/v20230901/api.json +1482 -118
  134. tccli/services/hunyuan/v20230901/examples.json +82 -18
  135. tccli/services/iai/v20180301/api.json +23 -19
  136. tccli/services/iai/v20180301/examples.json +2 -2
  137. tccli/services/iai/v20200303/api.json +530 -511
  138. tccli/services/iai/v20200303/examples.json +116 -86
  139. tccli/services/ig/__init__.py +4 -0
  140. tccli/services/ig/ig_client.py +195 -0
  141. tccli/services/ig/v20210518/api.json +83 -0
  142. tccli/services/ig/v20210518/examples.json +13 -0
  143. tccli/services/ioa/ioa_client.py +53 -0
  144. tccli/services/ioa/v20220601/api.json +662 -413
  145. tccli/services/ioa/v20220601/examples.json +24 -10
  146. tccli/services/iotexplorer/v20190423/api.json +73 -13
  147. tccli/services/iotexplorer/v20190423/examples.json +3 -3
  148. tccli/services/iotvideo/iotvideo_client.py +106 -0
  149. tccli/services/iotvideo/v20191126/api.json +256 -24
  150. tccli/services/iotvideo/v20191126/examples.json +19 -3
  151. tccli/services/iotvideo/v20201215/api.json +1 -1
  152. tccli/services/iotvideo/v20201215/examples.json +1 -1
  153. tccli/services/iotvideo/v20211125/api.json +1 -1
  154. tccli/services/iotvideo/v20211125/examples.json +2 -2
  155. tccli/services/iss/iss_client.py +69 -122
  156. tccli/services/iss/v20230517/api.json +10 -54
  157. tccli/services/iss/v20230517/examples.json +0 -14
  158. tccli/services/kms/v20190118/api.json +301 -268
  159. tccli/services/kms/v20190118/examples.json +45 -51
  160. tccli/services/lcic/lcic_client.py +159 -0
  161. tccli/services/lcic/v20220817/api.json +273 -1
  162. tccli/services/lcic/v20220817/examples.json +24 -0
  163. tccli/services/lighthouse/v20200324/api.json +56 -0
  164. tccli/services/live/live_client.py +159 -0
  165. tccli/services/live/v20180801/api.json +279 -9
  166. tccli/services/live/v20180801/examples.json +24 -0
  167. tccli/services/lke/v20231130/api.json +17 -17
  168. tccli/services/lke/v20231130/examples.json +19 -25
  169. tccli/services/mariadb/v20170312/api.json +7 -7
  170. tccli/services/market/v20191010/api.json +3 -3
  171. tccli/services/market/v20191010/examples.json +2 -2
  172. tccli/services/mmps/v20200710/api.json +47 -47
  173. tccli/services/mmps/v20200710/examples.json +3 -3
  174. tccli/services/mongodb/v20190725/api.json +10 -12
  175. tccli/services/monitor/v20180724/api.json +46 -19
  176. tccli/services/mps/v20190612/api.json +282 -5
  177. tccli/services/mps/v20190612/examples.json +25 -1
  178. tccli/services/mqtt/v20240516/api.json +2 -2
  179. tccli/services/mrs/v20200910/api.json +72 -34
  180. tccli/services/mrs/v20200910/examples.json +2 -2
  181. tccli/services/ms/v20180408/api.json +535 -506
  182. tccli/services/ms/v20180408/examples.json +25 -25
  183. tccli/services/oceanus/v20190422/api.json +130 -0
  184. tccli/services/ocr/ocr_client.py +232 -20
  185. tccli/services/ocr/v20181119/api.json +2263 -758
  186. tccli/services/ocr/v20181119/examples.json +200 -180
  187. tccli/services/omics/v20221128/api.json +614 -553
  188. tccli/services/omics/v20221128/examples.json +9 -9
  189. tccli/services/organization/organization_client.py +352 -34
  190. tccli/services/organization/v20210331/api.json +464 -4
  191. tccli/services/organization/v20210331/examples.json +49 -1
  192. tccli/services/partners/v20180321/api.json +244 -234
  193. tccli/services/partners/v20180321/examples.json +19 -19
  194. tccli/services/privatedns/privatedns_client.py +428 -4
  195. tccli/services/privatedns/v20201028/api.json +815 -11
  196. tccli/services/privatedns/v20201028/examples.json +64 -0
  197. tccli/services/pts/v20210728/api.json +18 -0
  198. tccli/services/pts/v20210728/examples.json +1 -1
  199. tccli/services/rce/rce_client.py +53 -0
  200. tccli/services/rce/v20201103/api.json +146 -0
  201. tccli/services/rce/v20201103/examples.json +8 -0
  202. tccli/services/redis/v20180412/api.json +42 -42
  203. tccli/services/redis/v20180412/examples.json +19 -19
  204. tccli/services/region/v20220627/api.json +1 -1
  205. tccli/services/rum/v20210622/api.json +9 -0
  206. tccli/services/scf/scf_client.py +269 -4
  207. tccli/services/scf/v20180416/api.json +569 -15
  208. tccli/services/scf/v20180416/examples.json +47 -1
  209. tccli/services/smop/v20201203/api.json +46 -42
  210. tccli/services/smop/v20201203/examples.json +2 -2
  211. tccli/services/soe/v20180724/api.json +10 -10
  212. tccli/services/sqlserver/v20180328/api.json +21 -8
  213. tccli/services/sqlserver/v20180328/examples.json +5 -5
  214. tccli/services/ssl/v20191205/api.json +98 -5
  215. tccli/services/ssm/v20190923/api.json +292 -231
  216. tccli/services/ssm/v20190923/examples.json +42 -42
  217. tccli/services/tat/v20201028/api.json +124 -122
  218. tccli/services/tat/v20201028/examples.json +24 -30
  219. tccli/services/tchd/v20230306/api.json +5 -5
  220. tccli/services/tchd/v20230306/examples.json +3 -3
  221. tccli/services/tcr/v20190924/api.json +1 -1
  222. tccli/services/tcr/v20190924/examples.json +1 -1
  223. tccli/services/tcss/v20201101/api.json +1984 -1437
  224. tccli/services/tcss/v20201101/examples.json +350 -368
  225. tccli/services/tdmq/v20200217/api.json +603 -464
  226. tccli/services/tdmq/v20200217/examples.json +105 -105
  227. tccli/services/tds/v20220801/api.json +4 -4
  228. tccli/services/tem/v20210701/api.json +429 -372
  229. tccli/services/tem/v20210701/examples.json +85 -85
  230. tccli/services/teo/teo_client.py +277 -12
  231. tccli/services/teo/v20220901/api.json +1029 -124
  232. tccli/services/teo/v20220901/examples.json +84 -8
  233. tccli/services/thpc/v20230321/api.json +5 -5
  234. tccli/services/tke/tke_client.py +270 -58
  235. tccli/services/tke/v20180525/api.json +79 -27
  236. tccli/services/tke/v20180525/examples.json +9 -1
  237. tccli/services/tke/v20220501/api.json +176 -0
  238. tccli/services/tke/v20220501/examples.json +24 -0
  239. tccli/services/tms/tms_client.py +4 -57
  240. tccli/services/tms/v20201229/api.json +0 -354
  241. tccli/services/tms/v20201229/examples.json +0 -8
  242. tccli/services/tmt/v20180321/api.json +38 -8
  243. tccli/services/trp/v20210515/api.json +86 -74
  244. tccli/services/trp/v20210515/examples.json +65 -65
  245. tccli/services/trro/v20220325/api.json +72 -71
  246. tccli/services/trro/v20220325/examples.json +8 -8
  247. tccli/services/trtc/trtc_client.py +8 -61
  248. tccli/services/trtc/v20190722/api.json +293 -52
  249. tccli/services/trtc/v20190722/examples.json +3 -11
  250. tccli/services/tse/tse_client.py +110 -4
  251. tccli/services/tse/v20201207/api.json +122 -7
  252. tccli/services/tse/v20201207/examples.json +25 -9
  253. tccli/services/vclm/v20240523/api.json +225 -82
  254. tccli/services/vclm/v20240523/examples.json +13 -19
  255. tccli/services/vod/v20180717/api.json +431 -4
  256. tccli/services/vod/v20180717/examples.json +25 -5
  257. tccli/services/vod/v20240718/api.json +11 -11
  258. tccli/services/vod/v20240718/examples.json +4 -4
  259. tccli/services/vod/vod_client.py +53 -0
  260. tccli/services/vpc/v20170312/api.json +1195 -892
  261. tccli/services/vpc/v20170312/examples.json +84 -68
  262. tccli/services/vpc/vpc_client.py +168 -62
  263. tccli/services/waf/v20180125/api.json +2611 -2187
  264. tccli/services/waf/v20180125/examples.json +224 -284
  265. tccli/services/waf/waf_client.py +225 -119
  266. tccli/services/wav/v20210129/api.json +48 -48
  267. tccli/services/wav/v20210129/examples.json +4 -4
  268. tccli/services/wedata/v20210820/api.json +1595 -25
  269. tccli/services/wedata/v20210820/examples.json +44 -4
  270. tccli/services/wedata/wedata_client.py +265 -0
  271. tccli/services/weilingwith/v20230427/api.json +6 -6
  272. tccli/services/weilingwith/v20230427/examples.json +3 -3
  273. tccli/sso.py +229 -0
  274. {tccli-3.0.1215.1.dist-info → tccli-3.0.1217.1.dist-info}/METADATA +6 -2
  275. {tccli-3.0.1215.1.dist-info → tccli-3.0.1217.1.dist-info}/RECORD +278 -265
  276. tccli/services/cr/__init__.py +0 -4
  277. tccli/services/cr/cr_client.py +0 -1626
  278. tccli/services/cr/v20180321/api.json +0 -2829
  279. tccli/services/cr/v20180321/examples.json +0 -235
  280. {tccli-3.0.1215.1.dist-info → tccli-3.0.1217.1.dist-info}/WHEEL +0 -0
  281. {tccli-3.0.1215.1.dist-info → tccli-3.0.1217.1.dist-info}/entry_points.txt +0 -0
  282. {tccli-3.0.1215.1.dist-info → tccli-3.0.1217.1.dist-info}/license_files/LICENSE +0 -0
tccli/__init__.py CHANGED
@@ -1 +1 @@
1
- __version__ = '3.0.1215.1'
1
+ __version__ = '3.0.1217.1'
tccli/argparser.py CHANGED
@@ -58,7 +58,7 @@ class BaseArgParser(argparse.ArgumentParser):
58
58
  def parse_known_args(self, args=None, namespace=None):
59
59
  parsed, remaining = super(BaseArgParser, self).parse_known_args(args, namespace)
60
60
  terminal_encoding = getattr(sys.stdin, 'encoding', 'utf-8')
61
- if terminal_encoding is None:
61
+ if terminal_encoding is None or terminal_encoding == 'cp65001':
62
62
  terminal_encoding = 'utf-8'
63
63
  for arg, value in vars(parsed).items():
64
64
  if isinstance(value, six.binary_type):
tccli/command.py CHANGED
@@ -7,7 +7,7 @@ import tccli.services as Services
7
7
  import tccli.options_define as Options_define
8
8
  from collections import OrderedDict
9
9
 
10
- from tccli import oauth
10
+ from tccli import credentials
11
11
  from tccli.utils import Utils
12
12
  from tccli.argument import CLIArgument, CustomArgument, ListArgument, BooleanArgument
13
13
  from tccli.exceptions import UnknownArgumentError
@@ -291,7 +291,7 @@ class ActionCommand(BaseCommand):
291
291
  action_parameters = self.cli_unfold_argument.build_action_parameters(parsed_args)
292
292
  else:
293
293
  action_parameters = self._build_action_parameters(parsed_args, self.argument_map)
294
- oauth.maybe_refresh_credential(parsed_globals.profile if parsed_globals.profile else "default")
294
+ credentials.maybe_refresh_credential(parsed_globals.profile if parsed_globals.profile else "default")
295
295
  return self._action_caller(action_parameters, vars(parsed_globals))
296
296
 
297
297
  def create_help_command(self):
tccli/configure.py CHANGED
@@ -230,6 +230,50 @@ class ConfigureSetCommand(BasicConfigure):
230
230
  self._init_configure(profile_name + '.credential', cred)
231
231
 
232
232
 
233
+ class ConfigureSetRootDomainCommand(BasicConfigure):
234
+ NAME = 'set-root-domain'
235
+ DESCRIPTION = 'Set the root domain name for all endpoints.'
236
+ USEAGE = 'tccli configure set-root-domain [root-domain-value] [--profile profile-name]'
237
+ AVAILABLECONFIG = "[cvm, cbs ...].endpoint: service [cvm cbs ...] access point root domain name"
238
+ EXAMPLES = "$ tccli configure set-root-domain internal.tencentcloudapi.com --profile test"
239
+ ARG_TABLE = [
240
+ {'name': 'varname',
241
+ 'help_text': 'The name of the root domain value to set.',
242
+ 'action': 'store',
243
+ 'nargs': '+',
244
+ 'cli_type_name': 'string',
245
+ 'positional_arg': True},
246
+ ]
247
+
248
+ def __init__(self):
249
+ super(ConfigureSetRootDomainCommand, self).__init__()
250
+
251
+ def _run_main(self, args, parsed_globals):
252
+ var_value = args.varname
253
+ if len(var_value) != 1:
254
+ raise ParamError("Unexpected format\n"
255
+ "Expected input format:\n\n"
256
+ " $tccli configure set-root-domain internal.tencentcloudapi.com\n")
257
+ profile_name = self._get_profile_name(parsed_globals)
258
+ profile_name = profile_name + '.configure'
259
+
260
+ conf_data = {}
261
+ is_exist, config_path = self._profile_existed(profile_name)
262
+ if is_exist:
263
+ conf_data = Utils.load_json_msg(config_path)
264
+ if profile_name.endswith(".configure"):
265
+ for mod in self._cli_data.get_available_services().keys():
266
+ if mod not in conf_data:
267
+ conf_data[mod] = {}
268
+ conf_data[mod]["endpoint"] = "%s.tencentcloudapi.com" % mod
269
+ if mod != 'autoscaling':
270
+ conf_data[mod]["endpoint"] = "%s.%s" % (mod, var_value[0])
271
+ else:
272
+ conf_data[mod]["endpoint"] = "as.%s" % var_value[0]
273
+ conf_data[mod]["version"] = self._cli_data.get_available_services()[mod][0]
274
+ Utils.dump_json_msg(config_path, conf_data)
275
+
276
+
233
277
  class ConfigureGetCommand(BasicConfigure):
234
278
  NAME = 'get'
235
279
  DESCRIPTION = "get your profile(eg:SecretId, SecretKey, Region)."
@@ -342,7 +386,8 @@ class ConfigureCommand(BasicConfigure):
342
386
  {'name': 'list', 'command_class': ConfigureListCommand},
343
387
  {'name': 'get', 'command_class': ConfigureGetCommand},
344
388
  {'name': 'set', 'command_class': ConfigureSetCommand},
345
- {'name': 'remove', 'command_class': ConfigureRemoveCommand}
389
+ {'name': 'remove', 'command_class': ConfigureRemoveCommand},
390
+ {'name': 'set-root-domain', 'command_class': ConfigureSetRootDomainCommand},
346
391
  ]
347
392
 
348
393
  VALUES_TO_PROMPT = [
tccli/credentials.py ADDED
@@ -0,0 +1,25 @@
1
+ import json
2
+ import os
3
+
4
+ from tccli import oauth, sso
5
+
6
+
7
+ def maybe_refresh_credential(profile):
8
+ try:
9
+ with open(cred_path_of_profile(profile), "r") as cred_file:
10
+ cred = json.load(cred_file)
11
+ except IOError:
12
+ # file not found, don't check
13
+ return
14
+
15
+ if cred.get("type", "") == "oauth":
16
+ oauth.maybe_refresh_credential(profile)
17
+ return
18
+
19
+ if cred.get("type", "") == "sso":
20
+ sso.maybe_refresh_credential(profile)
21
+ return
22
+
23
+
24
+ def cred_path_of_profile(profile):
25
+ return os.path.join(os.path.expanduser("~"), ".tccli", profile + ".credential")
tccli/main.py CHANGED
@@ -4,14 +4,18 @@ import _locale
4
4
  _locale._getdefaultlocale = (lambda *args: ['zh_CN', 'utf8'])
5
5
 
6
6
  import io
7
- import os
8
7
  import sys
9
8
  import six
10
- import signal
11
9
  from tccli.log import init
12
10
  from tencentcloud.common.exception.tencent_cloud_sdk_exception import TencentCloudSDKException
13
11
 
14
12
  try:
13
+ # cp65001 is utf-8 on windows platform
14
+ # python2 doesn't support cp65001 codec
15
+ if getattr(sys.stdin, 'encoding', 'utf-8') == "cp65001":
16
+ import codecs
17
+ codecs.register(lambda name: codecs.lookup('utf-8') if name == 'cp65001' else None)
18
+
15
19
  reload(sys) # Python 2.7
16
20
  sys.setdefaultencoding('utf8')
17
21
  except NameError:
@@ -0,0 +1,61 @@
1
+ # encoding: utf-8
2
+ from tccli.plugins.sso.login import login_command_entrypoint
3
+ from tccli.plugins.sso.logout import logout_command_entrypoint
4
+ from tccli.plugins.sso.configure import configure_command_entrypoint
5
+
6
+ service_name = "sso"
7
+ service_version = "2024-10-14"
8
+
9
+ _spec = {
10
+ "metadata": {
11
+ "serviceShortName": service_name,
12
+ "apiVersion": service_version,
13
+ "description": "sso related commands",
14
+ },
15
+ "actions": {
16
+ "configure": {
17
+ "name": "配置",
18
+ "document": "configure login url",
19
+ "input": "configureRequest",
20
+ "output": "configureResponse",
21
+ "action_caller": configure_command_entrypoint,
22
+ },
23
+ "login": {
24
+ "name": "登录",
25
+ "document": "login through sso",
26
+ "input": "loginRequest",
27
+ "output": "loginResponse",
28
+ "action_caller": login_command_entrypoint,
29
+ },
30
+ "logout": {
31
+ "name": "登出",
32
+ "document": "remove local credential file",
33
+ "input": "logoutRequest",
34
+ "output": "logoutResponse",
35
+ "action_caller": logout_command_entrypoint,
36
+ },
37
+ },
38
+ "objects": {
39
+ "loginRequest": {"members": []},
40
+ "loginResponse": {"members": []},
41
+ "logoutRequest": {"members": []},
42
+ "logoutResponse": {"members": []},
43
+ "configureRequest": {"members": [
44
+ {
45
+ "name": "url",
46
+ "member": "string",
47
+ "type": "string",
48
+ "required": True,
49
+ "document": "url for sso authentication",
50
+ },
51
+ ]},
52
+ "configureResponse": {"members": []},
53
+ },
54
+ "version": "1.0",
55
+ }
56
+
57
+
58
+ def register_service(specs):
59
+ specs[service_name] = {
60
+ service_version: _spec,
61
+ }
@@ -0,0 +1,4 @@
1
+ # encoding: utf-8
2
+ CLI_URL = "https://cli.cloud.tencent.com/sso"
3
+ SITE = "cn"
4
+ DEFAULT_LANG = "zh-CN"
@@ -0,0 +1,45 @@
1
+ # coding: utf-8
2
+ import json
3
+ try:
4
+ from urlparse import urlparse
5
+ except ImportError:
6
+ from urllib.parse import urlparse
7
+
8
+ from tccli import sso
9
+ from tccli.plugins.sso import texts, configs
10
+
11
+
12
+ def configure_command_entrypoint(args, parsed_globals):
13
+ language = parsed_globals.get("language")
14
+ if not language:
15
+ language = configs.DEFAULT_LANG
16
+ texts.set_lang(language)
17
+
18
+ profile = parsed_globals.get("profile", "default")
19
+ if not profile:
20
+ profile = "default"
21
+
22
+ cred_data = {}
23
+ try:
24
+ with open(sso.cred_path_of_profile(profile), "r") as cred_file:
25
+ cred_data = json.load(cred_file)
26
+ except IOError:
27
+ pass
28
+
29
+ if "sso" not in cred_data:
30
+ cred_data["sso"] = {}
31
+
32
+ auth_url = args.get("url")
33
+ if not auth_url.startswith("http://") and not auth_url.startswith("https://"):
34
+ auth_url = "https://" + auth_url
35
+
36
+ parsed_url = urlparse(auth_url)
37
+ if not (parsed_url.scheme in ("http", "https") and parsed_url.netloc):
38
+ print(texts.get("invalid_auth_url") % auth_url)
39
+ return
40
+
41
+ cred_data["sso"]["authUrl"] = auth_url
42
+ with open(sso.cred_path_of_profile(profile), "w") as cred_file:
43
+ json.dump(cred_data, cred_file, indent=4)
44
+
45
+ print(texts.get("configure_succeed") % auth_url)
@@ -0,0 +1,144 @@
1
+ # coding: utf-8
2
+ import json
3
+ import os.path
4
+ import random
5
+ import string
6
+ import sys
7
+ import time
8
+ import uuid
9
+ import webbrowser
10
+
11
+ from six.moves.urllib.parse import urlencode
12
+
13
+ from tccli import sso
14
+ from tccli.plugins.sso import texts, terminal, configs
15
+ from tccli.plugins.sso.texts import get as _
16
+
17
+
18
+ def print_message(msg):
19
+ print(msg)
20
+ sys.stdout.flush()
21
+
22
+
23
+ def login_command_entrypoint(args, parsed_globals):
24
+ language = parsed_globals.get("language")
25
+ if not language:
26
+ language = configs.DEFAULT_LANG
27
+ texts.set_lang(language)
28
+
29
+ profile = parsed_globals.get("profile", "default")
30
+ if not profile:
31
+ profile = "default"
32
+
33
+ login(profile, language)
34
+
35
+
36
+ def login(profile, language):
37
+ cred_path = sso.cred_path_of_profile(profile)
38
+ auth_url = ""
39
+ if os.path.exists(cred_path):
40
+ with open(cred_path, "r") as cred_file:
41
+ cred_data = json.load(cred_file)
42
+ auth_url = cred_data.get("sso", {}).get("authUrl", "")
43
+
44
+ if not auth_url:
45
+ profile_opt = ""
46
+ if profile != "default":
47
+ profile_opt = "--profile %s " % profile
48
+ print_message(_("auth_url_not_configured") % profile_opt)
49
+ return
50
+
51
+ characters = string.ascii_letters + string.digits
52
+ state = ''.join(random.choice(characters) for x in range(32))
53
+
54
+ token = _get_token(auth_url, state, language)
55
+
56
+ if token["State"] != state:
57
+ raise ValueError("invalid state %s" % token["state"])
58
+
59
+ print_message("")
60
+
61
+ login_token = token["Token"]
62
+ site = token["Site"]
63
+ accounts = sso.list_accounts_for_access_assignment(login_token, site)
64
+ if not accounts:
65
+ print_message(_("no_account"))
66
+ return
67
+
68
+ idx = terminal.select_from_items(
69
+ _("account_select_prompt"), ["%s:%s" % (x["Name"], x["Uin"]) for x in accounts], 10)
70
+ account = accounts[idx]
71
+ print_message("uin: %s" % account["Uin"])
72
+ print_message("username: %s" % account["Name"])
73
+
74
+ roles = sso.list_role_configurations_for_account(account["Uin"], login_token, site)
75
+ if not roles:
76
+ print_message(_("no_role"))
77
+ return
78
+
79
+ idx = terminal.select_from_items(
80
+ _("role_select_prompt"), [x["RoleConfigurationName"] for x in roles], 10)
81
+ role = roles[idx]
82
+ print_message("role: %s" % role["RoleConfigurationName"])
83
+
84
+ saml_resp = sso.gen_saml_response(
85
+ login_token, "RoleSAML", account["Uin"], "", role["RoleConfigurationId"], site)
86
+
87
+ token_info = sso.verify_login_skey(login_token, site)
88
+
89
+ role_arn = "qcs::cam::uin/%s:roleName/TencentCloudSSO-%s" % (account["Uin"], role["RoleConfigurationName"])
90
+ principal_arn = "qcs::cam::uin/%s:saml-provider/TencentReservedSSO-%s" % (account["Uin"], token_info["ZoneId"])
91
+ cred = sso.assume_role_with_saml(
92
+ saml_resp["SAMLResponse"], principal_arn, role_arn, "ses-%s" % uuid.uuid4(), 7200, site)
93
+
94
+ sso_info = {
95
+ "token": login_token,
96
+ "uin": account["Uin"],
97
+ "roleConfigurationId": role["RoleConfigurationId"],
98
+ "roleConfigurationName": role["RoleConfigurationName"],
99
+ "zoneId": token_info["ZoneId"],
100
+ "site": site,
101
+ "authUrl": auth_url,
102
+ "expiresAt": int(time.time()) + 3600 * 12,
103
+ }
104
+ sso.save_credential(cred, sso_info, profile)
105
+
106
+ print_message(_("login_success") % sso.cred_path_of_profile(profile))
107
+
108
+
109
+ def _get_token(auth_url, state, language):
110
+ cli_params = {
111
+ "lang": language,
112
+ "site": configs.SITE,
113
+ "state": state,
114
+ }
115
+ cli_query = urlencode(cli_params)
116
+ cli_url = configs.CLI_URL + "?" + cli_query
117
+ url_params = {
118
+ "loginType": "tccli",
119
+ "callback": cli_url,
120
+ "state": state,
121
+ }
122
+ url_query = urlencode(url_params)
123
+ auth_url = auth_url + "?" + url_query
124
+
125
+ print_message(_("try_login_with_url"))
126
+ print_message("")
127
+ print_message(auth_url)
128
+
129
+ webbrowser.open(auth_url)
130
+
131
+ while True:
132
+ time.sleep(1)
133
+
134
+ login_state = sso.check_login_state(state)
135
+ if "Error" in login_state:
136
+ raise ValueError(login_state["Error"])
137
+
138
+ if login_state["Status"] == "NotFound":
139
+ continue
140
+
141
+ if login_state["Status"] == "Finished":
142
+ return login_state["Token"]
143
+
144
+ raise ValueError("invalid resp: %s" % login_state)
@@ -0,0 +1,21 @@
1
+ # coding: utf-8
2
+ import os
3
+
4
+ from tccli import sso
5
+ from tccli.plugins.sso import texts, configs
6
+
7
+
8
+ def logout_command_entrypoint(args, parsed_globals):
9
+ language = parsed_globals.get("language")
10
+ if not language:
11
+ language = configs.DEFAULT_LANG
12
+ texts.set_lang(language)
13
+
14
+ profile = parsed_globals.get("profile", "default")
15
+ if not profile:
16
+ profile = "default"
17
+
18
+ cred_path = sso.cred_path_of_profile(profile)
19
+ if os.path.exists(cred_path):
20
+ os.remove(cred_path)
21
+ print(texts.get("logout_success") % cred_path)
@@ -0,0 +1,161 @@
1
+ # encoding: utf-8
2
+ import math
3
+ import sys
4
+ import os
5
+ from string import ascii_letters, digits, punctuation
6
+
7
+ _LEFT_ARROW = "LEFT_ARROW"
8
+ _RIGHT_ARROW = "RIGHT_ARROW"
9
+ _UP_ARROW = "UP_ARROW"
10
+ _DOWN_ARROW = "DOWN_ARROW"
11
+ _CTRL_C = "\x03"
12
+ _ENTER = "\r"
13
+ _BACKSPACE = "\x7f"
14
+ _EL = "\033[K"
15
+ _CPL = "\033[F"
16
+ _LIGHTBLUE = "\033[94m"
17
+ _LIGHTBLUE_END = "\033[0m"
18
+
19
+ _win = os.name == "nt"
20
+
21
+
22
+ class Printer(object):
23
+ def __init__(self):
24
+ self._n = 0
25
+
26
+ def print_lines(self, lines):
27
+ self.clear()
28
+ lines = [line + '\n' for line in lines]
29
+ sys.stdout.writelines(lines)
30
+ sys.stdout.flush()
31
+ self._n = len(lines)
32
+
33
+ def clear(self):
34
+ for _ in range(self._n):
35
+ self.move_up()
36
+ self.clear_cur_line()
37
+
38
+ @staticmethod
39
+ def clear_cur_line():
40
+ sys.stdout.write(_EL)
41
+
42
+ @staticmethod
43
+ def move_up():
44
+ sys.stdout.write(_CPL)
45
+
46
+
47
+ def _select_from_items_unix(prompt, items, page_size):
48
+ p = Printer()
49
+
50
+ selection = 0
51
+ search = ""
52
+
53
+ while True:
54
+ filtered_items = [item for item in items if search in item] if search else items
55
+
56
+ page_total = math.ceil(len(filtered_items) / float(page_size))
57
+ page_num = selection // page_size + 1
58
+ page_start = page_size * (page_num - 1)
59
+ page_items = list(filtered_items[page_start: page_start + page_size])
60
+
61
+ for i in range(len(page_items)):
62
+ selection_i = selection % page_size
63
+ selection_prompt = "* " if i == selection_i else " "
64
+ page_items[i] = selection_prompt + _LIGHTBLUE + page_items[i] + _LIGHTBLUE_END
65
+
66
+ page_lines = ["", "%s%s" % (prompt, search), ""] + page_items + ["", "page: %d/%d" % (page_num, page_total)]
67
+ p.print_lines(page_lines)
68
+
69
+ ch = _getch_wrap()
70
+
71
+ if ch == _CTRL_C:
72
+ raise KeyboardInterrupt()
73
+
74
+ if ch == _UP_ARROW:
75
+ selection = max(0, selection - 1)
76
+ elif ch == _DOWN_ARROW:
77
+ selection = min(len(filtered_items) - 1, selection + 1)
78
+ elif ch == _LEFT_ARROW:
79
+ if selection - page_size >= 0:
80
+ selection -= page_size
81
+ elif ch == _RIGHT_ARROW:
82
+ selection = min(len(filtered_items) - 1, selection + page_size)
83
+ elif ch == _BACKSPACE:
84
+ search = search[:len(search) - 1] if search else ""
85
+ selection = 0
86
+ elif ch == _ENTER:
87
+ idx = 0
88
+ matched = -1
89
+
90
+ for item in items:
91
+ if search in item:
92
+ matched += 1
93
+ if matched == selection:
94
+ p.print_lines([])
95
+ return idx
96
+ idx += 1
97
+
98
+ elif ch in (ascii_letters + digits + punctuation):
99
+ search += ch
100
+ selection = 0
101
+
102
+
103
+ def _select_from_items_win(prompt, items, page_size):
104
+ print("")
105
+ print("--------------------------------")
106
+ for i in range(len(items)):
107
+ print("%d. %s" % (i, items[i]))
108
+
109
+ print("--------------------------------")
110
+ sys.stdout.flush()
111
+
112
+ try:
113
+ input_func = raw_input
114
+ except NameError:
115
+ input_func = input
116
+
117
+ while True:
118
+ try:
119
+ sys.stdout.write(prompt)
120
+ idx = int(input_func())
121
+ if 0 <= idx < len(items):
122
+ return idx
123
+ except ValueError:
124
+ pass
125
+
126
+
127
+ select_from_items = _select_from_items_win if _win else _select_from_items_unix
128
+
129
+ if not _win:
130
+ def getch():
131
+ import sys
132
+ import tty
133
+ import termios
134
+ fd = sys.stdin.fileno()
135
+ old = termios.tcgetattr(fd)
136
+ try:
137
+ tty.setraw(fd)
138
+ return sys.stdin.read(1)
139
+ finally:
140
+ termios.tcsetattr(fd, termios.TCSADRAIN, old)
141
+
142
+
143
+ def _getch_wrap():
144
+ ch = getch()
145
+ if ch == "\x1b":
146
+ ch1 = getch()
147
+ if ch1 != "[":
148
+ raise KeyError(ch1)
149
+ ch2 = getch()
150
+ if ch2 == "A":
151
+ return _UP_ARROW
152
+ if ch2 == "B":
153
+ return _DOWN_ARROW
154
+ if ch2 == "C":
155
+ return _RIGHT_ARROW
156
+ if ch2 == "D":
157
+ return _LEFT_ARROW
158
+
159
+ raise KeyError(ch + ch1 + ch2)
160
+ else:
161
+ return ch
@@ -0,0 +1,40 @@
1
+ # encoding: utf-8
2
+ from tccli.plugins.sso import configs
3
+
4
+ _lang = configs.DEFAULT_LANG
5
+
6
+ texts = {
7
+ "zh-CN": {
8
+ "invalid_auth_url": "输入的 url 不合法: %s",
9
+ "auth_url_not_configured": "尚未配置 sso url, 使用 `tccli sso configure %s--url https://your-login-domain.com` 来进行配置",
10
+ "configure_succeed": "url 已配置为 '%s', 接下来可以使用 `tccli sso login` 进行登陆",
11
+ "try_login_with_url": "在浏览器中转到以下链接, 并根据提示完成登录:",
12
+ "account_select_prompt": "登录成功, 请选择您的用户: ",
13
+ "role_select_prompt": "请选择您的角色: ",
14
+ "login_success": "登录成功, 密钥凭证已被写入: %s",
15
+ "logout_success": "登出成功, 密钥凭证已被删除: %s",
16
+ "no_account": "未找到成员账号, 请确认是否同步过 CAM 角色",
17
+ "no_role": "当前成员账号不存在授权角色",
18
+ },
19
+ "en-US": {
20
+ "invalid_auth_url": "The entered url is invalid: %s",
21
+ "auth_url_not_configured": "sso url is not configured yet, use `tccli sso configure %s--url https://your-login-domain.com` to configure",
22
+ "configure_succeed": "The url has been configured as '%s', use `tccli sso login` to log in",
23
+ "try_login_with_url": "Go to the following link in your browser, and complete the sign-in prompts:",
24
+ "account_select_prompt": "Login succeed, choose your account: ",
25
+ "role_select_prompt": "choose your role: ",
26
+ "login_success": "Login succeed, credential has been written to %s",
27
+ "logout_success": "Logout succeed, credential has been removed: %s",
28
+ "no_account": "no account found, please confirm the account is synchronized",
29
+ "no_role": "no role found in current account",
30
+ }
31
+ }
32
+
33
+
34
+ def set_lang(lang):
35
+ global _lang
36
+ _lang = lang
37
+
38
+
39
+ def get(key):
40
+ return texts[_lang][key]
@@ -88,6 +88,9 @@ SERVICE_VERSIONS = {
88
88
  "bda": [
89
89
  "2020-03-24"
90
90
  ],
91
+ "bh": [
92
+ "2023-04-18"
93
+ ],
91
94
  "bi": [
92
95
  "2022-01-05"
93
96
  ],
@@ -236,9 +239,6 @@ SERVICE_VERSIONS = {
236
239
  "cpdp": [
237
240
  "2019-08-20"
238
241
  ],
239
- "cr": [
240
- "2018-03-21"
241
- ],
242
242
  "csip": [
243
243
  "2022-11-21"
244
244
  ],
@@ -401,6 +401,9 @@ SERVICE_VERSIONS = {
401
401
  "iecp": [
402
402
  "2021-09-14"
403
403
  ],
404
+ "ig": [
405
+ "2021-05-18"
406
+ ],
404
407
  "iir": [
405
408
  "2020-04-17"
406
409
  ],