示例#1
0
def signup_user():
    resp = ResponseFormater()
    data = request.get_json()
    hashed_password = generate_password_hash(data['password'], method='sha256')
    try:
        new_user = User(public_id=str(uuid.uuid4()),
                        name=data['name'],
                        username=data['username'],
                        password_hash=hashed_password,
                        admin=False)
        new_user.save()
    except NotUniqueError:
        return resp.failed(msg='user already exists').get_response()

    return resp.succeed(msg='registered successfully').get_response()
示例#2
0
def get_hosts(resp=None):
    if resp is None:
        resp = ResponseFormater()
    args = request.args if request.method == 'GET' else request.get_json(
        silent=True) or {}
    query_args = dict()
    if "name" in args:
        if boolean_parser(args.get("regex", False)):
            regex_name = re.compile("^{}$".format(
                args.get("name").strip(" ").lstrip("^").rstrip("$")))
            query_args["name"] = regex_name
        else:
            regex_name = re.compile(r"^{}$".format(
                re.escape(args.get("name")).replace("\*", ".*")))
            query_args["name"] = regex_name
    resp.add_result(Host.objects(**query_args))
    return resp.get_response()
示例#3
0
def delete_user():
    resp = ResponseFormater()
    request_args = merge_args_data(request.args, request.get_json(silent=True))
    user_kwargs = {
        key: request_args.get(key)
        for key in ["name", "username", "public_id"] if key in request_args
    }
    o_users = User.objects(**user_kwargs)
    if o_users:
        o_users.delete()
        resp.changed()
        resp.add_message("User(s) removed")
    else:
        resp.failed(msg="User(s) not found", status=404)
    return resp.get_response()
示例#4
0
def delete_hosts():
    resp = ResponseFormater()
    args = merge_args_data(request.args, request.get_json(silent=True))
    query_args = dict()
    if "name" in args:
        query_args["name__in"] = list_parser(args.get("name"))
    else:
        resp.failed(msg='name not defined')
        return resp.get_response()

    o_hosts = Host.objects(**query_args)

    if o_hosts.count() < 1:
        resp.failed(msg='%s not found' % (args.get('name')))
    else:
        #Remove host from all groups where the host is used
        Group.objects(hosts__in=o_hosts).update(pull_all__hosts=o_hosts)
        s_hosts = ','.join(o_hosts.scalar('name'))
        o_hosts.delete()
        resp.succeed(msg='Delete host %s' % (s_hosts), changed=True)
    return resp.get_response()
示例#5
0
def put_nodes():
    resp = ResponseFormater()
    args = merge_args_data(request.args, request.get_json(silent=True))
    node_type = args.get("type", None)
    if not node_type:
        resp.failed(msg='type not defined')
        return resp.get_response()
    elif node_type.lower() == "host":
        return put_hosts(resp=resp)
    elif node_type.lower() == "group":
        return put_groups(resp=resp)
    else:
        resp.failed(msg='unknown type: %s' % (node_type))
        return resp.get_response()
示例#6
0
def get_nodes():
    resp = ResponseFormater()
    args = request.args if request.method == 'GET' else request.get_json(
        silent=True) or {}
    query_args = dict()
    if "name" in args:
        if boolean_parser(args.get("regex", False)):
            regex_name = re.compile("^{}$".format(
                args.get("name").strip(" ").lstrip("^").rstrip("$")))
            query_args["name"] = regex_name
        else:
            regex_name = re.compile(r"^{}$".format(
                re.escape(args.get("name")).replace("\*", ".*")))
            query_args["name"] = regex_name
    if "type" in args:
        node_type = args.get("type")
        if node_type.lower() == "host":
            query_args["_cls"] = "Node.Host"
        elif node_type.lower() == "group":
            query_args["_cls"] = "Node.Group"
    o_nodes = Node.objects(**query_args)
    resp.add_result(o_nodes)
    return resp.get_response()
示例#7
0
def get_user():
    resp = ResponseFormater()
    user_kwargs = request.args if request.method == 'GET' else request.get_json(
        silent=True) or {}
    filtered_user_kwargs = {
        key: user_kwargs.get(key)
        for key in ["name", "username", "active", "public_id"]
        if key in user_kwargs
    }
    o_users = User.objects(**filtered_user_kwargs)
    if o_users:
        resp.add_result(o_users)
    else:
        resp.failed(msg="User(s) not found", status=404)
    return resp.get_response()
示例#8
0
def _add_user(**kwargs):
    resp = ResponseFormater()
    user_kwargs = kwargs.copy()

    if "password" not in user_kwargs and "password_hash" not in user_kwargs:
        user_kwargs["password"] = generate_password()
        resp.add_message("Generate random password for {}".format(
            user_kwargs.get("username", "unknown user")))

    if user_kwargs.get("roles") is not None:
        user_kwargs["roles"] = list_parser(user_kwargs.get("roles"))

    try:
        o_user = User(**user_kwargs)
        o_user.save()
        resp.add_message("User created")
        resp.changed()
    except NotUniqueError:
        raise NotUniqueError
    return resp
示例#9
0
def delete_nodes():
    resp = ResponseFormater()
    query_args = dict()
    if "name" in request.args:
        query_args["name__in"] = list_parser(request.args.get("name"))
    else:
        resp.failed(msg='name not defined')
        return resp.get_response()

    o_nodes = Node.objects(**query_args)
    if o_nodes.count() < 1:
        resp.failed(msg='%s not found' % (request.args.get('name')))
        return resp.get_response()
    s_nodes = ','.join(o_nodes.scalar('name'))
    o_nodes.delete()
    resp.succeed(msg='%s have been deleted' % (s_nodes))
    return resp.get_response()
示例#10
0
def put_groups(resp=None):
    if resp is None:
        resp = ResponseFormater()
    args = merge_args_data(request.args, request.get_json(silent=True))

    name = args.get("name", None)
    if name is None:
        abort(400, description="name not defined in request")

    # Create Group
    o_group = Group.objects(name=name).first()
    if o_group is None:
        try:
            query_args = dict(name=name)
            o_group = Group(**query_args)
            resp.succeed(changed=True, status=HTTPStatus.CREATED)
            resp.set_main_message("Create group {}".format(name))
        except NotUniqueError:
            resp.failed(msg='%s already exist' % (name))
            return resp.get_response()

    if "child_groups" in args or "child_groups_present" in args:
        child_groups = []
        child_groups.extend(list_parser(args.get("child_groups", [])))
        child_groups.extend(list_parser(args.get("child_groups_present", [])))
        child_groups = list(set(child_groups))

        for child_group in child_groups:
            o_child_group = Group.objects(name=child_group).first()
            if not o_child_group and args.get('create_groups', True):
                o_child_group = Group(name=child_group)
                o_child_group.save()
                resp.changed()
                resp.add_message("Create group {}".format(child_group))
            if o_child_group:
                if o_child_group not in o_group.child_groups:
                    o_group.child_groups.append(o_child_group)
                    resp.changed()
                    resp.add_message(
                        "Add {} group as child-group".format(child_group))
            else:
                resp.add_message(
                    "Can't add {} as child group. Group does not exist.")

    if "child_groups_set" in args:
        o_child_groups = []
        for child_group in list_parser(args.get("child_groups_set", [])):
            o_child_group = Group.objects(name=child_group).first()
            if not o_child_group and args.get('create_groups', True):
                o_child_group = Group(name=child_group)
                o_child_group.save()
                resp.changed()
                resp.add_message("Create group {}")
            if o_child_group:
                o_child_groups.append(o_child_group)
            else:
                resp.add_message(
                    "Can't set {} as child group. Group does not exist.")

        if set(o_group.child_groups) != set(o_child_groups):
            o_group.child_groups = o_child_groups
            resp.changed()
            if len(o_child_groups) == 0:
                resp.add_message("Remove all child-groups from {}".format(
                    o_group.name))
            else:
                resp.add_message("Set {} as child-group of {}".format(
                    ','.join([cg.name for cg in o_child_groups]),
                    o_group.name))

    if "child_groups_absent" in args:
        for child_group in list_parser(args.get("child_groups_absent")):
            o_child_group = Group.objects(name=child_group).first()
            if o_child_group is None:
                resp.add_message("{} group does not exist".format(child_group))
            elif o_child_group in o_group.child_groups:
                o_group.child_groups.remove(o_child_group)
                resp.changed()
                resp.add_message(
                    "Remove {} from child-groups".format(child_group))
            else:
                resp.add_message("{} is not a child-group of {}".format(
                    child_group, name))

    if "hosts" in args:
        hosts = list_parser(args.get("hosts")) or list_parser(
            args.get("hosts_present", []))

        o_hosts = Host.objects(name__in=hosts)
        hosts_not_found = list(
            set(hosts).difference(set(o_hosts.scalar('name'))))
        if len(hosts_not_found) > 0:
            resp.add_message("Hosts not found: {}".format(
                ",".join(hosts_not_found)))
        o_hosts_to_add = set(o_hosts).difference(o_group["hosts"])
        if len(o_hosts_to_add) > 0:
            o_group["hosts"].extend(o_hosts_to_add)
            resp.changed()

            resp.add_message("Add {} to hosts".format(",".join(
                map(lambda h: h.name, o_hosts_to_add))))
    if "hosts_set" in args:
        hosts = list_parser(args.get("hosts_set"))

        o_hosts = Host.objects(name__in=hosts)
        hosts_not_found = list(
            set(hosts).difference(set(o_hosts.scalar('name'))))
        if len(hosts_not_found) > 0:
            resp.add_message("Hosts not found: {}".format(
                ",".join(hosts_not_found)))
        if set(o_group.get("hosts")) != set(o_hosts):
            o_group["hosts"] = list(o_hosts)
            resp.changed()
            resp.add_message("Set {} to hosts".format(",".join(
                o_hosts_to_add.scalar('name'))))
    if "hosts_absent" in args:
        hosts = list_parser(args.get("hosts_absent"))
        o_hosts = Host.objects(name__in=hosts)
        o_hosts_to_remove = set(o_hosts).union(set(o_group["hosts"]))
        for o_host in o_hosts_to_remove:
            o_group["hosts"].remove(o_host)
            resp.changed()
            resp.add_message("Remove {} from hosts".format(o_host.get("name")))

    # Set variables
    barn_vars = args.get("vars", {})
    for k, v in barn_vars.items():
        if o_group.vars.get(k, None) != v:
            o_group.vars[k] = v
            resp.changed()

    # Delete variables
    vars_to_remove = args.get("vars_absent", [])
    for var_to_remove in vars_to_remove:
        if var_to_remove in o_group.vars:
            del o_group.vars[var_to_remove]
            resp.changed()

    # Save group
    if resp.get_changed():
        o_group.save()

    parent_groups_present = list_parser(
        args.get("parent_groups", args.get("parent_groups_present", [])))
    parent_groups_set = list_parser(args.get("parent_groups_set", []))
    parent_groups_absent = list_parser(args.get("parent_groups_absent", []))
    used_groups_list = parent_groups_present + parent_groups_set
    used_groups_list = list(set(used_groups_list))
    logging.debug("list used groups: %s", ",".join(used_groups_list))

    # Add groups who do not exist
    for g in used_groups_list:
        if Group.objects(name=g).first() is None:
            if args.get('create_groups', True):
                Group(name=g).save()
                resp.add_message("Create group {}".format(g))
                resp.changed()
            else:
                resp.add_message("{} group does not exist.".format(g))

    if "parent_groups" in args or "parent_groups_present" in args:
        o_parent_groups_to_add = Group.objects(name__in=parent_groups_present,
                                               child_groups__nin=[o_group])

        if len(o_parent_groups_to_add) > 0:
            o_parent_groups_to_add.update(add_to_set__child_groups=o_group)
            resp.changed()
            s_parent_groups_to_add = ",".join(
                [str(g) for g in o_parent_groups_to_add])
            resp.add_message("Add {} to child-groups of {}".format(
                o_group.name, s_parent_groups_to_add))

    if "parent_groups_set" in args:
        o_parent_groups_to_add = Group.objects(name__in=parent_groups_set,
                                               child_groups__nin=[o_group])
        if len(o_parent_groups_to_add) > 0:
            o_parent_groups_to_add.update(add_to_set__child_groups=o_group)
            resp.changed()
            s_parent_groups_to_add = ",".join(
                [str(g) for g in o_parent_groups_to_add])
            resp.add_message("Add {} to child-groups of {}".format(
                o_group.name, s_parent_groups_to_add))

        o_parent_groups_to_remove = Group.objects(name__nin=parent_groups_set,
                                                  child_groups__in=[o_group])
        if len(o_parent_groups_to_remove) > 0:
            o_parent_groups_to_remove.update(pull__child_groups=o_group)
            resp.changed()
            s_parent_groups_to_remove = ",".join(
                [str(g) for g in o_parent_groups_to_remove])
            resp.add_message("Remove {} from child-groups of {}".format(
                o_group.name, s_parent_groups_to_remove))

    if "parent_groups_absent" in args:
        o_parent_groups_to_remove = Group.objects(
            name__in=parent_groups_absent, child_groups__in=[o_group])
        if len(o_parent_groups_to_remove) > 0:
            o_parent_groups_to_remove.update(pull__child_groups=o_group)
            resp.changed()
            s_parent_groups_to_remove = ",".join(
                [str(g) for g in o_parent_groups_to_remove])
            resp.add_message("Remove {} from child-groups of {}".format(
                o_group.name, s_parent_groups_to_remove))

    return resp.get_response()
示例#11
0
def delete_groups():
    resp = ResponseFormater()
    args = merge_args_data(request.args, request.get_json(silent=True))
    query_args = dict()
    if "name" in args:
        query_args["name__in"] = list_parser(args.get("name"))
    else:
        resp.failed(msg='name not defined')
        return resp.get_response()

    o_groups = Group.objects(**query_args)
    logging.getLogger().info("remove groups: %s",
                             ','.join(o_groups.scalar('name')))
    Group.objects(child_groups__in=o_groups).update(
        pull_all__child_groups=o_groups)

    if o_groups.count() < 1:
        resp.failed(msg='%s not found' % (args.get('name')))
        return resp.get_response()
    s_groups = ','.join(o_groups.scalar('name'))
    o_groups.delete()

    resp.succeed(msg='%s have been deleted' % (s_groups))
    return resp.get_response()
示例#12
0
def put_user(action="present"):

    resp = ResponseFormater()
    request_args = request.get_json(silent=True)
    if request_args is None:
        abort(400, description="Bad Request")

    username = request_args.get("username", None)
    if not username:
        resp.failed("{} not defined".format("username"))
        return resp.get_response()

    o_user = User.objects(username=username).first()
    if not o_user:
        if action == "present" or action == "add":
            try:
                allowed_args = [
                    "username", "name", "active", "roles", "password",
                    "password_hash"
                ]
                user_kwargs = {
                    key: value
                    for key, value in request_args.items()
                    if key in allowed_args
                }
                resp += _add_user(**user_kwargs)
            except NotUniqueError:
                resp.failed("User already exist", status=400)
        else:
            resp.failed(
                "User does not exist. Set action to 'add' or 'present' if you want to create the user",
                status=400)
    else:
        if action == "update" or action == "present":
            allowed_args = [
                "username", "name", "active", "roles", "password",
                "password_hash"
            ]
            user_kwargs = {
                key: value
                for key, value in request_args.items() if key in allowed_args
            }
            resp += _modify_user(**user_kwargs)
        elif action == "add":
            resp.failed("User already exist", status=400)
        elif action == "passwd":
            new_password = request_args.get("password")
            if new_password:
                resp += _modify_user(username=username, password=new_password)
            else:
                resp.failed("password not defined", status=400)

    #create user
    if action == "present":
        pass

    return resp.get_response()
示例#13
0
def _modify_user(**user_kwargs):
    resp = ResponseFormater()

    username = user_kwargs.get("username")
    if username is None:
        resp.failed("{} not defined".format(username))
        return resp

    o_user = User.objects(username=username).first()
    o_user_hash = hash(o_user)
    if not o_user:
        resp.failed("{} user not found".format(username))
        return resp

    if "active" in user_kwargs and user_kwargs.get("active") != o_user.active:
        o_user.active = boolean_parser(user_kwargs.get("active"))

    if "name" in user_kwargs and user_kwargs.get("name") != o_user.active:
        o_user.name = user_kwargs.get("name")

    if "password_hash" in user_kwargs and user_kwargs.get(
            "password_hash") != o_user.password_hash:
        password_hash = user_kwargs.get("password_hash")
        if password_hash.startswith("sha256$"):
            o_user.password_hash = password_hash
        else:
            resp.add_message("invalid password hash")
    elif "password" in user_kwargs:
        password = user_kwargs.pop("password").strip()
        if not check_password_hash(o_user.password_hash, password):
            o_user.password_hash = generate_password_hash(password,
                                                          method='sha256')

    if user_kwargs.get("roles") is not None:
        o_user.roles = list(
            set(o_user.roles + list_parser(user_kwargs.get("roles"))))

    if o_user_hash != hash(o_user):
        o_user.save()
        resp.add_message("User modified")
        resp.changed()

    return resp
示例#14
0
def put_file_import():
    resp = ResponseFormater()
    hosts_to_add = []
    groups_to_add = []
    keep_existing_nodes = str(
        request.args.get("keep")
        or next(iter(request.form.getlist('keep')), None)).lower() in [
            "on", "true", "1", "yes"
        ]

    for file in request.files.values():
        fileextention = file.filename.split(".")[-1]
        to_add = None
        if fileextention.lower() in ("yaml", "yml"):
            try:
                to_add = yaml.load(file, Loader=yaml.FullLoader)
                resp.add_message("Successfully loaded %s" % (file.filename))
            except yaml.YAMLError as _:
                return resp.failed(
                    msg="failed to read yaml file: %s" % (file.filename),
                    changed=False,
                    status=HTTPStatus.BAD_REQUEST).get_response()
        elif fileextention.lower() == "json":
            try:
                to_add = json.load(file)
                resp.add_message("Successfully loaded %s" % (file.filename))
            except json.JSONDecodeError as _:
                return resp.failed(
                    msg="failed to read json file: %s" % (file.filename),
                    changed=False,
                    status=HTTPStatus.BAD_REQUEST).get_response()
        elif fileextention.lower() == "ini":
            try:
                data = file.read().decode('utf-8')
                to_add = _convert_ini(data)
            except Exception:
                return resp.failed(
                    msg="failed to read ini file: %s" % (file.filename),
                    changed=False,
                    status=HTTPStatus.BAD_REQUEST).get_response()
        else:
            return resp.failed("unsupported extention",
                               changed=False,
                               status=HTTPStatus.BAD_REQUEST).get_response()

        if "hosts" in to_add and isinstance(to_add["hosts"], list):
            hosts_to_add.extend(to_add["hosts"])
        if "groups" in to_add and isinstance(to_add["groups"], list):
            groups_to_add.extend(to_add["groups"])

        for node in to_add.get("nodes", []):
            if node.get("type", "").lower() == "host":
                hosts_to_add.append(node)
            elif node.get("type", "").lower() == "group":
                groups_to_add.append(node)

    if len(hosts_to_add) > 0 or len(groups_to_add) > 0:
        if not keep_existing_nodes:
            o_nodes_to_delete = Node.objects()
            if o_nodes_to_delete.count() > 0:
                o_nodes_to_delete.delete()
                resp.add_message("Remove old hosts and groups")
                logging.info("Remove all existing nodes during import")
                resp.changed()
            else:
                logging.info("Keep existing nodes during import")

        # first make sure all nodes exist
        for host in hosts_to_add:
            if host.get("name") and not Host.objects(name=host.get("name")):
                Host(name=host.get("name")).save()
        for group in groups_to_add:
            if group.get("name") and not Group.objects(name=group.get("name")):
                Group(name=group.get("name")).save()

        for host in hosts_to_add:
            try:
                o_host = Host.from_json(host, append=True)
                o_host.save()
                resp.add_result(o_host)
                resp.changed()
            except Exception as _:
                resp.add_message("Failed to import host %s" %
                                 (host.get("name", "unknown")))
        for group in groups_to_add:
            try:
                o_group = Group.from_json(group, append=True)
                o_group.save()
                resp.add_result(o_group)
                resp.changed()
            except Exception as _:
                resp.add_message("Failed to import group %s" %
                                 (group.get("name", "unknown")))
    else:
        resp.failed(msg="No valid hosts or groups in import")

    resp.add_message("Import completed")
    return resp.get_response()
示例#15
0
def put_hosts(action=None, resp=None):
    if resp is None:
        resp = ResponseFormater()
    args = merge_args_data(request.args, request.get_json(silent=True))

    name = args.get("name", None)
    if name is None:
        resp.failed(msg='name not defined')
        return resp.get_response()

    # Create Host
    o_host = Host.objects(name=name).first()
    if o_host is not None and action == "add":
        resp.failed(msg='%s already exist' % (args.get("name")))
        return resp.get_response()
    elif o_host is None:
        if action == "update":
            resp.failed(msg='Host not found: %s Does not exist' %
                        (args.get("name")))
            return resp.get_response()
        else:
            try:
                o_host = Host(name=name)
                resp.succeed(changed=True,
                             msg="Create host {}".format(name),
                             status=HTTPStatus.CREATED)
            except NotUniqueError:
                resp.failed(msg='%s already exist' % (args.get("name")))
                return resp.get_response()

    # Set variables
    barn_vars = args.get("vars", {})
    if action == "set" and barn_vars != o_host.vars:
        o_host.vars = {}
        resp.changed()
        resp.add_message("Reset host variables")

    for k, v in barn_vars.items():
        if o_host.vars.get(k, None) != v:
            o_host.vars[k] = v
            resp.changed()
            resp.add_message("Change variable: {}".format(k))

    # Delete variables
    if action != "add":
        vars_to_remove = args.get("vars_absent", [])
        for var_to_remove in vars_to_remove:
            if var_to_remove in o_host.vars:
                del o_host.vars[var_to_remove]
                resp.add_message("Remove variable: {}".format(var_to_remove))
                resp.changed()

    # Save Host
    if resp.get_changed():
        o_host.save()

    # Add host to group
    o_groups_remove_list = []
    o_groups_add_list = []
    if args.get("groups", False):
        groups = list_parser(args.get("groups"))
        for group in groups:
            o_group = Group.objects(name=group).first()
            if not o_group and args.get('create_groups', True):
                o_group = Group(name=group)
                resp.changed()
                resp.add_message("Create {} group".format(group))
            if o_group:
                o_groups_add_list.append(o_group)

    if args.get("groups_present", False):
        groups = list_parser(args.get("groups_present"))
        for group in groups:
            o_group = Group.objects(name=group).first()
            if not o_group and args.get('create_groups', True):
                o_group = Group(name=group)
            if o_group:
                o_groups_add_list.append(o_group)
    if args.get("groups_set", False) and not any(
            k in args for k in ("groups", "groups_present", "groups_absent")):
        groups = list_parser(args.get("groups_set"))

        o_groups_remove = Group.objects(name__not__in=groups,
                                        hosts__in=[o_host])
        for g in o_groups_remove:
            o_groups_remove_list.append(g)

        for group in groups:
            o_group = Group.objects(name=group).first()
            if not o_group and args.get('create_groups', True):
                o_group = Group(name=group)
            if o_group:
                o_groups_add_list.append(o_group)
    if args.get("groups_absent", False):
        groups = list_parser(args.get("groups_absent"))
        o_groups_remove = Group.objects(name__in=groups)
        for g in o_groups_remove:
            o_groups_remove_list.append(g)
    for g in list(set(o_groups_remove_list)):
        if o_host in g.hosts:
            g.hosts.remove(o_host)
            resp.add_message("Remove {} from {} group".format(name, g.name))
            g.save()
            resp.changed()
    for g in list(set(o_groups_add_list)):
        if o_host not in g.hosts:
            g.hosts.append(o_host)
            resp.add_message("Add {} into {} group".format(name, g.name))
            g.save()
            resp.changed()

    return resp.get_response()
示例#16
0
def test():
    logging.getLogger().critical("critical message")
    logging.getLogger().warning("warning message")
    logging.getLogger().info("info message")
    logging.getLogger().debug("debug message")
    return ResponseFormater().succeed(msg="it works").get_response()