diff --git a/lib/ansible/modules/cloud/alicloud/ali_dns_group_info.py b/lib/ansible/modules/cloud/alicloud/ali_dns_group_info.py index 6be56577..1cc03a10 100644 --- a/lib/ansible/modules/cloud/alicloud/ali_dns_group_info.py +++ b/lib/ansible/modules/cloud/alicloud/ali_dns_group_info.py @@ -26,7 +26,7 @@ DOCUMENTATION = ''' --- -module: ali_domain_group_info +module: ali_dns_group_info version_added: "2.8" short_description: Gather facts on domain group of Alibaba Cloud. description: diff --git a/lib/ansible/modules/cloud/alicloud/ali_rds_database.py b/lib/ansible/modules/cloud/alicloud/ali_rds_database.py new file mode 100644 index 00000000..2c011668 --- /dev/null +++ b/lib/ansible/modules/cloud/alicloud/ali_rds_database.py @@ -0,0 +1,270 @@ +#!/usr/bin/python +# Copyright (c) 2017-present Alibaba Group Holding Limited. He Guimin +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) +# +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see http://www.gnu.org/licenses/. + + +__metaclass__ = type + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'community'} + +DOCUMENTATION = ''' +--- +module: ali_rds_database +version_added: "2.9" +short_description: Create, delete or copy an database in Alibaba Cloud RDS. +description: + - Create, delete, copy or modify description for database in RDS. + - An unique ali_rds_database module is co-determined by parameters db_instance_id and db_name. +options: + state: + description: + - If I(state=present), database will be created. + - If I(state=present) and db_description exists, it will modify description. + - If I(state=present) and target_db_instance_id,target_db_name exists, it will copy database between instances. + - If I(state=absent), database will be removed. + default: 'present' + choices: ['present', 'absent'] + db_instance_id: + description: + - rds instance id. This is used in combination with C(db_name) to determine if the database already exists. + aliases: ['instance_id'] + required: True + db_name: + description: + - database name. It must be 2 to 64 characters in length.It must start with a lowercase letter and end with a + lowercase letter or digit. It can contain lowercase letters, digits, underscores (_), and hyphens (-). + this will specify unique database in one instance. + For more information about invalid characters, see Forbidden keywords table U(https://www.alibabacloud.com/help/doc-detail/26317.htm). + This is used in combination with C(db_instance_id) to determine if the database already exists. + aliases: ['name'] + required: True + character_set_name: + description: + - database character name. MySQL or MariaDB (utf8 | gbk | latin1 | utf8mb4). + SQL Server (Chinese_PRC_CI_AS | Chinese_PRC_CS_AS | SQL_Latin1_General_CP1_CI_AS | SQL_Latin1_General_CP1_CS_AS | Chinese_PRC_BIN). + see more U(https://www.alibabacloud.com/help/doc-detail/26258.htm) + Required when C(state=present). + aliases: ['character'] + db_description: + description: + - The description of the database. It must be 2 to 256 characters in length. + It can contain letters, digits, underscores (_), and hyphens (-), and must start with a letter. + aliases: ['description'] + target_db_instance_id: + description: + - The ID of the destination instance, which must differ from the ID of the source instance. + aliases: ['target_instance_id'] + target_db_name: + description: + - Target instance database name. + backup_id: + description: + - The ID of the backup set on the source instance. When you copy databases based on the backup set. + restore_time: + description: + - The time when the system copies the database. You can select any time within the backup retention period. + sync_user_privilege: + description: + - Indicates whether to copy users and permissions. +author: + - "Li Xue" +requirements: + - "python >= 3.6" + - "footmark >= 1.16.0" +extends_documentation_fragment: + - alicloud +''' + +EXAMPLES = ''' +# Note: These examples do not set authentication details, see the Alibaba Cloud Guide for details. +- name: Create Database + ali_rds_database: + db_instance_id: '{{ db_instance_id }}' + db_name: ansible + character_set_name: utf8 + db_description: create for ansible + state: present + +- name: Changed. Modify db description. + ali_rds_database: + db_instance_id: '{{ db_instance_id }}' + db_name: ansible + db_description: modify db description + +- name: Changed. Copy Database Between Instances + ali_rds_database: + db_instance_id: '{{ db_instance_id }}' + db_name: '{{ db_name }}' + target_db_instance_id: '{{ target_db_instance_id }}' + target_db_name: '{{ target_db_name }}' + +- name: Changed. Deleting database + ali_rds_database: + state: absent + db_instance_id: '{{ db_instance_id }}' + db_name: ansible +''' + +RETURN = ''' +database: + description: Describe the info after operating database. + returned: always + type: complex + contains: + character_set_name: + description: The character of database. + returned: always + type: string + sample: utf8 + db_description: + description: The description of database. + returned: always + type: string + sample: create for ansible + db_instance_id: + description: The id of rds instance. + returned: always + type: string + sample: rm-uf6wjk5xxxxxxx + db_name: + description: The name of database. + returned: always + type: string + sample: ansible + db_status: + description: The status of database. + returned: always + type: string + sample: Creating + description: + description: alias of 'db_description'. + returned: always + type: string + sample: create for ansible + engine: + description: The engine of database. + returned: always + type: string + sample: MySQL + name: + description: alias of 'db_name'. + returned: always + type: string + sample: ansible + status: + description: alias of 'db_status'. + returned: always + type: string + sample: Creating +''' + +import time +from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.alicloud_ecs import ecs_argument_spec, rds_connect, vpc_connect + +HAS_FOOTMARK = False + +try: + from footmark.exception import ECSResponseError + HAS_FOOTMARK = True +except ImportError: + HAS_FOOTMARK = False + + +def database_exists(modules, rds): + name = modules.params['db_name'] + match = '' + for db in rds.describe_databases(db_instance_id=modules.params['db_instance_id']): + if db.name == name: + match = db + return match + + +def main(): + argument_spec = ecs_argument_spec() + argument_spec.update(dict( + state=dict(default="present", choices=["present", "absent"]), + db_instance_id=dict(type='str', aliases=['instance_id'], required=True), + db_name=dict(type='str', aliases=['name'], required=True), + character_set_name=dict(type='str', aliases=['character']), + db_description=dict(type='str', aliases=['description']), + target_db_instance_id=dict(type='str', aliases=['target_instance_id']), + target_db_name=dict(type='str'), + backup_id=dict(type='str'), + restore_time=dict(type='str'), + sync_user_privilege=dict(type='bool', default=False) + )) + modules = AnsibleModule(argument_spec=argument_spec) + + if HAS_FOOTMARK is False: + modules.fail_json(msg="Package 'footmark' required for this module") + + rds = rds_connect(modules) + state = modules.params['state'] + db_description = modules.params['db_description'] + target_db_instance_id = modules.params['target_db_instance_id'] + target_db_name = modules.params['target_db_name'] + db_name = modules.params['db_name'] + sync_user_privilege = modules.params['sync_user_privilege'] + modules.params['sync_user_privilege'] = 'NO' + if sync_user_privilege: + modules.params['sync_user_privilege'] = 'YES' + db = '' + try: + db = database_exists(modules, rds) + except Exception as e: + modules.fail_json(msg=str("Unable to describe database, error:{0}".format(e))) + + if state == 'absent': + if not db: + modules.exit_json(changed=False, database={}) + try: + db.delete() + modules.exit_json(changed=True, database={}) + except Exception as e: + modules.fail_json(msg=str("Unable to delete database error: {0}".format(e))) + + if not db: + try: + modules.params['client_token'] = "Ansible-Alicloud-%s-%s" % (hash(str(modules.params)), str(time.time())) + db = rds.create_database(**modules.params) + modules.exit_json(changed=True, database=db.read()) + except Exception as e: + modules.fail_json(msg=str("Unable to create database error: {0}".format(e))) + + if db_description: + try: + res = db.modify_db_description(description=db_description) + modules.exit_json(changed=res, database=db.read()) + except Exception as e: + modules.fail_json(msg=str("Unable to modify db description error: {0}".format(e))) + + if target_db_instance_id and target_db_name: + try: + modules.params['db_names'] = str({db_name: target_db_name}) + res = db.copy_database_between_instances(**modules.params) + modules.exit_json(changed=res, database=db.read()) + except Exception as e: + modules.fail_json(msg=str("Unable to copy db instance id error: {0}".format(e))) + + +if __name__ == '__main__': + main() + diff --git a/lib/ansible/modules/cloud/alicloud/ali_rds_database_info.py b/lib/ansible/modules/cloud/alicloud/ali_rds_database_info.py new file mode 100644 index 00000000..9cb0141f --- /dev/null +++ b/lib/ansible/modules/cloud/alicloud/ali_rds_database_info.py @@ -0,0 +1,171 @@ +#!/usr/bin/python +# Copyright (c) 2017-present Alibaba Group Holding Limited. He Guimin +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) +# +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see http://www.gnu.org/licenses/. + + +__metaclass__ = type + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'community'} + +DOCUMENTATION = ''' +--- +module: ali_rds_database_info +version_added: "2.9" +short_description: Gather info on database of Alibaba Cloud RDS. +description: + - This module fetches data from the Open API in Alicloud. + The module must be called from within the RDS database itself. +options: + db_instance_id: + description: + - The ID of the instance. + aliases: ["instance_id"] + db_status: + description: + - The status of the database. Valid values (creating, running, deleting) + aliases: ["status"] + name_prefix: + description: + - Use a database name prefix to filter rds database. +author: + - "He Guimin (@xiaozhu36)" +requirements: + - "python >= 3.6" + - "footmark >= 1.16.0" +extends_documentation_fragment: + - alicloud +''' + +EXAMPLES = ''' +- name: Get the existing database with name prefix + ali_rds_database_info: + name_prefix: ansible_ + db_instance_id: '{{ db_instance_id}}' + +- name: Get the existing database with status + ali_rds_database_info: + db_status: creating + db_instance_id: '{{ db_instance_id }}' + +- name: Retrieving all database + ali_rds_database_info: + db_instance_id: '{{ db_instance_id }}' +''' + +RETURN = ''' +databases: + description: Describe the info after operating database. + returned: always + type: list + sample:[ + { + character_set_name: + description: The character of database. + returned: always + type: string + sample: utf8 + db_description: + description: The description of database. + returned: always + type: string + sample: test for ansible + db_instance_id: + description: The id of rds instance. + returned: always + type: string + sample: rm-uf6wjk5xxxxxxx + db_name: + description: The name of database. + returned: always + type: string + sample: ansible_test + db_status: + description: The status of database. + returned: always + type: string + sample: Creating + description: + description: alias of 'db_description'. + returned: always + type: string + sample: test for ansible + engine: + description: The engine of database. + returned: always + type: string + sample: MySQL + name: + description: alias of 'db_name'. + returned: always + type: string + sample: ansible_test + status: + description: alias of 'db_status'. + returned: always + type: string + sample: Creating + } + ] +''' + +from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.alicloud_ecs import ecs_argument_spec, rds_connect, vpc_connect + +HAS_FOOTMARK = False + +try: + from footmark.exception import RDSResponseError + HAS_FOOTMARK = True +except ImportError: + HAS_FOOTMARK = False + + +def main(): + argument_spec = ecs_argument_spec() + argument_spec.update(dict( + db_instance_id=dict(type='str', aliases=['instance_id'], required=True), + name_prefix=dict(type='str'), + db_status=dict(type='str', aliases=['status']) + )) + module = AnsibleModule(argument_spec=argument_spec) + rds = rds_connect(module) + name_prefix = module.params['name_prefix'] + db_status = module.params['db_status'] + + if HAS_FOOTMARK is False: + module.fail_json(msg="Package 'footmark' required for this module.") + + result = [] + names = [] + try: + for db in rds.describe_databases(**module.params): + if name_prefix and not db.dbname.startswith(name_prefix): + continue + if db_status and db.dbstatus.lower() != db_status.lower(): + continue + result.append(db.read()) + names.append(db.name) + module.exit_json(changed=False, names=names, databases=result) + except Exception as e: + module.fail_json(msg="Unable to describe rds database, and got an error: {0}.".format(e)) + + +if __name__ == '__main__': + main() diff --git a/lib/ansible/modules/cloud/alicloud/ali_rds_instance.py b/lib/ansible/modules/cloud/alicloud/ali_rds_instance.py index 8c91f2fc..022b24bd 100644 --- a/lib/ansible/modules/cloud/alicloud/ali_rds_instance.py +++ b/lib/ansible/modules/cloud/alicloud/ali_rds_instance.py @@ -28,306 +28,412 @@ --- module: ali_rds_instance version_added: "1.5.0" -short_description: Create, Restart or Terminate an Instance in RDS. +short_description: Create, Restart or Delete an RDS Instance in Alibaba Cloud. description: - - Create, restart, modify or terminate rds instances. + - Create, Restart, Delete and Modify network_type, connection_string, spec for RDS Instance. + - An unique ali_rds_instance module is determined by parameters db_instance_description(instance name). options: state: description: - - The state of the instance after operating. + - If I(state=present), instance will be created. + - If I(state=present) and instance exists, it will be updated. + - If I(state=absent), instance will be removed. + - If I(state=restart), instance will be restarted. + choices: ['present', 'restart', 'absent'] default: 'present' - choices: [ 'present', 'restart', 'absent' ] - aliases: ['status'] - alicloud_zone: + zone_id: description: - Aliyun availability zone ID in which to launch the instance. If it is not specified, it will be allocated by system automatically. - aliases: ['zone_id', 'zone'] + aliases: ['alicloud_zone'] engine: description: - - Database type. Required when C(state=present). - choices: [ 'MySQL', 'SQLServer', 'PostgreSQL', 'PPAS' ] + - The engine type of the database.Required when C(state=present). + choices: ['MySQL', 'SQLServer', 'PostgreSQL', 'PPAS', 'MariaDB'] engine_version: description: - - The database version number, as follows: - MySQL: 5.5 / 5.6 / 5.7; - SQLServer: 2008r2 / 2012; - PostgreSQL: 9.4; - PPAS: 9.3. - Required when C(state=present). - instance_type: + - The version of the database.Required when C(state=present). + - MySQL (5.5 | 5.6 | 5.7 | 8.0) + - SQL Server (2008r2 | 2012 | 2012_ent_ha | 2012_std_ha | 2012_web | 2016_ent_ha | 2016_std_ha | 2016_web | 2017_ent) + - PostgreSQL (9.4 | 10.0) + - PPAS (9.3 | 10.0) + - MariaDB (10.3) + - see more (https://www.alibabacloud.com/help/doc-detail/26228.htm) + db_instance_class: description: - - Instance specification. Required when C(state=present). - aliases: ['db_instance_class'] - instance_storage: + - The instance type (specifications). For more information, see(https://www.alibabacloud.com/help/doc-detail/26312.htm). + Required when C(state=present). + aliases: ['instance_class'] + db_instance_storage: description: - - Customize storage, range: - MySQL / PostgreSQL / PPAS dual high-availability version of [5,2000]; - MySQL 5.7 standalone basic version is [20,1000]; - SQL Server 2008R2 is [10,2000]; - SQL Server 2012 standalone basic version of [20,2000]; - Increased every 5G. Unit: GB. + - The storage capacity of the instance. Unit(GB). This value must be a multiple of 5. For more information see(https://www.alibabacloud.com/help/doc-detail/26312.htm). Required when C(state=present). - aliases: ['db_instance_storage'] - instance_net_type: + aliases: ['instance_storage'] + db_instance_net_type: description: - - Instance of the network connection type: Internet on behalf of the public network, Intranet on behalf of the private network. + - Instance of the network connection type (Internet on behalf of the public network, Intranet on behalf of the private network) Required when C(state=present). + aliases: ['instance_net_type'] choices: ["Internet", "Intranet"] - aliases: ['db_instance_net_type'] - description: + db_instance_name: description: - - Instance description or memo information, no more than 256 bytes; - Note: You can not start with http: //, https: //. Start with Chinese and English letters. - Can contain Chinese, English characters, "_", "-", the number of characters length 2 ~ 256. - aliases: ['db_instance_description'] - security_ips: + - The instance name. the unique identifier of the instance. It starts with a letter and contains 2 to 255 characters, including letters, digits, underscores (_), and hyphens (-). + It cannot start with http:// or https://. + This is used to determine if the rds instance already exists. + aliases: ['description', 'name'] + required: True + security_ip_list: description: - - Allow access to the IP list of all databases under this instance, - separated by commas, not repeatable, up to 1000; - Supported formats:%, 0.0.0.0/0,10.23.12.24 (IP), - or 10.23.12.24/24 (CIDR mode , No class interdomain routing, - / 24 indicates the length of the prefix in the address, - the range [1,32]) where 0.0.0.0 / 0, that does not limit + - The IP address whitelist of the instance. Separate multiple IP addresses with commas (,). It can include up to 1,000 IP addresses. The IP addresses support two formats. + IP address format. For example, 10.23.12.24. Classless Inter-Domain Routing (CIDR) format. For example, 10.23.12.24/24 (where /24 indicates the number of bits for the prefix of the IP address, in the range of 1 to 32.) Required when C(state=present). - instance_charge_type: + aliases: ['security_ips'] + pay_type: description: - - Type of payment. Postpaid: postpaid instance; Prepaid: prepaid instance. Required when C(state=present). - choices: [ "Postpaid", "Prepaid" ] + - The billing method of the instance.Required when C(state=present). + choices: ["PostPaid", "PrePaid"] period: description: - - The charge duration of the instance. Required when C(instance_charge_type=PrePaid). - choices: [1~9,12,24,36] - default: 1 + - The prepayment period of the instance. Required when C(pay_type=PrePaid). + choices: ['Year', 'Month'] + used_time: + description: + - The duration of the instance if the instance uses subscription billing. Required when C(pay_type=PrePaid). + If the value of the Period parameter is Year, the value of the UsedTime parameter ranges from 1 to 3. + If the value of the Period parameter is Month, the value of the UsedTime parameter ranges from 1 to 9. connection_mode: description: - - Performance is standard access mode; Safty is a high security access mode; default is RDS system allocation. - choices: ["Performance", "Safty"] + - The access mode of the instance. + choices: ["Standard", "Safe"] + instance_network_type: + description: + - The internet type of the instance. + choices: ["VPC", "Classic"] vswitch_id: description: - - Vswitch id + - The ID of the VSwitch. Separate multiple IDs with commas (,). + Required when C(engine=MariaDB) private_ip_address: description: - - Users can specify VSvitchId under vpcIp, if not input, the system automatically assigned. - instance_id: - description: - - Instance id, the unique identifier if the instance. Required when C(state in ["present", "absent", "restart"]) - aliases: ['db_instance_id'] - tags: - description: - - The query is bound to an instance of this tag, - the incoming value format is Json string, - including TagKey and TagValue, - TagKey can not be empty, - TagValue can be empty. - Format example: {"key1": "value1"} - page_size: - description: - - Number of records per page. - choices: [30,50,100] - default: 30 - page_number: - description: - - Page number greater than 0, and does not exceed the maximum value of Integer. - type: int - default: 1 - auto_renew_period: + - The intranet IP address of the instance. It must be within the IP address range provided by the switch. + By default, the system automatically assigns an IP address based on the VPCId and VSwitchId. + db_instance_id: description: - - Automatic renewal period. Required when C(auto_renew='True') - choices: [1, 2, 3, 6, 12] + - Instance id. + aliases: ['instance_id'] auto_renew: description: - - Automatic renewal. Required when C(auto_renew != None) + - Indicates whether the instance is automatically renewed type: bool - public_connection_string_prefix: + port: description: - - The prefix of the outer network connection string. Required when C(state in ['present', 'absent']). - dest_connection_string_prefix: - description: - - The prefix of the outer network connection string. Required when C(state in ['present', 'absent']). - private_connection_string_prefix: - description: - - The prefix of the outer network connection string. Required when C(state in ['present', 'absent']). - public_port: + - The target port. + current_connection_string: description: - - Port of public net work. - private_port: + - The current connection address of an instance. It can be an internal network address, a public network address, or a classic network address in the hybrid access mode. + connection_string_prefix: description: - - Port of private net work. - dest_port: + - The prefix of the target connection address. Only the prefix of CurrentConnectionString can be modified. + tags: description: - - Port to replace the old. - current_connection_string: + - A hash/dictionaries of rds tags. C({"key":"value"}) + purge_tags: description: - - Instance of a current connection string. Required when C(current_connection_string != None) + - Delete existing tags on the rds that are not specified in the task. + If True, it means you have to specify all the desired tags on each task affecting a rds. + default: False + type: bool author: - - "liu Qiang" + - "Li Xue" requirements: - - "python >= 2.6" - - "footmark >= 1.1.16" + - "python >= 3.6" + - "footmark >= 1.16.0" extends_documentation_fragment: - alicloud ''' EXAMPLES = ''' -# basic provisioning example to create rds instance -- name: create rds instance - hosts: localhost - vars: - alicloud_access_key: - alicloud_secret_key: - alicloud_region: cn-beijing - tasks: - - name: create instance - ali_rds_instance: - alicloud_access_key: '{{ alicloud_access_key }}' - alicloud_secret_key: '{{ alicloud_secret_key }}' - alicloud_region: '{{ alicloud_region }}' - state: present - engine: MySQL - engine_version: 5.6 - instance_class: rds.mysql.t1.small - instance_storage: 30 - instance_net_type: Internet - security_ips: 10.23.12.24/24 - instance_charge_type: Postpaid - -# basic provisioning example to modify instance auto renewal attribute -- name: modify instance auto renewal attribute - hosts: localhost - vars: - alicloud_access_key: - alicloud_secret_key: - alicloud_region: cn-beijing - tasks: - - name: modify instance auto renewal attribute - ali_rds_instance: - alicloud_access_key: '{{ alicloud_access_key }}' - alicloud_secret_key: '{{ alicloud_secret_key }}' - alicloud_region: '{{ alicloud_region }}' - state: present - instance_id: rm-2ze3083kmle92v50t - auto_renew: False - -# basic provisioning example to allocate instance private connection string -- name: allocate instance private connection string - hosts: localhost - vars: - alicloud_access_key: - alicloud_secret_key: - alicloud_region: cn-beijing - tasks: - - name: allocate instance private connection string - ali_rds_instance: - alicloud_access_key: '{{ alicloud_access_key }}' - alicloud_secret_key: '{{ alicloud_secret_key }}' - alicloud_region: '{{ alicloud_region }}' - state: present - private_connection_string_prefix: pirave-89asd - instance_id: rm-2ze3083kmle92v50t - -# basic provisioning example to allocate instance public connection string -- name: allocate instance public connection string - hosts: localhost - vars: - alicloud_access_key: - alicloud_secret_key: - alicloud_region: cn-beijing - tasks: - - name: allocate instance public connection string - ali_rds_instance: - alicloud_access_key: '{{ alicloud_access_key }}' - alicloud_secret_key: '{{ alicloud_secret_key }}' - alicloud_region: '{{ alicloud_region }}' - state: present - public_connection_string_prefix: pirave-89asd - public_port: 3212 - instance_id: rm-2ze3083kmle92v50t - -# basic provisioning example to modify instance current connection string -- name: modify instance current connection string - hosts: localhost - vars: - alicloud_access_key: - alicloud_secret_key: - alicloud_region: cn-beijing - tasks: - - name: modify instance current connection string - ali_rds_instance: - alicloud_access_key: '{{ alicloud_access_key }}' - alicloud_secret_key: '{{ alicloud_secret_key }}' - alicloud_region: '{{ alicloud_region }}' - state: present - current_connection_string: rm-2ze3083kmle92v50t.mysql.rds.aliyuncs.com - dest_connection_string_prefix: adsad-ewq4f - dest_port: 4321 - instance_id: rm-2ze3083kmle92v50t - -# basic provisioning example to release instance public connection string +- name: Changed. Add Tags. + ali_rds_instance: + db_instance_description: '{{ name }}' + tags: + TAG: "add1" + TAG2: "add2" + +- name: Changed. Removing tags. + ali_rds_instance: + db_instance_description: '{{ name }}' + purge_tags: True + tags: + TAG: "add1" + +- name: Changed. allocate instance public connection string + ali_rds_instance: + db_instance_description: '{{ name }}' + connection_string_prefix: publicave-89asd + port: 3165 + - name: release instance public connection string - hosts: localhost - vars: - alicloud_access_key: - alicloud_secret_key: - alicloud_region: cn-beijing - tasks: - - name: release instance public connection string - ali_rds_instance: - alicloud_access_key: '{{ alicloud_access_key }}' - alicloud_secret_key: '{{ alicloud_secret_key }}' - alicloud_region: '{{ alicloud_region }}' - state: absent - current_connection_string: rm-2ze3083kmle92v50t.mysql.rds.aliyuncs.com - instance_id: rm-2ze3083kmle92v50t - -# basic provisioning example to restart rds instacne -- name: restart rds instacne - hosts: localhost - vars: - alicloud_access_key: - alicloud_secret_key: - alicloud_region: cn-beijing - tasks: - - name: restart rds instacne - ali_rds_instance: - alicloud_access_key: '{{ alicloud_access_key }}' - alicloud_secret_key: '{{ alicloud_secret_key }}' - alicloud_region: '{{ alicloud_region }}' - state: restart - instance_id: rm-2ze3083kmle92v50t - -# basic provisioning example to release rds instacne -- name: release rds instacne - hosts: localhost - vars: - alicloud_access_key: - alicloud_secret_key: - alicloud_region: cn-beijing - tasks: - - name: release rds instacne - ali_rds_instance: - alicloud_access_key: '{{ alicloud_access_key }}' - alicloud_secret_key: '{{ alicloud_secret_key }}' - alicloud_region: '{{ alicloud_region }}' - state: absent - instance_id: rm-2ze3083kmle92v50t + ali_rds_instance: + state: absent + db_instance_description: '{{ name }}' + current_connection_string: publicave-89asd.mysql.rds.aliyuncs.com + +- name: restart rds instance + ali_rds_instance: + db_instance_description: '{{ name }}' + state: restart + +- name: Changed. modify instance network type + ali_rds_instance: + db_instance_description: '{{ name }}' + instance_network_type: Classic + +- name: Changed. modify instance spec + ali_rds_instance: + db_instance_description: '{{ name }}' + db_instance_class: rds.mysql.c2.xlarge + db_instance_storage: 40 + +- name: Changed. modify instance current connection string + ali_rds_instance: + current_connection_string: '{{ rds.instances.0.id }}.mysql.rds.aliyuncs.com' + db_instance_description: '{{ name }}' + connection_string_prefix: private-ansible + port: 3307 + +- name: Changed. Deleting rds + ali_rds_instance: + state: absent + db_instance_description: '{{ name }}' ''' RETURN = ''' -instance: - description: Describe the info after operating rds instance. - returned: when success - type: dict - sample: { - "connection_string": "rm-2ze3083kmle92v50t.mysql.rds.aliyuncs.com", - "db_instance_id": "rm-2ze3083kmle92v50t", - "db_instance_status": "Running", - "db_instance_storage": 30, - "db_instance_type": "Primary", - "db_instance_net_type": "Intranet", - "engine": "MySQL", - "engine_version": "5.6", - } +instances: + description: Describe the info after operating rds instance. + returned: always + type: complex + contains: + db_instance_class: + description: The type of the instance. + returned: always + type: string + sample: rds.mysql.t1.small + db_instance_description: + description: The description of the instance. + returned: always + type: string + sample: ansible_test_rds + db_instance_id: + description: The ID of the instance. + returned: always + type: string + sample: rm-uf6wjk5xxxxxxxxxx + db_instance_net_type: + description: The network type of the instance + returned: always + type: string + sample: Internet + db_instance_status: + description: The status of the instance + returned: always + type: string + sample: Running + db_instance_type: + description: The type of the instance role + returned: always + type: string + sample: Primary + engine: + description: The type of the database. + returned: always + type: string + sample: MySQL + engine_version: + description: The version of the database. + returned: always + type: string + sample: 5.6 + id: + description: alias of 'db_instance_id'. + returned: always + type: string + sample: rm-uf6wjk5xxxxxxxxxx + type: + description: alias of 'db_instance_type'. + returned: always + type: string + sample: Primary + instance_network_type: + description: The network type of the instance + returned: always + type: string + sample: VPC + name: + description: alias of 'db_instance_description' + returned: always + type: string + sample: ansible_test_rds + pay_type: + description: The billing method of the instance + returned: always + type: string + sample: Postpaid + resource_group_id: + description: The ID of the resource group + returned: always + type: string + sample: rg-acfmyxxxxxxx + status: + description: alias of 'db_instance_status' + returned: always + type: string + sample: Running + vpc_cloud_instance_id: + description: The ID of the VPC instance + returned: always + type: string + sample: rm-uf6wjk5xxxxxxx + vpc_id: + description: The ID of the VPC. + returned: always + type: string + sample: vpc-uf6f7l4fg90xxxxxxx + vswitch_id: + description: The ID of the VSwitch. + returned: always + type: string + sample: vsw-uf6adz52c2pxxxxxxx + lock_mode: + description: The lock mode of the instance + returned: always + type: string + sample: Unlock + connection_mode: + description: The access mode of the instance + returned: always + type: string + sample: Standard + account_max_quantity: + description: The maximum number of accounts that can be created in an instance. + returned: always + type: int + sample: 50 + account_type: + description: The type of the account. + returned: always + type: string + sample: Mix + auto_upgrade_minor_version: + description: The method of upgrading an instance to a minor version + returned: always + type: string + sample: Auto + availability_value: + description: The availability of the instance + returned: always + type: string + sample: 100.0% + category: + description: The edition (series) of the instance + returned: always + type: string + sample: Basic + connection_string: + description: The private IP address of the instance. + returned: always + type: string + sample: rm-uf6wjk5xxxxxxxxxx.mysql.rds.aliyuncs.com + creation_time: + description: The time when the instance is created + returned: always + type: string + sample: 2011-05-30T12:11:04Z + current_kernel_version: + description: The current kernel version. + returned: always + type: string + sample: rds_20181010 + db_instance_class_type: + description: The instance type (specifications). + returned: always + type: string + sample: rds.mys2.small + db_instance_cpu: + description: The count of the instance cpu. + returned: always + type: int + sample: 2 + db_instance_memory: + description: The memory of the instance. + returned: always + type: int + sample: 4096 + db_instance_storage: + description: The type of the instance. + returned: always + type: string + sample: rds.mysql.t1.small + db_instance_storage_type: + description: The storage capacity of the instance. + returned: always + type: int + sample: 10 + db_max_quantity: + description: The maximum number of databases that can be created in an instance. + returned: always + type: int + sample: 200 + dispense_mode: + description: The allocation mode. + returned: always + type: string + sample: ClassicDispenseMode + expire_time: + description: The expiration time. + returned: always + type: string + sample: 2019-03-27T16:00:00Z + maintain_time: + description: The maintenance period of the instance. + returned: always + type: string + sample: 00:00Z-02:00Z + max_connections: + description: The maximum number of concurrent connections. + returned: always + type: int + sample: 60 + max_iops: + description: The maximum number of I/O requests per second. + returned: always + type: int + sample: 60 + origin_configuration: + description: The type of the instance. + returned: always + type: string + sample: rds.mysql.t1.small + port: + description: The private port of the instance.. + returned: always + type: string + sample: 3306 + read_only_dbinstance_ids: + description: The IDs of read-only instances attached to the master instance. + returned: always + type: complex + contains: + read_only_dbinstance_id: + description: The ID of a read-only instance. + returned: always + type: list + sample: ['rr-bpxxxxxxxxx'] + security_ipmode: + description: The IP whitelist mode. + returned: always + type: complex + sample: normal ''' import time @@ -343,50 +449,46 @@ HAS_FOOTMARK = False -def get_info(obj): - if not obj: - return None - return dict(db_instance_id=obj.dbinstance_id, - db_instance_status=obj.dbinstance_status, - db_instance_storage=obj.dbinstance_storage, - db_instance_type=obj.dbinstance_type, - db_instance_net_type=obj.dbinstance_net_type, - engine=obj.engine, - engine_version=obj.engine_version, - connection_string=obj.connection_string) +def get_instance(name, modules, rds): + try: + instances = rds.describe_db_instances() + res = '' + for ins in instances: + if ins.name == name: + res = ins + if res: + res = rds.describe_db_instance_attribute(DBInstanceId=res.id) + return res + except Exception as e: + modules.fail_json(msg="Failed to describe rds: {0}".format(e)) def main(): argument_spec = ecs_argument_spec() argument_spec.update(dict( - state=dict(default="present", choices=["present", "absent", "restart"], alias=['status']), - alicloud_zone=dict(type='str', aliases=['zone_id', 'zone']), + state=dict(default="present", choices=["present", "absent", "restart"]), + zone_id=dict(type='str', aliases=['alicloud_zone']), engine=dict(type='str', choices=["MySQL", "SQLServer", "PostgreSQL", "PPAS"]), engine_version=dict(type='str'), - instance_net_type=dict(type='str', choices=["Internet", "Intranet"], aliases=['db_instance_net_type']), - description=dict(type='str', aliases=['db_instance_description']), - security_ips=dict(type='str'), - instance_charge_type=dict(type='str', choices=["Postpaid", "Prepaid"]), - period=dict(type='int', choices=list(range(1, 10)).extend([12, 24, 36])), - connection_mode=dict(type='str', choices=["Performance", "Safty"]), - vpc_id=dict(type='str'), + db_instance_net_type=dict(type='str', choices=["Internet", "Intranet"], aliases=['instance_net_type']), + db_instance_name=dict(type='str', aliases=['description', 'name'], required=True), + security_ip_list=dict(type='str', aliases=['security_ips']), + pay_type=dict(type='str', choices=["PostPaid", "PrePaid"]), + period=dict(type='str', choices=['Year', 'Month']), + connection_mode=dict(type='str', choices=["Standard", "Safe"]), vswitch_id=dict(type='str'), private_ip_address=dict(type='str'), - instance_id=dict(type='str', aliases=['db_instance_id']), - tags=dict(type='str', aliases=['instance_tags']), - page_size=dict(type='int', default=30, choices=[30, 50, 100]), - page_number=dict(type='int', default=1), - auto_renew_period=dict(type='int', choices=[1, 2, 3, 6, 12]), - auto_renew=dict(type='bool'), - public_connection_string_prefix=dict(type='str'), - private_connection_string_prefix=dict(type='str'), - dest_connection_string_prefix=dict(type='str'), - dest_port=dict(type='str'), - public_port=dict(type='str'), - private_port=dict(type='int', choices=list(range(3001, 4000))), + db_instance_id=dict(type='str', aliases=['instance_id']), + tags=dict(type='dict'), + purge_tags=dict(type='bool', default=False), + auto_pay=dict(type='bool', aliases=['auto_renew']), + connection_string_prefix=dict(type='str'), + port=dict(type='str'), current_connection_string=dict(type='str'), - instance_type=dict(type='str', aliases=['db_instance_class']), - instance_storage=dict(type='int', aliases=['db_instance_storage']) + db_instance_class=dict(type='str', aliases=['instance_class']), + db_instance_storage=dict(type='int', aliases=['instance_storage']), + instance_network_type=dict(type='str'), + used_time=dict(type='str') )) modules = AnsibleModule(argument_spec=argument_spec) @@ -397,122 +499,110 @@ def main(): vpc = vpc_connect(modules) state = modules.params['state'] - alicloud_zone = modules.params['alicloud_zone'] - engine = modules.params['engine'] - engine_version = modules.params['engine_version'] - instance_net_type = modules.params['instance_net_type'] - description = modules.params['description'] - security_ips = modules.params['security_ips'] - instance_charge_type = modules.params['instance_charge_type'] - period = modules.params['period'] - connection_mode = modules.params['connection_mode'] vswitch_id = modules.params['vswitch_id'] - private_ip_address = modules.params['private_ip_address'] - instance_id = modules.params['instance_id'] + connection_string_prefix = modules.params['connection_string_prefix'] + port = modules.params['port'] tags = modules.params['tags'] - page_size = modules.params['page_size'] - page_number = modules.params['page_number'] - auto_renew_period = modules.params['auto_renew_period'] - auto_renew = modules.params['auto_renew'] - public_connection_string_prefix = modules.params['public_connection_string_prefix'] - private_connection_string_prefix = modules.params['private_connection_string_prefix'] - public_port = modules.params['public_port'] - private_port = modules.params['private_port'] current_connection_string = modules.params['current_connection_string'] - dest_connection_string_prefix = modules.params['dest_connection_string_prefix'] - dest_port = modules.params['dest_port'] - instance_type = modules.params['instance_type'] - instance_storage = modules.params['instance_storage'] - - vpc_id = None - instance_network_type = 'Classic' + db_instance_description = modules.params['db_instance_name'] + modules.params['db_instance_description'] = db_instance_description + db_instance_class = modules.params['db_instance_class'] + db_instance_storage = modules.params['db_instance_storage'] + pay_type = modules.params['pay_type'] + if pay_type: + modules.params['pay_type'] = pay_type.capitalize() current_instance = None changed = False if vswitch_id: - instance_network_type = 'VPC' + modules.params['instance_network_type'] = 'VPC' try: - vswitch_obj = vpc.get_vswitch_attribute(vswitch_id) + vswitch_obj = vpc.describe_vswitch_attributes(vswitch_id=vswitch_id) if vswitch_obj: - vpc_id = vswitch_obj.vpc_id + modules.params['vpc_id'] = vswitch_obj.vpc_id except Exception as e: modules.fail_json(msg=str("Unable to get vswitch, error:{0}".format(e))) - if instance_id: - try: - current_instance = rds.describe_db_instance_attribute(instance_id) - except Exception as e: - modules.fail_json(msg=str("Unable to describe instance, error:{0}".format(e))) + + try: + current_instance = get_instance(db_instance_description, modules, rds) + except Exception as e: + modules.fail_json(msg=str("Unable to describe instance, error:{0}".format(e))) if state == 'absent': if current_instance: if current_connection_string: try: - changed = current_instance.release_public_connection_string(current_connection_string) - modules.exit_json(changed=changed, instance=get_info(current_instance)) + changed = rds.release_instance_public_connection(current_connection_string=current_connection_string, db_instance_id=current_instance.id) + modules.exit_json(changed=changed, instances=current_instance.read()) except Exception as e: modules.fail_json(msg=str("Unable to release public connection string error: {0}".format(e))) try: - changed = current_instance.terminate() - modules.exit_json(changed=changed, instance=get_info(current_instance)) + current_instance.delete() + modules.exit_json(changed=True, instances={}) except Exception as e: modules.fail_json(msg=str("Unable to release instance error: {0}".format(e))) modules.fail_json(msg=str("Unable to operate your instance, please check your instance_id and try again!")) + if state == 'restart': if current_instance: try: changed = current_instance.restart() - modules.exit_json(changed=changed, instance=get_info(current_instance)) + modules.exit_json(changed=changed, instances=current_instance.read()) except Exception as e: modules.fail_json(msg=str("Unable to restart instance error: {0}".format(e))) modules.fail_json(msg=str("Unable to restart your instance, please check your instance_id and try again!")) + if not current_instance: try: - client_token = "Ansible-Alicloud-%s-%s" % (hash(str(module.params)), str(time.time())) - current_instance = rds.create_rds_instance(engine=engine, - engine_version=engine_version, - db_instance_class=instance_type, - db_instance_storage=instance_storage, - db_instance_net_type=instance_net_type, - security_ip_list=security_ips, - pay_type=instance_charge_type, - client_token=client_token, - instance_network_type=instance_network_type, - period='Month', - used_time=period, - alicloud_zone=alicloud_zone, - db_instance_description=description, - connection_mode=connection_mode, - vpc_id=vpc_id, - vswitch_id=vswitch_id, - private_ip_address=private_ip_address) - instance_id = current_instance.dbinstance_id + modules.params['client_token'] = "Ansible-Alicloud-%s-%s" % (hash(str(modules.params)), str(time.time())) + current_instance = rds.create_db_instance(**modules.params) + modules.exit_json(changed=True, instances=current_instance.read()) except Exception as e: modules.fail_json(msg=str("Unable to create rds instance error: {0}".format(e))) - if auto_renew: + + if connection_string_prefix and port: + if current_connection_string: + try: + changed = current_instance.modify_db_instance_connection_string(current_connection_string=current_connection_string, connection_string_prefix=connection_string_prefix, port=port) + modules.exit_json(changed=changed, instances=current_instance.read()) + except Exception as e: + modules.fail_json(msg=str("Unable to modify current string error: {0}".format(e))) + else: + try: + changed = current_instance.allocate_public_connection_string(connection_string_prefix=connection_string_prefix, port=port) + modules.exit_json(changed=changed, instances=current_instance.read()) + except Exception as e: + modules.fail_json(msg=str("Unable to allocate public connection error: {0}".format(e))) + + if modules.params['instance_network_type'] and current_instance.instance_network_type != modules.params['instance_network_type']: try: - changed = current_instance.modify_auto_renewal_attribute(duration=auto_renew_period, auto_renew=auto_renew) + changed = current_instance.modify_network_type(instance_network_type=modules.params['instance_network_type']) except Exception as e: - modules.fail_json(msg=str("Unable to modify rds instance auto renewal attribute error: {0}".format(e))) - if public_connection_string_prefix and public_port: + modules.fail_json(msg=str("Unable to modify instance network type error: {0}".format(e))) + + if db_instance_class or db_instance_storage: try: - changed = current_instance.allocate_public_connection_string(public_connection_string_prefix, public_port) + changed = current_instance.modify_instance_spec(db_instance_class=db_instance_class, db_instance_storage=db_instance_storage) except Exception as e: - modules.fail_json(msg=str("Unable to allocate public connection error: {0}".format(e))) - if private_connection_string_prefix: + modules.fail_json(msg=str("Unable to modify instance spec: {0}".format(e))) + + if modules.params['purge_tags']: + if not tags: + tags = current_instance.tags try: - changed = current_instance.allocate_private_connection_string(private_connection_string_prefix, private_port) + if current_instance.remove_tags(tags): + changed = True + modules.exit_json(changed=changed, instances=current_instance.get().read()) except Exception as e: - modules.fail_json(msg=str("Unable to allocate private connection string error: {0}".format(e))) - if current_connection_string: + modules.fail_json(msg="{0}".format(e)) + + if tags: try: - changed = current_instance.modify_connection_string(current_connection_string, dest_connection_string_prefix, dest_port) + if current_instance.add_tags(tags): + changed = True except Exception as e: - modules.fail_json(msg=str("Unable to modify current connection string error: {0}".format(e))) - # get newest instance - try: - current_instance = rds.describe_db_instance_attribute(instance_id) - except Exception as e: - modules.fail_json(msg=str("Unable to describe instance error: {0}".format(e))) - modules.exit_json(changed=changed, instance=get_info(current_instance)) + modules.fail_json(msg="{0}".format(e)) + + modules.exit_json(changed=changed, instances=current_instance.get().read()) if __name__ == '__main__': diff --git a/lib/ansible/modules/cloud/alicloud/ali_rds_instance_info.py b/lib/ansible/modules/cloud/alicloud/ali_rds_instance_info.py index 8555fa95..b733f728 100644 --- a/lib/ansible/modules/cloud/alicloud/ali_rds_instance_info.py +++ b/lib/ansible/modules/cloud/alicloud/ali_rds_instance_info.py @@ -32,179 +32,265 @@ description: - This module fetches data from the Open API in Alicloud. The module must be called from within the RDS instance itself. - options: - instance_ids: - description: - - A list of RDS database instance ids. - aliases: [ "db_instance_ids" ] - engine: - description: - - Type of the database. - dbinstance_type: - description: - - Instance type. - instance_network_type: - description: - - Instance network type. - connection_mode: - description: - - Instance connection mode. - tags: - description: - - Database tags. - + db_instance_id: + description: + - RDS database instance id. + aliases: ["instance_id"] + name_prefix: + description: + - Use instance name prefix to filter rds. + tags: + description: + - A hash/dictionaries of rds tags. C({"key":"value"}) author: - "He Guimin (@xiaozhu36)" requirements: - - "python >= 2.6" - - "footmark" + - "python >= 3.6" + - "footmark >= 1.16.0" extends_documentation_fragment: - alicloud ''' EXAMPLES = ''' -# Fetch database instance details according to setting different filters -- name: fetch database instance details example - hosts: localhost - connection: local - vars: - alicloud_access_key: - alicloud_secret_key: - alicloud_region: cn-beijing - engine: MySQL - dbinstance_type: Temp - instance_network_type: Classic - connection_mode: Safe - tags: - rds: '01' - instance_ids: - - rm-dj163498yvlgy80ug - tasks: - - name: Find all database instance in the specified region - ali_rds_instance_info: - alicloud_access_key: '{{ alicloud_access_key }}' - alicloud_secret_key: '{{ alicloud_secret_key }}' - alicloud_region: '{{ alicloud_region }}' - register: all_db_instance - - debug: var=all_db_instance +- name: Get the existing rds with name prefix + ali_rds_instance_info: + name_prefix: ansible_test_rds + db_instance_id: '{{ db_instance_id }}' - - name: Find all database instance in the specified region based on instance ids - ali_rds_instance_info: - alicloud_access_key: '{{ alicloud_access_key }}' - alicloud_secret_key: '{{ alicloud_secret_key }}' - alicloud_region: '{{ alicloud_region }}' - instance_ids: '{{ instance_ids }}' - register: db_instance_by_ids - - debug: var=db_instance_by_ids - - - name: Find all database instance in the specified region based on database instance type - ali_rds_instance_info: - alicloud_access_key: '{{ alicloud_access_key }}' - alicloud_secret_key: '{{ alicloud_secret_key }}' - alicloud_region: '{{ alicloud_region }}' - instance_ids: '{{ instance_ids }}' - engine: '{{ engine }}' - register: db_instance_by_dbtype - - debug: var=db_instance_by_dbtype - - - name: Find all database instance in the specified region based on instance type - ali_rds_instance_info: - alicloud_access_key: '{{ alicloud_access_key }}' - alicloud_secret_key: '{{ alicloud_secret_key }}' - alicloud_region: '{{ alicloud_region }}' - instance_ids: '{{ instance_ids }}' - dbinstance_type: '{{ dbinstance_type }}' - register: db_instance_by_type - - debug: var=db_instance_by_type - - - name: Find all database instance in the specified region based on instance network type - ali_rds_instance_info: - alicloud_access_key: '{{ alicloud_access_key }}' - alicloud_secret_key: '{{ alicloud_secret_key }}' - alicloud_region: '{{ alicloud_region }}' - instance_ids: '{{ instance_ids }}' - instance_network_type: '{{ instance_network_type }}' - register: db_instance_by_network_type - - debug: var=db_instance_by_network_type - - - name: Find all database instance in the specified region based on instance connection mode and tags - ali_rds_instance_info: - alicloud_access_key: '{{ alicloud_access_key }}' - alicloud_secret_key: '{{ alicloud_secret_key }}' - alicloud_region: '{{ alicloud_region }}' - instance_ids: '{{ instance_ids }}' - connection_mode: '{{ connection_mode }}' - tags: '{{ tags }}' - register: db_instance_by_connection_mode - - debug: var=db_instance_by_connection_mode +- name: Retrieving all rds + ali_rds_instance_info: ''' RETURN = ''' -instance_ids: - description: List all database instance's id after operating RDS database instances. - returned: when success - type: list - sample: [ "rm-dj1d7a046kur7syix", "rm-dj164ju77728joefu" ] -rds_db_instances: - description: Details about the rds database instances that were created. - returned: when success +instances: + description: Describe the info after operating rds instance. + returned: always type: list - sample: [ - { - "connection_mode": "Safe", - "create_time": "2017-11-07T18:47Z", - "dbinstance_class": "rds.mysql.t1.small", - "dbinstance_id": "rm-dj1d7a046kur7syix", - "dbinstance_net_type": "Intranet", - "dbinstance_status": "Running", - "dbinstance_type": "Primary", - "engine": "MySQL", - "engine_version": "5.6", - "expire_time": "", - "ins_id": 1, - "instance_network_type": "Classic", - "lock_mode": "Unlock", - "lock_reason": "", - "mutri_orsignle": false, - "pay_type": "Postpaid", - "read_only_dbinstance_ids": { - "read_only_dbinstance_id": [] - }, - "region_id": "cn-beijing", - "resource_group_id": "rg-acfmv53ndviljcy", - "zone_id": "cn-beijing-a" - }, + sample:[ { - "connection_mode": "Safe", - "create_time": "2017-11-07T18:23Z", - "dbinstance_class": "rds.mysql.t1.small", - "dbinstance_id": "rm-dj164ju77728joefu", - "dbinstance_net_type": "Intranet", - "dbinstance_status": "Running", - "dbinstance_type": "Primary", - "engine": "MySQL", - "engine_version": "5.6", - "expire_time": "", - "ins_id": 1, - "instance_network_type": "Classic", - "lock_mode": "Unlock", - "lock_reason": "", - "mutri_orsignle": false, - "pay_type": "Postpaid", - "read_only_dbinstance_ids": { - "read_only_dbinstance_id": [] - }, - "region_id": "cn-beijing", - "resource_group_id": "rg-acfmv53ndviljcy", - "zone_id": "cn-beijing-a" - } - ] -total: - description: The number of all database instances after operating RDS database instances. - returned: when success - type: int - sample: 2 + db_instance_class: + description: The type of the instance. + returned: always + type: string + sample: rds.mysql.t1.small + db_instance_description: + description: The description of the instance. + returned: always + type: string + sample: ansible_test_rds + db_instance_id: + description: The ID of the instance. + returned: always + type: string + sample: rm-uf6wjk5xxxxxxxxxx + db_instance_net_type: + description: The network type of the instance + returned: always + type: string + sample: Internet + db_instance_status: + description: The status of the instance + returned: always + type: string + sample: Running + db_instance_type: + description: The type of the instance role + returned: always + type: string + sample: Primary + engine: + description: The type of the database. + returned: always + type: string + sample: MySQL + engine_version: + description: The version of the database. + returned: always + type: string + sample: 5.6 + id: + description: alias of 'db_instance_id'. + returned: always + type: string + sample: rm-uf6wjk5xxxxxxxxxx + type: + description: alias of 'db_instance_type'. + returned: always + type: string + sample: Primary + instance_network_type: + description: The network type of the instance + returned: always + type: string + sample: VPC + name: + description: alias of 'db_instance_description' + returned: always + type: string + sample: ansible_test_rds + pay_type: + description: The billing method of the instance + returned: always + type: string + sample: Postpaid + resource_group_id: + description: The ID of the resource group + returned: always + type: string + sample: rg-acfmyxxxxxxx + status: + description: alias of 'db_instance_status' + returned: always + type: string + sample: Running + vpc_cloud_instance_id: + description: The ID of the VPC instance + returned: always + type: string + sample: rm-uf6wjk5xxxxxxx + vpc_id: + description: The ID of the VPC. + returned: always + type: string + sample: vpc-uf6f7l4fg90xxxxxxx + vswitch_id: + description: The ID of the VSwitch. + returned: always + type: string + sample: vsw-uf6adz52c2pxxxxxxx + lock_mode: + description: The lock mode of the instance + returned: always + type: string + sample: Unlock + connection_mode: + description: The access mode of the instance + returned: always + type: string + sample: Standard + account_max_quantity: + description: The maximum number of accounts that can be created in an instance. + returned: always + type: int + sample: 50 + account_type: + description: The type of the account. + returned: always + type: string + sample: Mix + auto_upgrade_minor_version: + description: The method of upgrading an instance to a minor version + returned: always + type: string + sample: Auto + availability_value: + description: The availability of the instance + returned: always + type: string + sample: 100.0% + category: + description: The edition (series) of the instance + returned: always + type: string + sample: Basic + connection_string: + description: The private IP address of the instance. + returned: always + type: string + sample: rm-uf6wjk5xxxxxxxxxx.mysql.rds.aliyuncs.com + creation_time: + description: The time when the instance is created + returned: always + type: string + sample: 2011-05-30T12:11:04Z + current_kernel_version: + description: The current kernel version. + returned: always + type: string + sample: rds_20181010 + db_instance_class_type: + description: The instance type (specifications). + returned: always + type: string + sample: rds.mys2.small + db_instance_cpu: + description: The count of the instance cpu. + returned: always + type: int + sample: 2 + db_instance_memory: + description: The memory of the instance. + returned: always + type: int + sample: 4096 + db_instance_storage: + description: The type of the instance. + returned: always + type: string + sample: rds.mysql.t1.small + db_instance_storage_type: + description: The storage capacity of the instance. + returned: always + type: int + sample: 10 + db_max_quantity: + description: The maximum number of databases that can be created in an instance. + returned: always + type: int + sample: 200 + dispense_mode: + description: The allocation mode. + returned: always + type: string + sample: ClassicDispenseMode + expire_time: + description: The expiration time. + returned: always + type: string + sample: 2019-03-27T16:00:00Z + maintain_time: + description: The maintenance period of the instance. + returned: always + type: string + sample: 00:00Z-02:00Z + max_connections: + description: The maximum number of concurrent connections. + returned: always + type: int + sample: 60 + max_iops: + description: The maximum number of I/O requests per second. + returned: always + type: int + sample: 60 + origin_configuration: + description: The type of the instance. + returned: always + type: string + sample: rds.mysql.t1.small + port: + description: The private port of the instance.. + returned: always + type: string + sample: 3306 + read_only_dbinstance_ids: + description: The IDs of read-only instances attached to the master instance. + returned: always + type: complex + contains: + read_only_dbinstance_id: + description: The ID of a read-only instance. + returned: always + type: list + sample: ['rr-bpxxxxxxxxx'] + security_ipmode: + description: The IP whitelist mode. + returned: always + type: complex + sample: normal + } + ] ''' from ansible.module_utils.basic import AnsibleModule @@ -219,84 +305,30 @@ HAS_FOOTMARK = False -def get_info(obj): - if not obj: - return None - return dict( - resource_group_id=obj.resource_group_id, - region_id=obj.region_id, - mutri_orsignle=obj.mutri_orsignle, - create_time=obj.create_time, - dbinstance_class=obj.dbinstance_class, - dbinstance_net_type=obj.dbinstance_net_type, - lock_mode=obj.lock_mode, - pay_type=obj.pay_type, - read_only_dbinstance_ids=obj.read_only_dbinstance_ids, - dbinstance_type=obj.dbinstance_type, - engine=obj.engine, - instance_network_type=obj.instance_network_type, - dbinstance_status=obj.dbinstance_status, - expire_time=obj.expire_time, - dbinstance_id=obj.dbinstance_id, - zone_id=obj.zone_id, - lock_reason=obj.lock_reason, - connection_mode=obj.connection_mode, - ins_id=obj.ins_id, - engine_version=obj.engine_version - ) - - def main(): argument_spec = ecs_argument_spec() argument_spec.update(dict( - instance_ids=dict(type='list', aliases=['db_instance_ids']), - engine=dict(type='str'), - dbinstance_type=dict(type='str'), - instance_network_type=dict(type='str'), - connection_mode=dict(type='str'), - tags = dict(type='dict') + db_instance_id=dict(type='str', aliases=['instance_id']), + name_prefix=dict(type='str'), + tags=dict(type='str') )) module = AnsibleModule(argument_spec=argument_spec) + rds = rds_connect(module) + name_prefix = module.params['name_prefix'] if HAS_FOOTMARK is False: module.fail_json(msg="Package 'footmark' required for this module.") result = [] - ids = [] - instance_ids = module.params['instance_ids'] - engine = module.params['engine'] - dbinstance_type = module.params['dbinstance_type'] - instance_network_type = module.params['instance_network_type'] - connection_mode = module.params['connection_mode'] - tags = module.params['tags'] - - if instance_ids and (not isinstance(instance_ids, list) or len(instance_ids)) < 1: - module.fail_json(msg='instance_ids should be a list of db_instance id, aborting') - try: - rds = rds_connect(module) - # list rds db_instance by instance ids - if instance_ids: - instance_id = ",".join(instance_ids) - - for rds_instance in rds.get_rds_instances(instance_id=instance_id, engine=engine, - dbinstance_type=dbinstance_type, - instance_network_type=instance_network_type, - connection_mode=connection_mode, tags=tags): - result.append(get_info(rds_instance)) - ids.append(rds_instance.dbinstance_id) - - # list all db_instance available in specified region - else: - for rds_instance in rds.get_rds_instances(): - result.append(get_info(rds_instance)) - ids.append(rds_instance.dbinstance_id) - + for rds_instance in rds.describe_db_instances(**module.params): + if name_prefix and not rds_instance.read()['name'].startswith(name_prefix): + continue + result.append(rds_instance.get().read()) + module.exit_json(changed=False, instances=result) except Exception as e: module.fail_json(msg="Unable to describe rds db instance, and got an error: {0}.".format(e)) - module.exit_json(changed=False, db_instance_ids=ids, rds_db_instances=result, total=len(result)) - if __name__ == '__main__': main() diff --git a/tests/ali_rds_copy_database_between_instance_test.yml b/tests/ali_rds_copy_database_between_instance_test.yml new file mode 100644 index 00000000..5c74a714 --- /dev/null +++ b/tests/ali_rds_copy_database_between_instance_test.yml @@ -0,0 +1,90 @@ +--- +- name: Validate module ali_rds_database + hosts: localhost + remote_user: root + + roles: + - vpc + - vswitch + + tasks: + - name: Changed. Create a new RDS Instance + ali_rds_instance: + state: present + engine: SQLServer + engine_version: 2012_web + db_instance_class: mssql.x2.medium.w1 + db_instance_storage: 30 + db_instance_net_type: Intranet + security_ip_list: 10.23.12.24/24 + pay_type: PostPaid + vswitch_id: '{{ vswitches.vswitches.0.id }}' + db_instance_description: ansible_test_rds + register: rds + + - name: Get the existing rds + ali_rds_instance_info: + name_prefix: '{{ rds.instances.name }}' + register: rds + + - name: Changed. Create another RDS Instance + ali_rds_instance: + state: present + engine: SQLServer + engine_version: 2012_web + db_instance_class: mssql.x2.medium.w1 + db_instance_storage: 30 + db_instance_net_type: Intranet + security_ip_list: 10.23.12.24/24 + pay_type: PostPaid + vswitch_id: '{{ vswitches.vswitches.0.id }}' + db_instance_description: ansible_test_rds2 + register: rds2 + + - name: Get the existing rds + ali_rds_instance_info: + name_prefix: '{{ rds2.instances.name }}' + register: rds2 + + - name: Create Database + ali_rds_database: + db_instance_id: '{{ rds.instances.0.id }}' + db_name: ansible_test + character_set_name: utf8 + db_description: create for ansible test + state: present + + - name: Get the existing db + ali_rds_database_info: + name_prefix: ansible_test + db_instance_id: '{{ rds.instances.0.id }}' + register: db + + - name: Changed. Copy Database Between Instances + ali_rds_database: + db_instance_id: '{{ rds.instances.0.id }}' + db_name: '{{ db.databases.0.name }}' + target_db_instance_id: '{{ rds2.instances.0.id }}' + target_db_name: ansible_test2 + + - name: No Changed. Copy Database Between Instances + ali_rds_database: + db_instance_id: '{{ rds.instances.0.id }}' + db_name: '{{ db.databases.0.name }}' + target_db_instance_id: '{{ rds2.instances.0.id }}' + target_db_name: ansible_test2 + + - name: Changed. Deleting rds + ali_rds_instance: + state: absent + db_instance_description: '{{ rds.instances.0.name }}' + + + - name: Changed. Deleting another rds + ali_rds_instance: + state: absent + db_instance_description: '{{ rds.instances.0.name }}' + + + + diff --git a/tests/ali_rds_database_info_test.yml b/tests/ali_rds_database_info_test.yml new file mode 100644 index 00000000..02b87af2 --- /dev/null +++ b/tests/ali_rds_database_info_test.yml @@ -0,0 +1,51 @@ +--- +- name: Validate module ali_rds_database + hosts: localhost + remote_user: root + + roles: + - vpc + - vswitch + - rds + + tasks: + - name: Create Database + ali_rds_database: + db_instance_id: '{{ rds.instances.0.id }}' + db_name: ansible_test + character_set_name: utf8 + db_description: create for ansible test + state: present + + - name: Get the existing databse with name prefix + ali_rds_database_info: + name_prefix: ansible_ + db_instance_id: '{{ rds.instances.0.id }}' + + - name: Get the existing databse with status + ali_rds_database_info: + db_status: Running + db_instance_id: '{{ rds.instances.0.id }}' + + - name: Retrieving all database + ali_rds_database_info: + db_instance_id: '{{ rds.instances.0.id }}' + + - name: Changed. Deleting vswitches + ali_vswitch: + vpc_id: '{{ item.vpc_id}}' + cidr_block: '{{ item.cidr_block}}' + state: absent + with_items: '{{vswitches.vswitches}}' + + - name: Changed. Deleting vpcs + ali_vpc: + name: '{{vpc.vpc.vpc_name}}' + cidr_block: '{{vpc.vpc.cidr_block}}' + state: absent + + - name: Changed. Deleting rds + ali_rds_instance: + state: absent + db_instance_description: '{{ rds.instances.0.name }}' + diff --git a/tests/ali_rds_database_test.yml b/tests/ali_rds_database_test.yml new file mode 100644 index 00000000..bdd920b1 --- /dev/null +++ b/tests/ali_rds_database_test.yml @@ -0,0 +1,63 @@ +--- +- name: Validate module ali_rds_database + hosts: localhost + remote_user: root + + roles: + - vpc + - vswitch + - rds + + tasks: + - name: Create Database + ali_rds_database: + db_instance_id: '{{ rds.instances.0.id }}' + db_name: ansible_test + character_set_name: utf8 + db_description: create for ansible test + state: present + + - name: Get the existing db + ali_rds_database_info: + name_prefix: ansible_test + db_instance_id: '{{ rds.instances.0.id }}' + register: db + + - name: Changed. Modify db description. + ali_rds_database: + db_instance_id: '{{ rds.instances.0.id }}' + db_name: ansible_test + db_description: modify db description test + + - name: No Changed. Modify db description. + ali_rds_database: + db_instance_id: '{{ rds.instances.0.id }}' + db_name: ansible_test + db_description: modify db description test + + - name: Changed. Deleting database + ali_rds_database: + state: absent + db_instance_id: '{{ rds.instances.0.id }}' + db_name: ansible_test + + - name: Changed. Deleting rds + ali_rds_instance: + state: absent + db_instance_description: '{{ rds.instances.0.name }}' + + - name: Changed. Deleting vswitches + ali_vswitch: + vpc_id: '{{ item.vpc_id}}' + cidr_block: '{{ item.cidr_block}}' + state: absent + with_items: '{{vswitches.vswitches}}' + + - name: Changed. Deleting vpcs + ali_vpc: + name: '{{vpc.vpc.vpc_name}}' + cidr_block: '{{vpc.vpc.cidr_block}}' + state: absent + + + diff --git a/tests/ali_rds_instance_info_test.yml b/tests/ali_rds_instance_info_test.yml new file mode 100644 index 00000000..c0c4d23a --- /dev/null +++ b/tests/ali_rds_instance_info_test.yml @@ -0,0 +1,42 @@ +--- +- name: Validate module ali_rds_instance_info + hosts: localhost + remote_user: root + + roles: + - vpc + - vswitch + - rds + + tasks: + - name: Get the existing rds with name prefix + ali_rds_instance_info: + name_prefix: ansible_test_rds + + - name: Retrieving all rds + ali_rds_instance_info: + + - name: Filter rds using tags + ali_rds_instance_info: + tags: + Test2: "add3" + + - name: Changed. Deleting vswitches + ali_vswitch: + vpc_id: '{{ item.vpc_id}}' + cidr_block: '{{ item.cidr_block}}' + state: absent + with_items: '{{vswitches.vswitches}}' + + - name: Changed. Deleting vpcs + ali_vpc: + name: '{{vpc.vpc.vpc_name}}' + cidr_block: '{{vpc.vpc.cidr_block}}' + state: absent + + - name: Changed. Deleting rds + ali_rds_instance: + state: absent + db_instance_id: '{{ rds.instances.0.id }}' + + diff --git a/tests/ali_rds_instance_test.yml b/tests/ali_rds_instance_test.yml new file mode 100644 index 00000000..502746e3 --- /dev/null +++ b/tests/ali_rds_instance_test.yml @@ -0,0 +1,127 @@ +--- +- name: Validate module ali_rds_instance + hosts: localhost + remote_user: root + + roles: + - vpc + - vswitch + - rds + + tasks: + - name: Changed. Add Tags. + ali_rds_instance: + db_instance_description: '{{ rds.instances.0.name }}' + tags: + Test1: "add1" + Test2: "add2" + + - name: Filter rds using tags + ali_rds_instance_info: + tags: + Test1: "add1" + + - name: Changed. Modify Tags. + ali_rds_instance: + db_instance_description: '{{ rds.instances.0.name }}' + tags: + Test1: "add1" + Test2: "add3" + + - name: No Changed. No tags need to be added + ali_rds_instance: + db_instance_description: '{{ rds.instances.0.name }}' + tags: + Test1: "add1" + Test2: "add3" + + - name: Changed. Removing tags. + ali_rds_instance: + db_instance_description: '{{ rds.instances.0.name }}' + purge_tags: True + tags: + Test1: "add1" + + - name: Changed. allocate instance public connection string + ali_rds_instance: + db_instance_description: '{{ rds.instances.0.name }}' + connection_string_prefix: publicave-89asd + port: 3165 + + - name: release instance public connection string + ali_rds_instance: + state: absent + db_instance_description: '{{ rds.instances.0.name }}' + current_connection_string: publicave-89asd.mysql.rds.aliyuncs.com + + - name: Get the existing rds + ali_rds_instance_info: + name_prefix: '{{ rds.instances.0.name }}' + register: rds + + - name: restart rds instance + ali_rds_instance: + db_instance_description: '{{ rds.instances.0.name }}' + state: restart + + - name: Changed. modify instance network type + ali_rds_instance: + db_instance_description: '{{ rds.instances.0.name }}' + instance_network_type: Classic + + - name: No Changed. modify instance network type + ali_rds_instance: + db_instance_description: '{{ rds.instances.0.name }}' + instance_network_type: Classic + + - name: Changed. modify instance spec + ali_rds_instance: + db_instance_description: '{{ rds.instances.0.name }}' + db_instance_class: rds.mysql.c2.xlarge + db_instance_storage: 40 + + - name: No Changed. modify instance spec + ali_rds_instance: + db_instance_description: '{{ rds.instances.0.name }}' + db_instance_class: rds.mysql.c2.xlarge + db_instance_storage: 40 + + - name: Changed. modify instance current connection string + ali_rds_instance: + current_connection_string: '{{ rds.instances.0.id }}.mysql.rds.aliyuncs.com' + db_instance_description: '{{ rds.instances.0.name }}' + connection_string_prefix: private-ansible + port: 3307 + + - name: No Changed. modify instance current connection string + ali_rds_instance: + current_connection_string: '{{ rds.instances.0.id }}.mysql.rds.aliyuncs.com' + db_instance_description: '{{ rds.instances.0.name }}' + connection_string_prefix: private-ansible + port: 3307 + + - name: Get the existing rds + ali_rds_instance_info: + name_prefix: '{{ rds.instances.0.name }}' + register: rds + + - name: Changed. Deleting rds + ali_rds_instance: + state: absent + db_instance_description: '{{ rds.instances.0.name }}' + + - name: Changed. Deleting vswitches + ali_vswitch: + vpc_id: '{{ item.vpc_id}}' + cidr_block: '{{ item.cidr_block}}' + state: absent + with_items: '{{vswitches.vswitches}}' + + - name: Changed. Deleting vpcs + ali_vpc: + name: '{{vpc.vpc.vpc_name}}' + cidr_block: '{{vpc.vpc.cidr_block}}' + state: absent + + + diff --git a/tests/roles/rds/tasks/main.yml b/tests/roles/rds/tasks/main.yml new file mode 100644 index 00000000..85307222 --- /dev/null +++ b/tests/roles/rds/tasks/main.yml @@ -0,0 +1,19 @@ +--- +- name: Changed. Create a new RDS Instance + ali_rds_instance: + state: present + engine: MySQL + engine_version: 5.6 + db_instance_class: rds.mysql.t1.small + db_instance_storage: 30 + db_instance_net_type: Intranet + security_ip_list: 10.23.12.24/24 + pay_type: PostPaid + vswitch_id: '{{ vswitches.vswitches.0.id }}' + db_instance_description: ansible_test_rds + register: rds + +- name: Get the existing rds + ali_rds_instance_info: + db_instance_id: '{{ rds.instances.id }}' + register: rds