def create_snap(dataset, quiet=False):
    '''
    '''
    
    zettaknight_utils.zlog("create_snap started", "DEBUG")
 
    zettaknight_utils.check_quiet(quiet)
 
    snap = "{0}@{1}".format(dataset, zettaknight_globs.today_date)
    snap_list = zettaknight_utils.spawn_job("/sbin/zfs list -r -t snapshot -o name -H {0}".format(snap))
 
    if int(0) not in snap_list.iterkeys():
        ret = zettaknight_utils.spawn_job("/sbin/zfs snapshot -r {0}".format(snap))
    else:
        ret = {0: "Snapshot {0} already exists.".format(snap)}
        zettaknight_utils.zlog("snapshot {0} already exists".format(snap), "INFO")
 
    for exit_status, output in ret.iteritems():
        if str(exit_status) == "0" and str(output) == "Job succeeded":
            ret[exit_status] = "Snapshot created: {0}".format(snap)
            zettaknight_utils.zlog("snapshot created: {0}".format(snap), "SUCCESS")
 
    if not quiet:
        snap_out = {}
        snap_out[dataset] = {}
        snap_out[dataset][inspect.stack()[0][3]] = ret
        zettaknight_utils.parse_output(snap_out)
        
    zettaknight_utils.zlog("create_snap exiting", "DEBUG")    
 
    return ret
def create_snap(dataset, quiet=False):
    '''
    '''

    zettaknight_utils.zlog("create_snap started", "DEBUG")

    zettaknight_utils.check_quiet(quiet)

    snap = "{0}@{1}".format(dataset, zettaknight_globs.today_date)
    snap_list = zettaknight_utils.spawn_job(
        "/sbin/zfs list -r -t snapshot -o name -H {0}".format(snap))

    if int(0) not in snap_list.iterkeys():
        ret = zettaknight_utils.spawn_job(
            "/sbin/zfs snapshot -r {0}".format(snap))
    else:
        ret = {0: "Snapshot {0} already exists.".format(snap)}
        zettaknight_utils.zlog("snapshot {0} already exists".format(snap),
                               "INFO")

    for exit_status, output in ret.iteritems():
        if str(exit_status) == "0" and str(output) == "Job succeeded":
            ret[exit_status] = "Snapshot created: {0}".format(snap)
            zettaknight_utils.zlog("snapshot created: {0}".format(snap),
                                   "SUCCESS")

    if not quiet:
        snap_out = {}
        snap_out[dataset] = {}
        snap_out[dataset][inspect.stack()[0][3]] = ret
        zettaknight_utils.parse_output(snap_out)

    zettaknight_utils.zlog("create_snap exiting", "DEBUG")

    return ret
def scrub(pool):
    '''
    initiates a scrub of the pool
    '''
 
    ret = {}
    
    if zettaknight_globs.help_flag:
        ret = """Scrub:

    Initiates a scrub of provided pool.

    Usage:
        zettaknight scrub <pool>
        
    Required Arguments:
        pool
            Specifies the pool to scrub."""

        return ret
        
    ret[pool] = {}
    ret[pool]['Scrub'] = {}
    scrub_cmd = "/sbin/zpool scrub {0}".format(pool)
    scrub_run = zettaknight_utils.spawn_job(scrub_cmd)
    for k,v in scrub_run.iteritems():
        if str(k) is "0":
            ret[pool]['Scrub']['0'] = "Scrub initiated."
        else:
            ret[pool]['Scrub']['1'] = v
 
    zettaknight_utils.parse_output(ret)
 
    return ret
def scrub(pool):
    '''
    initiates a scrub of the pool
    '''

    ret = {}

    if zettaknight_globs.help_flag:
        ret = """Scrub:

    Initiates a scrub of provided pool.

    Usage:
        zettaknight scrub <pool>
        
    Required Arguments:
        pool
            Specifies the pool to scrub."""

        return ret

    ret[pool] = {}
    ret[pool]['Scrub'] = {}
    scrub_cmd = "/sbin/zpool scrub {0}".format(pool)
    scrub_run = zettaknight_utils.spawn_job(scrub_cmd)
    for k, v in scrub_run.iteritems():
        if str(k) is "0":
            ret[pool]['Scrub']['0'] = "Scrub initiated."
        else:
            ret[pool]['Scrub']['1'] = v

    zettaknight_utils.parse_output(ret)

    return ret
def create_snap(dataset, quiet=False):
    '''
    '''
 
    zettaknight_utils.check_quiet(quiet)
 
    snap = "{0}@{1}".format(dataset, zettaknight_globs.today_date)
    gerp_run = zettaknight_utils.pipe_this2("/sbin/zfs list -r -t snapshot -o name -H {0} | /bin/grep {1}".format(dataset, snap))
    gerp_out = gerp_run.stdout.read()
 
    if int(gerp_run.returncode) is not 0:
        ret = zettaknight_utils.spawn_job("/sbin/zfs snapshot -r {0}".format(snap))
 
    if int(gerp_run.returncode) == 0:
        ret = {0: "Snapshot {0} already exists.".format(snap)}
 
    for exit_status, output in ret.iteritems():
        if str(exit_status) == "0" and str(output) == "Job succeeded":
            ret[exit_status] = "Snapshot created: {0}".format(snap)
 
    if not quiet:
        snap_out = {}
        snap_out[dataset] = {}
        snap_out[dataset][inspect.stack()[0][3]] = ret
        zettaknight_utils.parse_output(snap_out)
 
    return ret
Exemple #6
0
def get_cifs_quota(**kwargs):
    '''
    get quota for user or group cifs share.
    '''

    if zettaknight_globs.help_flag:
        ret = """Get CIFS Quota:

    Function to get and display quota on a user or group CIFS share.  Arguments should be passed as key/value pairs.

    Required Arguments:
        user or group
            Specifies the username or group name tied to the relevant share to set the quota on.

   Optional Arguments:
        dataset
            Specifies the parent dataset to search for the share under.  If not specified, the default will be pulled from Zettaknight conf files"""
        return ret

    ret = {}
    user = False
    group = False

    try:
        if kwargs and kwargs['dataset']:
            dataset = kwargs['dataset']
    except:
        dataset = "{0}/{1}".format(zettaknight_globs.pool_name,
                                   zettaknight_globs.cifs_dset_suffix)
        pass

    if kwargs and "user" in kwargs.iterkeys():
        user = kwargs['user']

    if kwargs and "group" in kwargs.iterkeys():
        group = kwargs['group']

    if user and group:
        ret[dataset] = {}
        try:
            raise Exception(
                "Arguments user and group must be specified separately.  Arguments passed: {0}"
                .format(kwargs))
        except Exception as e:
            ret[dataset]['Get User Quota'] = {1: e}
            zettaknight_utils.parse_output(ret)
            return ret

    if user:
        dset = "{0}/{1}".format(dataset, user)
    elif group:
        dset = "{0}/{1}".format(dataset, group)

    ret[dset] = {}
    quota_cmd = "/sbin/zfs get refquota -H {0} -o value".format(dset)
    ret[dset]['Get User Quota'] = zettaknight_utils.spawn_job(quota_cmd)

    return ret
def create_zpool(pool=False, disk_list=False, raid=False, luks=False, slog=False, create_config=False, ldap=False, recordsize=False, ashift=False, keyfile=False):


    ret = {}

    ret[pool] = {}
    ret[pool]['Create Zpool'] = {}

    if not raid:
        raid = "12+2"
    try:
        disks, z_level = raid.split("+")
    except Exception as e:
        ret[pool]['Create Zpool'] = {'1': "{0}\nargument raid must be in x+y format, i.e. 2+1".format(e)}
        zettaknight_utils.parse_output(ret)
        sys.exit(0)

    create_cmd = "bash {0} -d {1} -z {2}".format(zettaknight_globs.zpool_create_script, disks, z_level)

    if disk_list:
        create_cmd = "{0} -f '{1}'".format(create_cmd, disk_list)

    if pool:
        create_cmd = "{0} -p '{1}'".format(create_cmd, pool)

    if luks:
        create_cmd = "{0} -l".format(create_cmd)

    if slog:
        create_cmd = "{0} -s '{1}'".format(create_cmd, slog)
        
    if ldap:
        create_cmd = "{0} -i".format(create_cmd)
        
    if recordsize:
        if any(i in recordsize for i in 'KM'):
            create_cmd = "{0} -r {1}".format(create_cmd, recordsize)
        else:
            print(zettaknight_utils.printcolors("Recordsize must be in number/unit format.  ie. 1M, or 512K", "FAIL"))
            sys.exit(0)
            
    if ashift:
        create_cmd = "{0} -a {1}".format(create_cmd, ashift)
    if keyfile:
        create_cmd = "{0} -k {1}".format(create_cmd, keyfile)

    try:
        ret[pool]['Create Zpool'] = zettaknight_utils.spawn_job(create_cmd)
        zettaknight_utils.parse_output(ret)
        if create_config:
            zettaknight_utils.create_config(pool)
    except Exception as e:
        print(zettaknight_utils.printcolors(e, "FAIL"))
        sys.exit(0)
        
    return ret
def get_cifs_quota(**kwargs):
    '''
    get quota for user or group cifs share.
    '''
    
    if zettaknight_globs.help_flag:
        ret = """Get CIFS Quota:

    Function to get and display quota on a user or group CIFS share.  Arguments should be passed as key/value pairs.

    Required Arguments:
        user or group
            Specifies the username or group name tied to the relevant share to set the quota on.

   Optional Arguments:
        dataset
            Specifies the parent dataset to search for the share under.  If not specified, the default will be pulled from Zettaknight conf files"""
        return ret
		
    ret = {}
    user = False
    group = False
        
    try:
        if kwargs and kwargs['dataset']:
            dataset = kwargs['dataset']
    except:
        dataset = "{0}/{1}".format(zettaknight_globs.pool_name, zettaknight_globs.cifs_dset_suffix)
        pass
    
    if kwargs and "user" in kwargs.iterkeys():
        user = kwargs['user']
        
    if kwargs and "group" in kwargs.iterkeys():
        group = kwargs['group']
  
    
    if user and group:
        ret[dataset] = {}
        try:
            raise Exception("Arguments user and group must be specified separately.  Arguments passed: {0}".format(kwargs))
        except Exception as e:
            ret[dataset]['Get User Quota'] = {1: e}
            zettaknight_utils.parse_output(ret)
            return ret

    if user:
        dset = "{0}/{1}".format(dataset, user)
    elif group:
        dset = "{0}/{1}".format(dataset, group)  
    
    ret[dset] = {}
    quota_cmd = "/sbin/zfs get refquota -H {0} -o value".format(dset)
    ret[dset]['Get User Quota'] = zettaknight_utils.spawn_job(quota_cmd)
    
    return ret
def get_cifs_share(**kwargs):
    '''
    get quota for user or group cifs share.
    '''
    
    ret = {}
    user = False
    group = False
        
    try:
        if kwargs and kwargs['dataset']:
            dataset = kwargs['dataset']
    except:
        dataset = "{0}/{1}".format(zettaknight_globs.pool_name, zettaknight_globs.cifs_dset_suffix)
        pass
    
    if kwargs and "user" in kwargs.iterkeys():
        user = kwargs['user']
        
    if kwargs and "group" in kwargs.iterkeys():
        group = kwargs['group']
  
    
    if user and group:
        ret[dataset] = {}
        try:
            raise Exception("Arguments user and group must be specified separately.  Arguments passed: {0}".format(kwargs))
        except Exception as e:
            ret[dataset]['Get User Quota'] = {1: e}
            zettaknight_utils.parse_output(ret)
            return ret

    if user:
        dset = "{0}/{1}".format(dataset, user)
    elif group:
        dset = "{0}/{1}".format(dataset, group)  
    
    ret[dset] = {}
    quota_cmd = "/sbin/zfs list -H {0} -o name".format(dset)
    #ret[dset]['Get User Share'] = zettaknight_utils.spawn_job(quota_cmd)
    job_out = zettaknight_utils.spawn_job(quota_cmd)
    print("JOB OUT: {0}".format(job_out))
    
    if 0 in job_out.iterkeys():
        job_out[0] = "//{0}/{1}/{2}".format(str(zettaknight_globs.samba_service_name), str(zettaknight_globs.samba_share_suffix), str(user)) 
        print("JOB OUT: {0}".format(job_out))
        
    ret[dset]['Get User Share'] = job_out    

    return ret
def zfs_monitor(email_recipients, protocol=False):
 
    ret = {}
    ret[zettaknight_globs.fqdn] = {}
 
    protocol = "ssh"
 
    for dataset in zettaknight_globs.zfs_conf.iterkeys():
        if str(zettaknight_globs.zfs_conf[dataset]['secure']) == "False":
            protocol = "xinetd"
 
    monitor_cmd = "bash {0} -r \"{1}\" -p \"{2}\"".format(zettaknight_globs.zfs_monitor_script, email_recipients, protocol)
    ret[zettaknight_globs.fqdn]['Monitor ZFS System Health'] = zettaknight_utils.spawn_job(monitor_cmd)
 
    zettaknight_utils.parse_output(ret)
 
    return ret
def scrub(pool):
    '''
    initiates a scrub of the pool
    '''
 
    ret = {}
    ret[pool] = {}
    ret[pool]['Scrub'] = {}
    scrub_cmd = "/sbin/zpool scrub {0}".format(pool)
    scrub_run = zettaknight_utils.spawn_job(scrub_cmd)
    for k,v in scrub_run.iteritems():
        if str(k) is "0":
            ret[pool]['Scrub']['0'] = "Scrub initiated."
        else:
            ret[pool]['Scrub']['1'] = v
 
    zettaknight_utils.parse_output(ret)
 
    return ret
def get_cifs_quota(**kwargs):
    '''
    get quota for user or group cifs share.
    '''
    
    ret = {}
    user = False
    group = False
        
    try:
        if kwargs and kwargs['dataset']:
            dataset = kwargs['dataset']
    except:
        dataset = "{0}/{1}".format(zettaknight_globs.pool_name, zettaknight_globs.cifs_dset_suffix)
        pass
    
    if kwargs and "user" in kwargs.iterkeys():
        user = kwargs['user']
        
    if kwargs and "group" in kwargs.iterkeys():
        group = kwargs['group']
  
    
    if user and group:
        ret[dataset] = {}
        try:
            raise Exception("Arguments user and group must be specified separately.  Arguments passed: {0}".format(kwargs))
        except Exception as e:
            ret[dataset]['Get User Quota'] = {1: e}
            zettaknight_utils.parse_output(ret)
            return ret

    if user:
        dset = "{0}/{1}".format(dataset, user)
    elif group:
        dset = "{0}/{1}".format(dataset, group)  
    
    ret[dset] = {}
    quota_cmd = "/sbin/zfs get quota -H {0} -o value".format(dset)
    ret[dset]['Get User Quota'] = zettaknight_utils.spawn_job(quota_cmd)
    
    return ret
def failover(dataset, remote_server=False):
    '''
    '''
    ret = {}
    ret[dataset] = {}
    ret[dataset]['Failover'] = {}
 
    try:
        user = zettaknight_globs.zfs_conf[dataset]['user']
        secure = zettaknight_globs.zfs_conf[dataset]['secure']
    except Exception as e:
        ret[dataset]['Failover']['1'] = "Dataset: {0} not configured in configuration file.".format(dataset)
        zettaknight_utils.parse_output(ret)
        sys.exit(0)
 
    try:
        if not remote_server:
            remote_server = zettaknight_globs.zfs_conf[dataset]['snap']['remote_server']
            if isinstance(remote_server, list):
                if len(remote_server) > 1:
                    raise Exception("Multiple remote servers defined in configuration.")
    except Exception as e:
        ret[dataset]['Failover']['1'] = "{0}\nRemote servers defined:\n - {1}\nRe-run with explicit remote server to failover to.".format(e, list(zettaknight_globs.zfs_conf[dataset]['snap']['remote_server']))
        zettaknight_utils.parse_output(ret)
        sys.exit(0)
 
    snap_cmd = "bash {0} -d {1} -s {2}@{3} -i {4} -f".format(zettaknight_globs.snap_script, dataset, user, remote_server[0], zettaknight_globs.identity_file)
    if secure:
        snap_cmd = "{0} -e".format(snap_cmd)
 
    ret[dataset]['Failover'] = zettaknight_utils.spawn_job(snap_cmd)
    zettaknight_utils.parse_output(ret)
 
    return ret
def failover(dataset, remote_server=False):
    '''
    '''
    ret = {}
    
    if zettaknight_globs.help_flag:
        ret = """Failover:

    Attempts a controlled failover for provided dataset to remote host defined in configuration files.

    Usage:
        zettaknight failover <dataset>
        
    Required Arguments:
        dataset
            Specifies the dataset to fail over.
            
    Optional Arguments:
        remote_server
            Specifies a remote server to attempt a failover to.  By default, this information is pulled from
            dataset configuration files."""

        return ret
        
    ret[dataset] = {}
    ret[dataset]['Failover'] = {}
 
    try:
        user = zettaknight_globs.zfs_conf[dataset]['user']
        secure = zettaknight_globs.zfs_conf[dataset]['secure']
    except Exception as e:
        ret[dataset]['Failover']['1'] = "Dataset: {0} not configured in configuration file.".format(dataset)
        zettaknight_utils.parse_output(ret)
        sys.exit(0)
 
    try:
        if not remote_server:
            remote_server = zettaknight_globs.zfs_conf[dataset]['snap']['remote_server']
            if isinstance(remote_server, list):
                if len(remote_server) > 1:
                    raise Exception("Multiple remote servers defined in configuration.")
    except Exception as e:
        ret[dataset]['Failover']['1'] = "{0}\nRemote servers defined:\n - {1}\nRe-run with explicit remote server to failover to.".format(e, list(zettaknight_globs.zfs_conf[dataset]['snap']['remote_server']))
        zettaknight_utils.parse_output(ret)
        sys.exit(0)
 
    snap_cmd = "bash {0} -d {1} -s {2}@{3} -i {4} -f".format(zettaknight_globs.snap_script, dataset, user, remote_server[0], zettaknight_globs.identity_file)
    if secure:
        snap_cmd = "{0} -e".format(snap_cmd)
 
    ret[dataset]['Failover'] = zettaknight_utils.spawn_job(snap_cmd)
    zettaknight_utils.parse_output(ret)
 
    return ret
def create_cifs_share(**kwargs):
    '''
    Creates a zfs dataset for a given user or group.    
    '''
    ret = {}
    
    user = False
    group = False
    
    if kwargs:
        try:
            if kwargs['dataset']:
                dataset = kwargs['dataset']
        except:
            dataset = "{0}/{1}".format(zettaknight_globs.pool_name, zettaknight_globs.cifs_dset_suffix)
            pass
    
    if kwargs and "user" in kwargs.iterkeys():
        user = kwargs['user']
        
    if kwargs and "group" in kwargs.iterkeys():
        group = kwargs['group']
    
    ret[dataset] = {}
    
    if user and group:
        try:
            raise Exception("Arguments user and group must be specified separately.  Arguments passed: {0}".format(kwargs))
        except Exception as e:
            ret[dataset]['Create CIFS Share'] = {1: e}
            zettaknight_utils.parse_output(ret)
            return ret
        
    if user:
        cifs_cmd = "{0} -u {1} -d {2}".format(zettaknight_globs.cifs_share_script, user, dataset)
    
    if group:
        cifs_cmd = "{0} -g {1} -d {2}".format(zettaknight_globs.cifs_share_script, group, dataset)
    
    if user:
        obj = user
    elif group:
        obj = group

    try:
        if str(zettaknight_globs.zfs_conf[dataset]['primary']) == str(zettaknight_globs.fqdn):
            if zettaknight_globs.zfs_conf[dataset]['snap']['remote_server']:
                for remote_server in zettaknight_globs.zfs_conf[dataset]['snap']['remote_server']:
                    remote_user = zettaknight_globs.zfs_conf[dataset]['user']
                    remote_ssh = "{0}@{1}".format(remote_user, remote_server)
                    try:
                        ssh2 = paramiko.SSHClient()
                        ssh2.set_missing_host_key_policy(paramiko.AutoAddPolicy())
                        ssh2.connect(remote_server, username=remote_user, key_filename=zettaknight_globs.identity_file)
                        remote_cmd = "zettaknight create_cifs_share user={0} dataset={1}".format(obj, dataset)
                        ssh2_stdin, ssh2_stdout, ssh2_stderr = ssh2.exec_command(remote_cmd)
                        ssh2.close()
                    except Exception as e:
                        pass
    except:
        pass

    try:
        ret[dataset]['Create CIFS Share'] = zettaknight_utils.spawn_job(cifs_cmd)
    except Exception as e:  
        ret[dataset]['Create CIFS Share'] = {1: e}
    
    #zettaknight_utils.parse_output(ret)
    
    return ret
def create_cifs_share(**kwargs):
    '''
    Creates a zfs dataset for a given user or group. 
    '''
    ret = {}
    
    if zettaknight_globs.help_flag:
        ret = """Create CIFS Share:

    Function to create a new directory with proper permissions for user/group access over CIFS on primary and secondary ZFS servers.  Arguments should be passed as key/value pairs.

    Required Arguments:
        user or group
            Specifies the username or group name to create the share for.

   Optional Arguments:
        dataset
            Specifies the parent dataset to create the share under.  If not specified, the default will be pulled from Zettaknight conf files"""
        return ret
  
    user = False
    group = False
    
    if kwargs:
        try:
            if kwargs['dataset']:
                dataset = kwargs['dataset']
        except:
            dataset = "{0}/{1}".format(zettaknight_globs.pool_name, zettaknight_globs.cifs_dset_suffix)
            pass
    
    if kwargs and "user" in kwargs.iterkeys():
        user = kwargs['user']
        
    if kwargs and "group" in kwargs.iterkeys():
        group = kwargs['group']
    
    ret[dataset] = {}
    
    if user and group:
        try:
            raise Exception("Arguments user and group must be specified separately.  Arguments passed: {0}".format(kwargs))
        except Exception as e:
            ret[dataset]['Create CIFS Share'] = {1: e}
            zettaknight_utils.parse_output(ret)
            return ret
        
    if user:
        cifs_cmd = "{0} -u {1} -d {2}".format(zettaknight_globs.cifs_share_script, user, dataset)
    
    if group:
        cifs_cmd = "{0} -g {1} -d {2}".format(zettaknight_globs.cifs_share_script, group, dataset)
    
    if user:
        obj = user
    elif group:
        obj = group

    try:
        if str(zettaknight_globs.zfs_conf[dataset]['primary']) == str(zettaknight_globs.fqdn):
            if zettaknight_globs.zfs_conf[dataset]['snap']['remote_server']:
                for remote_server in zettaknight_globs.zfs_conf[dataset]['snap']['remote_server']:
                    remote_user = zettaknight_globs.zfs_conf[dataset]['user']
                    remote_ssh = "{0}@{1}".format(remote_user, remote_server)
                    try:
                        ssh2 = paramiko.SSHClient()
                        ssh2.set_missing_host_key_policy(paramiko.AutoAddPolicy())
                        ssh2.connect(remote_server, username=remote_user, key_filename=zettaknight_globs.identity_file)
                        remote_cmd = "zettaknight create_cifs_share user={0} dataset={1}".format(obj, dataset)
                        ssh2_stdin, ssh2_stdout, ssh2_stderr = ssh2.exec_command(remote_cmd)
                        ssh2.close()
                    except Exception as e:
                        pass
    except:
        pass

    try:
        ret[dataset]['Create CIFS Share'] = zettaknight_utils.spawn_job(cifs_cmd)
    except Exception as e:  
        ret[dataset]['Create CIFS Share'] = {1: e}
    
    #zettaknight_utils.parse_output(ret)
    
    return ret
def get_cifs_share(**kwargs):
    '''
    get quota for user or group cifs share.
    '''
    
    if zettaknight_globs.help_flag:
        ret = """Get CIFS Share:

    Returns location UNC path of CIFS share for provided user or group.  Arguments should be passed as key/value pairs.

    Required Arguments:
        user or group
            Specifies the username or group name to query.

   Optional Arguments:
        dataset
            Specifies the parent dataset to query for the share under.  If not specified, the default will be pulled from Zettaknight conf files"""
        return ret
		
    ret = {}
    user = False
    group = False
        
    try:
        if kwargs and kwargs['dataset']:
            dataset = kwargs['dataset']
    except:
        dataset = "{0}/{1}".format(zettaknight_globs.pool_name, zettaknight_globs.cifs_dset_suffix)
        pass
    
    if kwargs and "user" in kwargs.iterkeys():
        user = kwargs['user']
        
    if kwargs and "group" in kwargs.iterkeys():
        group = kwargs['group']
  
    
    if user and group:
        ret[dataset] = {}
        try:
            raise Exception("Arguments user and group must be specified separately.  Arguments passed: {0}".format(kwargs))
        except Exception as e:
            ret[dataset]['Get User Quota'] = {1: e}
            zettaknight_utils.parse_output(ret)
            return ret

    if user:
        dset = "{0}/{1}".format(dataset, user)
    elif group:
        dset = "{0}/{1}".format(dataset, group)  
    
    ret[dset] = {}
    quota_cmd = "/sbin/zfs list -H {0} -o name".format(dset)
    #ret[dset]['Get User Share'] = zettaknight_utils.spawn_job(quota_cmd)
    job_out = zettaknight_utils.spawn_job(quota_cmd)
    print("JOB OUT: {0}".format(job_out))
    
    if 0 in job_out.iterkeys():
        job_out[0] = "//{0}/{1}/{2}".format(str(zettaknight_globs.samba_service_name), str(zettaknight_globs.samba_share_suffix), str(user)) 
        print("JOB OUT: {0}".format(job_out))
        
    ret[dset]['Get User Share'] = job_out    

    return ret
Exemple #18
0
def get_cifs_share(**kwargs):
    '''
    get quota for user or group cifs share.
    '''

    if zettaknight_globs.help_flag:
        ret = """Get CIFS Share:

    Returns location UNC path of CIFS share for provided user or group.  Arguments should be passed as key/value pairs.

    Required Arguments:
        user or group
            Specifies the username or group name to query.

   Optional Arguments:
        dataset
            Specifies the parent dataset to query for the share under.  If not specified, the default will be pulled from Zettaknight conf files"""
        return ret

    ret = {}
    user = False
    group = False

    try:
        if kwargs and kwargs['dataset']:
            dataset = kwargs['dataset']
    except:
        dataset = "{0}/{1}".format(zettaknight_globs.pool_name,
                                   zettaknight_globs.cifs_dset_suffix)
        pass

    if kwargs and "user" in kwargs.iterkeys():
        user = kwargs['user']

    if kwargs and "group" in kwargs.iterkeys():
        group = kwargs['group']

    if user and group:
        ret[dataset] = {}
        try:
            raise Exception(
                "Arguments user and group must be specified separately.  Arguments passed: {0}"
                .format(kwargs))
        except Exception as e:
            ret[dataset]['Get User Quota'] = {1: e}
            zettaknight_utils.parse_output(ret)
            return ret

    if user:
        dset = "{0}/{1}".format(dataset, user)
    elif group:
        dset = "{0}/{1}".format(dataset, group)

    ret[dset] = {}
    quota_cmd = "/sbin/zfs list -H {0} -o name".format(dset)
    #ret[dset]['Get User Share'] = zettaknight_utils.spawn_job(quota_cmd)
    job_out = zettaknight_utils.spawn_job(quota_cmd)
    print("JOB OUT: {0}".format(job_out))

    if 0 in job_out.iterkeys():
        job_out[0] = "//{0}/{1}/{2}".format(
            str(zettaknight_globs.samba_service_name),
            str(zettaknight_globs.samba_share_suffix), str(user))
        print("JOB OUT: {0}".format(job_out))

    ret[dset]['Get User Share'] = job_out

    return ret
def set_cifs_quota(**kwargs):
    '''
    Set quota for user or group cifs share.
    '''
    
    ret = {}
    
    if zettaknight_globs.help_flag:
        ret = """Set CIFS Quota:

    Function to set a quota on a user or group CIFS share.  Sets the quota on primary and secondary ZFS servers.  Arguments should be passed as key/value pairs.

    Required Arguments:
        user or group
            Specifies the username or group name tied to the relevant share to set the quota on.
        quota
            Quota to be set.  Should be specified with a number and unit, ie. 10T, 100G, 10M.  'None' should be specified to remove the quota.  
   Optional Arguments:
        dataset
            Specifies the parent dataset to search for the share under.  If not specified, the default will be pulled from Zettaknight conf files"""
        return ret
        
    user = False
    group = False
    quota = False
    
    try:
        if kwargs and kwargs['dataset']:
            dataset = kwargs['dataset']
    except:
        dataset = "{0}/{1}".format(zettaknight_globs.pool_name, zettaknight_globs.cifs_dset_suffix)
        pass
    
    if kwargs and "user" in kwargs.iterkeys():
        user = kwargs['user']
        
    if kwargs and "group" in kwargs.iterkeys():
        group = kwargs['group']
    
    if kwargs and "quota" in kwargs.iterkeys():
        quota = kwargs['quota']
    
    
    if user and group:
        ret[dataset] = {}
        try:
            raise Exception("Arguments user and group must be specified separately.  Arguments passed: {0}".format(kwargs))
        except Exception as e:
            ret[dataset]['Set User Quota'] = {1: e}
            zettaknight_utils.parse_output(ret)
            return ret

    if not quota:
        ret[dataset] = {}
        try:
            raise Exception("Quota argument must be supplied.  Arguments passed: {0}".format(kwargs))
        except Exception as e:
            ret[dataset]['Set User Quota'] = {1: e}
            zettaknight_utils.parse_output(ret)
            return ret

    if user:
        obj = user
        dset = "{0}/{1}".format(dataset, user)
    elif group:
        obj = group
        dset = "{0}/{1}".format(dataset, group)
    
    try:
        if str(zettaknight_globs.zfs_conf[dataset]['primary']) == str(zettaknight_globs.fqdn):
            if zettaknight_globs.zfs_conf[dataset]['snap']['remote_server']:
                for remote_server in zettaknight_globs.zfs_conf[dataset]['snap']['remote_server']:
                    remote_user = zettaknight_globs.zfs_conf[dataset]['user']
                    remote_ssh = "{0}@{1}".format(remote_user, remote_server)
                    try:
                        ssh2 = paramiko.SSHClient()
                        ssh2.set_missing_host_key_policy(paramiko.AutoAddPolicy())
                        ssh2.connect(remote_server, username=remote_user, key_filename=zettaknight_globs.identity_file)
                        remote_cmd = "zettaknight set_cifs_quota user={0} dataset={1} quota={2}".format(obj, dataset, quota)
                        ssh2_stdin, ssh2_stdout, ssh2_stderr = ssh2.exec_command(remote_cmd)
                        ssh2.close()
                    except Exception as e:
                        pass
    except:
        pass
                
    ret[dset] = {}
    
    quota_cmd = "/sbin/zfs set refquota={0} {1}".format(quota, dset)
    ret[dset]['Set User Quota'] = zettaknight_utils.spawn_job(quota_cmd)
    
    
    
    return ret
Exemple #20
0
def create_cifs_share(**kwargs):
    '''
    Creates a zfs dataset for a given user or group. 
    '''
    ret = {}

    if zettaknight_globs.help_flag:
        ret = """Create CIFS Share:

    Function to create a new directory with proper permissions for user/group access over CIFS on primary and secondary ZFS servers.  Arguments should be passed as key/value pairs.

    Required Arguments:
        user or group
            Specifies the username or group name to create the share for.

   Optional Arguments:
        dataset
            Specifies the parent dataset to create the share under.  If not specified, the default will be pulled from Zettaknight conf files"""
        return ret

    user = False
    group = False

    if kwargs:
        try:
            if kwargs['dataset']:
                dataset = kwargs['dataset']
        except:
            dataset = "{0}/{1}".format(zettaknight_globs.pool_name,
                                       zettaknight_globs.cifs_dset_suffix)
            pass

    if kwargs and "user" in kwargs.iterkeys():
        user = kwargs['user']

    if kwargs and "group" in kwargs.iterkeys():
        group = kwargs['group']

    ret[dataset] = {}

    if user and group:
        try:
            raise Exception(
                "Arguments user and group must be specified separately.  Arguments passed: {0}"
                .format(kwargs))
        except Exception as e:
            ret[dataset]['Create CIFS Share'] = {1: e}
            zettaknight_utils.parse_output(ret)
            return ret

    if user:
        cifs_cmd = "{0} -u {1} -d {2}".format(
            zettaknight_globs.cifs_share_script, user, dataset)

    if group:
        cifs_cmd = "{0} -g {1} -d {2}".format(
            zettaknight_globs.cifs_share_script, group, dataset)

    if user:
        obj = user
    elif group:
        obj = group

    try:
        if str(zettaknight_globs.zfs_conf[dataset]['primary']) == str(
                zettaknight_globs.fqdn):
            if zettaknight_globs.zfs_conf[dataset]['snap']['remote_server']:
                for remote_server in zettaknight_globs.zfs_conf[dataset][
                        'snap']['remote_server']:
                    remote_user = zettaknight_globs.zfs_conf[dataset]['user']
                    remote_ssh = "{0}@{1}".format(remote_user, remote_server)
                    try:
                        ssh2 = paramiko.SSHClient()
                        ssh2.set_missing_host_key_policy(
                            paramiko.AutoAddPolicy())
                        ssh2.connect(
                            remote_server,
                            username=remote_user,
                            key_filename=zettaknight_globs.identity_file)
                        remote_cmd = "zettaknight create_cifs_share user={0} dataset={1}".format(
                            obj, dataset)
                        ssh2_stdin, ssh2_stdout, ssh2_stderr = ssh2.exec_command(
                            remote_cmd)
                        ssh2.close()
                    except Exception as e:
                        pass
    except:
        pass

    try:
        ret[dataset]['Create CIFS Share'] = zettaknight_utils.spawn_job(
            cifs_cmd)
    except Exception as e:
        ret[dataset]['Create CIFS Share'] = {1: e}

    #zettaknight_utils.parse_output(ret)

    return ret
Exemple #21
0
def set_cifs_quota(**kwargs):
    '''
    Set quota for user or group cifs share.
    '''

    ret = {}

    if zettaknight_globs.help_flag:
        ret = """Set CIFS Quota:

    Function to set a quota on a user or group CIFS share.  Sets the quota on primary and secondary ZFS servers.  Arguments should be passed as key/value pairs.

    Required Arguments:
        user or group
            Specifies the username or group name tied to the relevant share to set the quota on.
        quota
            Quota to be set.  Should be specified with a number and unit, ie. 10T, 100G, 10M.  'None' should be specified to remove the quota.  
   Optional Arguments:
        dataset
            Specifies the parent dataset to search for the share under.  If not specified, the default will be pulled from Zettaknight conf files"""
        return ret

    user = False
    group = False
    quota = False

    try:
        if kwargs and kwargs['dataset']:
            dataset = kwargs['dataset']
    except:
        dataset = "{0}/{1}".format(zettaknight_globs.pool_name,
                                   zettaknight_globs.cifs_dset_suffix)
        pass

    if kwargs and "user" in kwargs.iterkeys():
        user = kwargs['user']

    if kwargs and "group" in kwargs.iterkeys():
        group = kwargs['group']

    if kwargs and "quota" in kwargs.iterkeys():
        quota = kwargs['quota']

    if user and group:
        ret[dataset] = {}
        try:
            raise Exception(
                "Arguments user and group must be specified separately.  Arguments passed: {0}"
                .format(kwargs))
        except Exception as e:
            ret[dataset]['Set User Quota'] = {1: e}
            zettaknight_utils.parse_output(ret)
            return ret

    if not quota:
        ret[dataset] = {}
        try:
            raise Exception(
                "Quota argument must be supplied.  Arguments passed: {0}".
                format(kwargs))
        except Exception as e:
            ret[dataset]['Set User Quota'] = {1: e}
            zettaknight_utils.parse_output(ret)
            return ret

    if user:
        obj = user
        dset = "{0}/{1}".format(dataset, user)
    elif group:
        obj = group
        dset = "{0}/{1}".format(dataset, group)

    try:
        if str(zettaknight_globs.zfs_conf[dataset]['primary']) == str(
                zettaknight_globs.fqdn):
            if zettaknight_globs.zfs_conf[dataset]['snap']['remote_server']:
                for remote_server in zettaknight_globs.zfs_conf[dataset][
                        'snap']['remote_server']:
                    remote_user = zettaknight_globs.zfs_conf[dataset]['user']
                    remote_ssh = "{0}@{1}".format(remote_user, remote_server)
                    try:
                        ssh2 = paramiko.SSHClient()
                        ssh2.set_missing_host_key_policy(
                            paramiko.AutoAddPolicy())
                        ssh2.connect(
                            remote_server,
                            username=remote_user,
                            key_filename=zettaknight_globs.identity_file)
                        remote_cmd = "zettaknight set_cifs_quota user={0} dataset={1} quota={2}".format(
                            obj, dataset, quota)
                        ssh2_stdin, ssh2_stdout, ssh2_stderr = ssh2.exec_command(
                            remote_cmd)
                        ssh2.close()
                    except Exception as e:
                        pass
    except:
        pass

    ret[dset] = {}

    quota_cmd = "/sbin/zfs set refquota={0} {1}".format(quota, dset)
    ret[dset]['Set User Quota'] = zettaknight_utils.spawn_job(quota_cmd)

    return ret
def find_versions(dataset, filename, quiet=False):
    '''
    '''
	
    if zettaknight_globs.help_flag:
        ret = """Find Versions:

	Usage:
		zettaknight find_versions zfs_data/<some dataset> <some filename>
	
    Searches snapshots of provided dataset for previous versions of filename.

    Required Arguments:
        dataset
            Specifies the dataset whose snapshots will be searched.
		filename
			Defines target file(s) to find previous versions of.  This can be a full path to a file (/zfs_data/<some dataset>/<some filename>.<ext>), just a filename with or without an extension (<some filename> or <some filename>.<ext>), or just an extension (.<ext>)"""
        return ret
		
    zettaknight_utils.check_quiet(quiet)
    
    snaps = {}
    ret = {}
    ret[dataset] = {}
    snaplist_cmd = "/sbin/zfs list -r -t snapshot -o name -H {0}".format(dataset)
    snaplist_run = subprocess.Popen(shlex.split(snaplist_cmd), stdout = subprocess.PIPE, stderr = subprocess.STDOUT)
    snaplist_run.wait()
    snaplist_out = snaplist_run.stdout.read()
    if not snaplist_out:
        try:
            out_dict = {}
            out_dict[dataset] = {}
            job = inspect.stack()[0][3]
            if str(inspect.stack()[1][3]) is 'recover':
                job = inspect.stack()[1][3]
                
            out_dict[dataset][job] = {}
            out_dict[dataset][job]['1'] = "No snapshots found."
            raise Exception
        except Exception as e:
            zettaknight_utils.parse_output(out_dict)
            sys.exit(0)
    
    for snap in snaplist_out.split():
        if snap.startswith("cannot"):
            try:
                raise Exception("{0}".format(snaplist_out))
            except Exception as e:
                zettaknight_utils.zlog("{0}".format(e), "ERROR")
                sys.exit(0)
                
        snapdiff_cmd = "/sbin/zfs diff {0}".format(snap)
        gerp_cmd = "/bin/grep {0}".format(filename)
        gerp_run = zettaknight_utils.pipe_this(snapdiff_cmd, gerp_cmd)

        gerp_out = gerp_run.stdout.read()
        gerp_list = []

        if gerp_out:
            for gerp in gerp_out.split('\n'):
                if gerp.startswith("-") or gerp.startswith("M") or gerp.startswith("R"):
                    gerp_list.append(gerp)

            if gerp_list:
                snaps[snap] = gerp_list
                gerp_msg = ""
                for z in gerp_list:
                    if gerp_msg:
                        gerp_msg = "{0}\n{1}".format(gerp_msg, z)
                    else:
                        gerp_msg = str(z)
                        
                    job = "Snapshot: {0}".format(snap)
                    ret[dataset][job] = {}
                    
                    job_out = "Path:\n{0}".format(gerp_msg)
                    ret[dataset][job]['0'] = job_out
                    
    if not ret[dataset]:
        ret[dataset]['Snapshot'] = {}
        ret[dataset]['Snapshot']['1'] = "No modified versions of {0} found.".format(filename, dataset)
        
    if not quiet:
        zettaknight_utils.parse_output(ret)
                       
    return snaps
def set_cifs_quota(**kwargs):
    '''
    Set quota for user or group cifs share.
    '''
    
    ret = {}
    user = False
    group = False
    quota = False
    
    try:
        if kwargs and kwargs['dataset']:
            dataset = kwargs['dataset']
    except:
        dataset = "{0}/{1}".format(zettaknight_globs.pool_name, zettaknight_globs.cifs_dset_suffix)
        pass
    
    if kwargs and "user" in kwargs.iterkeys():
        user = kwargs['user']
        
    if kwargs and "group" in kwargs.iterkeys():
        group = kwargs['group']
    
    if kwargs and "quota" in kwargs.iterkeys():
        quota = kwargs['quota']
    
    
    if user and group:
        ret[dataset] = {}
        try:
            raise Exception("Arguments user and group must be specified separately.  Arguments passed: {0}".format(kwargs))
        except Exception as e:
            ret[dataset]['Set User Quota'] = {1: e}
            zettaknight_utils.parse_output(ret)
            return ret

    if not quota:
        ret[dataset] = {}
        try:
            raise Exception("Quota argument must be supplied.  Arguments passed: {0}".format(kwargs))
        except Exception as e:
            ret[dataset]['Set User Quota'] = {1: e}
            zettaknight_utils.parse_output(ret)
            return ret

    if user:
        obj = user
        dset = "{0}/{1}".format(dataset, user)
    elif group:
        obj = group
        dset = "{0}/{1}".format(dataset, group)
    
    try:
        if str(zettaknight_globs.zfs_conf[dataset]['primary']) == str(zettaknight_globs.fqdn):
            if zettaknight_globs.zfs_conf[dataset]['snap']['remote_server']:
                for remote_server in zettaknight_globs.zfs_conf[dataset]['snap']['remote_server']:
                    remote_user = zettaknight_globs.zfs_conf[dataset]['user']
                    remote_ssh = "{0}@{1}".format(remote_user, remote_server)
                    try:
                        ssh2 = paramiko.SSHClient()
                        ssh2.set_missing_host_key_policy(paramiko.AutoAddPolicy())
                        ssh2.connect(remote_server, username=remote_user, key_filename=zettaknight_globs.identity_file)
                        remote_cmd = "zettaknight set_cifs_quota user={0} dataset={1} quota={2}".format(obj, dataset, quota)
                        ssh2_stdin, ssh2_stdout, ssh2_stderr = ssh2.exec_command(remote_cmd)
                        ssh2.close()
                    except Exception as e:
                        pass
    except:
        pass
		
    ret[dset] = {}
    
    quota_cmd = "/sbin/zfs set quota={0} {1}".format(quota, dset)
    ret[dset]['Set User Quota'] = zettaknight_utils.spawn_job(quota_cmd)
    
    return ret
def check_usage(dset=False, quiet=False):
    '''
    '''
    ret = {}
    zettaknight_utils.check_quiet(quiet)

    if dset and str(dset) not in zettaknight_globs.zfs_conf.iterkeys():
        ret[dset] = {}
        ret[dset]['Check Usage'] = {
            1: "{0} is not a Zettaknight controlled dataset.".format(dset)
        }
        zettaknight_utils.parse_output(ret)
        return ret

    for dataset in zettaknight_globs.zfs_conf.iterkeys():
        if dset:
            if str(dset) != str(dataset):
                continue

        ret[dataset] = {}
        ret[dataset]['Check Usage'] = {}
        quota = zettaknight_globs.zfs_conf[dataset]['quota']
        reservation = zettaknight_globs.zfs_conf[dataset]['reservation']

        #find conversion multiplier to convert reservation to bytes
        if 'G' in reservation:
            res_x = float(1073741824)
            res_unit = "G"
        if 'T' in reservation:
            res_x = float(1099511627776)
            res_unit = "T"
        if 'M' in reservation:
            res_x = float(1048576)
            res_unit = "M"
        if str(reservation) == 'none':
            res_x = float(1073741824)
            res_unit = "G"

        contact = zettaknight_globs.zfs_conf[dataset]['contact']

        check_usage_cmd = "/sbin/zfs list -ro space {0} -H -p".format(dataset)
        check_usage_run = zettaknight_utils.spawn_job(check_usage_cmd)
        chk_code, chk_msg = check_usage_run.popitem()
        chk_msg = re.sub("\n", "", chk_msg)
        chk_msg_split = chk_msg.split("\t")

        if not str(chk_code) == "0":
            ret[dataset]['Check Usage'][
                '1'] = "{0}Verify correct datasets are defined in configuration file\n".format(
                    re.sub("[\[\"\]]", "", str(chk_msg_split)))
            continue

        if str(chk_msg_split[0]) == str(dataset):
            avail = float(
                re.sub("[A-Za-z]", "",
                       chk_msg_split[1]))  #space available for dataset
            used = float(re.sub(
                "[A-Za-z]", "",
                chk_msg_split[2]))  #how much space is used by the dataset
            usnap = float(
                re.sub("[A-Za-z]", "", chk_msg_split[3]
                       ))  #how much of the used space is consumed by snapshots
            uds = float(
                re.sub("[A-Za-z]", "", chk_msg_split[4])
            )  #how much of the space is consumed by the dataset itself
            if str(reservation) != 'none':
                res = (float(re.sub("[A-Za-z]", "", reservation)) * res_x)

            avail_friendly = "{0:.2f}{1}".format((avail / res_x), res_unit)
            used_friendly = "{0:.2f}{1}".format((used / res_x), res_unit)
            usnap_friendly = "{0:.2f}{1}".format((usnap / res_x), res_unit)
            uds_friendly = "{0:.2f}{1}".format((uds / res_x), res_unit)
            if "e-" in str(used_friendly):
                used_friendly = "{0}{1}".format(int(0), res_unit)
            if "e-" in str(usnap_friendly):
                usnap_friendly = "{0}{1}".format(int(0), res_unit)
            if "e-" in str(uds_friendly):
                uds_friendly = "{0}{1}".format(int(0), res_unit)

            if str(reservation) != 'none' and used > res:
                a = "{0}: {1}\n\t\t".format(
                    zettaknight_utils.printcolors("Dataset", "OKBLUE"),
                    zettaknight_utils.printcolors(dataset, "FAIL"))
                b = "{0}: {1}\n{2}: {3}\n{4}: {5}\n{6}: {7}".format(
                    zettaknight_utils.printcolors("Reservation", "OKBLUE"),
                    zettaknight_utils.printcolors(reservation, "OKGREEN"),
                    zettaknight_utils.printcolors("Total Used", "OKBLUE"),
                    zettaknight_utils.printcolors(used_friendly, "WARNING"),
                    zettaknight_utils.printcolors("Used by Snapshots",
                                                  "OKBLUE"),
                    zettaknight_utils.printcolors(usnap_friendly, "WARNING"),
                    zettaknight_utils.printcolors("Active Dataset size",
                                                  "OKBLUE"),
                    zettaknight_utils.printcolors(uds_friendly, "WARNING"))
                c = zettaknight_utils.printcolors(
                    "\nDataset exceeds space reservation", "WARNING")
                msg = "{0}{1}{2}".format(a, b, c)
                ret[dataset]['Check Usage']['1'] = "{0}{1}".format(b, c)
            else:
                a = "{0}: {1}\n\t\t".format(
                    zettaknight_utils.printcolors("Dataset", "OKBLUE"),
                    zettaknight_utils.printcolors(dataset, "OKGREEN"))
                b = "{0}: {1}\n{2}: {3}\n{4}: {5}\n{6}: {7}".format(
                    zettaknight_utils.printcolors("Reservation", "OKBLUE"),
                    zettaknight_utils.printcolors(reservation, "OKGREEN"),
                    zettaknight_utils.printcolors("Total Used", "OKBLUE"),
                    zettaknight_utils.printcolors(used_friendly, "OKGREEN"),
                    zettaknight_utils.printcolors("Used by Snapshots",
                                                  "OKBLUE"),
                    zettaknight_utils.printcolors(usnap_friendly, "OKGREEN"),
                    zettaknight_utils.printcolors("Active Dataset size",
                                                  "OKBLUE"),
                    zettaknight_utils.printcolors(uds_friendly, "OKGREEN"))
                msg = "{0}{1}".format(a, b)
                ret[dataset]['Check Usage']['0'] = b

    return ret
def failover(dataset, remote_server=False):
    '''
    '''
    ret = {}

    if zettaknight_globs.help_flag:
        ret = """Failover:

    Attempts a controlled failover for provided dataset to remote host defined in configuration files.

    Usage:
        zettaknight failover <dataset>
        
    Required Arguments:
        dataset
            Specifies the dataset to fail over.
            
    Optional Arguments:
        remote_server
            Specifies a remote server to attempt a failover to.  By default, this information is pulled from
            dataset configuration files."""

        return ret

    ret[dataset] = {}
    ret[dataset]['Failover'] = {}

    try:
        user = zettaknight_globs.zfs_conf[dataset]['user']
        secure = zettaknight_globs.zfs_conf[dataset]['secure']
    except Exception as e:
        ret[dataset]['Failover'][
            '1'] = "Dataset: {0} not configured in configuration file.".format(
                dataset)
        zettaknight_utils.parse_output(ret)
        sys.exit(0)

    try:
        if not remote_server:
            remote_server = zettaknight_globs.zfs_conf[dataset]['snap'][
                'remote_server']
            if isinstance(remote_server, list):
                if len(remote_server) > 1:
                    raise Exception(
                        "Multiple remote servers defined in configuration.")
    except Exception as e:
        ret[dataset]['Failover'][
            '1'] = "{0}\nRemote servers defined:\n - {1}\nRe-run with explicit remote server to failover to.".format(
                e,
                list(zettaknight_globs.zfs_conf[dataset]['snap']
                     ['remote_server']))
        zettaknight_utils.parse_output(ret)
        sys.exit(0)

    snap_cmd = "bash {0} -d {1} -s {2}@{3} -i {4} -f".format(
        zettaknight_globs.snap_script, dataset, user, remote_server[0],
        zettaknight_globs.identity_file)
    if secure:
        snap_cmd = "{0} -e".format(snap_cmd)

    ret[dataset]['Failover'] = zettaknight_utils.spawn_job(snap_cmd)
    zettaknight_utils.parse_output(ret)

    return ret
def find_versions(dataset, filename, quiet=False):
    '''
    '''

    if zettaknight_globs.help_flag:
        ret = """Find Versions:

	Usage:
		zettaknight find_versions zfs_data/<some dataset> <some filename>
	
    Searches snapshots of provided dataset for previous versions of filename.

    Required Arguments:
        dataset
            Specifies the dataset whose snapshots will be searched.
		filename
			Defines target file(s) to find previous versions of.  This can be a full path to a file (/zfs_data/<some dataset>/<some filename>.<ext>), just a filename with or without an extension (<some filename> or <some filename>.<ext>), or just an extension (.<ext>)"""
        return ret

    zettaknight_utils.check_quiet(quiet)

    snaps = {}
    ret = {}
    ret[dataset] = {}
    snaplist_cmd = "/sbin/zfs list -r -t snapshot -o name -H {0}".format(
        dataset)
    snaplist_run = subprocess.Popen(shlex.split(snaplist_cmd),
                                    stdout=subprocess.PIPE,
                                    stderr=subprocess.STDOUT)
    snaplist_run.wait()
    snaplist_out = snaplist_run.stdout.read()
    if not snaplist_out:
        try:
            out_dict = {}
            out_dict[dataset] = {}
            job = inspect.stack()[0][3]
            if str(inspect.stack()[1][3]) is 'recover':
                job = inspect.stack()[1][3]

            out_dict[dataset][job] = {}
            out_dict[dataset][job]['1'] = "No snapshots found."
            raise Exception
        except Exception as e:
            zettaknight_utils.parse_output(out_dict)
            sys.exit(0)

    for snap in snaplist_out.split():
        if snap.startswith("cannot"):
            try:
                raise Exception("{0}".format(snaplist_out))
            except Exception as e:
                zettaknight_utils.zlog("{0}".format(e), "ERROR")
                sys.exit(0)

        snapdiff_cmd = "/sbin/zfs diff {0}".format(snap)
        gerp_cmd = "/bin/grep {0}".format(filename)
        gerp_run = zettaknight_utils.pipe_this(snapdiff_cmd, gerp_cmd)

        gerp_out = gerp_run.stdout.read()
        gerp_list = []

        if gerp_out:
            for gerp in gerp_out.split('\n'):
                if gerp.startswith("-") or gerp.startswith(
                        "M") or gerp.startswith("R"):
                    gerp_list.append(gerp)

            if gerp_list:
                snaps[snap] = gerp_list
                gerp_msg = ""
                for z in gerp_list:
                    if gerp_msg:
                        gerp_msg = "{0}\n{1}".format(gerp_msg, z)
                    else:
                        gerp_msg = str(z)

                    job = "Snapshot: {0}".format(snap)
                    ret[dataset][job] = {}

                    job_out = "Path:\n{0}".format(gerp_msg)
                    ret[dataset][job]['0'] = job_out

    if not ret[dataset]:
        ret[dataset]['Snapshot'] = {}
        ret[dataset]['Snapshot'][
            '1'] = "No modified versions of {0} found.".format(
                filename, dataset)

    if not quiet:
        zettaknight_utils.parse_output(ret)

    return snaps
def check_usage(dset=False, quiet=False):
    '''
    '''
    ret = {}
    zettaknight_utils.check_quiet(quiet)
 
    if dset and str(dset) not in zettaknight_globs.zfs_conf.iterkeys():
        ret[dset] = {}
        ret[dset]['Check Usage'] = {1: "{0} is not a Zettaknight controlled dataset.".format(dset)}
        zettaknight_utils.parse_output(ret)
        return ret
 
    for dataset in zettaknight_globs.zfs_conf.iterkeys():
        if dset:
            if str(dset) != str(dataset):
                continue
 
        ret[dataset] = {}
        ret[dataset]['Check Usage'] = {}
        quota = zettaknight_globs.zfs_conf[dataset]['quota']
        reservation = zettaknight_globs.zfs_conf[dataset]['reservation']
 
        #find conversion multiplier to convert reservation to bytes
        if 'G' in reservation:
            res_x = float(1073741824)
            res_unit = "G"
        if 'T' in reservation:
            res_x = float(1099511627776)
            res_unit = "T"
        if 'M' in reservation:
            res_x = float(1048576)
            res_unit = "M"
        if str(reservation) == 'none':
            res_x = float(1073741824)
            res_unit = "G"
 
        contact = zettaknight_globs.zfs_conf[dataset]['contact']
 
        check_usage_cmd = "/sbin/zfs list -ro space {0} -H -p".format(dataset)
        check_usage_run = zettaknight_utils.spawn_job(check_usage_cmd)
        chk_code, chk_msg = check_usage_run.popitem()
        chk_msg = re.sub("\n", "", chk_msg)
        chk_msg_split = chk_msg.split("\t")
 
        if not str(chk_code) == "0":
            ret[dataset]['Check Usage']['1'] = "{0}Verify correct datasets are defined in configuration file\n".format(re.sub("[\[\"\]]", "", str(chk_msg_split)))
            continue
 
        if str(chk_msg_split[0]) == str(dataset):
            avail = float(re.sub("[A-Za-z]", "", chk_msg_split[1])) #space available for dataset
            used = float(re.sub("[A-Za-z]", "", chk_msg_split[2])) #how much space is used by the dataset
            usnap = float(re.sub("[A-Za-z]", "", chk_msg_split[3])) #how much of the used space is consumed by snapshots
            uds = float(re.sub("[A-Za-z]", "", chk_msg_split[4])) #how much of the space is consumed by the dataset itself
            if str(reservation) != 'none':
                res = (float(re.sub("[A-Za-z]", "", reservation)) * res_x)
 
            avail_friendly = "{0:.2f}{1}".format((avail / res_x), res_unit)
            used_friendly = "{0:.2f}{1}".format((used / res_x), res_unit)
            usnap_friendly = "{0:.2f}{1}".format((usnap / res_x), res_unit)
            uds_friendly = "{0:.2f}{1}".format((uds / res_x), res_unit)
            if "e-" in str(used_friendly):
                used_friendly = "{0}{1}".format(int(0), res_unit)
            if "e-" in str(usnap_friendly):
                usnap_friendly = "{0}{1}".format(int(0), res_unit)
            if "e-" in str(uds_friendly):
                uds_friendly = "{0}{1}".format(int(0), res_unit)
 
            if str(reservation) != 'none' and used > res:
                a = "{0}: {1}\n\t\t".format(zettaknight_utils.printcolors("Dataset", "OKBLUE"),zettaknight_utils.printcolors(dataset, "FAIL"))
                b = "{0}: {1}\n{2}: {3}\n{4}: {5}\n{6}: {7}".format(zettaknight_utils.printcolors("Reservation", "OKBLUE"),zettaknight_utils.printcolors(reservation, "OKGREEN"),zettaknight_utils.printcolors("Total Used", "OKBLUE"),zettaknight_utils.printcolors(used_friendly, "WARNING"),zettaknight_utils.printcolors("Used by Snapshots", "OKBLUE"),zettaknight_utils.printcolors(usnap_friendly, "WARNING"),zettaknight_utils.printcolors("Active Dataset size", "OKBLUE"),zettaknight_utils.printcolors(uds_friendly, "WARNING"))
                c = zettaknight_utils.printcolors("\nDataset exceeds space reservation", "WARNING")
                msg = "{0}{1}{2}".format(a, b, c)
                ret[dataset]['Check Usage']['1'] = "{0}{1}".format(b, c)
            else:
                a = "{0}: {1}\n\t\t".format(zettaknight_utils.printcolors("Dataset", "OKBLUE"),zettaknight_utils.printcolors(dataset, "OKGREEN"))
                b = "{0}: {1}\n{2}: {3}\n{4}: {5}\n{6}: {7}".format(zettaknight_utils.printcolors("Reservation", "OKBLUE"),zettaknight_utils.printcolors(reservation, "OKGREEN"),zettaknight_utils.printcolors("Total Used", "OKBLUE"),zettaknight_utils.printcolors(used_friendly, "OKGREEN"),zettaknight_utils.printcolors("Used by Snapshots", "OKBLUE"),zettaknight_utils.printcolors(usnap_friendly, "OKGREEN"),zettaknight_utils.printcolors("Active Dataset size", "OKBLUE"),zettaknight_utils.printcolors(uds_friendly, "OKGREEN"))
                msg = "{0}{1}".format(a, b)
                ret[dataset]['Check Usage']['0'] = b
    
    return ret
def find_versions(dataset, filename, quiet=False):
    '''
    '''
    zettaknight_utils.check_quiet(quiet)
    
    snaps = {}
    ret = {}
    ret[dataset] = {}
    snaplist_cmd = "/sbin/zfs list -r -t snapshot -o name -H {0}".format(dataset)
    snaplist_run = subprocess.Popen(shlex.split(snaplist_cmd), stdout = subprocess.PIPE, stderr = subprocess.STDOUT)
    snaplist_run.wait()
    snaplist_out = snaplist_run.stdout.read()
    if not snaplist_out:
        try:
            out_dict = {}
            out_dict[dataset] = {}
            job = inspect.stack()[0][3]
            if str(inspect.stack()[1][3]) is 'recover':
                job = inspect.stack()[1][3]
                
            out_dict[dataset][job] = {}
            out_dict[dataset][job]['1'] = "No snapshots found."
            raise Exception
        except Exception as e:
            zettaknight_utils.parse_output(out_dict)
            sys.exit(0)
    
    for snap in snaplist_out.split():
        if snap.startswith("cannot"):
            try:
                raise Exception("{0}".format(snaplist_out))
            except Exception as e:
                print(zettaknight_utils.printcolors(e, "FAIL"))
                sys.exit(0)
                
        snapdiff_cmd = "/sbin/zfs diff {0}".format(snap)
        gerp_cmd = "/bin/grep {0}".format(filename)
        gerp_run = zettaknight_utils.pipe_this(snapdiff_cmd, gerp_cmd)

        gerp_out = gerp_run.stdout.read()
        gerp_list = []

        if gerp_out:
            for gerp in gerp_out.split('\n'):
                if gerp.startswith("-") or gerp.startswith("M"):
                    gerp_list.append(gerp)

            if gerp_list:
                snaps[snap] = gerp_list
                gerp_msg = ""
                for z in gerp_list:
                    if gerp_msg:
                        gerp_msg = "{0}\n{1}".format(gerp_msg, z)
                    else:
                        gerp_msg = str(z)
                        
                    job = "Snapshot: {0}".format(snap)
                    ret[dataset][job] = {}
                    
                    job_out = "Path:\n{0}".format(gerp_msg)
                    ret[dataset][job]['0'] = job_out
                    
    if not ret[dataset]:
        ret[dataset]['Snapshot'] = {}
        ret[dataset]['Snapshot']['1'] = "No modified versions of {0} found.".format(filename, dataset)
        
    if not quiet:
        zettaknight_utils.parse_output(ret)
                       
    return snaps
Exemple #29
0
def create_zpool(pool=False,
                 disk_list=False,
                 raid=False,
                 luks=False,
                 slog=False,
                 create_config=False,
                 ldap=False,
                 recordsize=False,
                 ashift=False,
                 keyfile=False):

    if zettaknight_globs.help_flag:
        ret = """Create Zpool:

		See help entry for create function.
		
		zettaknight help create
		"""
        return ret

    ret = {}

    ret[pool] = {}
    ret[pool]['Create Zpool'] = {}

    if not raid:
        raid = "12+2"
    try:
        disks, z_level = raid.split("+")
    except Exception as e:
        ret[pool]['Create Zpool'] = {
            '1': "{0}\nargument raid must be in x+y format, i.e. 2+1".format(e)
        }
        zettaknight_utils.parse_output(ret)
        sys.exit(0)

    create_cmd = "bash {0} -d {1} -z {2}".format(
        zettaknight_globs.zpool_create_script, disks, z_level)

    if disk_list:
        create_cmd = "{0} -f '{1}'".format(create_cmd, disk_list)

    if pool:
        create_cmd = "{0} -p '{1}'".format(create_cmd, pool)

    if luks:
        create_cmd = "{0} -l".format(create_cmd)

    if slog:
        create_cmd = "{0} -s '{1}'".format(create_cmd, slog)

    if ldap:
        create_cmd = "{0} -i".format(create_cmd)

    if recordsize:
        if any(i in recordsize for i in 'KM'):
            create_cmd = "{0} -r {1}".format(create_cmd, recordsize)
        else:
            print(
                zettaknight_utils.printcolors(
                    "Recordsize must be in number/unit format.  ie. 1M, or 512K",
                    "FAIL"))
            sys.exit(0)

    if ashift:
        create_cmd = "{0} -a {1}".format(create_cmd, ashift)
    if keyfile:
        create_cmd = "{0} -k {1}".format(create_cmd, keyfile)

    try:
        ret[pool]['Create Zpool'] = zettaknight_utils.spawn_job(create_cmd)
    except Exception as e:
        zettaknight_utils.zlog("{0}".format(e), "ERROR")
        ret[pool]['Create Zpool']['1'] = e

    return ret