Exemplo n.º 1
0
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
Exemplo n.º 2
0
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
Exemplo n.º 3
0
def sync(*args, **kwargs):
    '''
    '''

    zettaknight_utils.zlog("kwargs recieved by sync\n\t{0}".format(kwargs),
                           "DEBUG")

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

    Syncs snapshots to a remote server.

    Usage:
        zettaknight sync <dataset> <remote_ssh> 
        
    Required Arguments:
        dataset
            Specifies the dataset to sync.
        remote_ssh
            Specifies remote server to sync snapshots to."""

        return ret

    #if 'priority' in zettaknight_globs.zfs_conf[dataset]:
    #    priority = zettaknight_globs.zfs_conf[dataset]['priority']
    #    print(priority)
    #    if isinstance(priority, int):
    #        print("priority is an integer")
    #    os.nice(int(priority))
    try:
        if 'dataset' and 'remote_ssh' in kwargs.iterkeys():
            sync_cmd = "bash {0} -d {1} -s {2}".format(
                zettaknight_globs.sync_script, kwargs['dataset'],
                kwargs['remote_ssh'])
        else:
            raise Exception(
                "dataset and remote_ssh is are required kwargs for sync")

        if 'identity_file' in kwargs.iterkeys():
            sync_cmd = "{0} -i {1}".format(sync_cmd, kwargs['identity_file'])
        if 'pull_snap' in kwargs.iterkeys():
            if kwargs['pull_snap']:
                sync_cmd = "{0} -p".format(sync_cmd)
        if 'priority' in kwargs.iterkeys():
            sync_cmd = "{0} -n {1}".format(sync_cmd, kwargs['priority'])

        if str(inspect.stack()[1][3]) is 'sync_all':
            zettaknight_utils.zlog(
                "starting sync job:\n\t{0}".format(sync_cmd), "INFO")
            ret = zettaknight_utils.spawn_job(sync_cmd)
        else:
            ret = {}
            ret[dataset] = {}
            ret[dataset]['Snapshot sync'] = zettaknight_utils.spawn_job(
                sync_cmd)
    except Exception as e:
        zettaknight_utils.zlog("{0}".format(e), "CRITICAL")
        sys.exit(1)

    return ret
Exemplo n.º 4
0
def build_out_config(force=False):
    '''
    This function reads in the pool config file and creates the zfs data structures defined in it
    '''

    ret = {}
    ret[zettaknight_globs.fqdn] = {}
    ret[zettaknight_globs.fqdn]['Build Config'] = {}
    create_config = {}
    create_config['create_config'] = False
    create_config['nfs'] = False

    try:
        #create pools defined in zpool conf
        if zettaknight_globs.zpool_conf:
            for zpool in zettaknight_globs.zpool_conf.iterkeys():
                zettaknight_utils.zlog(
                    "determining if zpool {0} exists:\n\t[build_out_config] --> spawn_job : /sbin/zpool list -H {0}"
                    .format(zpool), "DEBUG")
                d = zettaknight_utils.spawn_job(
                    "/sbin/zpool list -H '{0}'".format(zpool))
                chk_code, chk_msg = d.popitem()
                if int(chk_code) is not 0:
                    ret[zettaknight_globs.fqdn]['Create {0}'.format(
                        zpool)] = {}
                    zettaknight_utils.zlog(
                        "creating {0}:\n\t[build_out_config] --> zettaknight_zpool.create_zpool"
                        .format(zpool), "DEBUG")
                    out1 = zettaknight_zpool.create_zpool(
                        zpool, **zettaknight_globs.zpool_conf[zpool])
                    ret[zettaknight_globs.fqdn]['Create {0}'.format(
                        zpool)] = out1[zpool]['Create Zpool']

        #print(ret)
        #create datasets defined in zfs_conf
        for dataset in zettaknight_globs.zfs_conf.iterkeys():
            zettaknight_utils.zlog(
                "determining if dataset {0} exists:\n\t[build_out_config] --> spawn_job : /sbin/zfs list -H {0}"
                .format(dataset), "DEBUG")
            d = zettaknight_utils.spawn_job(
                "/sbin/zfs list -H '{0}'".format(dataset))
            chk_code, chk_msg = d.popitem()
            if int(chk_code) is not 0:
                zettaknight_utils.zlog(
                    "creating {0}:\n\t[build_out_config] --> add_dataset".
                    format(dataset), "DEBUG")
                out2 = add_dataset(dataset, **create_config)
                ret[zettaknight_globs.fqdn]['Create dataset {0}'.format(
                    dataset)] = out2

        ret[zettaknight_globs.
            fqdn]['Build Config']['0'] = "Everything Looks Okay Here"

    except Exception as e:
        zettaknight_utils.zlog("{0}".format(e), "ERROR")
        ret[zettaknight_globs.fqdn]['Build Config']['1'] = e

    zettaknight_utils.zlog("ret for [build_out_config]:\n\t{0}".format(ret),
                           "DEBUG")
    return ret
Exemplo n.º 5
0
def sync(*args, **kwargs):
    '''
    '''
    
    zettaknight_utils.zlog("kwargs recieved by sync\n\t{0}".format(kwargs), "DEBUG")
    
    if zettaknight_globs.help_flag:
        ret = """Sync:

    Syncs snapshots to a remote server.

    Usage:
        zettaknight sync <dataset> <remote_ssh> 
        
    Required Arguments:
        dataset
            Specifies the dataset to sync.
        remote_ssh
            Specifies remote server to sync snapshots to."""

        return ret
    
    #if 'priority' in zettaknight_globs.zfs_conf[dataset]:
    #    priority = zettaknight_globs.zfs_conf[dataset]['priority']
    #    print(priority)
    #    if isinstance(priority, int):
    #        print("priority is an integer")
    #    os.nice(int(priority))
    try:
        if 'dataset' and 'remote_ssh' in kwargs.iterkeys():
            sync_cmd = "bash {0} -d {1} -s {2}".format(zettaknight_globs.sync_script, kwargs['dataset'], kwargs['remote_ssh'])
        else:
            raise Exception("dataset and remote_ssh is are required kwargs for sync")
    
        if 'identity_file' in kwargs.iterkeys():
            sync_cmd = "{0} -i {1}".format(sync_cmd, kwargs['identity_file'])
        if 'pull_snap' in kwargs.iterkeys():
            if kwargs['pull_snap']:
                sync_cmd = "{0} -p".format(sync_cmd)
        if 'priority' in kwargs.iterkeys():
            sync_cmd = "{0} -n {1}".format(sync_cmd, kwargs['priority'])
    
        if str(inspect.stack()[1][3]) is 'sync_all':
            zettaknight_utils.zlog("starting sync job:\n\t{0}".format(sync_cmd),"INFO")
            ret = zettaknight_utils.spawn_job(sync_cmd)
        else:
            ret = {}
            ret[dataset] = {}
            ret[dataset]['Snapshot sync'] = zettaknight_utils.spawn_job(sync_cmd)
    except Exception as e:
        zettaknight_utils.zlog("{0}".format(e),"CRITICAL")
        sys.exit(1)
    
    return ret
Exemplo n.º 6
0
def nuke(pool, force=True):
    '''
    '''
    ret = {}

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

    Destroys a zpool and cleans up files associated with the zpool being destroyed.

    Usage:
        zettaknight nuke <pool_name>
        
    Required Arguments:
        pool_name
            Specifies the zpool to destroy."""

        return ret
            
    ret[pool] = {}
    ret[pool]['Nuke Zpool'] = {}
 
    nuke_cmd = "bash {0} -p '{1}'".format(zettaknight_globs.zfs_nuke_script, pool)
    if force:
        nuke_cmd = "{0} -f".format(nuke_cmd)
    ret[pool]['Nuke Zpool'] = zettaknight_utils.spawn_job(nuke_cmd)
    #zettaknight_utils.parse_output(ret)
 
    return ret
Exemplo n.º 7
0
def set_refquota(dataset, refquota):
    '''
    '''
    
    refquota_cmd = "/sbin/zfs set refquota={0} {1}".format(refquota, dataset)
    
    ret = {}
    
    if zettaknight_globs.help_flag:
        ret = """Set RefQuota:

    Sets a ZFS refquota on provided dataset.

    Usage:
        zettaknight set_refquota <dataset> <refquota>
        
    Required Arguments:
        dataset
            Specifies the dataset to set a quota for.
        refquota
            Specifies the quota to set.  ie. 1T, 100G, etc."""

        return ret
        
    ret[dataset] = {}
    ret[dataset]['refquota'] = zettaknight_utils.spawn_job(refquota_cmd)
    
    for exit_status, output in ret[dataset]['refquota'].iteritems():
        if "Job succeeded" in output:
            ret[dataset]['refquota'][exit_status] = "refquota set to {0}".format(refquota)
 
    return ret
Exemplo n.º 8
0
def set_quota(dataset, quota):
    '''
    '''
 
    #quota_cmd = "bash {0} -d {1} -q {2}".format(zettaknight_globs.quota_script,dataset,quota)
    quota_cmd = "/sbin/zfs set quota={0} {1}".format(quota, dataset)
    
    ret = {}
    
    if zettaknight_globs.help_flag:
        ret = """Set Quota:

    Sets a ZFS quota on provided dataset.

    Usage:
        zettaknight set_quota <dataset> <quota>
        
    Required Arguments:
        dataset
            Specifies the dataset to set a quota for.
        quota
            Specifies the quota to set.  ie. 1T, 100G, etc."""

        return ret
        
    ret[dataset] = {}
    ret[dataset]['Quota'] = zettaknight_utils.spawn_job(quota_cmd)
    
    for exit_status, output in ret[dataset]['Quota'].iteritems():
        if "Job succeeded" in output:
            ret[dataset]['Quota'][exit_status] = "quota set to {0}".format(quota)
 
    return ret
Exemplo n.º 9
0
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
Exemplo n.º 10
0
def set_refreservation(dataset, refreservation):
    '''
    '''
    
    refreservation_cmd = "/sbin/zfs set refreservation={0} {1}".format(refreservation, dataset)
    
    ret = {}

    if zettaknight_globs.help_flag:
        ret = """Set Refreservation:

    Sets a ZFS Refreservation on provided dataset.

    Usage:
        zettaknight set_refreservation <dataset> <refreservation>
        
    Required Arguments:
        dataset
            Specifies the dataset to set a refreservation for.
        refreservation
            Specifies the refreservation to set.  ie. 1T, 100G, etc."""

        return ret
        
    ret[dataset] = {}
    ret[dataset]['refreservation'] = zettaknight_utils.spawn_job(refreservation_cmd)
    
    for exit_status, output in ret[dataset]['refreservation'].iteritems():
        if "Job succeeded" in output:
            ret[dataset]['refreservation'][exit_status] = "refreservation set to {0}".format(refreservation)
 
    return ret
Exemplo n.º 11
0
def take_snap(dataset,
              user,
              remote_server,
              secure,
              nosnap=False,
              pull_snap=False):
    '''
    '''

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

    if nosnap:
        snap_cmd = "{0} -r".format(snap_cmd)

    if pull_snap:
        snap_cmd = "{0} -p".format(snap_cmd)

    print("SNAP_COMMAND: {0}".format(snap_cmd))
    ret = zettaknight_utils.spawn_job(snap_cmd)

    return ret
Exemplo n.º 12
0
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
Exemplo n.º 13
0
def nuke(pool, force=True):
    '''
    '''
    ret = {}

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

    Destroys a zpool and cleans up files associated with the zpool being destroyed.

    Usage:
        zettaknight nuke <pool_name>
        
    Required Arguments:
        pool_name
            Specifies the zpool to destroy."""

        return ret

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

    nuke_cmd = "bash {0} -p '{1}'".format(zettaknight_globs.zfs_nuke_script,
                                          pool)
    if force:
        nuke_cmd = "{0} -f".format(nuke_cmd)
    ret[pool]['Nuke Zpool'] = zettaknight_utils.spawn_job(nuke_cmd)
    #zettaknight_utils.parse_output(ret)

    return ret
Exemplo n.º 14
0
def set_refquota(dataset, refquota):
    '''
    '''

    refquota_cmd = "/sbin/zfs set refquota={0} {1}".format(refquota, dataset)

    ret = {}

    if zettaknight_globs.help_flag:
        ret = """Set RefQuota:

    Sets a ZFS refquota on provided dataset.

    Usage:
        zettaknight set_refquota <dataset> <refquota>
        
    Required Arguments:
        dataset
            Specifies the dataset to set a quota for.
        refquota
            Specifies the quota to set.  ie. 1T, 100G, etc."""

        return ret

    ret[dataset] = {}
    ret[dataset]['refquota'] = zettaknight_utils.spawn_job(refquota_cmd)

    for exit_status, output in ret[dataset]['refquota'].iteritems():
        if "Job succeeded" in output:
            ret[dataset]['refquota'][
                exit_status] = "refquota set to {0}".format(refquota)

    return ret
Exemplo n.º 15
0
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
Exemplo n.º 16
0
def set_quota(dataset, quota):
    '''
    '''

    #quota_cmd = "bash {0} -d {1} -q {2}".format(zettaknight_globs.quota_script,dataset,quota)
    quota_cmd = "/sbin/zfs set quota={0} {1}".format(quota, dataset)

    ret = {}

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

    Sets a ZFS quota on provided dataset.

    Usage:
        zettaknight set_quota <dataset> <quota>
        
    Required Arguments:
        dataset
            Specifies the dataset to set a quota for.
        quota
            Specifies the quota to set.  ie. 1T, 100G, etc."""

        return ret

    ret[dataset] = {}
    ret[dataset]['Quota'] = zettaknight_utils.spawn_job(quota_cmd)

    for exit_status, output in ret[dataset]['Quota'].iteritems():
        if "Job succeeded" in output:
            ret[dataset]['Quota'][exit_status] = "quota set to {0}".format(
                quota)

    return ret
Exemplo n.º 17
0
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
Exemplo n.º 18
0
def generate_perf_stats(**kwargs):
    '''
    '''

    ret = {}
    ret[zettaknight_globs.fqdn] = {}
    ret[zettaknight_globs.fqdn]['Perf Stats'] = {}

    if zettaknight_globs.help_flag:
        help = """Performance Stats:

    Function to generate iostat data from defined zpools"""

        return help

    if not os.path.isdir(zettaknight_globs.zpool_perf_dir):
        os.mkdir(zettaknight_globs.zpool_perf_dir)

    if zettaknight_globs.zpool_iostat_file:
        perf_cmd = "bash {0} -f /{1}".format(
            zettaknight_globs.perf_stats_script,
            zettaknight_globs.zpool_iostat_file)
        ret[zettaknight_globs.
            fqdn]['Perf Stats'] = zettaknight_utils.spawn_job(perf_cmd)
    else:
        ret[zettaknight_globs.fqdn]['Perf Stats'][
            '1'] = "{0} is not defined, cannot continue".format(
                zettaknight_globs.zpool_iostat_file)

    return ret
Exemplo n.º 19
0
def generate_perf_stats(**kwargs):
    '''
    '''
    
    ret = {}
    ret[zettaknight_globs.fqdn] = {}
    ret[zettaknight_globs.fqdn]['Perf Stats'] = {}
    
    if zettaknight_globs.help_flag:
        help = """Performance Stats:

    Function to generate iostat data from defined zpools"""
    
        return help
        
    if not os.path.isdir(zettaknight_globs.zpool_perf_dir):
        os.mkdir(zettaknight_globs.zpool_perf_dir)
    
    if zettaknight_globs.zpool_iostat_file:
        perf_cmd = "bash {0} -f /{1}".format(zettaknight_globs.perf_stats_script, zettaknight_globs.zpool_iostat_file)
        ret[zettaknight_globs.fqdn]['Perf Stats'] = zettaknight_utils.spawn_job(perf_cmd)
    else:
        ret[zettaknight_globs.fqdn]['Perf Stats']['1'] = "{0} is not defined, cannot continue".format(zettaknight_globs.zpool_iostat_file)
    
    return ret
Exemplo n.º 20
0
def cleanup_snaps(dataset, retention):
    '''
    '''
 
    cleanup_cmd = "bash {0} -d {1} -k {2}".format(zettaknight_globs.cleanup_script, dataset, retention)
    ret = zettaknight_utils.spawn_job(cleanup_cmd)
 
    return ret
Exemplo n.º 21
0
def build_out_config(force=False):
    
    
    '''
    This function reads in the pool config file and creates the zfs data structures defined in it
    '''
    
    ret = {}
    ret[zettaknight_globs.fqdn] = {}
    ret[zettaknight_globs.fqdn]['Build Config'] = {}
    create_config = {}
    create_config['create_config'] = False
    create_config['nfs'] = False
    
    try:
        #create pools defined in zpool conf
        if zettaknight_globs.zpool_conf:
            for zpool in zettaknight_globs.zpool_conf.iterkeys():
                zettaknight_utils.zlog("determining if zpool {0} exists:\n\t[build_out_config] --> spawn_job : /sbin/zpool list -H {0}".format(zpool), "DEBUG")
                d = zettaknight_utils.spawn_job("/sbin/zpool list -H '{0}'".format(zpool))
                chk_code, chk_msg = d.popitem()
                if int(chk_code) is not 0:
                    ret[zettaknight_globs.fqdn]['Create {0}'.format(zpool)] = {}
                    zettaknight_utils.zlog("creating {0}:\n\t[build_out_config] --> zettaknight_zpool.create_zpool".format(zpool), "DEBUG")
                    out1 = zettaknight_zpool.create_zpool(zpool, **zettaknight_globs.zpool_conf[zpool])
                    ret[zettaknight_globs.fqdn]['Create {0}'.format(zpool)] = out1[zpool]['Create Zpool']
        
        #print(ret)
        #create datasets defined in zfs_conf
        for dataset in zettaknight_globs.zfs_conf.iterkeys():
            zettaknight_utils.zlog("determining if dataset {0} exists:\n\t[build_out_config] --> spawn_job : /sbin/zfs list -H {0}".format(dataset), "DEBUG")
            d = zettaknight_utils.spawn_job("/sbin/zfs list -H '{0}'".format(dataset))
            chk_code, chk_msg = d.popitem()
            if int(chk_code) is not 0:
                zettaknight_utils.zlog("creating {0}:\n\t[build_out_config] --> add_dataset".format(dataset), "DEBUG")
                out2 = add_dataset(dataset, **create_config)
                ret[zettaknight_globs.fqdn]['Create dataset {0}'.format(dataset)] = out2
            
        ret[zettaknight_globs.fqdn]['Build Config']['0'] = "Everything Looks Okay Here"
    
    except Exception as e:
        zettaknight_utils.zlog("{0}".format(e), "ERROR")
        ret[zettaknight_globs.fqdn]['Build Config']['1'] = e
    
    zettaknight_utils.zlog("ret for [build_out_config]:\n\t{0}".format(ret), "DEBUG")
    return ret
Exemplo n.º 22
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
Exemplo n.º 23
0
def cleanup_snaps(dataset, retention):
    '''
    '''

    cleanup_cmd = "bash {0} -d {1} -k {2}".format(
        zettaknight_globs.cleanup_script, dataset, retention)
    ret = zettaknight_utils.spawn_job(cleanup_cmd)

    return ret
Exemplo n.º 24
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):


    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
Exemplo n.º 25
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
Exemplo n.º 26
0
def sync(dataset, remote_ssh, identity_file=False, pull_snap=False):
    '''
    '''
    
    sync_cmd = "bash {0} -d {1} -s {2}".format(zettaknight_globs.sync_script, dataset, remote_ssh)
    
    if identity_file:
        sync_cmd = "{0} -i {1}".format(sync_cmd, identity_file)
    if pull_snap:
        sync_cmd = "{0} -p".format(sync_cmd)
    
    if str(inspect.stack()[1][3]) is 'sync_all':
        ret = zettaknight_utils.spawn_job(sync_cmd)
    else:
        ret = {}
        ret[dataset] = {}
        ret[dataset]['Snapshot sync'] = zettaknight_utils.spawn_job(sync_cmd)
    
    return ret
Exemplo n.º 27
0
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
Exemplo n.º 28
0
def add_dataset(dataset, **kwargs):
    '''if create_config=True is passed, a configuration file
    will be created for the dataset passed in to this function'''

    ret = {}
    ret[zettaknight_globs.fqdn] = {}
    question = False
    if 'create_config' in kwargs.iterkeys():
        create_config = kwargs['create_config']
    else:
        create_config = True
    if 'nfs' in kwargs.iterkeys():
        nfs = kwargs['nfs']
    else:
        nfs = True
    #append dataset to kwargs
    if dataset:
        kwargs['dataset'] = dataset

    gerp_run = zettaknight_utils.pipe_this2(
        "zfs list | /bin/grep {0}".format(dataset))
    gerp_out = gerp_run.stdout.read()

    #print(zettaknight_utils.printcolors("\nWill create {0} after completion of config file\n".format(dataset), "OKGREEN"))

    if create_config:
        ret[zettaknight_globs.fqdn]['Create Config'] = {}
        out1 = zettaknight_utils.create_config(**kwargs)
        ret[zettaknight_globs.fqdn]['Create Config'] = out1[
            zettaknight_globs.fqdn]['Create Config']

    #create dataset after commit of file
    if int(gerp_run.returncode) is not 0:
        create_cmd = "zfs create -p {0}".format(dataset)
        create_run = zettaknight_utils.spawn_job(create_cmd)
        ret[zettaknight_globs.fqdn]['add_dataset'] = create_run
    else:
        ret[zettaknight_globs.fqdn]['add_dataset'] = {
            '0': "{0} exists".format(dataset)
        }

    if nfs:
        question = zettaknight_utils.query_yes_no(
            "Would you like to create an NFS share for: {0}".format(dataset))
    if question:
        nfs_share = zettaknight_utils.query_return_item(
            "Where would you like to share it? <i.e 10.20.30.1/24 or my.server>"
        )
        ret[zettaknight_globs.fqdn]['NFS'] = {}
        ret[zettaknight_globs.fqdn]['NFS'] = zettaknight_utils.sharenfs(
            dataset, nfs_share)

    return ret
Exemplo n.º 29
0
def add_dataset(*args, **kwargs):
    '''if create_config=True is passed, a configuration file
    will be created for the dataset passed in to this function'''
 
 
    #kwargs = {}
    arg_list = list(args)
 
    #kwargs = zettaknight_utils.create_kwargs_from_args(arg_list)
    #print("This is kwargs : {0}".format(kwargs))
 
    for arg in arg_list[0:]:
        if "=" in arg:
            k, v = arg.split("=", 1)
            kwargs[k] = v
            arg_list.remove(arg)
 
    dataset = arg_list[0]
    ret = {}
    ret[dataset] = {}
    
    gerp_run = zettaknight_utils.pipe_this2("zfs list | /bin/grep {0}".format(dataset))
    gerp_out = gerp_run.stdout.read()
    
    
    if 'create_config' not in kwargs.iterkeys():
        kwargs['create_config'] = True
        
    if kwargs['create_config'] == 'False':
        kwargs['create_config'] == False
        
    if kwargs['create_config']:
        print(zettaknight_utils.printcolors("\nWill create {0} after completion of config file\n".format(dataset), "OKGREEN"))
        conf_dict = {'dataset' : dataset}
        zettaknight_utils.create_config(**conf_dict)
    
    #create dataset after commit of file
    if int(gerp_run.returncode) is not 0:
        create_cmd = "zfs create -p {0}".format(dataset)
        create_run = zettaknight_utils.spawn_job(create_cmd)
        ret[dataset]['add_dataset'] = create_run
    else:
        ret[dataset]['add_dataset'] = {'0' : "{0} exists".format(dataset)}
        
    question = zettaknight_utils.query_yes_no("Would you like to create an NFS share for: {0}".format(dataset))
    if question:
        nfs_share = zettaknight_utils.query_return_item("Where would you like to share it? <i.e 10.20.30.1/24 or my.server>")
        zettaknight_utils.sharenfs(dataset, nfs_share)
 
    #zettaknight_utils.parse_output(ret)
 
    return ret
Exemplo n.º 30
0
def nuke(pool, force=True):
    '''
    '''
    ret = {}
    ret[pool] = {}
    ret[pool]['Nuke Zpool'] = {}
 
    nuke_cmd = "bash {0} -p '{1}'".format(zettaknight_globs.zfs_nuke_script, pool)
    if force:
        nuke_cmd = "{0} -f".format(nuke_cmd)
    ret[pool]['Nuke Zpool'] = zettaknight_utils.spawn_job(nuke_cmd)
    #zettaknight_utils.parse_output(ret)
 
    return ret
Exemplo n.º 31
0
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
Exemplo n.º 32
0
def set_refreservation(dataset, refreservation):
    '''
    '''
    
    refreservation_cmd = "/sbin/zfs set refreservation={0} {1}".format(refreservation, dataset)
    
    ret = {}
    ret[dataset] = {}
    ret[dataset]['refreservation'] = zettaknight_utils.spawn_job(refreservation_cmd)
    
    for exit_status, output in ret[dataset]['refreservation'].iteritems():
        if "Job succeeded" in output:
            ret[dataset]['refreservation'][exit_status] = "refreservation set to {0}".format(refreservation)
 
    return ret
Exemplo n.º 33
0
def set_quota(dataset, quota):
    '''
    '''
 
    #quota_cmd = "bash {0} -d {1} -q {2}".format(zettaknight_globs.quota_script,dataset,quota)
    quota_cmd = "/sbin/zfs set quota={0} {1}".format(quota, dataset)
    
    ret = {}
    ret[dataset] = {}
    ret[dataset]['Quota'] = zettaknight_utils.spawn_job(quota_cmd)
    
    for exit_status, output in ret[dataset]['Quota'].iteritems():
        if "Job succeeded" in output:
            ret[dataset]['Quota'][exit_status] = "quota set to {0}".format(quota)
 
    return ret
Exemplo n.º 34
0
def add_dataset(dataset, **kwargs):
    '''if create_config=True is passed, a configuration file
    will be created for the dataset passed in to this function'''
    
    ret = {}
    ret[zettaknight_globs.fqdn] = {}
    question = False
    if 'create_config' in kwargs.iterkeys():
        create_config = kwargs['create_config']
    else:
        create_config = True
    if 'nfs' in kwargs.iterkeys():
        nfs = kwargs['nfs']
    else:
        nfs = True    
    #append dataset to kwargs
    if dataset:
        kwargs['dataset'] = dataset
    
    gerp_run = zettaknight_utils.pipe_this2("zfs list | /bin/grep {0}".format(dataset))
    gerp_out = gerp_run.stdout.read()
        
    #print(zettaknight_utils.printcolors("\nWill create {0} after completion of config file\n".format(dataset), "OKGREEN"))


    if create_config:
        ret[zettaknight_globs.fqdn]['Create Config'] = {}
        out1 = zettaknight_utils.create_config(**kwargs)
        ret[zettaknight_globs.fqdn]['Create Config'] = out1[zettaknight_globs.fqdn]['Create Config']

    #create dataset after commit of file
    if int(gerp_run.returncode) is not 0:
        create_cmd = "zfs create -p {0}".format(dataset)
        create_run = zettaknight_utils.spawn_job(create_cmd)
        ret[zettaknight_globs.fqdn]['add_dataset'] = create_run
    else:
        ret[zettaknight_globs.fqdn]['add_dataset'] = {'0' : "{0} exists".format(dataset)}
    
    if nfs:    
        question = zettaknight_utils.query_yes_no("Would you like to create an NFS share for: {0}".format(dataset))
    if question:
        nfs_share = zettaknight_utils.query_return_item("Where would you like to share it? <i.e 10.20.30.1/24 or my.server>")
        ret[zettaknight_globs.fqdn]['NFS'] = {}
        ret[zettaknight_globs.fqdn]['NFS'] = zettaknight_utils.sharenfs(dataset, nfs_share)
 
    return ret
Exemplo n.º 35
0
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
Exemplo n.º 36
0
def take_snap(dataset, user, remote_server, secure, nosnap=False, pull_snap=False):
    '''
    '''
 
    snap_cmd = "bash {0} -d {1} -i {2} -s {3}@{4}".format(zettaknight_globs.snap_script, dataset, zettaknight_globs.identity_file, user, remote_server)
    if secure:
        snap_cmd = "{0} -e".format(snap_cmd)
 
    if nosnap:
        snap_cmd = "{0} -r".format(snap_cmd)
    
    if pull_snap:
        snap_cmd = "{0} -p".format(snap_cmd)
 
    print("SNAP_COMMAND: {0}".format(snap_cmd))
    ret = zettaknight_utils.spawn_job(snap_cmd)
 
    return ret
Exemplo n.º 37
0
def set_reservation(dataset, reservation, quiet=False):
    '''
    '''
 
    zettaknight_utils.check_quiet(quiet)
 
    #reservation_cmd = "bash {0} -d {1} -r {2}".format(zettaknight_globs.quota_script,dataset,reservation)
    reservation_cmd = "/sbin/zfs set reservation={0} {1}".format(reservation, dataset)
    
    
    ret = {}
    ret[dataset] = {}
    ret[dataset]['Reservation'] = zettaknight_utils.spawn_job(reservation_cmd)
              
    for exit_status, output in ret[dataset]['Reservation'].iteritems():
        if "Job succeeded" in output:
            ret[dataset]['Reservation'][exit_status] = "reservation set to {0}".format(reservation)
 
    return ret
Exemplo n.º 38
0
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
Exemplo n.º 39
0
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
Exemplo n.º 40
0
def zfs_monitor(email_recipients, protocol=False):

    ret = {}
    ret[zettaknight_globs.fqdn] = {}
    zettaknight_globs.mm_flag = True

    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
Exemplo n.º 41
0
def set_reservation(dataset, reservation, quiet=False):
    '''
    '''

    zettaknight_utils.check_quiet(quiet)

    #reservation_cmd = "bash {0} -d {1} -r {2}".format(zettaknight_globs.quota_script,dataset,reservation)
    reservation_cmd = "/sbin/zfs set reservation={0} {1}".format(
        reservation, dataset)

    ret = {}

    if zettaknight_globs.help_flag:
        ret = """Set Reservation:

    Sets a ZFS reservation on provided dataset.

    Usage:
        zettaknight set_reservation <dataset> <reservation>
        
    Required Arguments:
        dataset
            Specifies the dataset to set a reservation for.
        reservation
            Specifies the reservation to set.  ie. 1T, 100G, etc."""

        return ret

    ret[dataset] = {}
    ret[dataset]['Reservation'] = zettaknight_utils.spawn_job(reservation_cmd)

    for exit_status, output in ret[dataset]['Reservation'].iteritems():
        if "Job succeeded" in output:
            ret[dataset]['Reservation'][
                exit_status] = "reservation set to {0}".format(reservation)

    return ret
Exemplo n.º 42
0
def recover(snapshot, filename, relocate=None):
    '''
    '''
    if zettaknight_globs.help_flag:
        ret = """Recover:

	Usage:
		zettaknight recover <snapshot> <filepath> (<directory to recover file to>)*optional
	
    Recovers a previous version of a file or folder from a specified snapshot.  Information to use in calling zettaknight recover can be found in the output from the find_versions function.  By default, files/folders will be recovered to their original location with .R appended to the end of the name.

    Required Arguments:
        snapshot
            Specifies the snapshot to recover files from.
		filename
			Defines target file(s) to recover.  This should be the full path to a file or folder (/zfs_data/<some dataset>/<some filename>.<ext>)
			
	Optional Arguments:
		relocate
			Defines an alternate path to recover files/folders to.  If used, .R will not be appended, and the recover will overwrite any existing files."""
        return ret

    file = filename
    snap = snapshot
    dataset, snap_date = snap.split('@', 1)
    find_snap = find_versions(dataset, file, "quiet")
    find_snap_keys = find_snap.iterkeys()
    snap_basedir = "/{0}/.zfs/snapshot".format(dataset)
    active_basedir = "/{0}".format(dataset)
    dir_flag = False
    ret = {}
    ret[dataset] = {}

    try:
        if str(dataset) in str(file):
            file = file.split(dataset, 1)[1]
            last_ref = file.rsplit("/", 1)[1]
    except Exception as e:
        pass

    if dataset in file.rsplit("/", 1):
        file = file.split(dataset, 1)[1]
        last_ref = file.rsplit("/", 1)[1]

    if snap not in find_snap_keys:
        try:
            raise Exception(
                "Recoverable versions of {0} not found in dataset {1}".format(
                    file, dataset))
        except Exception as e:
            zettaknight_utils.zlog("{0}".format(e), "ERROR")

    path_list1 = find_snap[snap]

    path_list = []

    if os.path.isdir("/{0}{1}".format(dataset, file)):
        dir_flag = True

    for line in path_list1:
        if line.startswith("-") or line.startswith("M") or line.startswith(
                "R"):
            a, b = line.rsplit("/", 1)
            if not dir_flag:
                try:
                    if str(b) == str(last_ref):
                        path_list.append(line)
                except:
                    if str(b) == str(file):
                        path_list.append(line)
                    pass

            else:
                if a.startswith("-") or line.startswith(
                        "M") or line.startswith("R"):
                    a, b = line.rsplit(dataset, 2)
                    if os.path.isdir("{0}/{1}{2}".format(
                            snap_basedir, snap_date, b)):
                        dir_flag = True
                        path_list.append(line)

    if len(path_list) > 1:
        exc_out = ""
        for i in path_list:
            if exc_out:
                exc_out = "{0}\n\t{1}".format(exc_out, i)
            else:
                exc_out = str(i)
        err_msg = "Matching files/folders in snapshot:"
        print(
            zettaknight_utils.printcolors(
                "\nAmbiguous recover request.  Multiple matches for {0}.".
                format(file), "FAIL"))
        print("{0} {1}".format(zettaknight_utils.printcolors(err_msg, "FAIL"),
                               zettaknight_utils.printcolors(snap, "OKBLUE")))
        print("\t{0}".format(zettaknight_utils.printcolors(exc_out,
                                                           "WARNING")))
        print(
            zettaknight_utils.printcolors(
                "Re-run with explicit path to file.\n", "FAIL"))
        try:
            raise Exception("Ambiguous file reference.")
        except Exception as e:
            zettaknight_utils.zlog("{0}".format(e), "ERROR")
            sys.exit(0)

    if len(path_list) < 1:
        try:
            raise Exception(
                "No restorable files or folders identified. \nRe-run with explicit path to file?"
            )
        except Exception as e:
            zettaknight_utils.zlog("{0}".format(e), "ERROR")
            sys.exit(0)

    a, p = path_list[0].split(dataset, 1)
    path, dirs = p.split(file, 1)

    if dir_flag:
        a, b = path_list[0].rsplit(dataset, 2)
        file_loc = "{0}/{1}{2}".format(snap_basedir, snap_date, b)
        #bad, dir_path = path_list[0].split(file, 1)
        #list_dirs = dir_path.rsplit("/", 1)
        #try:
        #    out_dir = list_dirs[0]
        #except:
        out_dir = ""
        #    pass

        #file_loc = "{0}/{1}/{2}{3}/".format(snap_basedir, snap_date, file, dir_path )
        #mkdir_cmd = "/bin/mkdir {0}/{1}.R".format(active_basedir, file)
        #mkdir_run = zettaknight_utils.spawn_job(mkdir_cmd)
        #mkdir_cmd = "/bin/mkdir -p {0}/{1}.R/{2}".format(active_basedir, file, dir_path)
        #mkdir_run = zettaknight_utils.spawn_job(mkdir_cmd)
        out_path = "{0}{1}{2}.R{3}/".format(active_basedir, str(path), file,
                                            out_dir)

    else:
        file_loc = "{0}/{1}/{2}".format(snap_basedir, snap_date, p)
        out_path = "{0}{1}{2}.R".format(active_basedir, str(path), file)

    if relocate:
        out_path = relocate

    rec_cmd = "/bin/cp " "-r -p " "{0}" " " "{1}".format(file_loc, out_path)
    rec_run = zettaknight_utils.spawn_job(rec_cmd)
    rec_dict = eval(str(rec_run))
    for k, v in rec_dict.iteritems():
        if str(k) is "0":
            print("Recover operation succeeded.")
            print("\tFilename: {0}".format(
                zettaknight_utils.printcolors(file, "OKBLUE")))
            print("\t\tFile(s) restored to version: {0}".format(
                zettaknight_utils.printcolors(snap_date, "OKGREEN")))
            print("\t\tFile(s) restored to: {0}".format(
                zettaknight_utils.printcolors(out_path, "OKGREEN")))

        if str(k) is not "0":
            print("Recover operation failed.")
            print("\tFilename: {0}".format(
                zettaknight_utils.printcolors(file, "OKBLUE")))
            print("\t\tRestore failed with error: {0}".format(
                zettaknight_utils.printcolors(v, "FAIL")))

    return
Exemplo n.º 43
0
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
Exemplo n.º 44
0
def first_step():
    ret = {}
    arg_dict = {}

    try:

        pool_name = "zfs_data"  #default pool name
        arg_dict["pool_name"] = pool_name

        ret[pool_name] = {}

        ############### creation of the zpool ################
        ######################################################

        #test if a zpool exists
        zpool_list_cmd = "/sbin/zpool list -H"
        zpool_list_run = zettaknight_utils.spawn_job(zpool_list_cmd)
        chk_code, chk_msg = zpool_list_run.popitem()
        if int(chk_code) != 0:  #if zpool list -H returns empty
            #query_return_item is defined in zettaknight_utils
            create_pool_question = zettaknight_utils.query_yes_no(
                "No pool detected, would you like to create one?")
            if create_pool_question:
                arg_dict["disk_list"] = zettaknight_utils.query_return_item(
                    "File containing all list of disks to be used for {0}, I.E /tmp/bunchofdisks.txt: "
                    .format(pool_name))
                arg_dict["raid"] = zettaknight_utils.query_return_item(
                    "Raid level to be used [1-3]. I.E. 4+1, 5+2, 1+1: ")
                arg_dict["ashift"] = zettaknight_utils.query_return_item(
                    "ashift value for {0}, value is 9 for 512 block disks and 12 for 4096 block disks: "
                    .format(pool_name))
                arg_dict["luks"] = zettaknight_utils.query_yes_no(
                    "encrypt data disks with LUKS? ")

                print("creating zpool: {0}".format(pool_name))
                create_output = zettaknight_zpools.create(
                    pool_name, **arg_dict)  #from zettaknight_zpools
            #ret[pool_name]['Zpool Create'] = create_output[pool_name]['Zpool Create'] #'NoneType' object has no attribute '__getitem__'
        else:
            print("a pool already exists, moving on")
        ######################################################
        ######################################################

        ################## ssh key creation  #################
        print("checking for {0}".format(zettaknight_globs.identity_file))
        if not os.path.isfile(zettaknight_globs.identity_file):
            print(
                zettaknight_utils.printcolors(
                    "zettaknight id file not found, generating.", "WARNING"))
            keygen_output = zettaknight_utils.ssh_keygen(
                zettaknight_globs.identity_file)
            ret[pool_name]['Generate SSH Keygen'] = keygen_output[
                zettaknight_globs.fqdn]['Generate SSH Key']
        else:
            print("{0} exists, moving on".format(
                zettaknight_globs.identity_file))
        ######################################################

        ############# backup luks headers ####################
        print("backing up luks headers for {0}".format(pool_name))
        luks_backup_output = zettaknight_utils.backup_luks_headers()
        ret[pool_name]['Backup Luks Headers'] = luks_backup_output[
            zettaknight_globs.fqdn]['Backup Luks Headers']
        ######################################################

        ######## create zettaknight configuration file #######
        if not os.path.isdir(zettaknight_globs.conf_dir_new
                             ):  #if new directory does not exists, make it
            print("creating {0}".format(zettaknight_globs.conf_dir_new))
            os.mkdir(zettaknight_globs.conf_dir_new)
        ######################################################

        ########### create zettaknight store #################
        ######################################################
        if not os.path.isdir("/{0}".format(
                zettaknight_globs.zettaknight_store)):
            dataset_check_run = zettaknight_utils.pipe_this2(
                "/sbin/zfs list -H | grep {0}".format(
                    zettaknight_globs.zettaknight_store))
            if int(dataset_check_run.returncode) != 0:
                print("creating configuration file for {0}".format(
                    zettaknight_globs.zettaknight_store))
                zettaknight_utils.create_config(
                    dataset=zettaknight_globs.zettaknight_store)

        gerp_run = zettaknight_utils.pipe_this2(
            "/sbin/zfs list -H | /bin/grep {0}".format(
                zettaknight_globs.zettaknight_store))
        if int(gerp_run.returncode) is not 0:
            zettaknight_zfs.add_dataset(zettaknight_globs.zettaknight_store)

        #backup files to store
        files = [
            "/etc/exports", "/etc/crypttab",
            "{0}".format(zettaknight_globs.config_file_new)
        ]
        for file in files:
            if os.path.exists(file):
                destination_dir = "/{0}/{1}".format(
                    zettaknight_globs.zettaknight_store, zettaknight_globs.fqdn
                )  #add leading slash, zfs_share defined
                filename = file.replace(
                    "/", ""
                )  #remove illegal characters from file path and save file as the concatenated version
                if not os.path.isdir(destination_dir):
                    os.mkdir(destination_dir)
                print("backing up {0} to {1}".format(file, destination_dir))
                shutil.copyfile(file, "{0}/{1}".format(destination_dir,
                                                       filename))
        ######################################################
        ######################################################

        ############ create the first dataset ################
        dataset = zettaknight_utils.query_return_list(
            "Datasets to be created on {0}: ".format(pool_name))
        for item in dataset:
            dset_args = []
            dataset_full = "{0}/{1}".format(pool_name, item)
            dset_args.append(dataset_full)
            dset_args.append("create_config=True")
            add_dset_output = zettaknight_zfs.add_dataset(
                *dset_args)  #from zettaknight_utils
            ret[pool_name]['Add dataset {0}'.format(
                dataset_full)] = add_dset_output[dataset_full]['add_dataset']
        ######################################################

        ###### create server to server transfer pathing ######
        replication_output = zettaknight_zfs.configure_replication(
        )  #from zettaknight_zfs
        for repl_job, repl_job_output in replication_output[
                dataset_full].itervalues():
            ret[pool_name]['{0}'.format(repl_job)] = repl_job_output
        ######################################################

    except Exception as e:
        print(zettaknight_utils.printcolors(e, "FAIL"))
        sys.exit(1)

    zettaknight_globs.zfs_conf = _get_conf()

    return ret
Exemplo n.º 45
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
Exemplo n.º 46
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
Exemplo n.º 47
0
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
Exemplo n.º 48
0
def recover(snapshot, filename, relocate=None):
    '''
    '''
    if zettaknight_globs.help_flag:
        ret = """Recover:

	Usage:
		zettaknight recover <snapshot> <filepath> (<directory to recover file to>)*optional
	
    Recovers a previous version of a file or folder from a specified snapshot.  Information to use in calling zettaknight recover can be found in the output from the find_versions function.  By default, files/folders will be recovered to their original location with .R appended to the end of the name.

    Required Arguments:
        snapshot
            Specifies the snapshot to recover files from.
		filename
			Defines target file(s) to recover.  This should be the full path to a file or folder (/zfs_data/<some dataset>/<some filename>.<ext>)
			
	Optional Arguments:
		relocate
			Defines an alternate path to recover files/folders to.  If used, .R will not be appended, and the recover will overwrite any existing files."""
        return ret
		
    file = filename
    snap = snapshot
    dataset, snap_date = snap.split('@', 1)
    find_snap = find_versions(dataset, file, "quiet")
    find_snap_keys = find_snap.iterkeys()
    snap_basedir = "/{0}/.zfs/snapshot".format(dataset)
    active_basedir = "/{0}".format(dataset)
    dir_flag = False
    ret = {}
    ret[dataset] = {}
    
  
    try:
        if str(dataset) in str(file):
            file = file.split(dataset, 1)[1]
            last_ref = file.rsplit("/", 1)[1]
    except Exception as e:
        pass

    if dataset in file.rsplit("/", 1):
        file = file.split(dataset, 1)[1]
        last_ref = file.rsplit("/",1)[1]

    if snap not in find_snap_keys:
        try:
            raise Exception("Recoverable versions of {0} not found in dataset {1}".format(file, dataset))
        except Exception as e:
            zettaknight_utils.zlog("{0}".format(e), "ERROR")
    
    path_list1 = find_snap[snap]
    
    path_list = []
    
    if os.path.isdir("/{0}{1}".format(dataset, file)):
        dir_flag = True

    for line in path_list1:
        if line.startswith("-") or line.startswith("M") or line.startswith("R"):
            a, b = line.rsplit("/", 1)
            if not dir_flag:
                try:
                    if str(b) == str(last_ref):
                        path_list.append(line)
                except:
                    if str(b) == str(file):
                        path_list.append(line)
                    pass
                        

            else:
                if a.startswith("-") or line.startswith("M") or line.startswith("R"):
                    a, b = line.rsplit(dataset, 2)
                    if os.path.isdir("{0}/{1}{2}".format(snap_basedir, snap_date, b)):
                        dir_flag = True
                        path_list.append(line)

    if len(path_list) > 1:
        exc_out = ""
        for i in path_list:
            if exc_out:
                exc_out = "{0}\n\t{1}".format(exc_out, i)
            else:
                exc_out = str(i)
        err_msg = "Matching files/folders in snapshot:"
        print(zettaknight_utils.printcolors("\nAmbiguous recover request.  Multiple matches for {0}.".format(file), "FAIL"))
        print("{0} {1}".format(zettaknight_utils.printcolors(err_msg, "FAIL"), zettaknight_utils.printcolors(snap, "OKBLUE")))
        print("\t{0}".format(zettaknight_utils.printcolors(exc_out, "WARNING")))
        print(zettaknight_utils.printcolors("Re-run with explicit path to file.\n", "FAIL"))
        try:
            raise Exception("Ambiguous file reference.")
        except Exception as e:
            zettaknight_utils.zlog("{0}".format(e), "ERROR")
            sys.exit(0)
    
    if len(path_list) < 1:
        try:
            raise Exception("No restorable files or folders identified. \nRe-run with explicit path to file?")
        except Exception as e:
            zettaknight_utils.zlog("{0}".format(e), "ERROR")
            sys.exit(0)
    
    a, p = path_list[0].split(dataset, 1)
    path, dirs = p.split(file, 1)

    if dir_flag:
        a, b = path_list[0].rsplit(dataset, 2)
        file_loc = "{0}/{1}{2}".format(snap_basedir, snap_date, b)
        #bad, dir_path = path_list[0].split(file, 1)
        #list_dirs = dir_path.rsplit("/", 1)
        #try:
        #    out_dir = list_dirs[0]
        #except:
        out_dir = ""
        #    pass
        
        #file_loc = "{0}/{1}/{2}{3}/".format(snap_basedir, snap_date, file, dir_path )
        #mkdir_cmd = "/bin/mkdir {0}/{1}.R".format(active_basedir, file)
        #mkdir_run = zettaknight_utils.spawn_job(mkdir_cmd)
        #mkdir_cmd = "/bin/mkdir -p {0}/{1}.R/{2}".format(active_basedir, file, dir_path)
        #mkdir_run = zettaknight_utils.spawn_job(mkdir_cmd)
        out_path = "{0}{1}{2}.R{3}/".format(active_basedir, str(path), file, out_dir)

    else:
        file_loc = "{0}/{1}/{2}".format(snap_basedir, snap_date, p)
        out_path = "{0}{1}{2}.R".format(active_basedir, str(path), file)

    if relocate:
        out_path = relocate
    
    rec_cmd = "/bin/cp ""-r -p ""{0}"" ""{1}".format(file_loc, out_path)
    rec_run = zettaknight_utils.spawn_job(rec_cmd)
    rec_dict = eval(str(rec_run))
    for k,v in rec_dict.iteritems():
        if str(k) is "0":
            print("Recover operation succeeded.")
            print("\tFilename: {0}".format(zettaknight_utils.printcolors(file, "OKBLUE")))
            print("\t\tFile(s) restored to version: {0}".format(zettaknight_utils.printcolors(snap_date, "OKGREEN")))
            print("\t\tFile(s) restored to: {0}".format(zettaknight_utils.printcolors(out_path, "OKGREEN")))

        if str(k) is not "0":
            print("Recover operation failed.")
            print("\tFilename: {0}".format(zettaknight_utils.printcolors(file, "OKBLUE")))
            print("\t\tRestore failed with error: {0}".format(zettaknight_utils.printcolors(v, "FAIL")))
    
    return
Exemplo n.º 49
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
Exemplo n.º 50
0
def rename_dataset(**kwargs):
    '''
    '''

    import paramiko

    try:

        conf_file = zettaknight_globs.config_file_new

        if not 'keyfile' in kwargs.iterkeys():
            keyfile = zettaknight_globs.identity_file

        if not 'dataset' in kwargs.iterkeys():
            raise ValueError('A very specific bad thing happened')
            #required argument, show_help
        else:
            dataset = kwargs['dataset']

        if not 'new_dataset' in kwargs.iterkeys():
            #required argument, show_help
            raise ValueError('A very specific bad thing happened')
        else:
            new_dataset = kwargs['new_dataset']

        if not 'user' in kwargs.iterkeys():
            user = zettaknight_globs.zfs_conf[dataset]['user']
            print("user is {0}".format(user))

        remote_server = []
        for r_server in zettaknight_globs.zfs_conf[dataset]['snap'][
                'remote_server']:
            remote_server.append(r_server)
            print(remote_server)

    except Exception as e:
        zettaknight_utils.zlog("{0}".format(e), "ERROR")
        sys.exit(1)

    ret = {}
    ret[zettaknight_globs.fqdn] = {}
    ret[zettaknight_globs.fqdn]['rename {0}'.format(dataset)] = {}

    try:
        for r in remote_server:
            ssh = paramiko.SSHClient()
            ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
            ssh.connect(r, username=user, key_filename=keyfile)
            remote_sudo_cmd = "zfs rename {0} {1}".format(dataset, new_dataset)
            ssh_stdin, ssh_stdout, ssh_stderr = ssh.exec_command(
                remote_sudo_cmd)
            print ssh_stdout.read()

        #call function replace_string
        replace_string(dataset, new_dataset, conf_file)

        cmd = "zfs rename {0} {1}".format(dataset, new_dataset)
        zettaknight_utils.spawn_job(cmd)
    except Exception as e:
        zettaknight_utils.zlog("{0}".format(e), "ERROR")
        sys.exit(1)

    ret[zettaknight_globs.fqdn]['rename {0}'.format(dataset)] = {
        0:
        "successfully renamed {0} to {1}, all records have been updated".
        format(dataset, new_dataset)
    }

    return ret
Exemplo n.º 51
0
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
Exemplo n.º 52
0
def recover(snapshot, filename, relocate=None):
    '''
    '''
    
    file = filename
    snap = snapshot
    dataset, snap_date = snap.split('@', 1)
    find_snap = find_versions(dataset, file, "quiet")
    find_snap_keys = find_snap.iterkeys()
    snap_basedir = "/{0}/.zfs/snapshot".format(dataset)
    active_basedir = "/{0}".format(dataset)
    dir_flag = False
    ret = {}
    ret[dataset] = {}
    
    
    if dataset in file.split("/"):
        file = file.split(dataset, 1)[1]
        last_ref = file.rsplit("/",1)[1]
    
    if snap not in find_snap_keys:
        try:
            raise Exception("Recoverable versions of {0} not found in dataset {1}".format(file, dataset))
        except Exception as e:
            print(zettaknight_utils.printcolors(e, "FAIL"))
    
    path_list1 = find_snap[snap]
    
    path_list = []
    
    if os.path.isdir("/{0}/{1}".format(dataset, file)):
        dir_flag = True
    
    for line in path_list1:
        if line.startswith("-") or line.startswith("M"):
            a, b = line.rsplit("/", 1)
            if not dir_flag:
                try:
                    if str(b) == str(last_ref):
                        path_list.append(line)
                except:
                    if str(b) == str(file):
                        path_list.append(line)
                    pass
                        

            else:
                if a.startswith("-"):
                    a, b = line.rsplit(dataset, 2)
                    if os.path.isdir("{0}/{1}{2}".format(snap_basedir, snap_date, b)):
                        dir_flag = True
                        path_list.append(line)

    if len(path_list) > 1:
        exc_out = ""
        for i in path_list:
            if exc_out:
                exc_out = "{0}\n\t{1}".format(exc_out, i)
            else:
                exc_out = str(i)
        err_msg = "Matching files/folders in snapshot:"
        print(zettaknight_utils.printcolors("\nAmbiguous recover request.  Multiple matches for {0}.".format(file), "FAIL"))
        print("{0} {1}".format(zettaknight_utils.printcolors(err_msg, "FAIL"), zettaknight_utils.printcolors(snap, "OKBLUE")))
        print("\t{0}".format(zettaknight_utils.printcolors(exc_out, "WARNING")))
        print(zettaknight_utils.printcolors("Re-run with explicit path to file.\n", "FAIL"))
        try:
            raise Exception("Ambiguous file reference.")
        except Exception as e:
            print(zettaknight_utils.printcolors(e, "FAIL"))
            sys.exit(0)
    
    if len(path_list) < 1:
        try:
            raise Exception("No restorable files or folders identified. \nRe-run with explicit path to file?")
        except Exception as e:
            print(zettaknight_utils.printcolors(e, "FAIL"))
            sys.exit(0)
    
    a, p = path_list[0].split(dataset, 1)
    path, dirs = p.split(file, 1)

    if dir_flag:
        bad, dir_path = path_list[0].split(file, 1)
        list_dirs = dir_path.rsplit("/", 1)
        try:
            out_dir = list_dirs[0]
        except:
            out_dir = ""
            pass
        
        file_loc = "{0}/{1}/{2}{3}/".format(snap_basedir, snap_date, file, dir_path )
        mkdir_cmd = "/bin/mkdir {0}/{1}.R".format(active_basedir, file)
        mkdir_run = zettaknight_utils.spawn_job(mkdir_cmd)
        mkdir_cmd = "/bin/mkdir -p {0}/{1}.R/{2}".format(active_basedir, file, dir_path)
        mkdir_run = zettaknight_utils.spawn_job(mkdir_cmd)
        out_path = "{0}{1}{2}.R{3}/".format(active_basedir, str(path), file, out_dir)

    else:
        file_loc = "{0}/{1}/{2}".format(snap_basedir, snap_date, p)
        out_path = "{0}{1}{2}.R".format(active_basedir, str(path), file)

    if relocate:
        out_path = relocate
    
    rec_cmd = "/bin/cp ""-r ""{0}"" ""{1}".format(file_loc, out_path)
    rec_run = zettaknight_utils.spawn_job(rec_cmd)
    rec_dict = eval(str(rec_run))
    for k,v in rec_dict.iteritems():
        if str(k) is "0":
            print("Recover operation succeeded.")
            print("\tFilename: {0}".format(zettaknight_utils.printcolors(file, "OKBLUE")))
            print("\t\tFile(s) restored to version: {0}".format(zettaknight_utils.printcolors(snap_date, "OKGREEN")))
            print("\t\tFile(s) restored to: {0}".format(zettaknight_utils.printcolors(out_path, "OKGREEN")))

        if str(k) is not "0":
            print("Recover operation failed.")
            print("\tFilename: {0}".format(zettaknight_utils.printcolors(file, "OKBLUE")))
            print("\t\tRestore failed with error: {0}".format(zettaknight_utils.printcolors(v, "FAIL")))
    
    return
Exemplo n.º 53
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