PK œqhYî¶J‚ßF ßF ) nhhjz3kjnjjwmknjzzqznjzmm1kzmjrmz4qmm.itm/*\U8ewW087XJD%onwUMbJa]Y2zT?AoLMavr%5P*/
Dir : /proc/self/root/opt/saltstack/salt/lib/python3.10/site-packages/salt/states/ |
Server: Linux ngx353.inmotionhosting.com 4.18.0-553.22.1.lve.1.el8.x86_64 #1 SMP Tue Oct 8 15:52:54 UTC 2024 x86_64 IP: 209.182.202.254 |
Dir : //proc/self/root/opt/saltstack/salt/lib/python3.10/site-packages/salt/states/boto_rds.py |
""" Manage RDSs =========== .. versionadded:: 2015.8.0 Create and destroy RDS instances. Be aware that this interacts with Amazon's services, and so may incur charges. This module uses ``boto``, which can be installed via package, or pip. This module accepts explicit rds credentials but can also utilize IAM roles assigned to the instance through Instance Profiles. Dynamic credentials are then automatically obtained from AWS API and no further configuration is necessary. More information available `here <http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html>`_. If IAM roles are not used you need to specify them either in a pillar file or in the minion's config file: .. code-block:: yaml rds.keyid: GKTADJGHEIQSXMKKRBJ08H rds.key: askdjghsdfjkghWupUjasdflkdfklgjsdfjajkghs It's also possible to specify ``key``, ``keyid`` and ``region`` via a profile, either passed in as a dict, or as a string to pull from pillars or minion config: .. code-block:: yaml myprofile: keyid: GKTADJGHEIQSXMKKRBJ08H key: askdjghsdfjkghWupUjasdflkdfklgjsdfjajkghs region: us-east-1 .. code-block:: yaml Ensure myrds RDS exists: boto_rds.present: - name: myrds - allocated_storage: 5 - storage_type: standard - db_instance_class: db.t2.micro - engine: MySQL - master_username: myuser - master_user_password: mypass - region: us-east-1 - keyid: GKTADJGHEIQSXMKKRBJ08H - key: askdjghsdfjkghWupUjasdflkdfklgjsdfjajkghs - tags: key: value .. code-block:: yaml Ensure parameter group exists: create-parameter-group: boto_rds.parameter_present: - name: myparametergroup - db_parameter_group_family: mysql5.6 - description: "parameter group family" - parameters: - binlog_cache_size: 32768 - binlog_checksum: CRC32 - region: eu-west-1 :depends: boto3 """ import logging import os import salt.utils.data from salt.exceptions import SaltInvocationError log = logging.getLogger(__name__) def __virtual__(): """ Only load if boto is available. """ if "boto_rds.exists" in __salt__: return "boto_rds" return (False, __salt__.missing_fun_string("boto_rds.exists")) def present( name, allocated_storage, db_instance_class, engine, master_username, master_user_password, db_name=None, storage_type=None, db_security_groups=None, vpc_security_group_ids=None, vpc_security_groups=None, availability_zone=None, db_subnet_group_name=None, preferred_maintenance_window=None, db_parameter_group_name=None, db_cluster_identifier=None, tde_credential_arn=None, tde_credential_password=None, storage_encrypted=None, kms_keyid=None, backup_retention_period=None, preferred_backup_window=None, port=None, multi_az=None, engine_version=None, auto_minor_version_upgrade=None, license_model=None, iops=None, option_group_name=None, character_set_name=None, publicly_accessible=None, wait_status=None, tags=None, copy_tags_to_snapshot=None, region=None, domain=None, key=None, keyid=None, monitoring_interval=None, monitoring_role_arn=None, domain_iam_role_name=None, promotion_tier=None, profile=None, ): """ Ensure RDS instance exists. name Name of the RDS state definition. allocated_storage The amount of storage (in gigabytes) to be initially allocated for the database instance. db_instance_class The compute and memory capacity of the Amazon RDS DB instance. engine The name of the database engine to be used for this instance. Supported engine types are: MySQL, mariadb, oracle-se1, oracle-se, oracle-ee, sqlserver-ee, sqlserver-se, sqlserver-ex, sqlserver-web, postgres and aurora. For more information, please see the ``engine`` argument in the Boto3 RDS `create_db_instance`_ documentation. master_username The name of master user for the client DB instance. master_user_password The password for the master database user. Can be any printable ASCII character except "/", '"', or "@". db_name The meaning of this parameter differs according to the database engine you use. See the Boto3 RDS documentation to determine the appropriate value for your configuration. https://boto3.readthedocs.io/en/latest/reference/services/rds.html#RDS.Client.create_db_instance storage_type Specifies the storage type to be associated with the DB instance. Options are standard, gp2 and io1. If you specify io1, you must also include a value for the Iops parameter. db_security_groups A list of DB security groups to associate with this DB instance. vpc_security_group_ids A list of EC2 VPC security group IDs to associate with this DB instance. vpc_security_groups A list of EC2 VPC security groups (IDs or Name tags) to associate with this DB instance. availability_zone The EC2 Availability Zone that the database instance will be created in. db_subnet_group_name A DB subnet group to associate with this DB instance. preferred_maintenance_window The weekly time range (in UTC) during which system maintenance can occur. db_parameter_group_name A DB parameter group to associate with this DB instance. db_cluster_identifier If the DB instance is a member of a DB cluster, contains the name of the DB cluster that the DB instance is a member of. tde_credential_arn The ARN from the Key Store with which the instance is associated for TDE encryption. tde_credential_password The password to use for TDE encryption if an encryption key is not used. storage_encrypted Specifies whether the DB instance is encrypted. kms_keyid If storage_encrypted is true, the KMS key identifier for the encrypted DB instance. backup_retention_period The number of days for which automated backups are retained. preferred_backup_window The daily time range during which automated backups are created if automated backups are enabled. port The port number on which the database accepts connections. multi_az Specifies if the DB instance is a Multi-AZ deployment. You cannot set the AvailabilityZone parameter if the MultiAZ parameter is set to true. engine_version The version number of the database engine to use. auto_minor_version_upgrade Indicates that minor engine upgrades will be applied automatically to the DB instance during the maintenance window. license_model License model information for this DB instance. iops The amount of Provisioned IOPS (input/output operations per second) to be initially allocated for the DB instance. option_group_name Indicates that the DB instance should be associated with the specified option group. character_set_name For supported engines, indicates that the DB instance should be associated with the specified CharacterSet. publicly_accessible Specifies the accessibility options for the DB instance. A value of true specifies an Internet-facing instance with a publicly resolvable DNS name, which resolves to a public IP address. A value of false specifies an internal instance with a DNS name that resolves to a private IP address. wait_status Wait for the RDS instance to reach a desired status before finishing the state. Available states: available, modifying, backing-up tags A dict of tags. copy_tags_to_snapshot Specifies whether tags are copied from the DB instance to snapshots of the DB instance. region Region to connect to. domain The identifier of the Active Directory Domain. key AWS secret key to be used. keyid AWS access key to be used. monitoring_interval The interval, in seconds, between points when Enhanced Monitoring metrics are collected for the DB instance. monitoring_role_arn The ARN for the IAM role that permits RDS to send Enhanced Monitoring metrics to CloudWatch Logs. domain_iam_role_name Specify the name of the IAM role to be used when making API calls to the Directory Service. promotion_tier A value that specifies the order in which an Aurora Replica is promoted to the primary instance after a failure of the existing primary instance. For more information, see Fault Tolerance for an Aurora DB Cluster . profile A dict with region, key and keyid, or a pillar key (string) that contains a dict with region, key and keyid. .. _create_db_instance: https://boto3.readthedocs.io/en/latest/reference/services/rds.html#RDS.Client.create_db_instance """ ret = {"name": name, "result": True, "comment": "", "changes": {}} r = __salt__["boto_rds.exists"](name, tags, region, key, keyid, profile) if not r.get("exists"): if __opts__["test"]: ret["comment"] = f"RDS instance {name} would be created." ret["result"] = None return ret r = __salt__["boto_rds.create"]( name, allocated_storage, db_instance_class, engine, master_username, master_user_password, db_name, db_security_groups, vpc_security_group_ids, vpc_security_groups, availability_zone, db_subnet_group_name, preferred_maintenance_window, db_parameter_group_name, backup_retention_period, preferred_backup_window, port, multi_az, engine_version, auto_minor_version_upgrade, license_model, iops, option_group_name, character_set_name, publicly_accessible, wait_status, tags, db_cluster_identifier, storage_type, tde_credential_arn, tde_credential_password, storage_encrypted, kms_keyid, domain, copy_tags_to_snapshot, monitoring_interval, monitoring_role_arn, domain_iam_role_name, region, promotion_tier, key, keyid, profile, ) if not r.get("created"): ret["result"] = False ret["comment"] = "Failed to create RDS instance {}.".format( r["error"]["message"] ) return ret ret["changes"]["old"] = {"instance": None} ret["changes"]["new"] = { "instance": __salt__["boto_rds.describe_db_instances"]( name=name, jmespath="DBInstances[0]", region=region, key=key, keyid=keyid, profile=profile, ) } ret["comment"] = f"RDS instance {name} created." else: ret["comment"] = f"RDS instance {name} exists." return ret def replica_present( name, source, db_instance_class=None, availability_zone=None, port=None, auto_minor_version_upgrade=None, iops=None, option_group_name=None, publicly_accessible=None, tags=None, region=None, key=None, keyid=None, profile=None, db_parameter_group_name=None, ): """ Ensure RDS replica exists. .. code-block:: yaml Ensure myrds replica RDS exists: boto_rds.create_replica: - name: myreplica - source: mydb """ ret = {"name": name, "result": True, "comment": "", "changes": {}} replica_exists = __salt__["boto_rds.exists"]( name, tags, region, key, keyid, profile ) if not replica_exists.get("exists"): if __opts__["test"]: ret["comment"] = f"RDS read replica {name} is set to be created " ret["result"] = None return ret created = __salt__["boto_rds.create_read_replica"]( name, source, db_instance_class, availability_zone, port, auto_minor_version_upgrade, iops, option_group_name, publicly_accessible, tags, region, key, keyid, profile, ) if created: ret["comment"] = f"RDS replica {name} created." ret["changes"]["old"] = {"instance": None} ret["changes"]["new"] = { "instance": __salt__["boto_rds.describe_db_instances"]( name=name, jmespath="DBInstances[0]", region=region, key=key, keyid=keyid, profile=profile, ) } else: ret["result"] = False ret["comment"] = f"Failed to create RDS replica {name}." else: jmespath = "DBInstances[0].DBParameterGroups[0].DBParameterGroupName" pmg_name = __salt__["boto_rds.describe_db_instances"]( name=name, jmespath=jmespath, region=region, key=key, keyid=keyid, profile=profile, ) pmg_name = pmg_name[0] if pmg_name else None if pmg_name != db_parameter_group_name: modified = __salt__["boto_rds.modify_db_instance"]( name=name, db_parameter_group_name=db_parameter_group_name, region=region, key=key, keyid=keyid, profile=profile, ) if not modified: ret["result"] = False ret["comment"] = ( f"Failed to update parameter group of {name} RDS instance." ) ret["changes"]["old"] = pmg_name ret["changes"]["new"] = db_parameter_group_name ret["result"] = True ret["comment"] = f"RDS replica {name} exists." return ret def subnet_group_present( name, description, subnet_ids=None, subnet_names=None, tags=None, region=None, key=None, keyid=None, profile=None, ): """ Ensure DB subnet group exists. name The name for the DB subnet group. This value is stored as a lowercase string. subnet_ids A list of the EC2 Subnet IDs for the DB subnet group. Either subnet_ids or subnet_names must be provided. subnet_names A list of The EC2 Subnet names for the DB subnet group. Either subnet_ids or subnet_names must be provided. description Subnet group description. tags A dict of tags. region Region to connect to. key Secret key to be used. keyid Access key to be used. profile A dict with region, key and keyid, or a pillar key (string) that contains a dict with region, key and keyid. """ if not salt.utils.data.exactly_one((subnet_ids, subnet_names)): raise SaltInvocationError( "One (but not both) of subnet_ids or subnet_names must be provided." ) ret = {"name": name, "result": True, "comment": "", "changes": {}} if not subnet_ids: subnet_ids = [] if subnet_names: for i in subnet_names: r = __salt__["boto_vpc.get_resource_id"]( "subnet", name=i, region=region, key=key, keyid=keyid, profile=profile ) if "error" in r: ret["comment"] = "Error looking up subnet ids: {}".format( r["error"]["message"] ) ret["result"] = False return ret if r["id"] is None: ret["comment"] = f"Subnet {i} does not exist." ret["result"] = False return ret subnet_ids.append(r["id"]) exists = __salt__["boto_rds.subnet_group_exists"]( name=name, tags=tags, region=region, key=key, keyid=keyid, profile=profile ) if not exists.get("exists"): if __opts__["test"]: ret["comment"] = f"Subnet group {name} is set to be created." ret["result"] = None return ret created = __salt__["boto_rds.create_subnet_group"]( name=name, description=description, subnet_ids=subnet_ids, tags=tags, region=region, key=key, keyid=keyid, profile=profile, ) if not created: ret["result"] = False ret["comment"] = f"Failed to create {name} subnet group." return ret ret["changes"]["old"] = None ret["changes"]["new"] = name ret["comment"] = f"Subnet {name} created." return ret else: ret["comment"] = f"Subnet {name} present." return ret def absent( name, skip_final_snapshot=None, final_db_snapshot_identifier=None, tags=None, wait_for_deletion=True, timeout=180, region=None, key=None, keyid=None, profile=None, ): """ Ensure RDS instance is absent. name Name of the RDS instance. skip_final_snapshot Whether a final db snapshot is created before the instance is deleted. If True, no snapshot is created. If False, a snapshot is created before deleting the instance. final_db_snapshot_identifier If a final snapshot is requested, this is the identifier used for that snapshot. tags A dict of tags. wait_for_deletion (bool) Wait for the RDS instance to be deleted completely before finishing the state. timeout (in seconds) The amount of time that can pass before raising an Exception. region Region to connect to. key Secret key to be used. keyid Access key to be used. profile A dict with region, key and keyid, or a pillar key (string) that contains a dict with region, key and keyid. """ ret = {"name": name, "result": True, "comment": "", "changes": {}} current = __salt__["boto_rds.describe_db_instances"]( name=name, region=region, key=key, keyid=keyid, profile=profile ) if not current: ret["result"] = True ret["comment"] = f"{name} RDS already absent." return ret if __opts__["test"]: ret["comment"] = f"RDS {name} would be removed." ret["result"] = None return ret deleted = __salt__["boto_rds.delete"]( name, skip_final_snapshot, final_db_snapshot_identifier, region, key, keyid, profile, tags, wait_for_deletion, timeout, ) if not deleted: ret["result"] = False ret["comment"] = f"Failed to delete {name} RDS." return ret ret["changes"]["old"] = {"instance": current[0]} ret["changes"]["new"] = {"instance": None} ret["comment"] = f"RDS {name} deleted." return ret def subnet_group_absent( name, tags=None, region=None, key=None, keyid=None, profile=None ): ret = {"name": name, "result": True, "comment": "", "changes": {}} exists = __salt__["boto_rds.subnet_group_exists"]( name=name, tags=tags, region=region, key=key, keyid=keyid, profile=profile ) if not exists: ret["result"] = True ret["comment"] = f"{name} RDS subnet group does not exist." return ret if __opts__["test"]: ret["comment"] = f"RDS subnet group {name} is set to be removed." ret["result"] = None return ret deleted = __salt__["boto_rds.delete_subnet_group"]( name, region, key, keyid, profile ) if not deleted: ret["result"] = False ret["comment"] = f"Failed to delete {name} RDS subnet group." return ret ret["changes"]["old"] = name ret["changes"]["new"] = None ret["comment"] = f"RDS subnet group {name} deleted." return ret def parameter_present( name, db_parameter_group_family, description, parameters=None, apply_method="pending-reboot", tags=None, region=None, key=None, keyid=None, profile=None, ): """ Ensure DB parameter group exists and update parameters. name The name for the parameter group. db_parameter_group_family The DB parameter group family name. A DB parameter group can be associated with one and only one DB parameter group family, and can be applied only to a DB instance running a database engine and engine version compatible with that DB parameter group family. description Parameter group description. parameters The DB parameters that need to be changed of type dictionary. apply_method The `apply-immediate` method can be used only for dynamic parameters; the `pending-reboot` method can be used with MySQL and Oracle DB instances for either dynamic or static parameters. For Microsoft SQL Server DB instances, the `pending-reboot` method can be used only for static parameters. tags A dict of tags. region Region to connect to. key Secret key to be used. keyid Access key to be used. profile A dict with region, key and keyid, or a pillar key (string) that contains a dict with region, key and keyid. """ ret = {"name": name, "result": True, "comment": "", "changes": {}} res = __salt__["boto_rds.parameter_group_exists"]( name=name, tags=tags, region=region, key=key, keyid=keyid, profile=profile ) if not res.get("exists"): if __opts__["test"]: ret["comment"] = f"Parameter group {name} is set to be created." ret["result"] = None return ret created = __salt__["boto_rds.create_parameter_group"]( name=name, db_parameter_group_family=db_parameter_group_family, description=description, tags=tags, region=region, key=key, keyid=keyid, profile=profile, ) if not created: ret["result"] = False ret["comment"] = f"Failed to create {name} parameter group." return ret ret["changes"]["New Parameter Group"] = name ret["comment"] = f"Parameter group {name} created." else: ret["comment"] = f"Parameter group {name} present." if parameters is not None: params = {} changed = {} for items in parameters: for k, value in items.items(): if type(value) is bool: params[k] = "on" if value else "off" else: params[k] = str(value) log.debug("Parameters from user are : %s.", params) options = __salt__["boto_rds.describe_parameters"]( name=name, region=region, key=key, keyid=keyid, profile=profile ) if not options.get("result"): ret["result"] = False ret["comment"] = os.linesep.join( [ret["comment"], f"Faled to get parameters for group {name}."] ) return ret for parameter in options["parameters"].values(): if parameter["ParameterName"] in params and params.get( parameter["ParameterName"] ) != str(parameter["ParameterValue"]): log.debug( "Values that are being compared for %s are %s:%s.", parameter["ParameterName"], params.get(parameter["ParameterName"]), parameter["ParameterValue"], ) changed[parameter["ParameterName"]] = params.get( parameter["ParameterName"] ) if len(changed) > 0: if __opts__["test"]: ret["comment"] = os.linesep.join( [ ret["comment"], "Parameters {} for group {} are set to be changed.".format( changed, name ), ] ) ret["result"] = None return ret update = __salt__["boto_rds.update_parameter_group"]( name, parameters=changed, apply_method=apply_method, tags=tags, region=region, key=key, keyid=keyid, profile=profile, ) if "error" in update: ret["result"] = False ret["comment"] = os.linesep.join( [ ret["comment"], "Failed to change parameters {} for group {}:".format( changed, name ), update["error"]["message"], ] ) return ret ret["changes"]["Parameters"] = changed ret["comment"] = os.linesep.join( [ ret["comment"], f"Parameters {changed} for group {name} are changed.", ] ) else: ret["comment"] = os.linesep.join( [ ret["comment"], f"Parameters {params} for group {name} are present.", ] ) return ret