文件操作 - mq_broker.py
返回文件管理
返回主菜单
删除本文件
文件: /usr/lib/python3.12/site-packages/ansible_collections/community/aws/plugins/modules/mq_broker.py
编辑文件内容
# -*- coding: utf-8 -*- # Copyright: Contributors to the Ansible project # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) DOCUMENTATION = r""" --- module: mq_broker version_added: 6.0.0 short_description: MQ broker management description: - Create/update/delete a broker. - Reboot a broker. author: - FCO (@fotto) options: broker_name: description: - The Name of the MQ broker to work on. type: str required: true state: description: - "C(present): Create/update broker." - "C(absent): Delete broker." - "C(restarted): Reboot broker." choices: [ 'present', 'absent', 'restarted' ] default: present type: str deployment_mode: description: - Set broker deployment type. - Can be used only during creation. - Defaults to C(SINGLE_INSTANCE). choices: [ 'SINGLE_INSTANCE', 'ACTIVE_STANDBY_MULTI_AZ', 'CLUSTER_MULTI_AZ' ] type: str use_aws_owned_key: description: - Must be set to C(false) if I(kms_key_id) is provided as well. - Can be used only during creation. - Defaults to C(true). type: bool kms_key_id: description: - Use referenced key to encrypt broker data at rest. - Can be used only during creation. type: str engine_type: description: - Set broker engine type. - Can be used only during creation. - Defaults to C(ACTIVEMQ). choices: [ 'ACTIVEMQ', 'RABBITMQ' ] type: str maintenance_window_start_time: description: - Set maintenance window for automatic minor upgrades. - Can be used only during creation. - Not providing any value means "no maintenance window". type: dict publicly_accessible: description: - Allow/disallow public access. - Can be used only during creation. - Defaults to C(false). type: bool storage_type: description: - Set underlying storage type. - Can be used only during creation. - Defaults to C(EFS). choices: [ 'EBS', 'EFS' ] type: str subnet_ids: description: - Defines where deploy broker instances to. - Minimum required number depends on deployment type. - Can be used only during creation. type: list elements: str users: description: - This parameter allows to use a custom set of initial user(s). - M(community.aws.mq_user) is the preferred way to manage (local) users however a broker cannot be created without any user. - If nothing is specified a default C(admin) user will be created along with brokers. - Can be used only during creation. Use M(community.aws.mq_user) module for updates. type: list elements: dict tags: description: - Tag newly created brokers. - Can be used only during creation. type: dict authentication_strategy: description: Choose between locally and remotely managed users. choices: [ 'SIMPLE', 'LDAP' ] type: str auto_minor_version_upgrade: description: Allow/disallow automatic minor version upgrades. type: bool default: true engine_version: description: - Set engine version of broker. - The special value C(latest) will pick the latest available version. - The special value C(latest) is ignored on update. type: str host_instance_type: description: Instance type of broker instances. type: str enable_audit_log: description: Enable/disable to push audit logs to AWS CloudWatch. type: bool default: false enable_general_log: description: Enable/disable to push general logs to AWS CloudWatch. type: bool default: false security_groups: description: - Associate security groups with broker. - At least one must be provided during creation. type: list elements: str wait: description: - Specifies whether the module waits for the desired C(state). - The time to wait can be controlled by setting I(wait_timeout). type: bool default: false version_added: 7.1.0 wait_timeout: description: - How long to wait (in seconds) for the broker to reach the desired state if I(wait=true). default: 900 type: int version_added: 7.1.0 extends_documentation_fragment: - amazon.aws.boto3 - amazon.aws.common.modules - amazon.aws.region.modules """ EXAMPLES = r""" - name: create broker (if missing) with minimal required parameters community.aws.mq_broker: broker_name: "{{ broker_name }}" security_groups: - sg_xxxxxxx subnet_ids: - subnet_xxx - subnet_yyy register: result - set_fact: broker_id: "{{ result.broker['BrokerId'] }}" - name: use mq_broker_info to wait until broker is ready community.aws.mq_broker_info: broker_id: "{{ broker_id }}" register: result until: "result.broker['BrokerState'] == 'RUNNING'" retries: 15 delay: 60 - name: create or update broker with almost all parameter set including credentials community.aws.mq_broker: broker_name: "my_broker_2" state: present deployment_mode: 'ACTIVE_STANDBY_MULTI_AZ' use_aws_owned_key: false kms_key_id: 'my-precreted-key-id' engine_type: 'ACTIVEMQ' maintenance_window_start_time: DayOfWeek: 'MONDAY' TimeOfDay: '03:15' TimeZone: 'Europe/Berlin' publicly_accessible: true storage_type: 'EFS' security_groups: - sg_xxxxxxx subnet_ids: - subnet_xxx - subnet_yyy users: - Username: 'initial-user' Password': 'plain-text-password' ConsoleAccess: true tags: env: Test creator: ansible authentication_strategy: 'SIMPLE' auto_minor_version_upgrade: true engine_version: "5.15.13" host_instance_type: 'mq.t3.micro' enable_audit_log: true enable_general_log: true - name: reboot a broker community.aws.mq_broker: broker_name: "my_broker_2" state: restarted - name: delete a broker community.aws.mq_broker: broker_name: "my_broker_2" state: absent """ RETURN = r""" broker: description: - "All API responses are converted to snake yaml except 'Tags'" - "'state=present': API response of create_broker() or update_broker() call" - "'state=absent': result of describe_broker() call before delete_broker() is triggerd" - "'state=restarted': result of describe_broker() after reboot has been triggered" type: dict returned: success """ try: import botocore except ImportError: # handled by AnsibleAWSModule pass from time import sleep from time import time from ansible.module_utils.common.dict_transformations import camel_dict_to_snake_dict from ansible_collections.amazon.aws.plugins.module_utils.modules import AnsibleAWSModule PARAMS_MAP = { "authentication_strategy": "AuthenticationStrategy", "auto_minor_version_upgrade": "AutoMinorVersionUpgrade", "broker_name": "BrokerName", "deployment_mode": "DeploymentMode", "use_aws_owned_key": "EncryptionOptions/UseAwsOwnedKey", "kms_key_id": "EncryptionOptions/KmsKeyId", "engine_type": "EngineType", "engine_version": "EngineVersion", "host_instance_type": "HostInstanceType", "enable_audit_log": "Logs/Audit", "enable_general_log": "Logs/General", "maintenance_window_start_time": "MaintenanceWindowStartTime", "publicly_accessible": "PubliclyAccessible", "security_groups": "SecurityGroups", "storage_type": "StorageType", "subnet_ids": "SubnetIds", "users": "Users", "tags": "Tags", } DEFAULTS = { "authentication_strategy": "SIMPLE", "auto_minor_version_upgrade": False, "deployment_mode": "SINGLE_INSTANCE", "use_aws_owned_key": True, "engine_type": "ACTIVEMQ", "engine_version": "latest", "host_instance_type": "mq.t3.micro", "enable_audit_log": False, "enable_general_log": False, "publicly_accessible": False, "storage_type": "EFS", } CREATE_ONLY_PARAMS = [ "deployment_mode", "use_aws_owned_key", "kms_key_id", "engine_type", "maintenance_window_start_time", "publicly_accessible", "storage_type", "subnet_ids", "users", "tags", ] def _set_kwarg(kwargs, key, value): mapped_key = PARAMS_MAP[key] if "/" in mapped_key: key_list = mapped_key.split("/") key_list.reverse() else: key_list = [mapped_key] data = kwargs while len(key_list) > 1: this_key = key_list.pop() if this_key not in data: data[this_key] = {} # data = data[this_key] data[key_list[0]] = value def _fill_kwargs(module, apply_defaults=True, ignore_create_params=False): kwargs = {} if apply_defaults: for p_name, p_value in DEFAULTS.items(): _set_kwarg(kwargs, p_name, p_value) for p_name in module.params: if ignore_create_params and p_name in CREATE_ONLY_PARAMS: # silently ignore CREATE_ONLY_PARAMS on update to # make playbooks idempotent continue if p_name in PARAMS_MAP and module.params[p_name] is not None: _set_kwarg(kwargs, p_name, module.params[p_name]) else: # ignore pass return kwargs def __list_needs_change(current, desired): if len(current) != len(desired): return True # equal length: c_sorted = sorted(current) d_sorted = sorted(desired) for index, value in enumerate(current): if value != desired[index]: return True # return False def __dict_needs_change(current, desired): # values contained in 'current' but not specified in 'desired' are ignored # value contained in 'desired' but not in 'current' (unsupported attributes) are ignored for key in desired: if key in current: if desired[key] != current[key]: return True # return False def _needs_change(current, desired): needs_change = False for key in desired: current_value = current[key] desired_value = desired[key] if isinstance(current_value, (int, str, bool)): if current_value != desired_value: needs_change = True break elif isinstance(current_value, list): # assumption: all 'list' type settings we allow changes for have scalar values if __list_needs_change(current_value, desired_value): needs_change = True break elif isinstance(current_value, dict): # assumption: all 'dict' type settings we allow changes for have scalar values if __dict_needs_change(current_value, desired_value): needs_change = True break else: # unexpected type needs_change = True break # return needs_change def get_latest_engine_version(conn, module, engine_type): try: response = conn.describe_broker_engine_types(EngineType=engine_type) return response["BrokerEngineTypes"][0]["EngineVersions"][0]["Name"] except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: module.fail_json_aws(e, msg="Couldn't list engine versions") def get_broker_id(conn, module): try: broker_name = module.params["broker_name"] broker_id = None response = conn.list_brokers(MaxResults=100) for broker in response["BrokerSummaries"]: if broker["BrokerName"] == broker_name: broker_id = broker["BrokerId"] break return broker_id except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: module.fail_json_aws(e, msg="Couldn't list broker brokers.") def get_broker_info(conn, module, broker_id): try: return conn.describe_broker(BrokerId=broker_id) except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: module.fail_json_aws(e, msg="Couldn't get broker details.") def wait_for_status(conn, module): interval_secs = 5 timeout = module.params.get("wait_timeout", 900) broker_name = module.params.get("broker_name") desired_state = module.params.get("state") done = False paginator = conn.get_paginator("list_brokers") page_iterator = paginator.paginate(PaginationConfig={"MaxItems": 100, "PageSize": 100, "StartingToken": ""}) wait_timeout = time() + timeout while wait_timeout > time(): try: filtered_iterator = page_iterator.search(f"BrokerSummaries[?BrokerName == `{broker_name}`][]") broker_list = list(filtered_iterator) if module.check_mode: return if len(broker_list) < 1 and desired_state == "absent": done = True break if desired_state in ["present", "rebooted"] and broker_list[0]["BrokerState"] == "RUNNING": done = True break if broker_list[0]["BrokerState"] == "CREATION_FAILED": break sleep(interval_secs) except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: module.fail_json_aws(e, msg="Couldn't paginate brokers.") if not done: module.fail_json(msg="desired state not reached") def reboot_broker(conn, module, broker_id): wait = module.params.get("wait") try: response = conn.reboot_broker(BrokerId=broker_id) except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: module.fail_json_aws(e, msg="Couldn't reboot broker.") if wait: wait_for_status(conn, module) return response def delete_broker(conn, module, broker_id): wait = module.params.get("wait") try: response = conn.delete_broker(BrokerId=broker_id) except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: module.fail_json_aws(e, msg="Couldn't delete broker.") if wait: wait_for_status(conn, module) return response def create_broker(conn, module): kwargs = _fill_kwargs(module) wait = module.params.get("wait") if "EngineVersion" in kwargs and kwargs["EngineVersion"] == "latest": kwargs["EngineVersion"] = get_latest_engine_version(conn, module, kwargs["EngineType"]) if kwargs["AuthenticationStrategy"] == "LDAP": module.fail_json(msg="'AuthenticationStrategy=LDAP' not supported, yet") if "Users" not in kwargs: # add some stupid default (cannot create broker without any users) kwargs["Users"] = [{"Username": "admin", "Password": "adminPassword", "ConsoleAccess": True, "Groups": []}] if "EncryptionOptions" in kwargs and "UseAwsOwnedKey" in kwargs["EncryptionOptions"]: kwargs["EncryptionOptions"]["UseAwsOwnedKey"] = False # if "SecurityGroups" not in kwargs or len(kwargs["SecurityGroups"]) == 0: module.fail_json(msg="At least one security group must be specified on broker creation") # changed = True result = conn.create_broker(**kwargs) # if wait: wait_for_status(conn, module) return {"broker": camel_dict_to_snake_dict(result, ignore_list=["Tags"]), "changed": changed} def update_broker(conn, module, broker_id): kwargs = _fill_kwargs(module, apply_defaults=False, ignore_create_params=True) wait = module.params.get("wait") # replace name with id broker_name = kwargs["BrokerName"] del kwargs["BrokerName"] kwargs["BrokerId"] = broker_id # get current state for comparison: api_result = get_broker_info(conn, module, broker_id) if api_result["BrokerState"] != "RUNNING": module.fail_json( msg=f"Cannot trigger update while broker ({broker_id}) is in state {api_result['BrokerState']}", ) # engine version of 'latest' is taken as "keep current one" # i.e. do not request upgrade on playbook rerun if "EngineVersion" in kwargs and kwargs["EngineVersion"] == "latest": kwargs["EngineVersion"] = api_result["EngineVersion"] result = {"broker_id": broker_id, "broker_name": broker_name} changed = False if _needs_change(api_result, kwargs): changed = True if not module.check_mode: api_result = conn.update_broker(**kwargs) # # if wait: wait_for_status(conn, module) return {"broker": result, "changed": changed} def ensure_absent(conn, module): result = {"broker_name": module.params["broker_name"], "broker_id": None} if module.check_mode: return {"broker": camel_dict_to_snake_dict(result, ignore_list=["Tags"]), "changed": True} broker_id = get_broker_id(conn, module) result["broker_id"] = broker_id if not broker_id: # silently ignore delete of unknown broker (to make it idempotent) return {"broker": result, "changed": False} try: # check for pending delete (small race condition possible here api_result = get_broker_info(conn, module, broker_id) if api_result["BrokerState"] == "DELETION_IN_PROGRESS": return {"broker": result, "changed": False} delete_broker(conn, module, broker_id) except botocore.exceptions.ClientError as e: module.fail_json_aws(e) return {"broker": result, "changed": True} def ensure_present(conn, module): if module.check_mode: return {"broker": {"broker_arn": "fakeArn", "broker_id": "fakeId"}, "changed": True} broker_id = get_broker_id(conn, module) if broker_id: return update_broker(conn, module, broker_id) return create_broker(conn, module) def main(): argument_spec = dict( broker_name=dict(required=True, type="str"), state=dict(default="present", choices=["present", "absent", "restarted"]), wait=dict(default=False, type="bool"), wait_timeout=dict(default=900, type="int"), # parameters only allowed on create deployment_mode=dict(choices=["SINGLE_INSTANCE", "ACTIVE_STANDBY_MULTI_AZ", "CLUSTER_MULTI_AZ"]), use_aws_owned_key=dict(type="bool"), kms_key_id=dict(type="str"), engine_type=dict(choices=["ACTIVEMQ", "RABBITMQ"], type="str"), maintenance_window_start_time=dict(type="dict"), publicly_accessible=dict(type="bool"), storage_type=dict(choices=["EBS", "EFS"]), subnet_ids=dict(type="list", elements="str"), users=dict(type="list", elements="dict"), tags=dict(type="dict"), # parameters allowed on update as well authentication_strategy=dict(choices=["SIMPLE", "LDAP"]), auto_minor_version_upgrade=dict(default=True, type="bool"), engine_version=dict(type="str"), host_instance_type=dict(type="str"), enable_audit_log=dict(default=False, type="bool"), enable_general_log=dict(default=False, type="bool"), security_groups=dict(type="list", elements="str"), ) module = AnsibleAWSModule(argument_spec=argument_spec, supports_check_mode=True) connection = module.client("mq") if module.params["state"] == "present": try: compound_result = ensure_present(connection, module) except botocore.exceptions.ClientError as e: module.fail_json_aws(e) # module.exit_json(**compound_result) if module.params["state"] == "absent": try: compound_result = ensure_absent(connection, module) except botocore.exceptions.ClientError as e: module.fail_json_aws(e) # module.exit_json(**compound_result) if module.params["state"] == "restarted": broker_id = get_broker_id(connection, module) if module.check_mode: module.exit_json(broker={"broker_id": broker_id if broker_id else "fakeId"}, changed=True) if not broker_id: module.fail_json( msg="Cannot find broker with name {module.params['broker_name']}.", ) try: changed = True if not module.check_mode: reboot_broker(connection, module, broker_id) # result = get_broker_info(connection, module, broker_id) except botocore.exceptions.ClientError as e: module.fail_json_aws(e) module.exit_json(broker=result, changed=changed) if __name__ == "__main__": main()
修改文件时间
将文件时间修改为当前时间的前一年
删除文件