Exemple #1
0
def update_account(name, data):
    """Update account.
    """
    data = dict((k, v) for k, v in data.items() if v)
    t_ret = (False, '')
    if not name:  # <name> should be specified.
        return t_ret
        
    s_rsc = '{}/account/{}'.format(etcdc.prefix, name)
    try:
        r = etcdc.read(s_rsc)
    except etcd.EtcdKeyNotFound as e:
        log.error(e)
        t_ret = (False, e)
        return t_ret

    d = ast.literal_eval(r.value)

    # Get iso 8601 format datetime for modified timestamp
    s_modified = datetime.utcnow().isoformat() + 'Z'
    # Put s_modified into data dict.
    data['modifiedAt'] = s_modified
    d.update(data.items())
    try:
        etcdc.write(s_rsc, d, prevExist=True)
    except etcd.EtcdKeyNotFound as e:
        log.error(e)
        t_ret = (False, e)
    else:
        t_ret = (True, 'user {} is updated.'.format(name))
    finally:
        return t_ret
Exemple #2
0
def create_account(data):
    """Create account.
    etcd_key: <ETCD_PREFIX>/account/<name>
    """
    t_ret = (False, '')
    s_rsc = ''
    # Create uid(uuid) for account
    s_uuid = str(uuid.uuid4())
    # Get iso 8601 format datetime for created timestamp
    s_created = datetime.utcnow().isoformat() + 'Z'
    # Put s_created into data dict.
    data['createdAt'] = s_created
    data['uid'] = s_uuid
    bytes_salt = bcrypt.gensalt()
    data['pass'] = bcrypt.hashpw(str.encode(data['pass']),
                                            bytes_salt).decode()
    data['salt'] = bytes_salt.decode()
    s_rsc = '{}/account/{}'.format(etcdc.prefix, data['name'])
    log.debug(data)
    try:
        etcdc.write(s_rsc, data, prevExist=False)
    except etcd.EtcdKeyAlreadyExist as e:
        log.error(e)
        t_ret = (False, e)
    else:
        t_ret = (True, 'user {} is created.'.format(data['name']))
    finally:
        return t_ret
Exemple #3
0
def update_catalog(name, data):
    """Update catalog
    catalogPatchSerializer
    """
    data = dict((k, v) for k, v in data.items() if v)
    t_ret = (False, '')
    if not name:
        return t_ret

    s_rsc = '{}/catalog/{}'.format(etcdc.prefix, name)
    try:
        r = etcdc.read(s_rsc)
    except etcd.EtcdKeyNotFound as e:
        log.error(e)
        t_ret = (False, e)
        return t_ret

    d = ast.literal_eval(r.value)

    data['modifiedAt'] = datetime.utcnow().isoformat() + 'Z'
    d.update(data.items())

    try:
        etcdc.write(s_rsc, d, prevExist=True)
    except etcd.EtcdKeyAlreadyExist as e:
        log.error(e)
        t_ret = (False, e)
    else:
        t_ret = (True, 'catalog {} is updated.'.format(name))
    finally:
        return t_ret
Exemple #4
0
def create_catalog(data):
    """Create catalog
    catalogPostSerializer
    """
    if not data.get('name'):
        return (False, 'Catalog name should be specified.')

    t_ret = (False, '')

    s_uuid = str(uuid.uuid4())
    s_created = datetime.utcnow().isoformat() + 'Z'

    data['createdAt'] = s_created
    data['uid'] = s_uuid

    log.debug(data)
    s_rsc = '{}/catalog/{}'.format(etcdc.prefix, data['name'])
    try:
        etcdc.write(s_rsc, data, prevExist=False)
    except etcd.EtcdKeyAlreadyExist as e:
        log.error(e)
        t_ret = (False, e)
    else:
        t_ret = (True, 'etcd {} is created.'.format(data['name']))
    finally:
        return t_ret
Exemple #5
0
def user_password_account(data):
    """Modify user account password.
    etcd_key: <ETCD_PREFIX>/account/<name>
    data: {'name': , 'pass': , 'pass1': , 'pass2': }
    """
    t_ret = (False, '')
    s_rsc = '{}/account/{}'.format(etcdc.prefix, data['name'])
    try:
        r = etcdc.read(s_rsc)
    except etcd.EtcdKeyNotFound as e:
        log.error(e)
        return (False, 'EtcdKeyNotFound')

    d = ast.literal_eval(r.value)

    # check if data['pass'] == d['pass']
    s_pass = bcrypt.hashpw(data['pass'].encode(), 
                           d['salt'].encode()).decode()
    if s_pass != d['pass']:  # current password mismatch
        return (False, 'Current password is not matched.')

    # since data['pass'] is matched, overwrite data['pass1'] to data['pass'] 
    # to validate new password.
    data['pass'] = data['pass1']
    (b_ret, s_msg) = _pass_validate(data)
    if not b_ret:
        log.debug((b_ret, s_msg))
        return (b_ret, s_msg)

    # password is okay. go head.
    new_data = dict()
    s_modified = datetime.utcnow().isoformat() + 'Z'
    data['modifiedAt'] = s_modified
    # Put d['pass'] to oldpass entry.
    if 'oldpass' in d:
        d['oldpass'].append(d['pass'])
    else:
        d['oldpass'] = [d['pass']]

    # Create new hashed password.
    bytes_salt = bytes(d['salt'], 'utf-8')
    d['pass'] = bcrypt.hashpw(str.encode(data['pass']),
                                         bytes_salt).decode()
    s_rsc = '{}/account/{}'.format(etcdc.prefix, data['name'])
    try:
        etcdc.write(s_rsc, d, prevExist=True)
    except etcd.EtcdKeyNotFound as e:
        log.error(e)
        t_ret = (False, e)
    else:
        t_ret = (True, 'user {} password is modified.'.format(data['name']))
    finally:
        return t_ret
Exemple #6
0
def create_app(data):
    """Create app
    appPostSerializer
    """
    if not data.get('name'):
        return (False, 'App name should be specified.')

    t_ret = (False, '')

    s_uuid = str(uuid.uuid4())
    s_created = datetime.utcnow().isoformat() + 'Z'

    data['createdAt'] = s_created
    data['uid'] = s_uuid

    # Get catalog information from data['catalog']
    s_catalog_rsc = '{}/catalog/{}'.format(etcdc.prefix, data['catalog'])
    try:
        r = etcdc.read(s_catalog_rsc)
    except etcd.EtcdKeyNotFound as e:
        log.error(e)
        return t_ret
    else:
        if r.value is not None:
            d = ast.literal_eval(r.value)
            log.debug(d)
            data['cpu_spec'] = d['cpu_spec']
            data['mem_spec'] = d['mem_spec']
            data['disk_spec'] = d['disk_spec'] + 1
            data['image_url'] = d['image_url']

    # Get type(vm or container) from data['catalog']
    s_cat_rsc = '{}/catalog/{}'.format(etcdc.prefix, data['catalog'])
    try:
        r = etcdc.read(s_cat_rsc)
    except etcd.EtcdKeyNotFound as e:
        log.error(e)
        return t_ret
    else:
        if r.value is not None:
            d = ast.literal_eval(r.value)
            log.debug(d)
            data['cat_type'] = d['type']
            data['cat_name'] = d['name']
        else:
            return t_ret

    # Get tenant from data['user']
    s_user_rsc = '{}/account/{}'.format(etcdc.prefix, data['user'])
    try:
        r = etcdc.read(s_user_rsc)
    except etcd.EtcdKeyNotFound as e:
        log.error(e)
        return t_ret
    else:
        if r.value is not None:
            d = ast.literal_eval(r.value)
            data['tenant'] = d['tenant']

    # Get edge from tenant
    s_tenant_rsc = '{}/tenant/{}'.format(etcdc.prefix, d['tenant'])
    try:
        r = etcdc.read(s_tenant_rsc)
    except etcd.EtcdKeyNotFound as e:
        log.error(e)
        return t_ret
    else:
        if r.value is not None:
            d = ast.literal_eval(r.value)
            log.debug(d)
            data['edge'] = d['edge']

    # Get edge endpoint
    s_edge_rsc = '{}/edge/{}'.format(etcdc.prefix, data['edge'])
    try:
        r = etcdc.read(s_edge_rsc)
    except etcd.EtcdKeyNotFound as e:
        log.error(e)
        return t_ret
    else:
        if r.value is not None:
            d = ast.literal_eval(r.value)
            log.debug(d)
            data['endpoint'] = d['endpoint']

    s_kubeconfig = PROJECT_ROOT + '/' + data['endpoint']

    if data['cat_type'] == 'vm':
        # Create VM image == app name <username>-<catalog>-<4_random_strings>
        # create vm manifest
        s_out = render_template('vm.j2', d=data)
        s_tpl = '{}/{}_vm.yaml'.format(KUBEMANIFEST, data['name'])
        try:
            with open(s_tpl, 'w') as f:
                f.write(s_out)
        except Exception as e:
            log.error(e)
            return (False, 'Cannot create a manifest file - {}.'.format(s_tpl))
        else:
            # Run kubectl apply
            s_cmd = '{} --kubeconfig={} '.format(KUBECTL, s_kubeconfig) + \
                    'apply -f {}'.format(s_tpl)
            log.debug(s_cmd)
            Popen(s_cmd, shell=True)

        # create vm service manifest
        s_out = render_template('svc.j2', d=data)
        s_tpl = '{}/{}_svc.yaml'.format(KUBEMANIFEST, data['name'])
        try:
            with open(s_tpl, 'w') as f:
                f.write(s_out)
        except Exception as e:
            log.error(e)
            return (False, 'Cannot create a manifest file - {}.'.format(s_tpl))
        else:
            # Run kubectl apply
            s_cmd = '{} --kubeconfig={} '.format(KUBECTL, s_kubeconfig) + \
                    'apply -f {}'.format(s_tpl)
            Popen(s_cmd, shell=True)
    elif data['cat_type'] == 'container':
        # Install using helm
        s_cmd = '{}/{}.sh install {} {}'.\
                format(BIN_DIR, data['cat_name'], s_kubeconfig, data['name'])
        log.debug(s_cmd)
        Popen(s_cmd, shell=True)

    s_rsc = '{}/app/{}'.format(etcdc.prefix, data['name'])
    try:
        etcdc.write(s_rsc, data, prevExist=False)
    except etcd.EtcdKeyAlreadyExist as e:
        log.error(e)
        t_ret = (False, e)
    else:
        t_ret = (True, 'App {} is created.'.format(data['name']))
    finally:
        return t_ret
Exemple #7
0
def cli():
    """Management script for collector."""
    while True:
        try:
            # Get the whole information on each edge.
            l_edge = list()
            s_rsc = '{}/edge'.format(etcdc.prefix)

            try:
                r = etcdc.read(s_rsc, recursive=True)
            except etcd.EtcdKeyNotFound as e:
                log.error(e)
            else:
                for child in r.children:
                    l_app = list()
                    d = ast.literal_eval(child.value)
                    # get hosts
                    print(PROJECT_ROOT + '/' + d['endpoint'])
                    l_hosts = kube_list_node(PROJECT_ROOT + '/' +
                                             d['endpoint'])
                    d['hosts'] = len(l_hosts)
                    d_nodes = dict()  # {'name': 'ip', ...}
                    for item in l_hosts:
                        d_nodes[item.metadata.
                                name] = item.status.addresses[0].address
                    # log.debug(d_nodes)
                    # get # of tenants and apps
                    l_tenants = get_tenant(d['name'])
                    d['tenants'] = len(l_tenants)
                    d['apps'] = 0
                    for e in l_tenants:
                        if 'app' in e:
                            d['apps'] += len(e['app'])

                    d['cpu'] = 0
                    d['memory'] = 0
                    i_total_cores = 0
                    i_total_memory = 0
                    i_total_storage = 0
                    for h in l_hosts:
                        i_total_cores += int(h.status.capacity['cpu'])
                        i_total_memory += int(
                            h.status.capacity['memory'].replace('Ki', ''))
                    d['tot_cpu'] = i_total_cores
                    d['tot_mem'] = int(i_total_memory / (1024 * 1024))

                    # Get loadavg and free mem
                    if d['name'] == 'edge1':
                        ssh_server = 'harden.iorchard.co.kr'
                    elif d['name'] == 'edge2':
                        ssh_server = 'durant.iorchard.co.kr'
                    RSC = 'ssh -p42544 {} get_rsc.sh'.format(ssh_server)
                    (b_res, s_out) = cmd(RSC, 3, False)
                    l = s_out.split("\n")
                    d['used_cpu'] = (float(l[0]) + float(l[1]) + float(l[2]))
                    avail_mem = (int(l[3]) + int(l[4]) + int(l[5])) / (1024 *
                                                                       1024)
                    d['used_mem'] = d['tot_mem'] - avail_mem
                    d['cpu'] = int(d['used_cpu'] / d['tot_cpu'] * 100)
                    d['memory'] = int(d['used_mem'] / d['tot_mem'] * 100)
                    # ceph storage
                    CEPH = "kubectl --kubeconfig " + PROJECT_ROOT + '/' \
                            + d['endpoint'] + " -n rook-ceph exec -it " \
                            + "$(kubectl --kubeconfig " + PROJECT_ROOT + '/' \
                            + d['endpoint'] + " -n rook-ceph get po " \
                            + "-l app=rook-ceph-tools " \
                            + "-o jsonpath='{.items[0].metadata.name}') -- " \
                            + "ceph df --format json"
                    (b_res, s_out) = cmd(CEPH, 3, False)
                    print(s_out)
                    d['status'] = 'Healthy' if b_res else 'Unhealthy'
                    d_stor = ast.literal_eval(s_out)
                    d['tot_stor'] = int(d_stor['stats']['total_bytes'] /
                                        pow(1024, 3))
                    d['used_stor'] = int(d_stor['stats']['total_used_bytes'] /
                                         pow(1024, 3))
                    d['storage'] = int(d['used_stor'] / d['tot_stor'] * 100)
                    # Update etcd status
                    try:
                        s = '{}/edge/{}'.format(etcdc.prefix, d['name'])
                        # log.debug(d)
                        etcdc.write(s, d, prevExist=True)
                    except etcd.EtcdKeyNotFound as e:
                        log.error(e)

                    # Update app status
                    s_app = '{}/app'.format(etcdc.prefix)
                    try:
                        r_app = etcdc.read(s_app, recursive=True)
                    except etcd.EtcdKeyNotFound as e:
                        log.error(e)
                    else:
                        for app_child in r_app.children:
                            if app_child.value is not None:
                                d_app = dict()
                                app = ast.literal_eval(app_child.value)
                                if app['edge'] == d['name']:
                                    d_app['name'] = app['name']
                                    d_app['username'] = GUAC_USER
                                    d_app['password'] = GUAC_PASS
                                # Get catalog info.
                                s_cat = '{}/catalog/{}'.format(
                                    etcdc.prefix, app['catalog'])
                                try:
                                    r_cat = etcdc.read(s_cat)
                                except etcd.EtcdKeyNotFound as e:
                                    log.error(e)
                                else:
                                    cat = ast.literal_eval(r_cat.value)
                                    app['cat_type'] = cat['type']
                                    app['cat_name'] = cat['name']
                                    app['cat_logo'] = cat['logo']
                                # Get app status
                                if app['cat_type'] == 'vm':
                                    # first, look at DataVolume status of app.
                                    CMD = "kubectl --kubeconfig " + PROJECT_ROOT + '/' \
                                        + d['endpoint'] + ' get dv ' \
                                        + app['name'] \
                                        + " -o jsonpath='{range .status}{.phase},{.progress}{end}'"
                                    (b_res, s_out) = cmd(CMD, 5, False)
                                    l_out = s_out.split(',')
                                    if l_out[0] == 'Succeeded':
                                        # Get vm status of app
                                        CMD = "kubectl --kubeconfig " + PROJECT_ROOT \
                                        + '/' \
                                        + d['endpoint'] + ' get vm ' \
                                        + app['name'] \
                                        + " -o jsonpath='{.status.ready}'"
                                        (b_res, s_out) = cmd(CMD, 5, False)
                                        if b_res and s_out == 'true':
                                            # update app status 'running'.
                                            app.update({'status': 'running'})

                                            if app['edge'] == d['name']:
                                                # Get where app is running.
                                                CMD = "kubectl --kubeconfig " \
                                                + PROJECT_ROOT + '/' \
                                                + d['endpoint'] + ' get vmi ' \
                                                + app['name'] \
                                                + " -o jsonpath='{.status.nodeName}'"
                                                (b_res,
                                                 s_out) = cmd(CMD, 5, False)
                                                if b_res:
                                                    d_app[
                                                        'hostname'] = d_nodes[
                                                            s_out]
                                                # Get nodeport for app.
                                                CMD = "kubectl --kubeconfig " \
                                                + PROJECT_ROOT + '/' \
                                                + d['endpoint'] + ' get svc ' \
                                                + app['name'] \
                                                + " -o jsonpath='{.spec.ports[0].nodePort}'"
                                                (b_res,
                                                 s_out) = cmd(CMD, 5, False)
                                                if b_res:
                                                    d_app['port'] = s_out
                                        else:
                                            # update app status 'stopped'
                                            app.update({'status': 'stopped'})
                                    elif l_out[0] == 'ImportInProgress':
                                        # update app status 'building' and
                                        app.update({
                                            'status':
                                            'building ({})'.format(l_out[1])
                                        })
                                elif app['cat_type'] == 'container':
                                    app.update({'status': 'running'})

                                try:
                                    s = '{}/app/{}'.format(
                                        etcdc.prefix, app['name'])
                                    # log.debug(app)
                                    etcdc.write(s, app, prevExist=True)
                                except etcd.EtcdKeyNotFound as e:
                                    log.error(e)

                                if 'port' in d_app:
                                    l_app.append(d_app)
                        # render guac-config.j2 and copy it to guac broker server
                        log.debug(l_app)
                        template = env.get_template('broker.j2')
                        s_out = template.render(l_app=l_app)
                        s_tmp = '/tmp/{}.broker'.format(d['name'])
                        try:
                            with open(s_tmp, 'w') as f:
                                f.write(s_out)
                        except Exception as e:
                            log.error(e)
                        else:
                            CMD = "scp " \
                            + "-P42544 {} {}".format(s_tmp, d['broker_ip']) \
                            + ":/etc/guacamole/noauth-config.xml"
                            log.debug(CMD)
                            (b_res, s_out) = cmd(CMD, 5, False)
                            if b_res:
                                d_app['port'] = s_out

                    l_edge.append(d)

            # log.debug(l_edge)
            log.debug(l_app)

            time.sleep(1)
        except:
            log.error('unknown error')