def human_to_bytes(size, default_unit=None, isbits=False): ''' Return bytes count from a human readable string ''' try: return formatters.human_to_bytes(size, default_unit, isbits) except Exception: raise AnsibleFilterError( "human_to_bytes() can't interpret following string: %s" % size)
def check_type_bytes(value): """Convert a human-readable string value to bytes Raises TypeError if unable to covert the value """ try: return human_to_bytes(value) except ValueError: raise TypeError('%s cannot be converted to a Byte value' % type(value))
def check_type_bits(value): """Convert a human-readable string bits value to bits in integer. Example: check_type_bits('1Mb') returns integer 1048576. Raises TypeError if unable to covert the value. """ try: return human_to_bytes(value, isbits=True) except ValueError: raise TypeError('%s cannot be converted to a Bit value' % type(value))
def main(): redis_auth_args = redis_auth_argument_spec(tls_default=False) module_args = dict( command=dict(type='str', choices=['config', 'flush', 'replica', 'slave']), master_host=dict(type='str'), master_port=dict(type='int'), replica_mode=dict(type='str', default='replica', choices=['master', 'replica', 'slave'], aliases=["slave_mode"]), db=dict(type='int'), flush_mode=dict(type='str', default='all', choices=['all', 'db']), name=dict(type='str'), value=dict(type='str'), ) module_args.update(redis_auth_args) module = AnsibleModule( argument_spec=module_args, supports_check_mode=True, ) fail_imports(module, module.params['tls']) redis_params = redis_auth_params(module) command = module.params['command'] if command == "slave": command = "replica" # Replica Command section ----------- if command == "replica": master_host = module.params['master_host'] master_port = module.params['master_port'] mode = module.params['replica_mode'] if mode == "slave": mode = "replica" # Check if we have all the data if mode == "replica": # Only need data if we want to be replica if not master_host: module.fail_json( msg='In replica mode master host must be provided') if not master_port: module.fail_json( msg='In replica mode master port must be provided') # Connect and check r = redis.StrictRedis(**redis_params) try: r.ping() except Exception as e: module.fail_json(msg="unable to connect to database: %s" % to_native(e), exception=traceback.format_exc()) # Check if we are already in the mode that we want info = r.info() if mode == "master" and info["role"] == "master": module.exit_json(changed=False, mode=mode) elif mode == "replica" and info["role"] == "slave" and info[ "master_host"] == master_host and info[ "master_port"] == master_port: status = dict( status=mode, master_host=master_host, master_port=master_port, ) module.exit_json(changed=False, mode=status) else: # Do the stuff # (Check Check_mode before commands so the commands aren't evaluated # if not necessary) if mode == "replica": if module.check_mode or set_replica_mode( r, master_host, master_port): info = r.info() status = { 'status': mode, 'master_host': master_host, 'master_port': master_port, } module.exit_json(changed=True, mode=status) else: module.fail_json(msg='Unable to set replica mode') else: if module.check_mode or set_master_mode(r): module.exit_json(changed=True, mode=mode) else: module.fail_json(msg='Unable to set master mode') # flush Command section ----------- elif command == "flush": db = module.params['db'] mode = module.params['flush_mode'] # Check if we have all the data if mode == "db": if db is None: module.fail_json( msg="In db mode the db number must be provided") # Connect and check r = redis.StrictRedis(db=db, **redis_params) try: r.ping() except Exception as e: module.fail_json(msg="unable to connect to database: %s" % to_native(e), exception=traceback.format_exc()) # Do the stuff # (Check Check_mode before commands so the commands aren't evaluated # if not necessary) if mode == "all": if module.check_mode or flush(r): module.exit_json(changed=True, flushed=True) else: # Flush never fails :) module.fail_json(msg="Unable to flush all databases") else: if module.check_mode or flush(r, db): module.exit_json(changed=True, flushed=True, db=db) else: # Flush never fails :) module.fail_json(msg="Unable to flush '%d' database" % db) elif command == 'config': name = module.params['name'] try: # try to parse the value as if it were the memory size if re.match(r'^\s*(\d*\.?\d*)\s*([A-Za-z]+)?\s*$', module.params['value'].upper()): value = str(human_to_bytes(module.params['value'].upper())) else: value = module.params['value'] except ValueError: value = module.params['value'] r = redis.StrictRedis(**redis_params) try: r.ping() except Exception as e: module.fail_json(msg="unable to connect to database: %s" % to_native(e), exception=traceback.format_exc()) try: old_value = r.config_get(name)[name] except Exception as e: module.fail_json(msg="unable to read config: %s" % to_native(e), exception=traceback.format_exc()) changed = old_value != value if module.check_mode or not changed: module.exit_json(changed=changed, name=name, value=value) else: try: r.config_set(name, value) except Exception as e: module.fail_json(msg="unable to write config: %s" % to_native(e), exception=traceback.format_exc()) module.exit_json(changed=changed, name=name, value=value) else: module.fail_json(msg='A valid command must be provided')
def main(): module = AnsibleModule( argument_spec=dict( command=dict(type='str', choices=['config', 'flush', 'slave']), login_password=dict(type='str', no_log=True), login_host=dict(type='str', default='localhost'), login_port=dict(type='int', default=6379), master_host=dict(type='str'), master_port=dict(type='int'), slave_mode=dict(type='str', default='slave', choices=['master', 'slave']), db=dict(type='int'), flush_mode=dict(type='str', default='all', choices=['all', 'db']), name=dict(type='str'), value=dict(type='str') ), supports_check_mode=True, ) if not redis_found: module.fail_json(msg=missing_required_lib('redis'), exception=REDIS_IMP_ERR) login_password = module.params['login_password'] login_host = module.params['login_host'] login_port = module.params['login_port'] command = module.params['command'] # Slave Command section ----------- if command == "slave": master_host = module.params['master_host'] master_port = module.params['master_port'] mode = module.params['slave_mode'] # Check if we have all the data if mode == "slave": # Only need data if we want to be slave if not master_host: module.fail_json(msg='In slave mode master host must be provided') if not master_port: module.fail_json(msg='In slave mode master port must be provided') # Connect and check r = redis.StrictRedis(host=login_host, port=login_port, password=login_password) try: r.ping() except Exception as e: module.fail_json(msg="unable to connect to database: %s" % to_native(e), exception=traceback.format_exc()) # Check if we are already in the mode that we want info = r.info() if mode == "master" and info["role"] == "master": module.exit_json(changed=False, mode=mode) elif mode == "slave" and info["role"] == "slave" and info["master_host"] == master_host and info["master_port"] == master_port: status = dict( status=mode, master_host=master_host, master_port=master_port, ) module.exit_json(changed=False, mode=status) else: # Do the stuff # (Check Check_mode before commands so the commands aren't evaluated # if not necessary) if mode == "slave": if module.check_mode or\ set_slave_mode(r, master_host, master_port): info = r.info() status = { 'status': mode, 'master_host': master_host, 'master_port': master_port, } module.exit_json(changed=True, mode=status) else: module.fail_json(msg='Unable to set slave mode') else: if module.check_mode or set_master_mode(r): module.exit_json(changed=True, mode=mode) else: module.fail_json(msg='Unable to set master mode') # flush Command section ----------- elif command == "flush": db = module.params['db'] mode = module.params['flush_mode'] # Check if we have all the data if mode == "db": if db is None: module.fail_json(msg="In db mode the db number must be provided") # Connect and check r = redis.StrictRedis(host=login_host, port=login_port, password=login_password, db=db) try: r.ping() except Exception as e: module.fail_json(msg="unable to connect to database: %s" % to_native(e), exception=traceback.format_exc()) # Do the stuff # (Check Check_mode before commands so the commands aren't evaluated # if not necessary) if mode == "all": if module.check_mode or flush(r): module.exit_json(changed=True, flushed=True) else: # Flush never fails :) module.fail_json(msg="Unable to flush all databases") else: if module.check_mode or flush(r, db): module.exit_json(changed=True, flushed=True, db=db) else: # Flush never fails :) module.fail_json(msg="Unable to flush '%d' database" % db) elif command == 'config': name = module.params['name'] try: # try to parse the value as if it were the memory size if re.match(r'^\s*(\d*\.?\d*)\s*([A-Za-z]+)?\s*$', module.params['value'].upper()): value = str(human_to_bytes(module.params['value'].upper())) else: value = module.params['value'] except ValueError: value = module.params['value'] r = redis.StrictRedis(host=login_host, port=login_port, password=login_password) try: r.ping() except Exception as e: module.fail_json(msg="unable to connect to database: %s" % to_native(e), exception=traceback.format_exc()) try: old_value = r.config_get(name)[name] except Exception as e: module.fail_json(msg="unable to read config: %s" % to_native(e), exception=traceback.format_exc()) changed = old_value != value if module.check_mode or not changed: module.exit_json(changed=changed, name=name, value=value) else: try: r.config_set(name, value) except Exception as e: module.fail_json(msg="unable to write config: %s" % to_native(e), exception=traceback.format_exc()) module.exit_json(changed=changed, name=name, value=value) else: module.fail_json(msg='A valid command must be provided')
def test_human_to_bytes_wrong_unit(test_input): """Test of human_to_bytes function, wrong units.""" with pytest.raises(ValueError, match="The suffix must be one of"): human_to_bytes(test_input)
def test_human_to_bytes_wrong_number(test_input): """Test of human_to_bytes function, nubmer param is invalid string / number.""" with pytest.raises(ValueError, match="can't interpret"): human_to_bytes(test_input)
def test_human_to_bytes_number(input_data, expected): """Test of human_to_bytes function, only number arg is passed.""" assert human_to_bytes(input_data) == expected
def test_human_to_bytes_number_unit(input_data, unit, expected): """Test of human_to_bytes function, number and default_unit args are passed.""" assert human_to_bytes(input_data, default_unit=unit) == expected
def test_human_to_bytes_number_unit(input_data, unit): """Test of human_to_bytes function, number and default_unit args are passed.""" assert human_to_bytes(input_data, default_unit=unit) == NUM_IN_METRIC.get(unit[0], 1024)
def test_human_to_bytes_isbits_wrong_default_unit(test_input, unit, isbits): """Test of human_to_bytes function, default_unit is in an invalid format for isbits value.""" with pytest.raises(ValueError, match="Value is not a valid string"): human_to_bytes(test_input, default_unit=unit, isbits=isbits)
def test_human_to_bytes_isbits_default_unit(input_data, unit): """Test of human_to_bytes function, isbits = True and default_unit args are passed.""" assert human_to_bytes(input_data, default_unit=unit, isbits=True) == NUM_IN_METRIC.get(unit[0], 1024)
def test_human_to_bytes_isbits(input_data, expected): """Test of human_to_bytes function, isbits = True.""" assert human_to_bytes(input_data, isbits=True) == expected
def create_json_record(self, create=False): record = {} user_metadata = {} self.result['changed'] = False # Get the current user record if not creating a new user record. if not create: rc, user_metadata, stderr = self.get_user_metadata() user_metadata = json.loads(user_metadata) # Remove elements that are not meant to be updated from record. # These are always part of the record when a user exists. user_metadata.pop('signature', None) user_metadata.pop('binding', None) user_metadata.pop('status', None) # Let last change Usec be updated by homed when command runs. user_metadata.pop('lastChangeUSec', None) # Now only change fields that are called on leaving whats currently in the record intact. record = user_metadata record['userName'] = self.name record['secret'] = {'password': [self.password]} if create: password_hash = self._hash_password(self.password) record['privileged'] = {'hashedPassword': [password_hash]} self.result['changed'] = True if self.uid and self.gid and create: record['uid'] = self.uid record['gid'] = self.gid self.result['changed'] = True if self.memberof: member_list = list(self.memberof.split(',')) if member_list != record.get('memberOf', [None]): record['memberOf'] = member_list self.result['changed'] = True if self.realname: if self.realname != record.get('realName'): record['realName'] = self.realname self.result['changed'] = True # Cannot update storage unless were creating a new user. # See 'Fields in the binding section' at https://systemd.io/USER_RECORD/ if self.storage and create: record['storage'] = self.storage self.result['changed'] = True # Cannot update homedir unless were creating a new user. # See 'Fields in the binding section' at https://systemd.io/USER_RECORD/ if self.homedir and create: record['homeDirectory'] = self.homedir self.result['changed'] = True # Cannot update imagepath unless were creating a new user. # See 'Fields in the binding section' at https://systemd.io/USER_RECORD/ if self.imagepath and create: record['imagePath'] = self.imagepath self.result['changed'] = True if self.disksize: # convert humand readble to bytes if self.disksize != record.get('diskSize'): record['diskSize'] = human_to_bytes(self.disksize) self.result['changed'] = True if self.realm: if self.realm != record.get('realm'): record['realm'] = self.realm self.result['changed'] = True if self.email: if self.email != record.get('emailAddress'): record['emailAddress'] = self.email self.result['changed'] = True if self.location: if self.location != record.get('location'): record['location'] = self.location self.result['changed'] = True if self.iconname: if self.iconname != record.get('iconName'): record['iconName'] = self.iconname self.result['changed'] = True if self.skeleton: if self.skeleton != record.get('skeletonDirectory'): record['skeletonDirectory'] = self.skeleton self.result['changed'] = True if self.shell: if self.shell != record.get('shell'): record['shell'] = self.shell self.result['changed'] = True if self.umask: if self.umask != record.get('umask'): record['umask'] = self.umask self.result['changed'] = True if self.environment: if self.environment != record.get('environment', [None]): record['environment'] = list(self.environment.split(',')) self.result['changed'] = True if self.timezone: if self.timezone != record.get('timeZone'): record['timeZone'] = self.timezone self.result['changed'] = True if self.locked: if self.locked != record.get('locked'): record['locked'] = self.locked self.result['changed'] = True if self.passwordhint: if self.passwordhint != record.get('privileged', {}).get('passwordHint'): record['privileged']['passwordHint'] = self.passwordhint self.result['changed'] = True if self.sshkeys: if self.sshkeys != record.get('privileged', {}).get('sshAuthorizedKeys'): record['privileged']['sshAuthorizedKeys'] = list( self.sshkeys.split(',')) self.result['changed'] = True if self.language: if self.locked != record.get('preferredLanguage'): record['preferredLanguage'] = self.language self.result['changed'] = True if self.notbefore: if self.locked != record.get('notBeforeUSec'): record['notBeforeUSec'] = self.notbefore self.result['changed'] = True if self.notafter: if self.locked != record.get('notAfterUSec'): record['notAfterUSec'] = self.notafter self.result['changed'] = True if self.mountopts: opts = list(self.mountopts.split(',')) if 'nosuid' in opts: if record.get('mountNoSuid') is not True: record['mountNoSuid'] = True self.result['changed'] = True else: if record.get('mountNoSuid') is not False: record['mountNoSuid'] = False self.result['changed'] = True if 'nodev' in opts: if record.get('mountNoDevices') is not True: record['mountNoDevices'] = True self.result['changed'] = True else: if record.get('mountNoDevices') is not False: record['mountNoDevices'] = False self.result['changed'] = True if 'noexec' in opts: if record.get('mountNoExecute') is not True: record['mountNoExecute'] = True self.result['changed'] = True else: if record.get('mountNoExecute') is not False: record['mountNoExecute'] = False self.result['changed'] = True return jsonify(record)