profile.py 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. import os
  2. import configparser
  3. from typing import Dict
  4. import aiofiles
  5. from alibabacloud_credentials.provider import StaticAKCredentialsProvider, EcsRamRoleCredentialsProvider, \
  6. RamRoleArnCredentialsProvider, OIDCRoleArnCredentialsProvider, RsaKeyPairCredentialsProvider
  7. from alibabacloud_credentials.provider.refreshable import Credentials
  8. from alibabacloud_credentials_api import ICredentialsProvider
  9. from alibabacloud_credentials.utils import auth_constant as ac
  10. from alibabacloud_credentials.utils import auth_util as au
  11. from alibabacloud_credentials.exceptions import CredentialException
  12. async def _load_ini_async(file_path: str) -> Dict[str, Dict[str, str]]:
  13. config = configparser.ConfigParser()
  14. async with aiofiles.open(file_path, mode='r') as f:
  15. content = await f.read()
  16. config.read_string(content)
  17. ini_map = {}
  18. for section in config.sections():
  19. option = {}
  20. for key, value in config.items(section):
  21. if '#' in value:
  22. option[key] = value.split('#')[0].strip()
  23. else:
  24. option[key] = value.strip()
  25. ini_map[section] = option
  26. return ini_map
  27. def _load_ini(file_path: str) -> Dict[str, Dict[str, str]]:
  28. config = configparser.ConfigParser()
  29. config.read(file_path, encoding='utf-8')
  30. ini_map = {}
  31. for section in config.sections():
  32. option = {}
  33. for key, value in config.items(section):
  34. if '#' in value:
  35. option[key] = value.split('#')[0].strip()
  36. else:
  37. option[key] = value.strip()
  38. ini_map[section] = option
  39. return ini_map
  40. def _get_default_file() -> str:
  41. return os.path.join(ac.HOME, ".alibabacloud/credentials.ini")
  42. class ProfileCredentialsProvider(ICredentialsProvider):
  43. def __init__(self, *,
  44. profile_file: str = None,
  45. profile_name: str = None):
  46. self._profile_file = profile_file or au.environment_credentials_file
  47. self._profile_name = profile_name or au.client_type
  48. self.__innerProvider = None
  49. if self._profile_file is None or self._profile_file == '':
  50. self._profile_file = _get_default_file()
  51. def _should_reload_credentials_provider(self) -> bool:
  52. if self.__innerProvider is None:
  53. return True
  54. return False
  55. def get_credentials(self) -> Credentials:
  56. if self._should_reload_credentials_provider():
  57. ini_map = _load_ini(self._profile_file)
  58. section = ini_map.get(self._profile_name)
  59. if section is None:
  60. raise CredentialException(f'failed to get credential from credentials file: ${self._profile_file}')
  61. self.__innerProvider = self._get_credentials_provider(section)
  62. cre = self.__innerProvider.get_credentials()
  63. credentials = Credentials(
  64. access_key_id=cre.get_access_key_id(),
  65. access_key_secret=cre.get_access_key_secret(),
  66. security_token=cre.get_security_token(),
  67. provider_name=f'{self.get_provider_name()}/{cre.get_provider_name()}'
  68. )
  69. return credentials
  70. async def get_credentials_async(self) -> Credentials:
  71. if self._should_reload_credentials_provider():
  72. ini_map = await _load_ini_async(self._profile_file)
  73. section = ini_map.get(self._profile_name)
  74. if section is None:
  75. raise CredentialException(f'failed to get credential from credentials file: ${self._profile_file}')
  76. self.__innerProvider = self._get_credentials_provider(section)
  77. cre = await self.__innerProvider.get_credentials_async()
  78. credentials = Credentials(
  79. access_key_id=cre.get_access_key_id(),
  80. access_key_secret=cre.get_access_key_secret(),
  81. security_token=cre.get_security_token(),
  82. provider_name=f'{self.get_provider_name()}/{cre.get_provider_name()}'
  83. )
  84. return credentials
  85. def _get_credentials_provider(self, section: Dict) -> ICredentialsProvider:
  86. config_type = section.get(ac.INI_TYPE)
  87. if 'access_key' == config_type:
  88. return StaticAKCredentialsProvider(
  89. access_key_id=section.get('access_key_id'),
  90. access_key_secret=section.get('access_key_secret')
  91. )
  92. elif 'ram_role_arn' == config_type:
  93. pre_provider = StaticAKCredentialsProvider(
  94. access_key_id=section.get('access_key_id'),
  95. access_key_secret=section.get('access_key_secret')
  96. )
  97. return RamRoleArnCredentialsProvider(
  98. credentials_provider=pre_provider,
  99. role_arn=section.get('role_arn'),
  100. role_session_name=section.get('role_session_name'),
  101. policy=section.get('policy')
  102. )
  103. elif 'oidc_role_arn' == config_type:
  104. return OIDCRoleArnCredentialsProvider(
  105. role_arn=section.get('role_arn'),
  106. oidc_provider_arn=section.get('oidc_provider_arn'),
  107. oidc_token_file_path=section.get('oidc_token_file_path'),
  108. role_session_name=section.get('role_session_name'),
  109. policy=section.get('policy')
  110. )
  111. elif 'ecs_ram_role' == config_type:
  112. return EcsRamRoleCredentialsProvider(
  113. role_name=section.get('role_name')
  114. )
  115. elif 'rsa_key_pair' == config_type:
  116. return RsaKeyPairCredentialsProvider(
  117. public_key_id=section.get('public_key_id'),
  118. private_key_file=section.get('private_key_file')
  119. )
  120. else:
  121. raise CredentialException(
  122. f'unsupported credential type {config_type} from credentials file {self._profile_file}')
  123. def get_provider_name(self) -> str:
  124. return 'profile'