From 5e9592e15ee8e5f0dc7cbdc1b4fb624f6c301ad2 Mon Sep 17 00:00:00 2001 From: Rene Moser Date: Tue, 2 Feb 2021 17:23:12 +0100 Subject: [PATCH] Remove INI config support --- plugins/doc_fragments/cloudstack.py | 33 ++++------------- plugins/doc_fragments/remove-ini-config.yml | 3 ++ plugins/module_utils/cloudstack.py | 40 ++++++++------------- 3 files changed, 24 insertions(+), 52 deletions(-) create mode 100644 plugins/doc_fragments/remove-ini-config.yml diff --git a/plugins/doc_fragments/cloudstack.py b/plugins/doc_fragments/cloudstack.py index af13a3af..5ca01bcc 100644 --- a/plugins/doc_fragments/cloudstack.py +++ b/plugins/doc_fragments/cloudstack.py @@ -16,63 +16,42 @@ class ModuleDocFragment(object): description: - API key of the CloudStack API. - If not given, the C(CLOUDSTACK_KEY) env variable is considered. - - As the last option, the value is taken from the ini config file, also see the notes. type: str + required: true api_secret: description: - Secret key of the CloudStack API. - If not set, the C(CLOUDSTACK_SECRET) env variable is considered. - - As the last option, the value is taken from the ini config file, also see the notes. type: str + required: true api_url: description: - URL of the CloudStack API e.g. https://cloud.example.com/client/api. - If not given, the C(CLOUDSTACK_ENDPOINT) env variable is considered. - - As the last option, the value is taken from the ini config file, also see the notes. type: str + required: true api_http_method: description: - HTTP method used to query the API endpoint. - If not given, the C(CLOUDSTACK_METHOD) env variable is considered. - - As the last option, the value is taken from the ini config file, also see the notes. - - Fallback value is C(get) if not specified. type: str choices: [ get, post ] + default: get api_timeout: description: - HTTP timeout in seconds. - If not given, the C(CLOUDSTACK_TIMEOUT) env variable is considered. - - As the last option, the value is taken from the ini config file, also see the notes. - - Fallback value is 10 seconds if not specified. type: int - api_region: - description: - - Name of the ini section in the C(cloustack.ini) file. - - If not given, the C(CLOUDSTACK_REGION) env variable is considered. - type: str - default: cloudstack + default: 10 api_verify_ssl_cert: description: - - CA authority cert file. + - Verify CA authority cert file. - If not given, the C(CLOUDSTACK_VERIFY) env variable is considered. - - As the last option, the value is taken from the ini config file, also see the notes. - - Fallback value is C(null) if not specified. type: str requirements: - python >= 2.6 - cs >= 0.9.0 notes: - - Ansible uses the C(cs) library's configuration method if credentials are not - provided by the arguments C(api_url), C(api_key), C(api_secret). - Configuration is read from several locations, in the following order. - The C(CLOUDSTACK_ENDPOINT), C(CLOUDSTACK_KEY), C(CLOUDSTACK_SECRET) and - C(CLOUDSTACK_METHOD). C(CLOUDSTACK_TIMEOUT) environment variables. - A C(CLOUDSTACK_CONFIG) environment variable pointing to an C(.ini) file. - A C(cloudstack.ini) file in the current working directory. - A C(.cloudstack.ini) file in the users home directory. - Optionally multiple credentials and endpoints can be specified using ini sections in C(cloudstack.ini). - Use the argument C(api_region) to select the section name, default section is C(cloudstack). - See https://github.com/exoscale/cs for more information. - A detailed guide about cloudstack modules can be found in the L(CloudStack Cloud Guide,../scenario_guides/guide_cloudstack.html). - This module supports check mode. ''' diff --git a/plugins/doc_fragments/remove-ini-config.yml b/plugins/doc_fragments/remove-ini-config.yml new file mode 100644 index 00000000..078c78f5 --- /dev/null +++ b/plugins/doc_fragments/remove-ini-config.yml @@ -0,0 +1,3 @@ +breaking_changes: + - Authentication option using INI files e.g. ``cloudstack.ini`` has been removed. The only supported option to authenticate + is by using the module params with fallback to the ENV variables. diff --git a/plugins/module_utils/cloudstack.py b/plugins/module_utils/cloudstack.py index ac310ecb..abbd2077 100644 --- a/plugins/module_utils/cloudstack.py +++ b/plugins/module_utils/cloudstack.py @@ -12,11 +12,11 @@ import traceback from ansible.module_utils._text import to_text, to_native -from ansible.module_utils.basic import missing_required_lib +from ansible.module_utils.basic import missing_required_lib, env_fallback CS_IMP_ERR = None try: - from cs import CloudStack, CloudStackException, read_config + from cs import CloudStack, CloudStackException HAS_LIB_CS = True except ImportError: CS_IMP_ERR = traceback.format_exc() @@ -29,18 +29,17 @@ def cs_argument_spec(): return dict( - api_key=dict(default=os.environ.get('CLOUDSTACK_KEY')), - api_secret=dict(default=os.environ.get('CLOUDSTACK_SECRET'), no_log=True), - api_url=dict(default=os.environ.get('CLOUDSTACK_ENDPOINT')), - api_http_method=dict(choices=['get', 'post'], default=os.environ.get('CLOUDSTACK_METHOD')), - api_timeout=dict(type='int', default=os.environ.get('CLOUDSTACK_TIMEOUT')), - api_region=dict(default=os.environ.get('CLOUDSTACK_REGION') or 'cloudstack'), - api_verify_ssl_cert=dict(default=os.environ.get('CLOUDSTACK_VERIFY')), + api_key=dict(type='str', fallback=(env_fallback, ['CLOUDSTACK_KEY']), required=True), + api_secret=dict(type='str', fallback=(env_fallback, ['CLOUDSTACK_SECRET']), required=True, no_log=True), + api_url=dict(type='str', fallback=(env_fallback, ['CLOUDSTACK_ENDPOINT']), required=True), + api_http_method=dict(type='str', fallback=(env_fallback, ['CLOUDSTACK_METHOD']), choices=['get', 'post'], default='get'), + api_timeout=dict(type='int', fallback=(env_fallback, ['CLOUDSTACK_TIMEOUT']), default=10), + api_verify_ssl_cert=dict(type='str', fallback=(env_fallback, ['CLOUDSTACK_VERIFY'])), ) def cs_required_together(): - return [['api_key', 'api_secret']] + return [] class AnsibleCloudStack: @@ -114,30 +113,21 @@ def cs(self): return self._cs def get_api_config(self): - api_region = self.module.params.get('api_region') or os.environ.get('CLOUDSTACK_REGION') - try: - config = read_config(api_region) - except KeyError: - config = {} - api_config = { - 'endpoint': self.module.params.get('api_url') or config.get('endpoint'), - 'key': self.module.params.get('api_key') or config.get('key'), - 'secret': self.module.params.get('api_secret') or config.get('secret'), - 'timeout': self.module.params.get('api_timeout') or config.get('timeout') or 10, - 'method': self.module.params.get('api_http_method') or config.get('method') or 'get', - 'verify': self.module.params.get('api_verify_ssl_cert') or config.get('verify'), + 'endpoint': self.module.params.get('api_url'), + 'key': self.module.params.get('api_key'), + 'secret': self.module.params.get('api_secret'), + 'timeout': self.module.params.get('api_timeout'), + 'method': self.module.params.get('api_http_method'), + 'verify': self.module.params.get('api_verify_ssl_cert'), } self.result.update({ - 'api_region': api_region, 'api_url': api_config['endpoint'], 'api_key': api_config['key'], 'api_timeout': int(api_config['timeout']), 'api_http_method': api_config['method'], 'api_verify_ssl_cert': api_config['verify'], }) - if not all([api_config['endpoint'], api_config['key'], api_config['secret']]): - self.fail_json(msg="Missing api credentials: can not authenticate") return api_config def fail_json(self, **kwargs):