def directory(name, user=None, group=None, recurse=None, max_depth=None, dir_mode=None, file_mode=None, makedirs=False, clean=False, require=None, exclude_pat=None, follow_symlinks=False, force=False, backupname=None, allow_symlink=True, children_only=False, win_owner=None, win_perms=None, win_deny_perms=None, win_inheritance=True, **kwargs):
 name = os.path.expanduser(name)
 ret = {'name': name, 'changes': {}, 'pchanges': {}, 'result': True, 'comment': ''}
 if (not name):
  return _error(ret, 'Must provide name to file.directory')
 if ((name[(-1)] == '/') and (name != '/')):
  name = name[:(-1)]
 if ((max_depth is not None) and clean):
  return _error(ret, 'Cannot specify both max_depth and clean')
 user = _test_owner(kwargs, user=user)
 if salt.utils.is_windows():
  if (win_owner is None):
   win_owner = (user if user else None)
  if (group is not None):
   log.warning('The group argument for {0} has been ignored as this is a Windows system. Please use the `win_*` parameters to set permissions in Windows.'.format(name))
  group = user
 if (('mode' in kwargs) and (not dir_mode)):
  dir_mode = kwargs.get('mode', [])
 if (not file_mode):
  file_mode = dir_mode
 dir_mode = salt.utils.normalize_mode(dir_mode)
 file_mode = salt.utils.normalize_mode(file_mode)
 if salt.utils.is_windows():
  try:
   salt.utils.win_dacl.get_sid(win_owner)
  except CommandExecutionError as exc:
   return _error(ret, exc)
 else:
  u_check = _check_user(user, group)
  if u_check:
   return _error(ret, u_check)
 if (not os.path.isabs(name)):
  return _error(ret, 'Specified file {0} is not an absolute path'.format(name))
 if (os.path.isfile(name) or ((not allow_symlink) and os.path.islink(name))):
  if (backupname is not None):
   if os.path.lexists(backupname):
    if (not force):
     return _error(ret, 'File exists where the backup target {0} should go'.format(backupname))
    else:
     __salt__['file.remove'](backupname)
   os.rename(name, backupname)
  elif force:
   if os.path.isfile(name):
    os.remove(name)
    ret['changes']['forced'] = 'File was forcibly replaced'
   elif __salt__['file.is_link'](name):
    __salt__['file.remove'](name)
    ret['changes']['forced'] = 'Symlink was forcibly replaced'
   else:
    __salt__['file.remove'](name)
  elif os.path.isfile(name):
   return _error(ret, 'Specified location {0} exists and is a file'.format(name))
  elif os.path.islink(name):
   return _error(ret, 'Specified location {0} exists and is a symlink'.format(name))
 if salt.utils.is_windows():
  (presult, pcomment, ret['pchanges']) = _check_directory_win(name, win_owner, win_perms, win_deny_perms, win_inheritance)
 else:
  (presult, pcomment, ret['pchanges']) = _check_directory(name, user, group, (recurse or []), dir_mode, clean, require, exclude_pat, max_depth, follow_symlinks)
 if __opts__['test']:
  ret['result'] = presult
  ret['comment'] = pcomment
  return ret
 if (not os.path.isdir(name)):
  if (not os.path.isdir(os.path.dirname(name))):
   if makedirs:
    if salt.utils.is_windows():
     (drive, path) = os.path.splitdrive(name)
     if (not os.path.isdir(drive)):
      return _error(ret, 'Drive {0} is not mapped'.format(drive))
     __salt__['file.makedirs'](name, win_owner, win_perms, win_deny_perms, win_inheritance)
    else:
     __salt__['file.makedirs'](name, user=user, group=group, mode=dir_mode)
   else:
    return _error(ret, 'No directory to create {0} in'.format(name))
  if salt.utils.is_windows():
   __salt__['file.mkdir'](name, win_owner, win_perms, win_deny_perms, win_inheritance)
  else:
   __salt__['file.mkdir'](name, user=user, group=group, mode=dir_mode)
  ret['changes'][name] = 'New Dir'
 if (not os.path.isdir(name)):
  return _error(ret, 'Failed to create directory {0}'.format(name))
 if (not children_only):
  if salt.utils.is_windows():
   ret = __salt__['file.check_perms'](name, ret, win_owner, win_perms, win_deny_perms, win_inheritance)
  else:
   (ret, perms) = __salt__['file.check_perms'](name, ret, user, group, dir_mode, follow_symlinks)
 errors = []
 if (recurse or clean):
  walk_l = list(_depth_limited_walk(name, max_depth))
  walk_d = {}
  for i in walk_l:
   walk_d[i[0]] = (i[1], i[2])
 recurse_set = None
 if recurse:
  try:
   recurse_set = _get_recurse_set(recurse)
  except (TypeError, ValueError) as exc:
   ret['result'] = False
   ret['comment'] = '{0}'.format(exc)
 if recurse_set:
  if ('user' in recurse_set):
   if user:
    uid = __salt__['file.user_to_uid'](user)
    if isinstance(uid, six.string_types):
     ret['result'] = False
     ret['comment'] = 'Failed to enforce ownership for user {0} (user does not exist)'.format(user)
   else:
    ret['result'] = False
    ret['comment'] = 'user not specified, but configured as a target for recursive ownership management'
  else:
   user = None
  if ('group' in recurse_set):
   if group:
    gid = __salt__['file.group_to_gid'](group)
    if isinstance(gid, six.string_types):
     ret['result'] = False
     ret['comment'] = 'Failed to enforce group ownership for group {0}'.format(group)
   else:
    ret['result'] = False
    ret['comment'] = 'group not specified, but configured as a target for recursive ownership management'
  else:
   group = None
  if ('mode' not in recurse_set):
   file_mode = None
   dir_mode = None
  check_files = ('ignore_files' not in recurse_set)
  check_dirs = ('ignore_dirs' not in recurse_set)
  for (root, dirs, files) in walk_l:
   if check_files:
    for fn_ in files:
     full = os.path.join(root, fn_)
     try:
      if salt.utils.is_windows():
       ret = __salt__['file.check_perms'](full, ret, win_owner, win_perms, win_deny_perms, win_inheritance)
      else:
       (ret, _) = __salt__['file.check_perms'](full, ret, user, group, file_mode, follow_symlinks)
     except CommandExecutionError as exc:
      if (not exc.strerror.endswith('does not exist')):
       errors.append(exc.strerror)
   if check_dirs:
    for dir_ in dirs:
     full = os.path.join(root, dir_)
     try:
      if salt.utils.is_windows():
       ret = __salt__['file.check_perms'](full, ret, win_owner, win_perms, win_deny_perms, win_inheritance)
      else:
       (ret, _) = __salt__['file.check_perms'](full, ret, user, group, dir_mode, follow_symlinks)
     except CommandExecutionError as exc:
      if (not exc.strerror.endswith('does not exist')):
       errors.append(exc.strerror)
 if clean:
  keep = _gen_keep_files(name, require, walk_d)
  log.debug('List of kept files when use file.directory with clean: %s', keep)
  removed = _clean_dir(name, list(keep), exclude_pat)
  if removed:
   ret['changes']['removed'] = removed
   ret['comment'] = 'Files cleaned from directory {0}'.format(name)
 if (not ret['comment']):
  if children_only:
   ret['comment'] = 'Directory {0}/* updated'.format(name)
  else:
   ret['comment'] = 'Directory {0} updated'.format(name)
 if __opts__['test']:
  ret['comment'] = 'Directory {0} not updated'.format(name)
 elif ((not ret['changes']) and ret['result']):
  orig_comment = None
  if ret['comment']:
   orig_comment = ret['comment']
  ret['comment'] = 'Directory {0} is in the correct state'.format(name)
  if orig_comment:
   ret['comment'] = '\n'.join([ret['comment'], orig_comment])
 if errors:
  ret['result'] = False
  ret['comment'] += '\n\nThe following errors were encountered:\n'
  for error in errors:
   ret['comment'] += '\n- {0}'.format(error)
 return ret

def directory ( name , user = None , group = None , recurse = None , max_depth = None , dir_mode = None , file_mode = None , makedirs = False , clean = False , require = None , exclude_pat = None , follow_symlinks = False , force = False , backupname = None , allow_symlink = True , children_only = False , win_owner = None , win_perms = None , win_deny_perms = None , win_inheritance = True , ** kwargs ) : name = os . path . expanduser ( name ) ret = { 'name' : name , 'changes' : { } , 'pchanges' : { } , 'result' : True , 'comment' : '' } if ( not name ) : return _error ( ret , 'Must provide name to file.directory' ) if ( ( name [ ( - 1 ) ] == '/' ) and ( name != '/' ) ) : name = name [ : ( - 1 ) ] if ( ( max_depth is not None ) and clean ) : return _error ( ret , 'Cannot specify both max_depth and clean' ) user = _test_owner ( kwargs , user = user ) if salt . utils . is_windows ( ) : if ( win_owner is None ) : win_owner = ( user if user else None ) if ( group is not None ) : log . warning ( 'The group argument for {0} has been ignored as this is a Windows system. Please use the `win_*` parameters to set permissions in Windows.' . format ( name ) ) group = user if ( ( 'mode' in kwargs ) and ( not dir_mode ) ) : dir_mode = kwargs . get ( 'mode' , [ ] ) if ( not file_mode ) : file_mode = dir_mode dir_mode = salt . utils . normalize_mode ( dir_mode ) file_mode = salt . utils . normalize_mode ( file_mode ) if salt . utils . is_windows ( ) : try : salt . utils . win_dacl . get_sid ( win_owner ) except CommandExecutionError as exc : return _error ( ret , exc ) else : u_check = _check_user ( user , group ) if u_check : return _error ( ret , u_check ) if ( not os . path . isabs ( name ) ) : return _error ( ret , 'Specified file {0} is not an absolute path' . format ( name ) ) if ( os . path . isfile ( name ) or ( ( not allow_symlink ) and os . path . islink ( name ) ) ) : if ( backupname is not None ) : if os . path . lexists ( backupname ) : if ( not force ) : return _error ( ret , 'File exists where the backup target {0} should go' . format ( backupname ) ) else : __salt__ [ 'file.remove' ] ( backupname ) os . rename ( name , backupname ) elif force : if os . path . isfile ( name ) : os . remove ( name ) ret [ 'changes' ] [ 'forced' ] = 'File was forcibly replaced' elif __salt__ [ 'file.is_link' ] ( name ) : __salt__ [ 'file.remove' ] ( name ) ret [ 'changes' ] [ 'forced' ] = 'Symlink was forcibly replaced' else : __salt__ [ 'file.remove' ] ( name ) elif os . path . isfile ( name ) : return _error ( ret , 'Specified location {0} exists and is a file' . format ( name ) ) elif os . path . islink ( name ) : return _error ( ret , 'Specified location {0} exists and is a symlink' . format ( name ) ) if salt . utils . is_windows ( ) : ( presult , pcomment , ret [ 'pchanges' ] ) = _check_directory_win ( name , win_owner , win_perms , win_deny_perms , win_inheritance ) else : ( presult , pcomment , ret [ 'pchanges' ] ) = _check_directory ( name , user , group , ( recurse or [ ] ) , dir_mode , clean , require , exclude_pat , max_depth , follow_symlinks ) if __opts__ [ 'test' ] : ret [ 'result' ] = presult ret [ 'comment' ] = pcomment return ret if ( not os . path . isdir ( name ) ) : if ( not os . path . isdir ( os . path . dirname ( name ) ) ) : if makedirs : if salt . utils . is_windows ( ) : ( drive , path ) = os . path . splitdrive ( name ) if ( not os . path . isdir ( drive ) ) : return _error ( ret , 'Drive {0} is not mapped' . format ( drive ) ) __salt__ [ 'file.makedirs' ] ( name , win_owner , win_perms , win_deny_perms , win_inheritance ) else : __salt__ [ 'file.makedirs' ] ( name , user = user , group = group , mode = dir_mode ) else : return _error ( ret , 'No directory to create {0} in' . format ( name ) ) if salt . utils . is_windows ( ) : __salt__ [ 'file.mkdir' ] ( name , win_owner , win_perms , win_deny_perms , win_inheritance ) else : __salt__ [ 'file.mkdir' ] ( name , user = user , group = group , mode = dir_mode ) ret [ 'changes' ] [ name ] = 'New Dir' if ( not os . path . isdir ( name ) ) : return _error ( ret , 'Failed to create directory {0}' . format ( name ) ) if ( not children_only ) : if salt . utils . is_windows ( ) : ret = __salt__ [ 'file.check_perms' ] ( name , ret , win_owner , win_perms , win_deny_perms , win_inheritance ) else : ( ret , perms ) = __salt__ [ 'file.check_perms' ] ( name , ret , user , group , dir_mode , follow_symlinks ) errors = [ ] if ( recurse or clean ) : walk_l = list ( _depth_limited_walk ( name , max_depth ) ) walk_d = { } for i in walk_l : walk_d [ i [ 0 ] ] = ( i [ 1 ] , i [ 2 ] ) recurse_set = None if recurse : try : recurse_set = _get_recurse_set ( recurse ) except ( TypeError , ValueError ) as exc : ret [ 'result' ] = False ret [ 'comment' ] = '{0}' . format ( exc ) if recurse_set : if ( 'user' in recurse_set ) : if user : uid = __salt__ [ 'file.user_to_uid' ] ( user ) if isinstance ( uid , six . string_types ) : ret [ 'result' ] = False ret [ 'comment' ] = 'Failed to enforce ownership for user {0} (user does not exist)' . format ( user ) else : ret [ 'result' ] = False ret [ 'comment' ] = 'user not specified, but configured as a target for recursive ownership management' else : user = None if ( 'group' in recurse_set ) : if group : gid = __salt__ [ 'file.group_to_gid' ] ( group ) if isinstance ( gid , six . string_types ) : ret [ 'result' ] = False ret [ 'comment' ] = 'Failed to enforce group ownership for group {0}' . format ( group ) else : ret [ 'result' ] = False ret [ 'comment' ] = 'group not specified, but configured as a target for recursive ownership management' else : group = None if ( 'mode' not in recurse_set ) : file_mode = None dir_mode = None check_files = ( 'ignore_files' not in recurse_set ) check_dirs = ( 'ignore_dirs' not in recurse_set ) for ( root , dirs , files ) in walk_l : if check_files : for fn_ in files : full = os . path . join ( root , fn_ ) try : if salt . utils . is_windows ( ) : ret = __salt__ [ 'file.check_perms' ] ( full , ret , win_owner , win_perms , win_deny_perms , win_inheritance ) else : ( ret , _ ) = __salt__ [ 'file.check_perms' ] ( full , ret , user , group , file_mode , follow_symlinks ) except CommandExecutionError as exc : if ( not exc . strerror . endswith ( 'does not exist' ) ) : errors . append ( exc . strerror ) if check_dirs : for dir_ in dirs : full = os . path . join ( root , dir_ ) try : if salt . utils . is_windows ( ) : ret = __salt__ [ 'file.check_perms' ] ( full , ret , win_owner , win_perms , win_deny_perms , win_inheritance ) else : ( ret , _ ) = __salt__ [ 'file.check_perms' ] ( full , ret , user , group , dir_mode , follow_symlinks ) except CommandExecutionError as exc : if ( not exc . strerror . endswith ( 'does not exist' ) ) : errors . append ( exc . strerror ) if clean : keep = _gen_keep_files ( name , require , walk_d ) log . debug ( 'List of kept files when use file.directory with clean: %s' , keep ) removed = _clean_dir ( name , list ( keep ) , exclude_pat ) if removed : ret [ 'changes' ] [ 'removed' ] = removed ret [ 'comment' ] = 'Files cleaned from directory {0}' . format ( name ) if ( not ret [ 'comment' ] ) : if children_only : ret [ 'comment' ] = 'Directory {0}/* updated' . format ( name ) else : ret [ 'comment' ] = 'Directory {0} updated' . format ( name ) if __opts__ [ 'test' ] : ret [ 'comment' ] = 'Directory {0} not updated' . format ( name ) elif ( ( not ret [ 'changes' ] ) and ret [ 'result' ] ) : orig_comment = None if ret [ 'comment' ] : orig_comment = ret [ 'comment' ] ret [ 'comment' ] = 'Directory {0} is in the correct state' . format ( name ) if orig_comment : ret [ 'comment' ] = '\n' . join ( [ ret [ 'comment' ] , orig_comment ] ) if errors : ret [ 'result' ] = False ret [ 'comment' ] += '\n\nThe following errors were encountered:\n' for error in errors : ret [ 'comment' ] += '\n- {0}' . format ( error ) return ret
require a directory to exist .