mirror of https://github.com/jumpserver/jumpserver
				
				
				
			merge with cmdb
						commit
						3b07198b8a
					
				| 
						 | 
				
			
			@ -37,6 +37,7 @@ nosetests.xml
 | 
			
		|||
.mr.developer.cfg
 | 
			
		||||
.project
 | 
			
		||||
.pydevproject
 | 
			
		||||
*.xlsx
 | 
			
		||||
node_modules
 | 
			
		||||
logs
 | 
			
		||||
keys
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,459 @@
 | 
			
		|||
# -*- coding: utf-8 -*-
 | 
			
		||||
 | 
			
		||||
from ansible.inventory.group import Group
 | 
			
		||||
from ansible.inventory.host import Host
 | 
			
		||||
from ansible.inventory import Inventory
 | 
			
		||||
from ansible.runner import Runner
 | 
			
		||||
from ansible.playbook import PlayBook
 | 
			
		||||
 | 
			
		||||
from ansible import callbacks
 | 
			
		||||
from ansible import utils
 | 
			
		||||
from passlib.hash import sha512_crypt
 | 
			
		||||
 | 
			
		||||
# from utils import get_rand_pass
 | 
			
		||||
 | 
			
		||||
import random
 | 
			
		||||
import os.path
 | 
			
		||||
API_DIR = os.path.dirname(os.path.abspath(__file__))
 | 
			
		||||
ANSIBLE_DIR = os.path.join(API_DIR, 'playbooks')
 | 
			
		||||
 | 
			
		||||
def get_rand_pass():
 | 
			
		||||
    """
 | 
			
		||||
    get a reandom password.
 | 
			
		||||
    """
 | 
			
		||||
    lower = [chr(i) for i in range(97,123)]
 | 
			
		||||
    upper = [chr(i).upper() for i in range(97,123)]
 | 
			
		||||
    digit = [str(i) for i in range(10)]
 | 
			
		||||
    password_pool = []
 | 
			
		||||
    password_pool.extend(lower)
 | 
			
		||||
    password_pool.extend(upper)
 | 
			
		||||
    password_pool.extend(digit)
 | 
			
		||||
    pass_list = [random.choice(password_pool) for i in range(1,14)]
 | 
			
		||||
    pass_list.insert(random.choice(range(1,14)), '@')
 | 
			
		||||
    pass_list.insert(random.choice(range(1,14)), random.choice(digit))
 | 
			
		||||
    password = ''.join(pass_list)
 | 
			
		||||
    return password
 | 
			
		||||
 | 
			
		||||
class AnsibleError(StandardError):
 | 
			
		||||
    """
 | 
			
		||||
    the base AnsibleError which contains error(required),
 | 
			
		||||
    data(optional) and message(optional).
 | 
			
		||||
    存储所有Ansible 异常对象
 | 
			
		||||
    """
 | 
			
		||||
    def __init__(self, error, data='', message=''):
 | 
			
		||||
        super(AnsibleError, self).__init__(message)
 | 
			
		||||
        self.error = error
 | 
			
		||||
        self.data = data
 | 
			
		||||
        self.message = message
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class CommandValueError(AnsibleError):
 | 
			
		||||
    """
 | 
			
		||||
    indicate the input value has error or invalid.
 | 
			
		||||
    the data specifies the error field of input form.
 | 
			
		||||
    输入不合法 异常对象
 | 
			
		||||
    """
 | 
			
		||||
    def __init__(self, field, message=''):
 | 
			
		||||
        super(CommandValueError, self).__init__('value:invalid', field, message)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class MyInventory(object):
 | 
			
		||||
    """
 | 
			
		||||
    this is my ansible inventory object.
 | 
			
		||||
    """
 | 
			
		||||
    def __init__(self, resource):
 | 
			
		||||
        """
 | 
			
		||||
        resource的数据格式是一个列表字典,比如
 | 
			
		||||
            {
 | 
			
		||||
                "group1": {
 | 
			
		||||
                    "hosts": [{"hostname": "10.10.10.10", "port": "22", "username": "test", "password": "mypass"}, ...],
 | 
			
		||||
                    "vars": {"var1": value1, "var2": value2, ...}
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        如果你只传入1个列表,这默认该列表内的所有主机属于my_group组,比如
 | 
			
		||||
            [{"hostname": "10.10.10.10", "port": "22", "username": "test", "password": "mypass"}, ...]
 | 
			
		||||
        """
 | 
			
		||||
        self.resource = resource
 | 
			
		||||
        self.inventory = Inventory()
 | 
			
		||||
        self.gen_inventory()
 | 
			
		||||
 | 
			
		||||
    def add_group(self, hosts, groupname, groupvars=None):
 | 
			
		||||
        """
 | 
			
		||||
        add hosts to a group
 | 
			
		||||
        """
 | 
			
		||||
        my_group = Group(name=groupname)
 | 
			
		||||
 | 
			
		||||
        # if group variables exists, add them to group
 | 
			
		||||
        if groupvars:
 | 
			
		||||
            for key, value in groupvars.iteritems():
 | 
			
		||||
                my_group.set_variable(key, value)
 | 
			
		||||
 | 
			
		||||
        # add hosts to group
 | 
			
		||||
        for host in hosts:
 | 
			
		||||
            # set connection variables
 | 
			
		||||
            hostname = host.get("hostname")
 | 
			
		||||
            hostport = host.get("port")
 | 
			
		||||
            username = host.get("username")
 | 
			
		||||
            password = host.get("password")
 | 
			
		||||
            my_host = Host(name=hostname, port=hostport)
 | 
			
		||||
            my_host.set_variable('ansible_ssh_host', hostname)
 | 
			
		||||
            my_host.set_variable('ansible_ssh_port', hostport)
 | 
			
		||||
            my_host.set_variable('ansible_ssh_user', username)
 | 
			
		||||
            my_host.set_variable('ansible_ssh_pass', password)
 | 
			
		||||
            # set other variables
 | 
			
		||||
            for key, value in host.iteritems():
 | 
			
		||||
                if key not in ["hostname", "port", "username", "password"]:
 | 
			
		||||
                    my_host.set_variable(key, value)
 | 
			
		||||
            # add to group
 | 
			
		||||
            my_group.add_host(my_host)
 | 
			
		||||
 | 
			
		||||
        self.inventory.add_group(my_group)
 | 
			
		||||
 | 
			
		||||
    def gen_inventory(self):
 | 
			
		||||
        """
 | 
			
		||||
        add hosts to inventory.
 | 
			
		||||
        """
 | 
			
		||||
        if isinstance(self.resource, list):
 | 
			
		||||
            self.add_group(self.resource, 'my_group')
 | 
			
		||||
        elif isinstance(self.resource, dict):
 | 
			
		||||
            for groupname, hosts_and_vars in self.resource.iteritems():
 | 
			
		||||
                self.add_group(hosts_and_vars.get("hosts"), groupname, hosts_and_vars.get("vars"))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Command(MyInventory):
 | 
			
		||||
    """
 | 
			
		||||
    this is a command object for parallel execute command.
 | 
			
		||||
    """
 | 
			
		||||
    def __init__(self, *args, **kwargs):
 | 
			
		||||
        super(Command, self).__init__(*args, **kwargs)
 | 
			
		||||
        self.results = ''
 | 
			
		||||
 | 
			
		||||
    def run(self, command, module_name="command", timeout=5, forks=10, group='my_group'):
 | 
			
		||||
        """
 | 
			
		||||
        run command from andible ad-hoc.
 | 
			
		||||
        command  : 必须是一个需要执行的命令字符串, 比如
 | 
			
		||||
                 'uname -a'
 | 
			
		||||
        """
 | 
			
		||||
        if module_name not in ["raw", "command", "shell"]:
 | 
			
		||||
            raise  CommandValueError("module_name",
 | 
			
		||||
                                     "module_name must be of the 'raw, command, shell'")
 | 
			
		||||
        hoc = Runner(module_name=module_name,
 | 
			
		||||
                     module_args=command,
 | 
			
		||||
                     timeout=timeout,
 | 
			
		||||
                     inventory=self.inventory,
 | 
			
		||||
                     subset=group,
 | 
			
		||||
                     forks=forks
 | 
			
		||||
                     )
 | 
			
		||||
        self.results = hoc.run()
 | 
			
		||||
 | 
			
		||||
        if self.stdout:
 | 
			
		||||
            return {"ok": self.stdout}
 | 
			
		||||
        else:
 | 
			
		||||
            msg = []
 | 
			
		||||
            if self.stderr:
 | 
			
		||||
                msg.append(self.stderr)
 | 
			
		||||
            if self.dark:
 | 
			
		||||
                msg.append(self.dark)
 | 
			
		||||
            return {"failed": msg}
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def raw_results(self):
 | 
			
		||||
        """
 | 
			
		||||
        get the ansible raw results.
 | 
			
		||||
        """
 | 
			
		||||
        return self.results
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def exec_time(self):
 | 
			
		||||
        """
 | 
			
		||||
        get the command execute time.
 | 
			
		||||
        """
 | 
			
		||||
        result = {}
 | 
			
		||||
        all = self.results.get("contacted")
 | 
			
		||||
        for key, value in all.iteritems():
 | 
			
		||||
            result[key] = {
 | 
			
		||||
                    "start": value.get("start"),
 | 
			
		||||
                    "end"  : value.get("end"),
 | 
			
		||||
                    "delta": value.get("delta"),}
 | 
			
		||||
        return result
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def stdout(self):
 | 
			
		||||
        """
 | 
			
		||||
        get the comamnd standard output.
 | 
			
		||||
        """
 | 
			
		||||
        result = {}
 | 
			
		||||
        all = self.results.get("contacted")
 | 
			
		||||
        for key, value in all.iteritems():
 | 
			
		||||
            result[key] =  value.get("stdout")
 | 
			
		||||
        return result
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def stderr(self):
 | 
			
		||||
        """
 | 
			
		||||
        get the command standard error.
 | 
			
		||||
        """
 | 
			
		||||
        result = {}
 | 
			
		||||
        all = self.results.get("contacted")
 | 
			
		||||
        for key, value in all.iteritems():
 | 
			
		||||
            result[key] = {
 | 
			
		||||
                    "stderr": value.get("stderr"),
 | 
			
		||||
                    "warnings": value.get("warnings"),}
 | 
			
		||||
        return result
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def dark(self):
 | 
			
		||||
        """
 | 
			
		||||
        get the dark results.
 | 
			
		||||
        """
 | 
			
		||||
        return self.results.get("dark")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Tasks(Command):
 | 
			
		||||
    """
 | 
			
		||||
    this is a tasks object for include the common command.
 | 
			
		||||
    """
 | 
			
		||||
    def __init__(self, *args, **kwargs):
 | 
			
		||||
        super(Tasks, self).__init__(*args, **kwargs)
 | 
			
		||||
 | 
			
		||||
    def __run(self, module_args, module_name="command", timeout=5, forks=10, group='my_group'):
 | 
			
		||||
        """
 | 
			
		||||
        run command from andible ad-hoc.
 | 
			
		||||
        command  : 必须是一个需要执行的命令字符串, 比如
 | 
			
		||||
                 'uname -a'
 | 
			
		||||
        """
 | 
			
		||||
        hoc = Runner(module_name=module_name,
 | 
			
		||||
                     module_args=module_args,
 | 
			
		||||
                     timeout=timeout,
 | 
			
		||||
                     inventory=self.inventory,
 | 
			
		||||
                     subset=group,
 | 
			
		||||
                     forks=forks
 | 
			
		||||
                     )
 | 
			
		||||
 | 
			
		||||
        self.results = hoc.run()
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def msg(self):
 | 
			
		||||
        """
 | 
			
		||||
        get the contacted and dark msg
 | 
			
		||||
        """
 | 
			
		||||
        msg = {}
 | 
			
		||||
        for result in ["contacted", "dark"]:
 | 
			
		||||
            all = self.results.get(result)
 | 
			
		||||
            for key, value in all.iteritems():
 | 
			
		||||
                if value.get("msg"):
 | 
			
		||||
                    msg[key] = value.get("msg")
 | 
			
		||||
        return msg
 | 
			
		||||
 | 
			
		||||
    def push_key(self, user, key_path):
 | 
			
		||||
        """
 | 
			
		||||
        push the ssh authorized key to target.
 | 
			
		||||
        """
 | 
			
		||||
        module_args = 'user="%s" key="{{ lookup("file", "%s") }}"' % (user, key_path)
 | 
			
		||||
        self.__run(module_args, "authorized_key")
 | 
			
		||||
 | 
			
		||||
        return {"status": "failed","msg": self.msg} if self.msg else {"status": "ok"}
 | 
			
		||||
 | 
			
		||||
    def del_key(self, user, key_path):
 | 
			
		||||
        """
 | 
			
		||||
        push the ssh authorized key to target.
 | 
			
		||||
        """
 | 
			
		||||
        module_args = 'user="%s" key="{{ lookup("file", "%s") }}" state="absent"' % (user, key_path)
 | 
			
		||||
        self.__run(module_args, "authorized_key")
 | 
			
		||||
 | 
			
		||||
        return {"status": "failed","msg": self.msg} if self.msg else {"status": "ok"}
 | 
			
		||||
 | 
			
		||||
    def add_user(self, username, password):
 | 
			
		||||
        """
 | 
			
		||||
        add a host user.
 | 
			
		||||
        """
 | 
			
		||||
        encrypt_pass = sha512_crypt.encrypt(password)
 | 
			
		||||
        module_args = 'name=%s shell=/bin/bash password=%s' % (username, encrypt_pass)
 | 
			
		||||
        self.__run(module_args, "user")
 | 
			
		||||
 | 
			
		||||
        return {"status": "failed","msg": self.msg} if self.msg else {"status": "ok"}
 | 
			
		||||
 | 
			
		||||
    def add_multi_user(self, *args):
 | 
			
		||||
        """
 | 
			
		||||
        add multi user
 | 
			
		||||
        :param args:
 | 
			
		||||
            user
 | 
			
		||||
        :return:
 | 
			
		||||
        """
 | 
			
		||||
        results = {}
 | 
			
		||||
        users = {}
 | 
			
		||||
        action = results["action_info"] = {}
 | 
			
		||||
        for user in args:
 | 
			
		||||
            users[user] = get_rand_pass()
 | 
			
		||||
        for user, password in users.iteritems():
 | 
			
		||||
            ret = self.add_user(user, password)
 | 
			
		||||
            action[user] = ret
 | 
			
		||||
        results["user_info"] = users
 | 
			
		||||
 | 
			
		||||
        return results
 | 
			
		||||
 | 
			
		||||
    def del_user(self, username):
 | 
			
		||||
        """
 | 
			
		||||
        delete a host user.
 | 
			
		||||
        """
 | 
			
		||||
        module_args = 'name=%s state=absent remove=yes move_home=yes force=yes' % (username)
 | 
			
		||||
        self.__run(module_args, "user")
 | 
			
		||||
 | 
			
		||||
        return {"status": "failed","msg": self.msg} if self.msg else {"status": "ok"}
 | 
			
		||||
 | 
			
		||||
    def add_init_users(self):
 | 
			
		||||
        """
 | 
			
		||||
        add initail users: SA, DBA, DEV
 | 
			
		||||
        """
 | 
			
		||||
        results = {}
 | 
			
		||||
        action = results["action_info"] = {}
 | 
			
		||||
        users = {"SA": get_rand_pass(), "DBA": get_rand_pass(), "DEV": get_rand_pass()}
 | 
			
		||||
        for user, password in users.iteritems():
 | 
			
		||||
            ret = self.add_user(user, password)
 | 
			
		||||
            action[user] = ret
 | 
			
		||||
        results["user_info"] = users
 | 
			
		||||
 | 
			
		||||
        return results
 | 
			
		||||
 | 
			
		||||
    def del_init_users(self):
 | 
			
		||||
        """
 | 
			
		||||
        delete initail users: SA, DBA, DEV
 | 
			
		||||
        """
 | 
			
		||||
        results = {}
 | 
			
		||||
        action = results["action_info"] = {}
 | 
			
		||||
        for user in ["SA", "DBA", "DEV"]:
 | 
			
		||||
            ret = self.del_user(user)
 | 
			
		||||
            action[user] = ret
 | 
			
		||||
        return results
 | 
			
		||||
 | 
			
		||||
    def get_host_info(self):
 | 
			
		||||
        """
 | 
			
		||||
        use the setup module get host informations
 | 
			
		||||
        :return:
 | 
			
		||||
          all_ip is list
 | 
			
		||||
          processor_count is int
 | 
			
		||||
          system_dist_version is string
 | 
			
		||||
          system_type is string
 | 
			
		||||
          disk is dict (device_name: device_size}
 | 
			
		||||
          system_dist is string
 | 
			
		||||
          processor_type is string
 | 
			
		||||
          default_ip is string
 | 
			
		||||
          hostname is string
 | 
			
		||||
          product_sn is string
 | 
			
		||||
          memory_total is int (MB)
 | 
			
		||||
          default_mac is string
 | 
			
		||||
          product_name is string
 | 
			
		||||
        """
 | 
			
		||||
        self.__run('', 'setup')
 | 
			
		||||
 | 
			
		||||
        result = {}
 | 
			
		||||
        all = self.results.get("contacted")
 | 
			
		||||
        for key, value in all.iteritems():
 | 
			
		||||
            setup =value.get("ansible_facts")
 | 
			
		||||
            # get disk informations
 | 
			
		||||
            disk_all = setup.get("ansible_devices")
 | 
			
		||||
            disk_need = {}
 | 
			
		||||
            for disk_name, disk_info in disk_all.iteritems():
 | 
			
		||||
                if disk_name.startswith('sd') or disk_name.startswith('hd') or disk_name.startswith('vd'):
 | 
			
		||||
                    disk_need[disk_name] = disk_info.get("size")
 | 
			
		||||
 | 
			
		||||
            result[key] = {
 | 
			
		||||
                    "other_ip": setup.get("ansible_all_ipv4_addresses"),
 | 
			
		||||
                    "hostname": setup.get("ansible_hostname" ),
 | 
			
		||||
                    "ip": setup.get("ansible_default_ipv4").get("address"),
 | 
			
		||||
                    "mac": setup.get("ansible_default_ipv4").get("macaddress"),
 | 
			
		||||
                    "brand": setup.get("ansible_product_name"),
 | 
			
		||||
                    "cpu_type": setup.get("ansible_processor"),
 | 
			
		||||
                    "cpu_cores": setup.get("ansible_processor_count"),
 | 
			
		||||
                    "memory": setup.get("ansible_memtotal_mb"),
 | 
			
		||||
                    "disk": disk_need,
 | 
			
		||||
                    "system_type": setup.get("ansible_distribution"),
 | 
			
		||||
                    "system_version": setup.get("ansible_distribution_version"),
 | 
			
		||||
                    "asset_type": setup.get("ansible_system"),
 | 
			
		||||
                    "sn": setup.get("ansible_product_serial")
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        return {"status": "failed", "msg": self.msg} if self.msg else {"status": "ok", "result": result}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class CustomAggregateStats(callbacks.AggregateStats):
 | 
			
		||||
    """
 | 
			
		||||
    Holds stats about per-host activity during playbook runs.
 | 
			
		||||
    """
 | 
			
		||||
    def __init__(self):
 | 
			
		||||
        super(CustomAggregateStats, self).__init__()
 | 
			
		||||
        self.results = []
 | 
			
		||||
 | 
			
		||||
    def compute(self, runner_results, setup=False, poll=False,
 | 
			
		||||
                ignore_errors=False):
 | 
			
		||||
        """
 | 
			
		||||
        Walk through all results and increment stats.
 | 
			
		||||
        """
 | 
			
		||||
        super(CustomAggregateStats, self).compute(runner_results, setup, poll,
 | 
			
		||||
                                              ignore_errors)
 | 
			
		||||
 | 
			
		||||
        self.results.append(runner_results)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    def summarize(self, host):
 | 
			
		||||
        """
 | 
			
		||||
        Return information about a particular host
 | 
			
		||||
        """
 | 
			
		||||
        summarized_info = super(CustomAggregateStats, self).summarize(host)
 | 
			
		||||
 | 
			
		||||
        # Adding the info I need
 | 
			
		||||
        summarized_info['result'] = self.results
 | 
			
		||||
 | 
			
		||||
        return summarized_info
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class MyPlaybook(MyInventory):
 | 
			
		||||
    """
 | 
			
		||||
    this is my playbook object for execute playbook.
 | 
			
		||||
    """
 | 
			
		||||
    def __init__(self, *args, **kwargs):
 | 
			
		||||
        super(MyPlaybook, self).__init__(*args, **kwargs)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    def run(self, playbook_relational_path, extra_vars=None):
 | 
			
		||||
        """
 | 
			
		||||
        run ansible playbook,
 | 
			
		||||
        only surport relational path.
 | 
			
		||||
        """
 | 
			
		||||
        stats = callbacks.AggregateStats()
 | 
			
		||||
        playbook_cb = callbacks.PlaybookCallbacks(verbose=utils.VERBOSITY)
 | 
			
		||||
        runner_cb = callbacks.PlaybookRunnerCallbacks(stats, verbose=utils.VERBOSITY)
 | 
			
		||||
        playbook_path = os.path.join(ANSIBLE_DIR, playbook_relational_path)
 | 
			
		||||
 | 
			
		||||
        pb = PlayBook(
 | 
			
		||||
            playbook = playbook_path,
 | 
			
		||||
            stats = stats,
 | 
			
		||||
            callbacks = playbook_cb,
 | 
			
		||||
            runner_callbacks = runner_cb,
 | 
			
		||||
            inventory = self.inventory,
 | 
			
		||||
            extra_vars = extra_vars,
 | 
			
		||||
            check=False)
 | 
			
		||||
 | 
			
		||||
        self.results = pb.run()
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def raw_results(self):
 | 
			
		||||
        """
 | 
			
		||||
        get the raw results after playbook run.
 | 
			
		||||
        """
 | 
			
		||||
        return self.results
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class App(MyPlaybook):
 | 
			
		||||
    """
 | 
			
		||||
    this is a app object for inclue the common playbook.
 | 
			
		||||
    """
 | 
			
		||||
    def __init__(self, *args, **kwargs):
 | 
			
		||||
        super(App, self).__init__(*args, **kwargs)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
if __name__ == "__main__":
 | 
			
		||||
    pass
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,5 +1,9 @@
 | 
			
		|||
# coding: utf-8
 | 
			
		||||
import xlrd
 | 
			
		||||
import xlsxwriter
 | 
			
		||||
from django.db.models import AutoField
 | 
			
		||||
from jumpserver.api import *
 | 
			
		||||
from jasset.models import ASSET_STATUS, ASSET_TYPE, ASSET_ENV, IDC, AssetRecord
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def group_add_asset(group, asset_id=None, asset_ip=None):
 | 
			
		||||
| 
						 | 
				
			
			@ -32,6 +36,21 @@ def db_add_group(**kwargs):
 | 
			
		|||
            group_add_asset(group, asset_id)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def db_update_group(**kwargs):
 | 
			
		||||
    """
 | 
			
		||||
    add a asset group in database
 | 
			
		||||
    数据库中更新资产
 | 
			
		||||
    """
 | 
			
		||||
    group_id = kwargs.pop('id')
 | 
			
		||||
    asset_id_list = kwargs.pop('asset_select')
 | 
			
		||||
    group = get_object(AssetGroup, id=group_id)
 | 
			
		||||
 | 
			
		||||
    for asset_id in asset_id_list:
 | 
			
		||||
        group_add_asset(group, asset_id)
 | 
			
		||||
 | 
			
		||||
    AssetGroup.objects.filter(id=group_id).update(**kwargs)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def db_asset_add(**kwargs):
 | 
			
		||||
    """
 | 
			
		||||
    add asset to db
 | 
			
		||||
| 
						 | 
				
			
			@ -80,11 +99,12 @@ def db_asset_update(**kwargs):
 | 
			
		|||
    asset_id = kwargs.pop('id')
 | 
			
		||||
    Asset.objects.filter(id=asset_id).update(**kwargs)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
#
 | 
			
		||||
# def batch_host_edit(host_info, j_user='', j_password=''):
 | 
			
		||||
# def batch_host_edit(host_alter_dic, j_user='', j_password=''):
 | 
			
		||||
#     """ 批量修改主机函数 """
 | 
			
		||||
#     j_id, j_ip, j_idc, j_port, j_type, j_group, j_dept, j_active, j_comment = host_info
 | 
			
		||||
#     j_id, j_ip, j_idc, j_port, j_type, j_group, j_dept, j_active, j_comment = host_alter_dic
 | 
			
		||||
#     groups, depts = [], []
 | 
			
		||||
#     is_active = {u'是': '1', u'否': '2'}
 | 
			
		||||
#     login_types = {'LDAP': 'L', 'MAP': 'M'}
 | 
			
		||||
| 
						 | 
				
			
			@ -156,3 +176,230 @@ def db_asset_update(**kwargs):
 | 
			
		|||
#     else:
 | 
			
		||||
#         return httperror(request, '删除失败, 没有这个IDC!')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def sort_ip_list(ip_list):
 | 
			
		||||
    """ ip地址排序 """
 | 
			
		||||
    ip_list.sort(key=lambda s: map(int, s.split('.')))
 | 
			
		||||
    return ip_list
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def get_tuple_name(asset_tuple, value):
 | 
			
		||||
    """"""
 | 
			
		||||
    for t in asset_tuple:
 | 
			
		||||
        if t[0] == value:
 | 
			
		||||
            return t[1]
 | 
			
		||||
 | 
			
		||||
    return ''
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def get_tuple_diff(asset_tuple, field_name, value):
 | 
			
		||||
    """"""
 | 
			
		||||
    old_name = get_tuple_name(asset_tuple, int(value[0])) if value[0] else u''
 | 
			
		||||
    new_name = get_tuple_name(asset_tuple, int(value[1])) if value[1] else u''
 | 
			
		||||
    alert_info = [field_name, old_name, new_name]
 | 
			
		||||
    return alert_info
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def asset_diff(before, after):
 | 
			
		||||
    """
 | 
			
		||||
    asset change before and after
 | 
			
		||||
    """
 | 
			
		||||
    alter_dic = {}
 | 
			
		||||
    before_dic, after_dic = before, dict(after.iterlists())
 | 
			
		||||
    for k, v in before_dic.items():
 | 
			
		||||
        after_dic_values = after_dic.get(k, [])
 | 
			
		||||
        if k == 'group':
 | 
			
		||||
            after_dic_value = after_dic_values if len(after_dic_values) > 0 else u''
 | 
			
		||||
            uv = v if v is not None else u''
 | 
			
		||||
        else:
 | 
			
		||||
            after_dic_value = after_dic_values[0] if len(after_dic_values) > 0 else u''
 | 
			
		||||
            uv = unicode(v) if v is not None else u''
 | 
			
		||||
        if uv != after_dic_value:
 | 
			
		||||
            alter_dic.update({k: [uv, after_dic_value]})
 | 
			
		||||
 | 
			
		||||
    for k, v in alter_dic.items():
 | 
			
		||||
        if v == [None, u'']:
 | 
			
		||||
            alter_dic.pop(k)
 | 
			
		||||
 | 
			
		||||
    return alter_dic
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def asset_diff_one(before, after):
 | 
			
		||||
    print before.__dict__, after.__dict__
 | 
			
		||||
    fields = Asset._meta.get_all_field_names()
 | 
			
		||||
    for field in fields:
 | 
			
		||||
        print before.field, after.field
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def db_asset_alert(asset, username, alert_dic):
 | 
			
		||||
    """
 | 
			
		||||
    asset alert info to db
 | 
			
		||||
    """
 | 
			
		||||
    alert_list = []
 | 
			
		||||
    asset_tuple_dic = {'status': ASSET_STATUS, 'env': ASSET_ENV, 'asset_type': ASSET_TYPE}
 | 
			
		||||
    for field, value in alert_dic.iteritems():
 | 
			
		||||
        print field
 | 
			
		||||
        field_name = Asset._meta.get_field_by_name(field)[0].verbose_name
 | 
			
		||||
        if field == 'idc':
 | 
			
		||||
            old = IDC.objects.filter(id=value[0]) if value[0] else u''
 | 
			
		||||
            new = IDC.objects.filter(id=value[1]) if value[1] else u''
 | 
			
		||||
            old_name = old[0].name if old else u''
 | 
			
		||||
            new_name = new[0].name if new else u''
 | 
			
		||||
            alert_info = [field_name, old_name, new_name]
 | 
			
		||||
 | 
			
		||||
        elif field in ['status', 'env', 'asset_type']:
 | 
			
		||||
            alert_info = get_tuple_diff(asset_tuple_dic.get(field), field_name, value)
 | 
			
		||||
 | 
			
		||||
        elif field == 'group':
 | 
			
		||||
            old, new = [], []
 | 
			
		||||
            for group_id in value[0]:
 | 
			
		||||
                group_name = AssetGroup.objects.get(id=int(group_id)).name
 | 
			
		||||
                old.append(group_name)
 | 
			
		||||
            for group_id in value[1]:
 | 
			
		||||
                group_name = AssetGroup.objects.get(id=int(group_id)).name
 | 
			
		||||
                new.append(group_name)
 | 
			
		||||
            if old == new:
 | 
			
		||||
                continue
 | 
			
		||||
            else:
 | 
			
		||||
                alert_info = [field_name, ','.join(old), ','.join(new)]
 | 
			
		||||
 | 
			
		||||
        elif field == 'use_default_auth':
 | 
			
		||||
            if unicode(value[0]) == 'True' and unicode(value[1]) == 'on' or \
 | 
			
		||||
                                    unicode(value[0]) == 'False' and unicode(value[1]) == '':
 | 
			
		||||
                continue
 | 
			
		||||
            else:
 | 
			
		||||
                name = asset.username
 | 
			
		||||
                alert_info = [field_name, u'默认', name] if unicode(value[0]) == 'True' else \
 | 
			
		||||
                    [field_name, name, u'默认']
 | 
			
		||||
 | 
			
		||||
        elif field in ['username', 'password']:
 | 
			
		||||
            continue
 | 
			
		||||
 | 
			
		||||
        elif field == 'is_active':
 | 
			
		||||
            if unicode(value[0]) == 'True' and unicode(value[1]) == '1' or \
 | 
			
		||||
                                    unicode(value[0]) == 'False' and unicode(value[1]) == '0':
 | 
			
		||||
                continue
 | 
			
		||||
            else:
 | 
			
		||||
                alert_info = [u'是否激活', u'激活', u'禁用'] if unicode(value[0]) == 'True' else \
 | 
			
		||||
                    [u'是否激活', u'禁用', u'激活']
 | 
			
		||||
 | 
			
		||||
        else:
 | 
			
		||||
            alert_info = [field_name, unicode(value[0]), unicode(value[1])]
 | 
			
		||||
 | 
			
		||||
        if 'alert_info' in dir():
 | 
			
		||||
            alert_list.append(alert_info)
 | 
			
		||||
 | 
			
		||||
    if alert_list:
 | 
			
		||||
        AssetRecord.objects.create(asset=asset, username=username, content=alert_list)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def write_excel(asset_all):
 | 
			
		||||
    data = []
 | 
			
		||||
    now = datetime.datetime.now().strftime('%Y_%m_%d_%H_%M')
 | 
			
		||||
    file_name = 'cmdb_excel_' + now + '.xlsx'
 | 
			
		||||
    workbook = xlsxwriter.Workbook('static/files/excels/%s' % file_name)
 | 
			
		||||
    worksheet = workbook.add_worksheet(u'CMDB数据')
 | 
			
		||||
    worksheet.set_first_sheet()
 | 
			
		||||
    worksheet.set_column('A:Z', 14)
 | 
			
		||||
    title = [u'主机名', u'IP', u'IDC', u'MAC', u'远控IP', u'CPU', u'内存', u'硬盘', u'操作系统', u'机柜位置',
 | 
			
		||||
             u'所属主机组', u'机器状态', u'备注']
 | 
			
		||||
    for asset in asset_all:
 | 
			
		||||
        group_list = []
 | 
			
		||||
        for p in asset.group.all():
 | 
			
		||||
            group_list.append(p.name)
 | 
			
		||||
 | 
			
		||||
        group_all = '/'.join(group_list)
 | 
			
		||||
        status = asset.get_status_display()
 | 
			
		||||
        idc_name = asset.idc.name if asset.idc else u''
 | 
			
		||||
        alter_dic = [asset.hostname, asset.ip, idc_name, asset.mac, asset.remote_ip, asset.cpu, asset.memory,
 | 
			
		||||
                     asset.disk, (asset.system_type + asset.system_version), asset.cabinet, group_all, status,
 | 
			
		||||
                     asset.comment]
 | 
			
		||||
        data.append(alter_dic)
 | 
			
		||||
    format = workbook.add_format()
 | 
			
		||||
    format.set_border(1)
 | 
			
		||||
    format.set_align('center')
 | 
			
		||||
 | 
			
		||||
    format_title = workbook.add_format()
 | 
			
		||||
    format_title.set_border(1)
 | 
			
		||||
    format_title.set_bg_color('#cccccc')
 | 
			
		||||
    format_title.set_align('center')
 | 
			
		||||
    format_title.set_bold()
 | 
			
		||||
 | 
			
		||||
    format_ave = workbook.add_format()
 | 
			
		||||
    format_ave.set_border(1)
 | 
			
		||||
    format_ave.set_num_format('0.00')
 | 
			
		||||
 | 
			
		||||
    worksheet.write_row('A1', title, format_title)
 | 
			
		||||
    i = 2
 | 
			
		||||
    for alter_dic in data:
 | 
			
		||||
        location = 'A' + str(i)
 | 
			
		||||
        worksheet.write_row(location, alter_dic, format)
 | 
			
		||||
        i += 1
 | 
			
		||||
 | 
			
		||||
    workbook.close()
 | 
			
		||||
    ret = (True, file_name)
 | 
			
		||||
    return ret
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def copy_model_instance(obj):
 | 
			
		||||
    initial = dict([(f.name, getattr(obj, f.name))
 | 
			
		||||
                    for f in obj._meta.fields
 | 
			
		||||
                    if not isinstance(f, AutoField) and \
 | 
			
		||||
                    not f in obj._meta.parents.values()])
 | 
			
		||||
    return obj.__class__(**initial)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def ansible_record(asset, ansible_dic, username):
 | 
			
		||||
    alert_dic = {}
 | 
			
		||||
    asset_dic = asset.__dict__
 | 
			
		||||
    for field, value in ansible_dic.items():
 | 
			
		||||
        old = asset_dic.get(field)
 | 
			
		||||
        new = ansible_dic.get(field)
 | 
			
		||||
        if unicode(old) != unicode(new):
 | 
			
		||||
            print old, new, type(old), type(new)
 | 
			
		||||
            setattr(asset, field, value)
 | 
			
		||||
            asset.save()
 | 
			
		||||
            alert_dic[field] = [old, new]
 | 
			
		||||
 | 
			
		||||
    db_asset_alert(asset, username, alert_dic)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def excel_to_db(excel_file):
 | 
			
		||||
    """
 | 
			
		||||
    Asset add batch function
 | 
			
		||||
    """
 | 
			
		||||
    try:
 | 
			
		||||
        data = xlrd.open_workbook(filename=None, file_contents=excel_file.read())
 | 
			
		||||
    except Exception, e:
 | 
			
		||||
        return False
 | 
			
		||||
 | 
			
		||||
    else:
 | 
			
		||||
        table = data.sheets()[0]
 | 
			
		||||
        rows = table.nrows
 | 
			
		||||
        group_instance = []
 | 
			
		||||
        for row_num in range(1, rows):
 | 
			
		||||
            row = table.row_values(row_num)
 | 
			
		||||
            if row:
 | 
			
		||||
                ip, port, hostname, use_default_auth, username, password, group = row
 | 
			
		||||
                print ip
 | 
			
		||||
                use_default_auth = 1 if use_default_auth == u'默认' else 0
 | 
			
		||||
                if get_object(Asset, ip=ip):
 | 
			
		||||
                    continue
 | 
			
		||||
                if ip and port:
 | 
			
		||||
                    asset = Asset(ip=ip,
 | 
			
		||||
                                  port=port,
 | 
			
		||||
                                  use_default_auth=use_default_auth,
 | 
			
		||||
                                  username=username,
 | 
			
		||||
                                  password=password
 | 
			
		||||
                                  )
 | 
			
		||||
                    asset.save()
 | 
			
		||||
                    group_list = group.split('/')
 | 
			
		||||
                    for group_name in group_list:
 | 
			
		||||
                        group = get_object(AssetGroup, name=group_name)
 | 
			
		||||
                        if group:
 | 
			
		||||
                            group_instance.append(group)
 | 
			
		||||
                    if group_instance:
 | 
			
		||||
                        print group_instance
 | 
			
		||||
                        asset.group = group_instance
 | 
			
		||||
                    asset.save()
 | 
			
		||||
        return True
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,32 @@
 | 
			
		|||
# coding:utf-8
 | 
			
		||||
from django import forms
 | 
			
		||||
 | 
			
		||||
from jasset.models import IDC, Asset, AssetGroup
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class AssetForm(forms.ModelForm):
 | 
			
		||||
 | 
			
		||||
    class Meta:
 | 
			
		||||
        model = Asset
 | 
			
		||||
 | 
			
		||||
        fields = [
 | 
			
		||||
            "ip", "other_ip", "hostname", "port", "group", "username", "password", "use_default_auth",
 | 
			
		||||
            "idc", "mac", "remote_ip", "brand", "cpu", "memory", "disk", "system_type", "system_version",
 | 
			
		||||
            "cabinet", "position", "number", "status", "asset_type", "env", "sn", "is_active", "comment"
 | 
			
		||||
        ]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class AssetGroupForm(forms.ModelForm):
 | 
			
		||||
    class Meta:
 | 
			
		||||
        model = AssetGroup
 | 
			
		||||
        fields = [
 | 
			
		||||
            "name", "comment"
 | 
			
		||||
        ]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class IdcForm(forms.ModelForm):
 | 
			
		||||
    class Meta:
 | 
			
		||||
        model = IDC
 | 
			
		||||
        fields = ['name', "bandwidth", "operator", 'linkman', 'phone', 'address', 'network', 'comment']
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										155
									
								
								jasset/models.py
								
								
								
								
							
							
						
						
									
										155
									
								
								jasset/models.py
								
								
								
								
							| 
						 | 
				
			
			@ -1,6 +1,25 @@
 | 
			
		|||
# coding: utf-8
 | 
			
		||||
 | 
			
		||||
import datetime
 | 
			
		||||
from django.db import models
 | 
			
		||||
# from juser.models import User, UserGroup
 | 
			
		||||
from juser.models import User, UserGroup
 | 
			
		||||
 | 
			
		||||
ASSET_ENV = (
 | 
			
		||||
    (1, U'生产环境'),
 | 
			
		||||
    (2, U'测试环境')
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
ASSET_STATUS = (
 | 
			
		||||
    (1, u"已使用"),
 | 
			
		||||
    (2, u"未使用"),
 | 
			
		||||
    (3, u"报废")
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
ASSET_TYPE = (
 | 
			
		||||
    (1, u"服务器"),
 | 
			
		||||
    (2, u"网络设备"),
 | 
			
		||||
    (3, u"其他")
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class AssetGroup(models.Model):
 | 
			
		||||
| 
						 | 
				
			
			@ -14,86 +33,74 @@ class AssetGroup(models.Model):
 | 
			
		|||
    def __unicode__(self):
 | 
			
		||||
        return self.name
 | 
			
		||||
 | 
			
		||||
    # def get_asset(self):
 | 
			
		||||
    #     return self.asset_set.all()
 | 
			
		||||
    #
 | 
			
		||||
    # def get_asset_info(self, printable=False):
 | 
			
		||||
    #     assets = self.get_asset()
 | 
			
		||||
    #     ip_comment = {}
 | 
			
		||||
    #     for asset in assets:
 | 
			
		||||
    #         ip_comment[asset.ip] = asset.comment
 | 
			
		||||
    #
 | 
			
		||||
    #     for ip in sorted(ip_comment):
 | 
			
		||||
    #         if ip_comment[ip]:
 | 
			
		||||
    #             print '%-15s -- %s' % (ip, ip_comment[ip])
 | 
			
		||||
    #         else:
 | 
			
		||||
    #             print '%-15s' % ip
 | 
			
		||||
    #     print ''
 | 
			
		||||
    #
 | 
			
		||||
    # def get_asset_num(self):
 | 
			
		||||
    #     return len(self.get_asset())
 | 
			
		||||
    #
 | 
			
		||||
    # def get_user_group(self):
 | 
			
		||||
    #     perm_list = self.perm_set.all()
 | 
			
		||||
    #     user_group_list = []
 | 
			
		||||
    #     for perm in perm_list:
 | 
			
		||||
    #         user_group_list.append(perm.user_group)
 | 
			
		||||
    #     return user_group_list
 | 
			
		||||
    #
 | 
			
		||||
    # def get_user(self):
 | 
			
		||||
    #     user_list = []
 | 
			
		||||
    #     user_group_list = self.get_user_group()
 | 
			
		||||
    #     for user_group in user_group_list:
 | 
			
		||||
    #         user_list.extend(user_group.user_set.all())
 | 
			
		||||
    #     return user_list
 | 
			
		||||
    #
 | 
			
		||||
    # def is_permed(self, user=None, user_group=None):
 | 
			
		||||
    #     if user:
 | 
			
		||||
    #         if user in self.get_user():
 | 
			
		||||
    #             return True
 | 
			
		||||
    #
 | 
			
		||||
    #     if user_group:
 | 
			
		||||
    #         if user_group in self.get_user_group():
 | 
			
		||||
    #             return True
 | 
			
		||||
    #     return False
 | 
			
		||||
 | 
			
		||||
class IDC(models.Model):
 | 
			
		||||
    name = models.CharField(max_length=32, verbose_name=u'机房名称')
 | 
			
		||||
    bandwidth = models.CharField(max_length=32, blank=True, null=True, verbose_name=u'机房带宽')
 | 
			
		||||
    linkman = models.CharField(max_length=16, null=True, verbose_name=u'联系人')
 | 
			
		||||
    phone = models.CharField(max_length=32, verbose_name=u'联系电话')
 | 
			
		||||
    address = models.CharField(max_length=128, blank=True, null=True, verbose_name=u"机房地址")
 | 
			
		||||
    network = models.TextField(blank=True, null=True, verbose_name=u"IP地址段")
 | 
			
		||||
    date_added = models.DateField(auto_now=True, default=datetime.datetime.now(), null=True)
 | 
			
		||||
    operator = models.IntegerField(max_length=32, blank=True, null=True, verbose_name=u"运营商")
 | 
			
		||||
    comment = models.CharField(max_length=128, blank=True, null=True, verbose_name=u"备注")
 | 
			
		||||
 | 
			
		||||
    def __unicode__(self):
 | 
			
		||||
        return self.name
 | 
			
		||||
 | 
			
		||||
    class Meta:
 | 
			
		||||
        verbose_name = u"IDC机房"
 | 
			
		||||
        verbose_name_plural = verbose_name
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Asset(models.Model):
 | 
			
		||||
    ip = models.GenericIPAddressField(unique=True)
 | 
			
		||||
    port = models.IntegerField()
 | 
			
		||||
    group = models.ManyToManyField(AssetGroup)
 | 
			
		||||
    username = models.CharField(max_length=20, blank=True, null=True)
 | 
			
		||||
    password = models.CharField(max_length=80, blank=True, null=True)
 | 
			
		||||
    use_default_auth = models.BooleanField(default=True)
 | 
			
		||||
    date_added = models.DateTimeField(auto_now_add=True)
 | 
			
		||||
    is_active = models.BooleanField(default=True)
 | 
			
		||||
    comment = models.CharField(max_length=100, blank=True, null=True)
 | 
			
		||||
    """
 | 
			
		||||
    asset modle
 | 
			
		||||
    """
 | 
			
		||||
    ip = models.IPAddressField(unique=True, verbose_name=u"主机IP")
 | 
			
		||||
    other_ip = models.CharField(max_length=255, blank=True, null=True, verbose_name=u"其他IP")
 | 
			
		||||
    hostname = models.CharField(max_length=64, blank=True, null=True, verbose_name=u"主机名")
 | 
			
		||||
    port = models.IntegerField(max_length=6, verbose_name=u"端口号")
 | 
			
		||||
    group = models.ManyToManyField(AssetGroup, blank=True, null=True, verbose_name=u"所属主机组")
 | 
			
		||||
    username = models.CharField(max_length=16, blank=True, null=True, verbose_name=u"管理用户名")
 | 
			
		||||
    password = models.CharField(max_length=64, blank=True, null=True, verbose_name=u"密码")
 | 
			
		||||
    use_default_auth = models.BooleanField(default=True, verbose_name=u"使用默认管理账号")
 | 
			
		||||
    idc = models.ForeignKey(IDC, blank=True, null=True,  on_delete=models.SET_NULL, verbose_name=u'机房')
 | 
			
		||||
    mac = models.CharField(max_length=20, blank=True, null=True, verbose_name=u"MAC地址")
 | 
			
		||||
    remote_ip = models.CharField(max_length=16, blank=True, null=True, verbose_name=u'远控卡')
 | 
			
		||||
    brand = models.CharField(max_length=64, blank=True, null=True, verbose_name=u'硬件厂商型号')
 | 
			
		||||
    cpu = models.CharField(max_length=64, blank=True, null=True, verbose_name=u'CPU')
 | 
			
		||||
    memory = models.CharField(max_length=128, blank=True, null=True, verbose_name=u'内存')
 | 
			
		||||
    disk = models.CharField(max_length=128, blank=True, null=True, verbose_name=u'硬盘')
 | 
			
		||||
    system_type = models.CharField(max_length=32, blank=True, null=True, verbose_name=u"系统类型")
 | 
			
		||||
    system_version = models.CharField(max_length=8, blank=True, null=True, verbose_name=u"版本号")
 | 
			
		||||
    cabinet = models.CharField(max_length=32, blank=True, null=True, verbose_name=u'机柜号')
 | 
			
		||||
    position = models.IntegerField(max_length=2, blank=True, null=True, verbose_name=u'机器位置')
 | 
			
		||||
    number = models.CharField(max_length=32, blank=True, null=True, verbose_name=u'资产编号')
 | 
			
		||||
    status = models.IntegerField(max_length=2, choices=ASSET_STATUS, blank=True, null=True, default=1, verbose_name=u"机器状态")
 | 
			
		||||
    asset_type = models.IntegerField(max_length=2, choices=ASSET_TYPE, blank=True, null=True, verbose_name=u"主机类型")
 | 
			
		||||
    env = models.IntegerField(max_length=2, choices=ASSET_ENV, blank=True, null=True, verbose_name=u"运行环境")
 | 
			
		||||
    sn = models.CharField(max_length=128, blank=True, null=True, verbose_name=u"SN编号")
 | 
			
		||||
    date_added = models.DateTimeField(auto_now=True, default=datetime.datetime.now(), null=True)
 | 
			
		||||
    is_active = models.BooleanField(default=True, verbose_name=u"是否激活")
 | 
			
		||||
    comment = models.CharField(max_length=128, blank=True, null=True, verbose_name=u"备注")
 | 
			
		||||
 | 
			
		||||
    def __unicode__(self):
 | 
			
		||||
        return self.ip
 | 
			
		||||
 | 
			
		||||
    # def get_user(self):
 | 
			
		||||
    #     perm_list = []
 | 
			
		||||
    #     asset_group_all = self.bis_group.all()
 | 
			
		||||
    #     for asset_group in asset_group_all:
 | 
			
		||||
    #         perm_list.extend(asset_group.perm_set.all())
 | 
			
		||||
    #
 | 
			
		||||
    #     user_group_list = []
 | 
			
		||||
    #     for perm in perm_list:
 | 
			
		||||
    #         user_group_list.append(perm.user_group)
 | 
			
		||||
    #
 | 
			
		||||
    #     user_permed_list = []
 | 
			
		||||
    #     for user_group in user_group_list:
 | 
			
		||||
    #         user_permed_list.extend(user_group.user_set.all())
 | 
			
		||||
    #     user_permed_list = list(set(user_permed_list))
 | 
			
		||||
    #     return user_permed_list
 | 
			
		||||
 | 
			
		||||
class AssetRecord(models.Model):
 | 
			
		||||
    asset = models.ForeignKey(Asset)
 | 
			
		||||
    username = models.CharField(max_length=30, null=True)
 | 
			
		||||
    alert_time = models.DateTimeField(auto_now_add=True)
 | 
			
		||||
    content = models.TextField(null=True, blank=True)
 | 
			
		||||
    comment = models.TextField(null=True, blank=True)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class AssetAlias(models.Model):
 | 
			
		||||
    pass
 | 
			
		||||
#     user = models.ForeignKey(User)
 | 
			
		||||
#     asset = models.ForeignKey(Asset)
 | 
			
		||||
#     alias = models.CharField(max_length=100, blank=True, null=True)
 | 
			
		||||
#
 | 
			
		||||
#     def __unicode__(self):
 | 
			
		||||
#         return self.alias
 | 
			
		||||
    user = models.ForeignKey(User)
 | 
			
		||||
    asset = models.ForeignKey(Asset)
 | 
			
		||||
    alias = models.CharField(max_length=100, blank=True, null=True)
 | 
			
		||||
 | 
			
		||||
    def __unicode__(self):
 | 
			
		||||
        return self.alias
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,23 +4,27 @@ from jasset.views import *
 | 
			
		|||
 | 
			
		||||
urlpatterns = patterns('',
 | 
			
		||||
    url(r'^asset_add/$', asset_add),
 | 
			
		||||
    # url(r"^host_add_multi/$", host_add_batch),
 | 
			
		||||
    url(r'^group_add/$', group_add),
 | 
			
		||||
    url(r'^group_list/$', group_list),
 | 
			
		||||
    url(r"^asset_add_batch/$", asset_add_batch),
 | 
			
		||||
    url(r'^group_del/$', group_del),
 | 
			
		||||
    url(r'^asset_list/$', asset_list),
 | 
			
		||||
    url(r'^asset_del/$', asset_del),
 | 
			
		||||
    url(r"^asset_detail/$", asset_detail),
 | 
			
		||||
    url(r'^asset_edit/$', asset_edit),
 | 
			
		||||
    url(r'^asset_update/$', asset_update),
 | 
			
		||||
    # url(r'^search/$', host_search),
 | 
			
		||||
    # url(r"^host_detail/$", host_detail),
 | 
			
		||||
    # url(r"^dept_host_ajax/$", dept_host_ajax),
 | 
			
		||||
    # url(r"^show_all_ajax/$", show_all_ajax),
 | 
			
		||||
    # url(r'^group_edit/$', group_edit),
 | 
			
		||||
    # url(r'^group_list/$', group_list),
 | 
			
		||||
    # url(r'^group_detail/$', group_detail),
 | 
			
		||||
    url(r'^group_add/$', group_add),
 | 
			
		||||
    url(r'^group_list/$', group_list),
 | 
			
		||||
    url(r'^group_edit/$', group_edit),
 | 
			
		||||
    url(r'^group_list/$', group_list),
 | 
			
		||||
    url(r'^group_detail/$', group_detail),
 | 
			
		||||
    # url(r'^group_del_host/$', group_del_host),
 | 
			
		||||
 | 
			
		||||
    # url(r'^host_edit/batch/$', host_edit_batch),
 | 
			
		||||
    url(r'^asset_edit_batch/$', asset_edit_batch),
 | 
			
		||||
    # url(r'^host_edit_common/batch/$', host_edit_common_batch),
 | 
			
		||||
    url(r'^idc_add/$', idc_add),
 | 
			
		||||
    url(r'^idc_list/$', idc_list),
 | 
			
		||||
    url(r'^idc_detail/$', idc_detail),
 | 
			
		||||
    url(r'^idc_edit/$', idc_edit),
 | 
			
		||||
    url(r'^idc_del/$', idc_del),
 | 
			
		||||
    url(r'^upload/$', asset_upload),
 | 
			
		||||
)
 | 
			
		||||
							
								
								
									
										396
									
								
								jasset/views.py
								
								
								
								
							
							
						
						
									
										396
									
								
								jasset/views.py
								
								
								
								
							| 
						 | 
				
			
			@ -1,13 +1,13 @@
 | 
			
		|||
# coding:utf-8
 | 
			
		||||
 | 
			
		||||
import ast
 | 
			
		||||
 | 
			
		||||
from django.db.models import Q
 | 
			
		||||
from django.template import RequestContext
 | 
			
		||||
from django.shortcuts import get_object_or_404
 | 
			
		||||
 | 
			
		||||
from jasset.asset_api import *
 | 
			
		||||
from jumpserver.api import *
 | 
			
		||||
from jasset.forms import AssetForm, IdcForm
 | 
			
		||||
from jasset.models import Asset, IDC, AssetGroup, ASSET_TYPE, ASSET_STATUS
 | 
			
		||||
from ansible_api import Tasks
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@require_role('admin')
 | 
			
		||||
| 
						 | 
				
			
			@ -36,13 +36,69 @@ def group_add(request):
 | 
			
		|||
 | 
			
		||||
        except ServerError:
 | 
			
		||||
            pass
 | 
			
		||||
 | 
			
		||||
        else:
 | 
			
		||||
            db_add_group(name=name, comment=comment, asset_select=asset_select)
 | 
			
		||||
            msg = u"主机组 %s 添加成功" % name
 | 
			
		||||
            smg = u"主机组 %s 添加成功" % name
 | 
			
		||||
 | 
			
		||||
    return my_render('jasset/group_add.html', locals(), request)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@require_role('admin')
 | 
			
		||||
def group_edit(request):
 | 
			
		||||
    """
 | 
			
		||||
    Edit asset group
 | 
			
		||||
    编辑资产组
 | 
			
		||||
    """
 | 
			
		||||
    header_title, path1, path2 = u'编辑主机组', u'资产管理', u'编辑主机组'
 | 
			
		||||
    group_id = request.GET.get('id', '')
 | 
			
		||||
    group = get_object(AssetGroup, id=group_id)
 | 
			
		||||
 | 
			
		||||
    asset_all = Asset.objects.all()
 | 
			
		||||
    asset_select = Asset.objects.filter(group=group)
 | 
			
		||||
    asset_no_select = [a for a in asset_all if a not in asset_select]
 | 
			
		||||
 | 
			
		||||
    if request.method == 'POST':
 | 
			
		||||
        name = request.POST.get('name', '')
 | 
			
		||||
        asset_select = request.POST.getlist('asset_select', [])
 | 
			
		||||
        comment = request.POST.get('comment', '')
 | 
			
		||||
 | 
			
		||||
        try:
 | 
			
		||||
            if not name:
 | 
			
		||||
                emg = u'组名不能为空'
 | 
			
		||||
                raise ServerError(emg)
 | 
			
		||||
 | 
			
		||||
            if group.name != name:
 | 
			
		||||
                asset_group_test = get_object(AssetGroup, name=name)
 | 
			
		||||
                if asset_group_test:
 | 
			
		||||
                    emg = u"该组名 %s 已存在" % name
 | 
			
		||||
                    raise ServerError(emg)
 | 
			
		||||
 | 
			
		||||
        except ServerError:
 | 
			
		||||
            pass
 | 
			
		||||
 | 
			
		||||
        else:
 | 
			
		||||
            group.asset_set.clear()
 | 
			
		||||
            db_update_group(id=group_id, name=name, comment=comment, asset_select=asset_select)
 | 
			
		||||
            smg = u"主机组 %s 添加成功" % name
 | 
			
		||||
 | 
			
		||||
        return HttpResponseRedirect('/jasset/group_list')
 | 
			
		||||
 | 
			
		||||
    return my_render('jasset/group_edit.html', locals(), request)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@require_role('admin')
 | 
			
		||||
def group_detail(request):
 | 
			
		||||
    """ 主机组详情 """
 | 
			
		||||
    header_title, path1, path2 = u'主机组详情', u'资产管理', u'主机组详情'
 | 
			
		||||
    group_id = request.GET.get('id', '')
 | 
			
		||||
    group = get_object(AssetGroup, id=group_id)
 | 
			
		||||
    asset_all = Asset.objects.filter(group=group).order_by('ip')
 | 
			
		||||
 | 
			
		||||
    contact_list, p, contacts, page_range, current_page, show_first, show_end = pages(asset_all, request)
 | 
			
		||||
    return my_render('jasset/group_detail.html', locals(), request)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@require_role('admin')
 | 
			
		||||
def group_list(request):
 | 
			
		||||
    """
 | 
			
		||||
| 
						 | 
				
			
			@ -85,23 +141,13 @@ def asset_add(request):
 | 
			
		|||
    """
 | 
			
		||||
    header_title, path1, path2 = u'添加资产', u'资产管理', u'添加资产'
 | 
			
		||||
    asset_group_all = AssetGroup.objects.all()
 | 
			
		||||
    af = AssetForm()
 | 
			
		||||
    if request.method == 'POST':
 | 
			
		||||
        ip = request.POST.get('ip')
 | 
			
		||||
        groups = request.POST.getlist('groups')
 | 
			
		||||
        use_default = True if request.POST.getlist('use_default', []) else False
 | 
			
		||||
        is_active = True if request.POST.get('is_active') else False
 | 
			
		||||
        comment = request.POST.get('comment')
 | 
			
		||||
 | 
			
		||||
        if not use_default:
 | 
			
		||||
            username = request.POST.get('username')
 | 
			
		||||
            password = request.POST.get('password')
 | 
			
		||||
            port = request.POST.get('port')
 | 
			
		||||
            password_encode = password
 | 
			
		||||
        else:
 | 
			
		||||
            username = None
 | 
			
		||||
            port = None
 | 
			
		||||
            password_encode = None
 | 
			
		||||
 | 
			
		||||
        af_post = AssetForm(request.POST)
 | 
			
		||||
        print af_post
 | 
			
		||||
        ip = request.POST.get('ip', '')
 | 
			
		||||
        is_active = True if request.POST.get('is_active') == '1' else False
 | 
			
		||||
        use_default_auth = request.POST.get('use_default_auth', '')
 | 
			
		||||
        try:
 | 
			
		||||
            if Asset.objects.filter(ip=str(ip)):
 | 
			
		||||
                error = u'该IP %s 已存在!' % ip
 | 
			
		||||
| 
						 | 
				
			
			@ -110,34 +156,27 @@ def asset_add(request):
 | 
			
		|||
        except ServerError:
 | 
			
		||||
            pass
 | 
			
		||||
        else:
 | 
			
		||||
            db_asset_add(
 | 
			
		||||
                ip=ip, port=port, use_default=use_default, is_active=is_active, comment=comment,
 | 
			
		||||
                groups=groups, username=username, password=password_encode
 | 
			
		||||
            )
 | 
			
		||||
            if af_post.is_valid():
 | 
			
		||||
                asset_save = af_post.save(commit=False)
 | 
			
		||||
                if not use_default_auth:
 | 
			
		||||
                    password = request.POST.get('password', '')
 | 
			
		||||
                    password_encode = CRYPTOR.encrypt(password)
 | 
			
		||||
                    asset_save.password = password_encode
 | 
			
		||||
                asset_save.is_active = True if is_active else False
 | 
			
		||||
                asset_save.save()
 | 
			
		||||
                af_post.save_m2m()
 | 
			
		||||
 | 
			
		||||
                msg = u'主机 %s 添加成功' % ip
 | 
			
		||||
            else:
 | 
			
		||||
                esg = u'主机 %s 添加失败' % ip
 | 
			
		||||
 | 
			
		||||
    return my_render('jasset/asset_add.html', locals(), request)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@require_role(role='user')
 | 
			
		||||
def asset_list(request):
 | 
			
		||||
    """
 | 
			
		||||
    list assets
 | 
			
		||||
    列出资产表
 | 
			
		||||
    """
 | 
			
		||||
    header_title, path1, path2 = u'查看主机', u'资产管理', u'查看主机'
 | 
			
		||||
    keyword = request.GET.get('keyword', '')
 | 
			
		||||
    gid = request.GET.get('gid', '')  # asset group id
 | 
			
		||||
    sid = request.GET.get('sid', '')
 | 
			
		||||
    assets_list = Asset.objects.all().order_by('ip')
 | 
			
		||||
 | 
			
		||||
    if keyword:
 | 
			
		||||
        assets_list = assets_list.filter(Q(ip__contains=keyword) |
 | 
			
		||||
                                        Q(comment__contains=keyword)).distinct().order_by('ip')
 | 
			
		||||
 | 
			
		||||
    assets_list, p, assets, page_range, current_page, show_first, show_end = pages(assets_list, request)
 | 
			
		||||
    return my_render('jasset/asset_list.html', locals(), request)
 | 
			
		||||
@require_role('admin')
 | 
			
		||||
def asset_add_batch(request):
 | 
			
		||||
    header_title, path1, path2 = u'添加资产', u'资产管理', u'批量添加'
 | 
			
		||||
    return my_render('jasset/asset_add_batch.html', locals(), request)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@require_role('admin')
 | 
			
		||||
| 
						 | 
				
			
			@ -149,64 +188,279 @@ def asset_del(request):
 | 
			
		|||
    asset_id = request.GET.get('id', '')
 | 
			
		||||
    if asset_id:
 | 
			
		||||
        Asset.objects.filter(id=asset_id).delete()
 | 
			
		||||
 | 
			
		||||
    if request.method == 'POST':
 | 
			
		||||
        asset_batch = request.GET.get('arg', '')
 | 
			
		||||
        asset_id_all = str(request.POST.get('asset_id_all', ''))
 | 
			
		||||
 | 
			
		||||
        if asset_batch:
 | 
			
		||||
            for asset_id in asset_id_all.split(','):
 | 
			
		||||
                asset = get_object(Asset, id=asset_id)
 | 
			
		||||
                asset.delete()
 | 
			
		||||
 | 
			
		||||
    return HttpResponse(u'删除成功')
 | 
			
		||||
    return Http404
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@require_role(role='super')
 | 
			
		||||
def asset_edit(request):
 | 
			
		||||
    """ 修改主机 """
 | 
			
		||||
    """
 | 
			
		||||
    edit a asset
 | 
			
		||||
    修改主机
 | 
			
		||||
    """
 | 
			
		||||
    header_title, path1, path2 = u'修改资产', u'资产管理', u'修改资产'
 | 
			
		||||
 | 
			
		||||
    asset_id = request.GET.get('id', '')
 | 
			
		||||
    if not asset_id:
 | 
			
		||||
        return HttpResponse('没有该主机')
 | 
			
		||||
    username = request.session.get('username', 'admin')
 | 
			
		||||
    asset = get_object(Asset, id=asset_id)
 | 
			
		||||
 | 
			
		||||
    asset_old = copy_model_instance(asset)
 | 
			
		||||
    af = AssetForm(instance=asset)
 | 
			
		||||
    if request.method == 'POST':
 | 
			
		||||
        ip = request.POST.get('ip')
 | 
			
		||||
        groups = request.POST.getlist('groups')
 | 
			
		||||
        use_default = True if request.POST.getlist('use_default', []) else False
 | 
			
		||||
        is_active = True if request.POST.get('is_active') else False
 | 
			
		||||
        comment = request.POST.get('comment')
 | 
			
		||||
 | 
			
		||||
        if not use_default:
 | 
			
		||||
            username = request.POST.get('username')
 | 
			
		||||
            password = request.POST.get('password')
 | 
			
		||||
            port = request.POST.get('port')
 | 
			
		||||
            if password == asset.password:
 | 
			
		||||
                password_encode = password
 | 
			
		||||
            else:
 | 
			
		||||
                password_encode = CRYPTOR.encrypt(password)
 | 
			
		||||
        else:
 | 
			
		||||
            username = None
 | 
			
		||||
            password_encode = None
 | 
			
		||||
            port = 22
 | 
			
		||||
 | 
			
		||||
        af_post = AssetForm(request.POST, instance=asset)
 | 
			
		||||
        ip = request.POST.get('ip', '')
 | 
			
		||||
        use_default_auth = request.POST.get('use_default_auth')
 | 
			
		||||
        try:
 | 
			
		||||
            asset_test = get_object(Asset, ip=ip)
 | 
			
		||||
            if asset_test and asset_id != str(asset_test.id):
 | 
			
		||||
            if asset_test and asset_id != unicode(asset_test.id):
 | 
			
		||||
                error = u'该IP %s 已存在!' % ip
 | 
			
		||||
                raise ServerError(error)
 | 
			
		||||
        except ServerError:
 | 
			
		||||
            pass
 | 
			
		||||
        else:
 | 
			
		||||
            db_asset_update(id=asset_id, ip=ip, port=port, use_default=use_default,
 | 
			
		||||
                            username=username, password=password_encode,
 | 
			
		||||
                            is_active=is_active, comment=comment)
 | 
			
		||||
            if af_post.is_valid():
 | 
			
		||||
                af_save = af_post.save(commit=False)
 | 
			
		||||
                if use_default_auth:
 | 
			
		||||
                    af_save.username = ''
 | 
			
		||||
                    af_save.password = ''
 | 
			
		||||
                af_save.save()
 | 
			
		||||
                af_post.save_m2m()
 | 
			
		||||
                # asset_new = get_object(Asset, id=asset_id)
 | 
			
		||||
                # asset_diff_one(asset_old, asset_new)
 | 
			
		||||
                info = asset_diff(af_post.__dict__.get('initial'), request.POST)
 | 
			
		||||
                db_asset_alert(asset, username, info)
 | 
			
		||||
 | 
			
		||||
                msg = u'主机 %s 修改成功' % ip
 | 
			
		||||
            else:
 | 
			
		||||
                emg = u'主机 %s 修改失败' % ip
 | 
			
		||||
            return HttpResponseRedirect('/jasset/asset_detail/?id=%s' % asset_id)
 | 
			
		||||
 | 
			
		||||
    return my_render('jasset/asset_edit.html', locals(), request)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@require_role('user')
 | 
			
		||||
def asset_list(request):
 | 
			
		||||
    """
 | 
			
		||||
    asset list view
 | 
			
		||||
    """
 | 
			
		||||
    idc_all = IDC.objects.filter()
 | 
			
		||||
    asset_group_all = AssetGroup.objects.all()
 | 
			
		||||
    asset_types = ASSET_TYPE
 | 
			
		||||
    asset_status = ASSET_STATUS
 | 
			
		||||
 | 
			
		||||
    idc_name = request.GET.get('idc', '')
 | 
			
		||||
    group_name = request.GET.get('group', '')
 | 
			
		||||
    asset_type = request.GET.get('asset_type', '')
 | 
			
		||||
    status = request.GET.get('status', '')
 | 
			
		||||
    keyword = request.GET.get('keyword', '')
 | 
			
		||||
    export = request.GET.get("export", False)
 | 
			
		||||
 | 
			
		||||
    asset_find = Asset.objects.all()
 | 
			
		||||
    if idc_name:
 | 
			
		||||
        asset_find = asset_find.filter(idc__name__contains=idc_name)
 | 
			
		||||
 | 
			
		||||
    if group_name:
 | 
			
		||||
        asset_find = asset_find.filter(group__name__contains=group_name)
 | 
			
		||||
 | 
			
		||||
    if asset_type:
 | 
			
		||||
        asset_find = asset_find.filter(asset_type__contains=asset_type)
 | 
			
		||||
 | 
			
		||||
    if status:
 | 
			
		||||
        asset_find = asset_find.filter(status__contains=status)
 | 
			
		||||
 | 
			
		||||
    if keyword:
 | 
			
		||||
        asset_find = asset_find.filter(
 | 
			
		||||
            Q(hostname__contains=keyword) |
 | 
			
		||||
            Q(other_ip__contains=keyword) |
 | 
			
		||||
            Q(ip__contains=keyword) |
 | 
			
		||||
            Q(remote_ip__contains=keyword) |
 | 
			
		||||
            Q(comment__contains=keyword) |
 | 
			
		||||
            Q(group__name__contains=keyword) |
 | 
			
		||||
            Q(cpu__contains=keyword) |
 | 
			
		||||
            Q(memory__contains=keyword) |
 | 
			
		||||
            Q(disk__contains=keyword))
 | 
			
		||||
 | 
			
		||||
    if export:
 | 
			
		||||
        s = write_excel(asset_find)
 | 
			
		||||
        if s[0]:
 | 
			
		||||
            file_name = s[1]
 | 
			
		||||
        smg = 'excel文件已生成,请点击下载!'
 | 
			
		||||
        return my_render('jasset/asset_excel_download.html', locals(), request)
 | 
			
		||||
    assets_list, p, assets, page_range, current_page, show_first, show_end = pages(asset_find, request)
 | 
			
		||||
    return my_render('jasset/asset_list.html', locals(), request)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@require_role('admin')
 | 
			
		||||
def asset_edit_batch(request):
 | 
			
		||||
    af = AssetForm()
 | 
			
		||||
    asset_group_all = AssetGroup.objects.all()
 | 
			
		||||
    return my_render('jasset/asset_edit_batch.html', locals(), request)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@require_role('admin')
 | 
			
		||||
def asset_detail(request):
 | 
			
		||||
    """ 主机详情 """
 | 
			
		||||
    """
 | 
			
		||||
    Asset detail view
 | 
			
		||||
    """
 | 
			
		||||
    header_title, path1, path2 = u'主机详细信息', u'资产管理', u'主机详情'
 | 
			
		||||
    asset_id = request.GET.get('id', '')
 | 
			
		||||
    asset = get_object(Asset, id=asset_id)
 | 
			
		||||
    asset_record = AssetRecord.objects.filter(asset=asset).order_by('-alert_time')
 | 
			
		||||
 | 
			
		||||
    return my_render('jasset/asset_detail.html', locals(), request)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@require_role('admin')
 | 
			
		||||
def asset_update(request):
 | 
			
		||||
    """
 | 
			
		||||
    Asset update host info via ansible view
 | 
			
		||||
    """
 | 
			
		||||
    asset_id = request.GET.get('id', '')
 | 
			
		||||
    asset = get_object(Asset, id=asset_id)
 | 
			
		||||
    if not asset:
 | 
			
		||||
        return HttpResponseRedirect('/jasset/asset_detail/?id=%s' % asset_id)
 | 
			
		||||
    name = request.session.get('username', 'admin')
 | 
			
		||||
    if asset.use_default_auth:
 | 
			
		||||
        username = 'root'
 | 
			
		||||
        password = '123456'
 | 
			
		||||
    else:
 | 
			
		||||
        username = asset.username
 | 
			
		||||
        password = asset.password
 | 
			
		||||
 | 
			
		||||
    resource = [{"hostname": asset.ip, "port": asset.port,
 | 
			
		||||
                 "username": username, "password": password}]
 | 
			
		||||
 | 
			
		||||
    ansible_instance = Tasks(resource)
 | 
			
		||||
    ansible_asset_info = ansible_instance.get_host_info()
 | 
			
		||||
    if ansible_asset_info['status'] == 'ok':
 | 
			
		||||
        asset_info = ansible_asset_info['result'][asset.ip]
 | 
			
		||||
        if asset_info:
 | 
			
		||||
            hostname = asset_info.get('hostname')
 | 
			
		||||
            other_ip = ','.join(asset_info.get('other_ip'))
 | 
			
		||||
            cpu_type = asset_info.get('cpu_type')[1]
 | 
			
		||||
            cpu_cores = asset_info.get('cpu_cores')
 | 
			
		||||
            cpu = cpu_type + ' * ' + unicode(cpu_cores)
 | 
			
		||||
            memory = asset_info.get('memory')
 | 
			
		||||
            disk = asset_info.get('disk')
 | 
			
		||||
            sn = asset_info.get('sn')
 | 
			
		||||
            brand = asset_info.get('brand')
 | 
			
		||||
            system_type = asset_info.get('system_type')
 | 
			
		||||
            system_version = asset_info.get('system_version')
 | 
			
		||||
 | 
			
		||||
            asset_dic = {"hostname": hostname, "other_ip": other_ip, "cpu": cpu,
 | 
			
		||||
                         "memory": memory, "disk": disk, "system_type": system_type,
 | 
			
		||||
                         "system_version": system_version, "brand": brand, "sn": sn
 | 
			
		||||
                         }
 | 
			
		||||
 | 
			
		||||
            ansible_record(asset, asset_dic, name)
 | 
			
		||||
 | 
			
		||||
    return HttpResponseRedirect('/jasset/asset_detail/?id=%s' % asset_id)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@require_role('admin')
 | 
			
		||||
def idc_add(request):
 | 
			
		||||
    """
 | 
			
		||||
    IDC add view
 | 
			
		||||
    """
 | 
			
		||||
    header_title, path1, path2 = u'添加IDC', u'资产管理', u'添加IDC'
 | 
			
		||||
    if request.method == 'POST':
 | 
			
		||||
        idc_form = IdcForm(request.POST)
 | 
			
		||||
        if idc_form.is_valid():
 | 
			
		||||
            idc_name = idc_form.cleaned_data['name']
 | 
			
		||||
 | 
			
		||||
            if IDC.objects.filter(name=idc_name):
 | 
			
		||||
                emg = u'添加失败, 此IDC %s 已存在!' % idc_name
 | 
			
		||||
                return my_render('jasset/idc_add.html', locals(), request)
 | 
			
		||||
            else:
 | 
			
		||||
                idc_form.save()
 | 
			
		||||
                smg = u'IDC: %s添加成功' % idc_name
 | 
			
		||||
            return HttpResponseRedirect("/jasset/idc_list/")
 | 
			
		||||
    else:
 | 
			
		||||
        idc_form = IdcForm()
 | 
			
		||||
    return render_to_response('jasset/idc_add.html',
 | 
			
		||||
                              locals(),
 | 
			
		||||
                              context_instance=RequestContext(request))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@require_role('admin')
 | 
			
		||||
def idc_list(request):
 | 
			
		||||
    """
 | 
			
		||||
    IDC list view
 | 
			
		||||
    """
 | 
			
		||||
    header_title, path1, path2 = u'查看IDC', u'资产管理', u'查看IDC'
 | 
			
		||||
    posts = IDC.objects.all()
 | 
			
		||||
    keyword = request.GET.get('keyword', '')
 | 
			
		||||
    if keyword:
 | 
			
		||||
        posts = IDC.objects.filter(Q(name__contains=keyword) | Q(comment__contains=keyword))
 | 
			
		||||
    else:
 | 
			
		||||
        posts = IDC.objects.exclude(name='ALL').order_by('id')
 | 
			
		||||
    contact_list, p, contacts, page_range, current_page, show_first, show_end = pages(posts, request)
 | 
			
		||||
    return render_to_response('jasset/idc_list.html',
 | 
			
		||||
                              locals(),
 | 
			
		||||
                              context_instance=RequestContext(request))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@require_role('admin')
 | 
			
		||||
def idc_edit(request):
 | 
			
		||||
    """
 | 
			
		||||
    IDC edit view
 | 
			
		||||
    """
 | 
			
		||||
    header_title, path1, path2 = u'编辑IDC', u'资产管理', u'编辑IDC'
 | 
			
		||||
    idc_id = request.GET.get('id', '')
 | 
			
		||||
    idc = get_object(IDC, id=idc_id)
 | 
			
		||||
    if request.method == 'POST':
 | 
			
		||||
        idc_form = IdcForm(request.POST, instance=idc)
 | 
			
		||||
        if idc_form.is_valid():
 | 
			
		||||
            idc_form.save()
 | 
			
		||||
            return HttpResponseRedirect("/jasset/idc_list/")
 | 
			
		||||
    else:
 | 
			
		||||
        idc_form = IdcForm(instance=idc)
 | 
			
		||||
        return my_render('jasset/idc_edit.html', locals(), request)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@require_role('admin')
 | 
			
		||||
def idc_detail(request):
 | 
			
		||||
    """
 | 
			
		||||
    IDC detail view
 | 
			
		||||
    """
 | 
			
		||||
    header_title, path1, path2 = u'IDC详情', u'资产管理', u'IDC详情'
 | 
			
		||||
    idc_id = request.GET.get('id', '')
 | 
			
		||||
    idc = get_object(IDC, id=idc_id)
 | 
			
		||||
    posts = Asset.objects.filter(idc=idc).order_by('ip')
 | 
			
		||||
    contact_list, p, contacts, page_range, current_page, show_first, show_end = pages(posts, request)
 | 
			
		||||
 | 
			
		||||
    return my_render('jasset/idc_detail.html', locals(), request)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@require_role('admin')
 | 
			
		||||
def idc_del(request):
 | 
			
		||||
    """
 | 
			
		||||
    IDC delete view
 | 
			
		||||
    """
 | 
			
		||||
    uuid = request.GET.get('uuid', '')
 | 
			
		||||
    idc = get_object_or_404(IDC, uuid=uuid)
 | 
			
		||||
    idc.delete()
 | 
			
		||||
    return HttpResponseRedirect('/jasset/idc_list/')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@require_role('admin')
 | 
			
		||||
def asset_upload(request):
 | 
			
		||||
    """
 | 
			
		||||
    Upload file view
 | 
			
		||||
    """
 | 
			
		||||
    if request.method == 'POST':
 | 
			
		||||
        excel_file = request.FILES.get('file_name', '')
 | 
			
		||||
        ret = excel_to_db(excel_file)
 | 
			
		||||
        if ret:
 | 
			
		||||
            smg = u'批量添加成功'
 | 
			
		||||
        else:
 | 
			
		||||
            emg = u'批量添加失败,请检查格式.'
 | 
			
		||||
    return my_render('jasset/asset_add_batch.html', locals(), request)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -15,8 +15,6 @@ database = jumpserver
 | 
			
		|||
[websocket]
 | 
			
		||||
web_socket_host = 127.0.0.1:3000
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
[mail]
 | 
			
		||||
mail_enable = 1
 | 
			
		||||
email_host = smtp.exmail.qq.com
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -65,12 +65,12 @@ INSTALLED_APPS = (
 | 
			
		|||
    'django.contrib.messages',
 | 
			
		||||
    'django.contrib.staticfiles',
 | 
			
		||||
    'django.contrib.humanize',
 | 
			
		||||
    'bootstrapform',
 | 
			
		||||
    'jumpserver',
 | 
			
		||||
    'juser',
 | 
			
		||||
    'jasset',
 | 
			
		||||
    'jperm',
 | 
			
		||||
    'jlog',
 | 
			
		||||
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
MIDDLEWARE_CLASSES = (
 | 
			
		||||
| 
						 | 
				
			
			@ -146,3 +146,5 @@ USE_TZ = False
 | 
			
		|||
# https://docs.djangoproject.com/en/1.7/howto/static-files/
 | 
			
		||||
 | 
			
		||||
STATIC_URL = '/static/'
 | 
			
		||||
 | 
			
		||||
BOOTSTRAP_COLUMN_COUNT = 10
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -182,3 +182,132 @@ def asset_which_group(asset, member):
 | 
			
		|||
    names = [members.name for members in member.all()]
 | 
			
		||||
 | 
			
		||||
    return ','.join(names)
 | 
			
		||||
#
 | 
			
		||||
#
 | 
			
		||||
# @register.filter(name='get_user_asset_group')
 | 
			
		||||
# def get_user_asset_group(user):
 | 
			
		||||
#     return user.get_asset_group()
 | 
			
		||||
#
 | 
			
		||||
#
 | 
			
		||||
# @register.filter(name='group_asset_list')
 | 
			
		||||
# def group_asset_list(group):
 | 
			
		||||
#     return group.asset_set.all()
 | 
			
		||||
#
 | 
			
		||||
#
 | 
			
		||||
# @register.filter(name='group_asset_list_count')
 | 
			
		||||
# def group_asset_list_count(group):
 | 
			
		||||
#     return group.asset_set.all().count()
 | 
			
		||||
#
 | 
			
		||||
#
 | 
			
		||||
# @register.filter(name='time_delta')
 | 
			
		||||
# def time_delta(time_before):
 | 
			
		||||
#     delta = datetime.datetime.now() - time_before
 | 
			
		||||
#     days = delta.days
 | 
			
		||||
#     if days:
 | 
			
		||||
#         return "%s 天前" % days
 | 
			
		||||
#     else:
 | 
			
		||||
#         hours = delta.seconds/3600
 | 
			
		||||
#         if hours:
 | 
			
		||||
#             return "%s 小时前" % hours
 | 
			
		||||
#         else:
 | 
			
		||||
#             mins = delta.seconds/60
 | 
			
		||||
#             if mins:
 | 
			
		||||
#                 return '%s 分钟前' % mins
 | 
			
		||||
#             else:
 | 
			
		||||
#                 return '%s 秒前' % delta.seconds
 | 
			
		||||
#
 | 
			
		||||
#
 | 
			
		||||
# @register.filter(name='sudo_cmd_list')
 | 
			
		||||
# def sudo_cmd_list(cmd_group_id):
 | 
			
		||||
#     cmd_group = CmdGroup.objects.filter(id=cmd_group_id)
 | 
			
		||||
#     if cmd_group:
 | 
			
		||||
#         cmd_group = cmd_group[0]
 | 
			
		||||
#         return cmd_group.cmd.split(',')
 | 
			
		||||
#
 | 
			
		||||
#
 | 
			
		||||
# @register.filter(name='sudo_cmd_count')
 | 
			
		||||
# def sudo_cmd_count(user_group_id):
 | 
			
		||||
#     user_group = UserGroup.objects.filter(id=user_group_id)
 | 
			
		||||
#     cmds = []
 | 
			
		||||
#     if user_group:
 | 
			
		||||
#         user_group = user_group[0]
 | 
			
		||||
#         cmd_groups = []
 | 
			
		||||
#
 | 
			
		||||
#         for perm in user_group.sudoperm_set.all():
 | 
			
		||||
#             cmd_groups.extend(perm.cmd_group.all())
 | 
			
		||||
#
 | 
			
		||||
#         for cmd_group in cmd_groups:
 | 
			
		||||
#             cmds.extend(cmd_group.cmd.split(','))
 | 
			
		||||
#         return len(set(cmds))
 | 
			
		||||
#
 | 
			
		||||
#     else:
 | 
			
		||||
#         return 0
 | 
			
		||||
#
 | 
			
		||||
#
 | 
			
		||||
# @register.filter(name='sudo_cmd_count')
 | 
			
		||||
# def sudo_cmd_count(user_group_id):
 | 
			
		||||
#     user_group = UserGroup.objects.filter(id=user_group_id)
 | 
			
		||||
#     cmds = []
 | 
			
		||||
#     if user_group:
 | 
			
		||||
#         user_group = user_group[0]
 | 
			
		||||
#         cmd_groups = []
 | 
			
		||||
#         for perm in user_group.sudoperm_set.all():
 | 
			
		||||
#             cmd_groups.extend(perm.cmd_group.all())
 | 
			
		||||
#
 | 
			
		||||
#         for cmd_group in cmd_groups:
 | 
			
		||||
#             cmds.extend(cmd_group.cmd.split(','))
 | 
			
		||||
#         return len(set(cmds))
 | 
			
		||||
#     else:
 | 
			
		||||
#         return 0
 | 
			
		||||
#
 | 
			
		||||
#
 | 
			
		||||
# @register.filter(name='sudo_cmd_ids')
 | 
			
		||||
# def sudo_cmd_ids(user_group_id):
 | 
			
		||||
#     user_group = UserGroup.objects.filter(id=user_group_id)
 | 
			
		||||
#     if user_group:
 | 
			
		||||
#         user_group = user_group[0]
 | 
			
		||||
#         cmd_groups = []
 | 
			
		||||
#         for perm in user_group.sudoperm_set.all():
 | 
			
		||||
#             cmd_groups.extend(perm.cmd_group.all())
 | 
			
		||||
#         cmd_ids = [str(cmd_group.id) for cmd_group in cmd_groups]
 | 
			
		||||
#         return ','.join(cmd_ids)
 | 
			
		||||
#     else:
 | 
			
		||||
#         return '0'
 | 
			
		||||
#
 | 
			
		||||
#
 | 
			
		||||
# @register.filter(name='cmd_group_split')
 | 
			
		||||
# def cmd_group_split(cmd_group):
 | 
			
		||||
#     return cmd_group.cmd.split(',')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@register.filter(name='str_to_list')
 | 
			
		||||
def str_to_list(info):
 | 
			
		||||
    """
 | 
			
		||||
    str to list
 | 
			
		||||
    """
 | 
			
		||||
    print ast.literal_eval(info), type(ast.literal_eval(info))
 | 
			
		||||
    return ast.literal_eval(info)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@register.filter(name='str_to_dic')
 | 
			
		||||
def str_to_dic(info):
 | 
			
		||||
    """
 | 
			
		||||
    str to list
 | 
			
		||||
    """
 | 
			
		||||
    return ast.literal_eval(info).iteritems()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@register.filter(name='str_to_code')
 | 
			
		||||
def str_to_code(char_str):
 | 
			
		||||
    if char_str:
 | 
			
		||||
        return char_str
 | 
			
		||||
    else:
 | 
			
		||||
        return u'空'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@register.filter(name='ip_str_to_list')
 | 
			
		||||
def ip_str_to_list(ip_str):
 | 
			
		||||
    """
 | 
			
		||||
    ip str to list
 | 
			
		||||
    """
 | 
			
		||||
    return ip_str.split(',')
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4562,3 +4562,8 @@ body.skin-3 {
 | 
			
		|||
.red-fonts {
 | 
			
		||||
    color: #ed5565;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.form-group.required .control-label:after {
 | 
			
		||||
  content: " *";
 | 
			
		||||
  color: red;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -135,3 +135,11 @@ function selectAll(){
 | 
			
		|||
//        })
 | 
			
		||||
//}
 | 
			
		||||
 | 
			
		||||
function getIDall() {
 | 
			
		||||
    var check_array = [];
 | 
			
		||||
    $(".gradeX input:checked").each(function () {
 | 
			
		||||
        var id = $(this).attr("value");
 | 
			
		||||
        check_array.push(id);
 | 
			
		||||
    });
 | 
			
		||||
    return check_array.join(",");
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,5 +1,6 @@
 | 
			
		|||
{% extends 'base.html' %}
 | 
			
		||||
{% load mytags %}
 | 
			
		||||
{% load bootstrap %}
 | 
			
		||||
{% block content %}
 | 
			
		||||
{% include 'nav_cat_bar.html' %}
 | 
			
		||||
<div class="wrapper wrapper-content animated fadeInRight">
 | 
			
		||||
| 
						 | 
				
			
			@ -26,7 +27,7 @@
 | 
			
		|||
                        <div class="panel-options">
 | 
			
		||||
                            <ul class="nav nav-tabs">
 | 
			
		||||
                                <li class="active"><a href="/jasset/asset_add/" class="text-center"><i class="fa fa-laptop"></i> 单台添加 </a></li>
 | 
			
		||||
                                <li><a href="/jasset/host_add_multi" class="text-center"><i class="fa fa-bar-chart-o"></i> 批量添加 </a></li>
 | 
			
		||||
                                <li><a href="/jasset/asset_add_batch" class="text-center"><i class="fa fa-bar-chart-o"></i> 批量添加 </a></li>
 | 
			
		||||
                            </ul>
 | 
			
		||||
                        </div>
 | 
			
		||||
                        <div class="panel-body">
 | 
			
		||||
| 
						 | 
				
			
			@ -38,17 +39,23 @@
 | 
			
		|||
                                    {% if msg %}
 | 
			
		||||
                                        <div class="alert alert-success text-center">{{ msg }}</div>
 | 
			
		||||
                                    {% endif %}
 | 
			
		||||
 | 
			
		||||
                                    <form id="assetForm" method="post" class="form-horizontal">
 | 
			
		||||
                                        <div class="form-group"><label class="col-sm-2 control-label"> IP地址<span class="red-fonts">*</span> </label>
 | 
			
		||||
                                            <div class="col-sm-8"><input type="text" name="ip" placeholder="IP" class="form-control"></div>
 | 
			
		||||
                                        </div>
 | 
			
		||||
                                        {{ af.ip|bootstrap_horizontal }}
 | 
			
		||||
 | 
			
		||||
                                        <div class="hr-line-dashed"></div>
 | 
			
		||||
                                        {{ af.port|bootstrap_horizontal }}
 | 
			
		||||
 | 
			
		||||
                                        <div class="hr-line-dashed"></div>
 | 
			
		||||
                                        {{ af.idc|bootstrap_horizontal }}
 | 
			
		||||
 | 
			
		||||
                                        <div class="hr-line-dashed"></div>
 | 
			
		||||
                                        <div class="form-group">
 | 
			
		||||
                                            <label for="j_group" class="col-sm-2 control-label">使用默认</label>
 | 
			
		||||
                                            <div class="col-sm-1">
 | 
			
		||||
                                            <label for="j_group" class="col-sm-2 control-label">管理账号<span class="red-fonts"> *</span></label>
 | 
			
		||||
                                            <div class="col-sm-2">
 | 
			
		||||
                                                <div class="radio i-checks">
 | 
			
		||||
                                                    <label>
 | 
			
		||||
                                                        <input type="checkbox" checked="" value="1" id="use_default" name="use_default">
 | 
			
		||||
                                                        <input type="checkbox" checked="" id="id_use_default_auth" name="use_default_auth"><span> 使用默认 </span>
 | 
			
		||||
                                                    </label>
 | 
			
		||||
                                                </div>
 | 
			
		||||
                                            </div>
 | 
			
		||||
| 
						 | 
				
			
			@ -73,16 +80,9 @@
 | 
			
		|||
                                        </div>
 | 
			
		||||
 | 
			
		||||
                                        <div class="hr-line-dashed"></div>
 | 
			
		||||
                                        <div class="form-group">
 | 
			
		||||
                                            <label for="groups" class="col-sm-2 control-label">所属主机组</label>
 | 
			
		||||
                                            <div class="col-sm-8">
 | 
			
		||||
                                                <select id="groups" name="groups" class="form-control m-b" multiple size="10">
 | 
			
		||||
                                                    {% for asset_group in asset_group_all %}
 | 
			
		||||
                                                        <option type="checkbox" value="{{ asset_group.id }}">{{ asset_group.name }} {% if asset_group.comment %} --- {{ asset_group.comment }} {% endif %}</option>
 | 
			
		||||
                                                    {% endfor %}
 | 
			
		||||
                                                </select>
 | 
			
		||||
                                            </div>
 | 
			
		||||
                                        </div>
 | 
			
		||||
                                        {{ af.group|bootstrap_horizontal }}
 | 
			
		||||
 | 
			
		||||
{#                                        {{ af.is_active|bootstrap_horizontal }}#}
 | 
			
		||||
 | 
			
		||||
                                        <div class="hr-line-dashed"></div>
 | 
			
		||||
                                        <div class="form-group"><label class="col-sm-2 control-label"> 是否激活<span class="red-fonts"> *</span> </label>
 | 
			
		||||
| 
						 | 
				
			
			@ -94,11 +94,6 @@
 | 
			
		|||
                                            </div>
 | 
			
		||||
                                        </div>
 | 
			
		||||
 | 
			
		||||
                                        <div class="hr-line-dashed"></div>
 | 
			
		||||
                                        <div class="form-group"><label class="col-sm-2 control-label"> 备注 </label>
 | 
			
		||||
                                            <div class="col-sm-8"><input type="text" placeholder="comment" name="comment" class="form-control"></div>
 | 
			
		||||
                                        </div>
 | 
			
		||||
 | 
			
		||||
                                        <div class="hr-line-dashed"></div>
 | 
			
		||||
                                        <div class="form-group">
 | 
			
		||||
                                            <div class="col-sm-4 col-sm-offset-2">
 | 
			
		||||
| 
						 | 
				
			
			@ -120,7 +115,18 @@
 | 
			
		|||
 | 
			
		||||
{% block self_footer_js %}
 | 
			
		||||
<script>
 | 
			
		||||
    $('document').ready(function(){
 | 
			
		||||
        $('#id_use_default_auth').click(function(){
 | 
			
		||||
            if ($(this).is(':checked')){
 | 
			
		||||
                $('#admin_account').css('display', 'none')
 | 
			
		||||
            }
 | 
			
		||||
            else {
 | 
			
		||||
                $('#admin_account').css('display', 'block')
 | 
			
		||||
            }
 | 
			
		||||
        })
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
$('document').ready(function(){
 | 
			
		||||
    $('#use_default').click(function(){
 | 
			
		||||
        if ($(this).is(':checked')){
 | 
			
		||||
| 
						 | 
				
			
			@ -147,10 +153,36 @@ $('#assetForm').validator({
 | 
			
		|||
            tip: "输入IP",
 | 
			
		||||
            ok: "",
 | 
			
		||||
            msg: {required: "必须填写!"}
 | 
			
		||||
=======
 | 
			
		||||
    var required_fields = ["id_hostname", "id_ip", "id_port"];
 | 
			
		||||
    required_fields.forEach(function(field) {
 | 
			
		||||
        $('label[for="' + field + '"]').parent().addClass("required");
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    $('#assetForm').validator({
 | 
			
		||||
        timely: 2,
 | 
			
		||||
        theme: "yellow_right_effect",
 | 
			
		||||
        rules: {
 | 
			
		||||
            check_ip: [/^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])(\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])){3}$/, 'ip地址不正确'],
 | 
			
		||||
            check_port: [/^\d{1,5}$/, '端口号不正确'],
 | 
			
		||||
        },
 | 
			
		||||
        fields: {
 | 
			
		||||
            "ip": {
 | 
			
		||||
                rule: "required;check_ip",
 | 
			
		||||
                tip: "输入IP",
 | 
			
		||||
                ok: "",
 | 
			
		||||
                msg: {required: "必须填写!"}
 | 
			
		||||
            },
 | 
			
		||||
            "port": {
 | 
			
		||||
                rule: "required;check_port",
 | 
			
		||||
                tip: "输入端口号",
 | 
			
		||||
                ok: "",
 | 
			
		||||
                msg: {required: "必须填写!"}
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
        valid: function(form) {
 | 
			
		||||
            form.submit();
 | 
			
		||||
>>>>>>> cmdb
 | 
			
		||||
        }
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,166 @@
 | 
			
		|||
{% extends 'base.html' %}
 | 
			
		||||
{% load mytags %}
 | 
			
		||||
{% block content %}
 | 
			
		||||
{% include 'nav_cat_bar.html' %}
 | 
			
		||||
<div class="wrapper wrapper-content animated fadeInRight">
 | 
			
		||||
    <div class="row">
 | 
			
		||||
        <div class="col-lg-10">
 | 
			
		||||
            <div class="ibox float-e-margins">
 | 
			
		||||
                <div id="ibox-content" class="ibox-title">
 | 
			
		||||
                    <h5> 填写资产基本信息 </h5>
 | 
			
		||||
                    <div class="ibox-tools">
 | 
			
		||||
                        <a class="collapse-link">
 | 
			
		||||
                            <i class="fa fa-chevron-up"></i>
 | 
			
		||||
                        </a>
 | 
			
		||||
                        <a class="dropdown-toggle" data-toggle="dropdown" href="#">
 | 
			
		||||
                            <i class="fa fa-wrench"></i>
 | 
			
		||||
                        </a>
 | 
			
		||||
                        <a class="close-link">
 | 
			
		||||
                            <i class="fa fa-times"></i>
 | 
			
		||||
                        </a>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
 | 
			
		||||
                <div class="ibox-content">
 | 
			
		||||
                    <div class="panel blank-panel">
 | 
			
		||||
                        <div class="panel-options">
 | 
			
		||||
                            <ul class="nav nav-tabs">
 | 
			
		||||
                                <li class="active"><a href="/jasset/asset_add/" class="text-center"><i class="fa fa-laptop"></i> 单台添加 </a></li>
 | 
			
		||||
                                <li><a href="/jasset/host_add_multi" class="text-center"><i class="fa fa-bar-chart-o"></i> 批量添加 </a></li>
 | 
			
		||||
                            </ul>
 | 
			
		||||
                        </div>
 | 
			
		||||
                        <div class="panel-body">
 | 
			
		||||
                            <div class="tab-content">
 | 
			
		||||
                                <div id="tab-1" class="ibox float-e-margins tab-pane active">
 | 
			
		||||
                                    {% if error %}
 | 
			
		||||
                                        <div class="alert alert-warning text-center">{{ error }}</div>
 | 
			
		||||
                                    {% endif %}
 | 
			
		||||
                                    {% if msg %}
 | 
			
		||||
                                        <div class="alert alert-success text-center">{{ msg }}</div>
 | 
			
		||||
                                    {% endif %}
 | 
			
		||||
                                    <form id="assetForm" method="post" class="form-horizontal">
 | 
			
		||||
                                        <div class="form-group"><label class="col-sm-2 control-label"> IP地址<span class="red-fonts">*</span> </label>
 | 
			
		||||
                                            <div class="col-sm-8"><input type="text" name="ip" placeholder="IP" class="form-control"></div>
 | 
			
		||||
                                        </div>
 | 
			
		||||
 | 
			
		||||
                                        <div class="hr-line-dashed"></div>
 | 
			
		||||
                                        <div class="form-group">
 | 
			
		||||
                                            <label class="col-sm-2 control-label"> 端口号<span class="red-fonts">*</span> </label>
 | 
			
		||||
                                            <div class="col-sm-8">
 | 
			
		||||
                                                <input type="text" placeholder="Port" name="port" class="form-control">
 | 
			
		||||
                                            </div>
 | 
			
		||||
                                        </div>
 | 
			
		||||
 | 
			
		||||
                                        <div class="hr-line-dashed"></div>
 | 
			
		||||
                                        <div class="form-group">
 | 
			
		||||
                                            <label for="j_group" class="col-sm-2 control-label">管理账号</label>
 | 
			
		||||
                                            <div class="col-sm-2">
 | 
			
		||||
                                                <div class="radio i-checks">
 | 
			
		||||
                                                    <label>
 | 
			
		||||
                                                        <input type="checkbox" checked="" value="1" id="use_default_auth" name="use_default_auth"><span> 使用默认 </span>
 | 
			
		||||
                                                    </label>
 | 
			
		||||
                                                </div>
 | 
			
		||||
                                            </div>
 | 
			
		||||
                                        </div>
 | 
			
		||||
 | 
			
		||||
                                        <div class="form-group" id="admin_account" style="display: none">
 | 
			
		||||
                                            <label class="col-sm-2 control-label"> 管理用户名<span class="red-fonts">*</span> </label>
 | 
			
		||||
                                            <div class="col-sm-3">
 | 
			
		||||
                                                <input type="text" placeholder="Username" name="username" class="form-control">
 | 
			
		||||
                                            </div>
 | 
			
		||||
 | 
			
		||||
                                            <label class="col-sm-1 control-label"> 密码<span class="red-fonts">*</span> </label>
 | 
			
		||||
                                            <div class="col-sm-4">
 | 
			
		||||
                                                <input type="password" placeholder="Password" name="password" class="form-control">
 | 
			
		||||
                                            </div>
 | 
			
		||||
                                        </div>
 | 
			
		||||
 | 
			
		||||
                                        <div class="hr-line-dashed"></div>
 | 
			
		||||
                                        <div class="form-group">
 | 
			
		||||
                                            <label for="groups" class="col-sm-2 control-label">所属主机组</label>
 | 
			
		||||
                                            <div class="col-sm-8">
 | 
			
		||||
                                                <select id="groups" name="groups" class="form-control m-b" multiple size="10">
 | 
			
		||||
                                                    {% for asset_group in asset_group_all %}
 | 
			
		||||
                                                        <option type="checkbox" value="{{ asset_group.id }}">{{ asset_group.name }} {% if asset_group.comment %} --- {{ asset_group.comment }} {% endif %}</option>
 | 
			
		||||
                                                    {% endfor %}
 | 
			
		||||
                                                </select>
 | 
			
		||||
                                            </div>
 | 
			
		||||
                                        </div>
 | 
			
		||||
 | 
			
		||||
                                        <div class="hr-line-dashed"></div>
 | 
			
		||||
                                        <div class="form-group"><label class="col-sm-2 control-label"> 是否激活<span class="red-fonts">*</span> </label>
 | 
			
		||||
                                            <div class="col-sm-8">
 | 
			
		||||
                                                <div class="radio i-checks">
 | 
			
		||||
                                                    <label> <input type="radio" checked="" value="1" name="is_active">激活 </label>
 | 
			
		||||
                                                    <label> <input type="radio"  value="0" name="is_active"> 禁用</label>
 | 
			
		||||
                                                </div>
 | 
			
		||||
                                            </div>
 | 
			
		||||
                                        </div>
 | 
			
		||||
 | 
			
		||||
                                        <div class="hr-line-dashed"></div>
 | 
			
		||||
                                        <div class="form-group"><label class="col-sm-2 control-label"> 备注 </label>
 | 
			
		||||
                                            <div class="col-sm-8"><input type="text" placeholder="comment" name="comment" class="form-control"></div>
 | 
			
		||||
                                        </div>
 | 
			
		||||
 | 
			
		||||
                                        <div class="hr-line-dashed"></div>
 | 
			
		||||
                                        <div class="form-group">
 | 
			
		||||
                                            <div class="col-sm-4 col-sm-offset-2">
 | 
			
		||||
                                                <button class="btn btn-white" type="reset"> 重置 </button>
 | 
			
		||||
                                                <button class="btn btn-primary" type="submit"> 提交 </button>
 | 
			
		||||
                                            </div>
 | 
			
		||||
                                        </div>
 | 
			
		||||
                                    </form>
 | 
			
		||||
                                </div>
 | 
			
		||||
                            </div>
 | 
			
		||||
                        </div>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
            </div>
 | 
			
		||||
        </div>
 | 
			
		||||
    </div>
 | 
			
		||||
</div>
 | 
			
		||||
{% endblock %}
 | 
			
		||||
 | 
			
		||||
{% block self_footer_js %}
 | 
			
		||||
<script>
 | 
			
		||||
 | 
			
		||||
$('document').ready(function(){
 | 
			
		||||
    $('#use_default_auth').click(function(){
 | 
			
		||||
        if ($(this).is(':checked')){
 | 
			
		||||
            $('#admin_account').css('display', 'none')
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            $('#admin_account').css('display', 'block')
 | 
			
		||||
        }
 | 
			
		||||
    })
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
$('#assetForm').validator({
 | 
			
		||||
    timely: 2,
 | 
			
		||||
    theme: "yellow_right_effect",
 | 
			
		||||
    rules: {
 | 
			
		||||
        check_ip: [/^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])(\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])){3}$/, 'ip地址不正确'],
 | 
			
		||||
        check_port: [/^\d{1,5}$/, '端口号不正确'],
 | 
			
		||||
    },
 | 
			
		||||
    fields: {
 | 
			
		||||
        "ip": {
 | 
			
		||||
            rule: "required;check_ip",
 | 
			
		||||
            tip: "输入IP",
 | 
			
		||||
            ok: "",
 | 
			
		||||
            msg: {required: "必须填写!"}
 | 
			
		||||
        },
 | 
			
		||||
        "port": {
 | 
			
		||||
            rule: "required;check_port",
 | 
			
		||||
            tip: "输入端口号",
 | 
			
		||||
            ok: "",
 | 
			
		||||
            msg: {required: "必须填写!"}
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
    valid: function(form) {
 | 
			
		||||
        form.submit();
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
{% endblock %}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,65 @@
 | 
			
		|||
{% extends 'base.html' %}
 | 
			
		||||
{% block content %}
 | 
			
		||||
{% include 'nav_cat_bar.html' %}
 | 
			
		||||
<style>
 | 
			
		||||
    .file-box{ position:relative;width:340px}
 | 
			
		||||
    .txt{ height:22px; border:1px solid #cdcdcd; width:180px;}
 | 
			
		||||
    .file{ position:absolute; top:0; right:80px; height:24px; filter:alpha(opacity:0);opacity: 0;width:260px }
 | 
			
		||||
</style>
 | 
			
		||||
<div class="wrapper wrapper-content animated fadeInRight">
 | 
			
		||||
    <div class="row">
 | 
			
		||||
        <div class="col-lg-10">
 | 
			
		||||
            <div class="ibox float-e-margins">
 | 
			
		||||
                <div id="ibox-content" class="ibox-title">
 | 
			
		||||
                    <h5> 填写主机基本信息 </h5>
 | 
			
		||||
                    <div class="ibox-tools">
 | 
			
		||||
                        <a class="collapse-link">
 | 
			
		||||
                            <i class="fa fa-chevron-up"></i>
 | 
			
		||||
                        </a>
 | 
			
		||||
                        <a class="dropdown-toggle" data-toggle="dropdown" href="#">
 | 
			
		||||
                            <i class="fa fa-wrench"></i>
 | 
			
		||||
                        </a>
 | 
			
		||||
                        <ul class="dropdown-menu dropdown-user">
 | 
			
		||||
                        </ul>
 | 
			
		||||
                        <a class="close-link">
 | 
			
		||||
                            <i class="fa fa-times"></i>
 | 
			
		||||
                        </a>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
 | 
			
		||||
                <div class="ibox-content">
 | 
			
		||||
                    <div class="panel blank-panel">
 | 
			
		||||
                        <div class="panel-options">
 | 
			
		||||
                            <ul class="nav nav-tabs">
 | 
			
		||||
                                <li><a href="/jasset/asset_add/" class="text-center"><i class="fa fa-laptop"></i> 单台添加 </a></li>
 | 
			
		||||
                                <li class="active"><a href="/jasset/asset_add_batch/" class="text-center"><i class="fa fa-bar-chart-o"></i> 批量添加 </a></li>
 | 
			
		||||
                            </ul>
 | 
			
		||||
                        </div>
 | 
			
		||||
                        <div class="panel-body">
 | 
			
		||||
                            <div id="tab-2" class="ibox float-e-margins tab-pane active">
 | 
			
		||||
                                {% if emg %}
 | 
			
		||||
                                    <div class="alert alert-warning text-center">{{ emg }}</div>
 | 
			
		||||
                                {% endif %}
 | 
			
		||||
                                {% if smg %}
 | 
			
		||||
                                    <div class="alert alert-success text-center">{{ smg }}</div>
 | 
			
		||||
                                {% endif %}
 | 
			
		||||
                                <p>请下载Excel文件, 按照格式填写主机信息, 上传导入. <a href="/static/files/excels/asset.xlsx">点击下载模板</a></p>
 | 
			
		||||
                                <form action="/jasset/upload/" method="POST" enctype="multipart/form-data">
 | 
			
		||||
                                    <div class="file-box">
 | 
			
		||||
                                        <input id='textfield' />
 | 
			
		||||
                                        <input type="button" class="btn btn-info btn-sm" name="file_name" value="点击选择文件">
 | 
			
		||||
                                        <input type="file" name="file_name" class="file" id="fileField" size="28" onchange="document.getElementById('textfield').value=this.value" />
 | 
			
		||||
                                        <button class="btn btn-primary btn-sm" type="submit">上传文件</button>
 | 
			
		||||
                                    </div>
 | 
			
		||||
 | 
			
		||||
                                </form>
 | 
			
		||||
                            </div>
 | 
			
		||||
                        </div>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
            </div>
 | 
			
		||||
        </div>
 | 
			
		||||
    </div>
 | 
			
		||||
</div>
 | 
			
		||||
 | 
			
		||||
{% endblock %}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,6 +1,6 @@
 | 
			
		|||
{% extends 'base.html' %}
 | 
			
		||||
{% load mytags %}
 | 
			
		||||
 | 
			
		||||
{% load humanize %}
 | 
			
		||||
 | 
			
		||||
{% block content %}
 | 
			
		||||
    {% include 'nav_cat_bar.html' %}
 | 
			
		||||
| 
						 | 
				
			
			@ -33,6 +33,28 @@
 | 
			
		|||
                                        <td class="text-navy">IP</td>
 | 
			
		||||
                                        <td>{{ asset.ip }}</td>
 | 
			
		||||
                                    </tr>
 | 
			
		||||
                                    <tr>
 | 
			
		||||
                                        <td class="text-navy">主机名</td>
 | 
			
		||||
                                        <td>{{ asset.hostname }}</td>
 | 
			
		||||
                                    </tr>
 | 
			
		||||
                                    <tr>
 | 
			
		||||
                                        <td class="text-navy">其他IP</td>
 | 
			
		||||
                                        <td>
 | 
			
		||||
                                            <table class="table">
 | 
			
		||||
                                                {% if asset.other_ip %}
 | 
			
		||||
                                                    {% for ip in asset.other_ip|ip_str_to_list %}
 | 
			
		||||
                                                        <tr>
 | 
			
		||||
                                                            <td>{{ ip }}</td>
 | 
			
		||||
                                                        </tr>
 | 
			
		||||
                                                    {% endfor %}
 | 
			
		||||
                                                {% endif %}
 | 
			
		||||
                                            </table>
 | 
			
		||||
                                        </td>
 | 
			
		||||
                                    </tr>
 | 
			
		||||
                                    <tr>
 | 
			
		||||
                                        <td class="text-navy">远控IP</td>
 | 
			
		||||
                                        <td>{{ asset.remote_ip }}</td>
 | 
			
		||||
                                    </tr>
 | 
			
		||||
                                    <tr>
 | 
			
		||||
                                        <td class="text-navy">端口</td>
 | 
			
		||||
                                        <td>{{ asset.port }}</td>
 | 
			
		||||
| 
						 | 
				
			
			@ -42,12 +64,80 @@
 | 
			
		|||
                                        <td class="text-navy">主机组</td>
 | 
			
		||||
                                        <td>
 | 
			
		||||
                                             <table class="table">
 | 
			
		||||
                                                 {% for asset_group in asset.group.all %}
 | 
			
		||||
                                                    <tr>
 | 
			
		||||
                                                        <td>{{ asset_group.name }}</td>
 | 
			
		||||
                                                    </tr>
 | 
			
		||||
                                                 {% endfor %}
 | 
			
		||||
                                             </table>
 | 
			
		||||
                                        </td>
 | 
			
		||||
                                    </tr>
 | 
			
		||||
                                    <tr>
 | 
			
		||||
                                        <td class="text-navy">使用默认管理账号</td>
 | 
			
		||||
                                        <td>{{ asset.use_default_auth|bool2str }}</td>
 | 
			
		||||
{#                                        <td>{{ asset.use_default_auth|bool2str }}</td>#}
 | 
			
		||||
                                        <td>{{ asset.use_default_auth|bool2str }} {% if not asset.use_default_auth %} <span class="text-info">{{ asset.username }}</span> {% endif %}</td>
 | 
			
		||||
                                    </tr>
 | 
			
		||||
                                    <tr>
 | 
			
		||||
                                        <td class="text-navy">机房</td>
 | 
			
		||||
                                        <td>{{ asset.idc.name }}</td>
 | 
			
		||||
                                    </tr>
 | 
			
		||||
                                    <tr>
 | 
			
		||||
                                        <td class="text-navy">硬件厂商型号</td>
 | 
			
		||||
                                        <td>{{ asset.brand }}</td>
 | 
			
		||||
                                    </tr>
 | 
			
		||||
                                    <tr>
 | 
			
		||||
                                        <td class="text-navy">CPU</td>
 | 
			
		||||
                                        <td>{{ asset.cpu }}</td>
 | 
			
		||||
                                    </tr>
 | 
			
		||||
                                    <tr>
 | 
			
		||||
                                        <td class="text-navy">内存</td>
 | 
			
		||||
                                        <td>{{ asset.memory }}M</td>
 | 
			
		||||
                                    </tr>
 | 
			
		||||
                                    <tr>
 | 
			
		||||
                                        <td class="text-navy">硬盘</td>
 | 
			
		||||
                                        <td>
 | 
			
		||||
                                            <table class="table">
 | 
			
		||||
                                            {% if asset.disk %}
 | 
			
		||||
                                                 {% for disk, value in asset.disk|str_to_dic %}
 | 
			
		||||
                                                    <tr>
 | 
			
		||||
                                                        <td><span class="text-navy">{{ disk }}</span>     {{ value }}</td>
 | 
			
		||||
                                                    </tr>
 | 
			
		||||
                                                 {% endfor %}
 | 
			
		||||
                                            {% endif %}
 | 
			
		||||
                                            </table>
 | 
			
		||||
                                        </td>
 | 
			
		||||
                                    </tr>
 | 
			
		||||
                                    <tr>
 | 
			
		||||
                                        <td class="text-navy">资产编号</td>
 | 
			
		||||
                                        <td>{{ asset.number }}</td>
 | 
			
		||||
                                    </tr>
 | 
			
		||||
                                    <tr>
 | 
			
		||||
                                        <td class="text-navy">SN</td>
 | 
			
		||||
                                        <td>{{ asset.sn }}</td>
 | 
			
		||||
                                    </tr>
 | 
			
		||||
                                    <tr>
 | 
			
		||||
                                        <td class="text-navy">主机类型</td>
 | 
			
		||||
                                        <td>{{ asset.get_asset_type_display }}</td>
 | 
			
		||||
                                    </tr>
 | 
			
		||||
                                    <tr>
 | 
			
		||||
                                        <td class="text-navy">系统版本</td>
 | 
			
		||||
                                        <td>{{ asset.system_type }} {{ asset.system_version }}</td>
 | 
			
		||||
                                    </tr>
 | 
			
		||||
                                    <tr>
 | 
			
		||||
                                        <td class="text-navy">运行环境</td>
 | 
			
		||||
                                        <td>{{ asset.get_env_display }}</td>
 | 
			
		||||
                                    </tr>
 | 
			
		||||
                                    <tr>
 | 
			
		||||
                                        <td class="text-navy">机器状态</td>
 | 
			
		||||
                                        <td>{{ asset.get_status_display }}</td>
 | 
			
		||||
                                    </tr>
 | 
			
		||||
                                    <tr>
 | 
			
		||||
                                        <td class="text-navy">机柜号</td>
 | 
			
		||||
                                        <td>{{ asset.cabinet }}</td>
 | 
			
		||||
                                    </tr>
 | 
			
		||||
                                    <tr>
 | 
			
		||||
                                        <td class="text-navy">机柜位置</td>
 | 
			
		||||
                                        <td>{{ asset.position }}</td>
 | 
			
		||||
                                    </tr>
 | 
			
		||||
                                    <tr>
 | 
			
		||||
                                        <td class="text-navy">激活</td>
 | 
			
		||||
| 
						 | 
				
			
			@ -91,8 +181,8 @@
 | 
			
		|||
                    </div>
 | 
			
		||||
                    <div class="ibox-content">
 | 
			
		||||
                        <div>
 | 
			
		||||
                            <div class="text-left">
 | 
			
		||||
                                <table class="table">
 | 
			
		||||
{#                            <div class="text-left">#}
 | 
			
		||||
{#                                <table class="table">#}
 | 
			
		||||
{#                                    {% if user_permed_list %}#}
 | 
			
		||||
{#                                        {% for user in user_permed_list %}#}
 | 
			
		||||
{#                                            <tr>#}
 | 
			
		||||
| 
						 | 
				
			
			@ -104,9 +194,49 @@
 | 
			
		|||
{#                                    {% else %}#}
 | 
			
		||||
{#                                        <p class="text-center">(暂无)</p>#}
 | 
			
		||||
{#                                    {% endif %}#}
 | 
			
		||||
                                </table>
 | 
			
		||||
{#                                </table>#}
 | 
			
		||||
{#                            </div>#}
 | 
			
		||||
                        </div>
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <div class="ibox-title">
 | 
			
		||||
                        <h5>主机修改记录</h5>
 | 
			
		||||
                        <div class="ibox-tools">
 | 
			
		||||
                            <a class="collapse-link">
 | 
			
		||||
                                <i class="fa fa-chevron-up"></i>
 | 
			
		||||
                            </a>
 | 
			
		||||
                            <a class="dropdown-toggle" data-toggle="dropdown" href="#">
 | 
			
		||||
                                <i class="fa fa-wrench"></i>
 | 
			
		||||
                            </a>
 | 
			
		||||
                            <ul class="dropdown-menu dropdown-user">
 | 
			
		||||
                            </ul>
 | 
			
		||||
                            <a class="close-link">
 | 
			
		||||
                                <i class="fa fa-times"></i>
 | 
			
		||||
                            </a>
 | 
			
		||||
                        </div>
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <div class="ibox-content ibox-heading">
 | 
			
		||||
                        <h3>主机修改记录</h3>
 | 
			
		||||
                        <small><i class="fa fa-map-marker"></i> 包含了此主机所有历史修改记录.</small>
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <div class="ibox-content">
 | 
			
		||||
                        <div class="feed-activity-list">
 | 
			
		||||
                            {% if asset_record %}
 | 
			
		||||
                                {% for r in asset_record %}
 | 
			
		||||
                                    <div class="feed-element">
 | 
			
		||||
                                        <div>
 | 
			
		||||
                                            <small class="pull-right">{{ r.alert_time|naturaltime }}</small>
 | 
			
		||||
                                            <strong class="text-navy">{{ r.username }}</strong>
 | 
			
		||||
                                                {% for i in r.content|str_to_list %}
 | 
			
		||||
                                                    <div>{{ i.0 }} 由 <span class="text-success">{{ i.1|str_to_code }}</span> 改为 <span class="text-warning">{{ i.2|str_to_code }}</span></div>
 | 
			
		||||
                                                {% endfor %}
 | 
			
		||||
                                            <small class="text-success">{{ r.alert_time }}</small>
 | 
			
		||||
                                        </div>
 | 
			
		||||
                                    </div>
 | 
			
		||||
                                {% endfor %}
 | 
			
		||||
                            {% else %}
 | 
			
		||||
                                <p class="text-center">(暂无)</p>
 | 
			
		||||
                            {% endif %}
 | 
			
		||||
                        </div>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
            </div>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,6 @@
 | 
			
		|||
{% extends 'base.html' %}
 | 
			
		||||
{% load mytags %}
 | 
			
		||||
{% load bootstrap %}
 | 
			
		||||
{% block content %}
 | 
			
		||||
{% include 'nav_cat_bar.html' %}
 | 
			
		||||
<div class="wrapper wrapper-content animated fadeInRight">
 | 
			
		||||
| 
						 | 
				
			
			@ -32,53 +33,86 @@
 | 
			
		|||
                                        <div class="alert alert-success text-center">{{ msg }}</div>
 | 
			
		||||
                                    {% endif %}
 | 
			
		||||
                                    <form id="assetForm" method="post" class="form-horizontal">
 | 
			
		||||
                                        <div class="form-group"><label class="col-sm-2 control-label"> IP地址<span class="red-fonts">*</span> </label>
 | 
			
		||||
                                            <div class="col-sm-8"><input type="text" name="ip" value="{{ asset.ip }}" class="form-control"></div>
 | 
			
		||||
                                        </div>
 | 
			
		||||
 | 
			
		||||
                                        {{ af.ip|bootstrap_horizontal }}
 | 
			
		||||
 | 
			
		||||
                                        <div class="hr-line-dashed"></div>
 | 
			
		||||
                                        {{ af.hostname|bootstrap_horizontal }}
 | 
			
		||||
 | 
			
		||||
                                        <div class="hr-line-dashed"></div>
 | 
			
		||||
                                        {{ af.other_ip|bootstrap_horizontal }}
 | 
			
		||||
 | 
			
		||||
                                        <div class="hr-line-dashed"></div>
 | 
			
		||||
                                        {{ af.remote_ip|bootstrap_horizontal }}
 | 
			
		||||
 | 
			
		||||
                                        <div class="hr-line-dashed"></div>
 | 
			
		||||
                                        {{ af.port|bootstrap_horizontal }}
 | 
			
		||||
 | 
			
		||||
                                        <div class="hr-line-dashed"></div>
 | 
			
		||||
                                        <div class="form-group">
 | 
			
		||||
                                            <label class="col-sm-2 control-label"> 端口号<span class="red-fonts">*</span> </label>
 | 
			
		||||
                                            <div class="col-sm-8">
 | 
			
		||||
                                                <input type="text" value="{{ asset.port }}" name="port" class="form-control">
 | 
			
		||||
                                            </div>
 | 
			
		||||
                                        </div>
 | 
			
		||||
 | 
			
		||||
                                        <div class="hr-line-dashed"></div>
 | 
			
		||||
                                        <div class="form-group">
 | 
			
		||||
                                            <label for="j_group" class="col-sm-2 control-label">使用默认管理账号</label>
 | 
			
		||||
                                            <div class="col-sm-1">
 | 
			
		||||
                                            <label for="j_group" class="col-sm-2 control-label">管理账号 <span class="red-fonts">*</span></label>
 | 
			
		||||
                                            <div class="col-sm-2">
 | 
			
		||||
                                                <div class="radio i-checks">
 | 
			
		||||
                                                    <label>
 | 
			
		||||
                                                        <input type="checkbox" {% ifequal asset.use_default 1 %} checked="" {% endifequal %} value="1" id="use_default" name="use_default">
 | 
			
		||||
                                                        <input type="checkbox" {% if asset.use_default_auth %} checked="" {% endif %} id="id_use_default_auth" name="use_default_auth"><span> 使用默认 </span>
 | 
			
		||||
                                                    </label>
 | 
			
		||||
                                                </div>
 | 
			
		||||
                                            </div>
 | 
			
		||||
                                        </div>
 | 
			
		||||
 | 
			
		||||
                                        <div class="form-group" id="admin_account" {% ifequal asset.use_default 1 %} style="display: none" {% endifequal %}>
 | 
			
		||||
                                        <div class="form-group" id="admin_account" {% if asset.use_default_auth %} style="display: none" {% endif %}>
 | 
			
		||||
                                            <label class="col-sm-2 control-label"> 管理用户名 <span class="red-fonts">*</span> </label>
 | 
			
		||||
                                            <div class="col-sm-3">
 | 
			
		||||
                                                <input type="text" {% ifnotequal asset.use_default 1 %} value="{{ asset.username }}" {% endifnotequal %} name="username" class="form-control">
 | 
			
		||||
                                                <input type="text" value="{{ asset.username }}" name="username" class="form-control">
 | 
			
		||||
                                            </div>
 | 
			
		||||
 | 
			
		||||
                                            <label class="col-sm-1 control-label"> 密码<span class="red-fonts">*</span> </label>
 | 
			
		||||
                                            <div class="col-sm-4">
 | 
			
		||||
                                                <input type="password" {% ifnotequal asset.use_default 1 %} value="{{ asset.password }}" {% endifnotequal %}  name="password" class="form-control">
 | 
			
		||||
                                                <input type="password" value="{{ asset.password }}" name="password" class="form-control">
 | 
			
		||||
                                            </div>
 | 
			
		||||
                                        </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                                        <div class="hr-line-dashed"></div>
 | 
			
		||||
                                        <div class="form-group">
 | 
			
		||||
                                            <label for="groups" class="col-sm-2 control-label">所属主机组</label>
 | 
			
		||||
                                            <div class="col-sm-8">
 | 
			
		||||
                                                <select id="groups" name="groups" class="form-control m-b" multiple size="10">
 | 
			
		||||
                                                    {% for g in egroup %}
 | 
			
		||||
                                                        <option type="checkbox" value="{{ g.id }}">{{ g.name }} {% if g.comment %} --- {{ g.comment }} {% endif %}</option>
 | 
			
		||||
                                                    {% endfor %}
 | 
			
		||||
                                                </select>
 | 
			
		||||
                                            </div>
 | 
			
		||||
                                        </div>
 | 
			
		||||
                                        {{ af.group|bootstrap_horizontal }}
 | 
			
		||||
 | 
			
		||||
                                        <div class="hr-line-dashed"></div>
 | 
			
		||||
                                        {{ af.idc|bootstrap_horizontal }}
 | 
			
		||||
 | 
			
		||||
                                       <div class="hr-line-dashed"></div>
 | 
			
		||||
                                        {{ af.brand|bootstrap_horizontal }}
 | 
			
		||||
 | 
			
		||||
                                        <div class="hr-line-dashed"></div>
 | 
			
		||||
                                        {{ af.cpu|bootstrap_horizontal }}
 | 
			
		||||
 | 
			
		||||
                                        <div class="hr-line-dashed"></div>
 | 
			
		||||
                                        {{ af.memory|bootstrap_horizontal }}
 | 
			
		||||
 | 
			
		||||
                                        <div class="hr-line-dashed"></div>
 | 
			
		||||
                                        {{ af.disk|bootstrap_horizontal }}
 | 
			
		||||
 | 
			
		||||
                                        <div class="hr-line-dashed"></div>
 | 
			
		||||
                                        {{ af.number|bootstrap_horizontal }}
 | 
			
		||||
 | 
			
		||||
                                        <div class="hr-line-dashed"></div>
 | 
			
		||||
                                        {{ af.sn|bootstrap_horizontal }}
 | 
			
		||||
 | 
			
		||||
                                        <div class="hr-line-dashed"></div>
 | 
			
		||||
                                        {{ af.cabinet|bootstrap_horizontal }}
 | 
			
		||||
 | 
			
		||||
                                        <div class="hr-line-dashed"></div>
 | 
			
		||||
                                        {{ af.position|bootstrap_horizontal }}
 | 
			
		||||
 | 
			
		||||
                                        <div class="hr-line-dashed"></div>
 | 
			
		||||
                                        {{ af.asset_type|bootstrap_horizontal }}
 | 
			
		||||
 | 
			
		||||
                                        <div class="hr-line-dashed"></div>
 | 
			
		||||
                                        {{ af.env|bootstrap_horizontal }}
 | 
			
		||||
 | 
			
		||||
                                        <div class="hr-line-dashed"></div>
 | 
			
		||||
                                        {{ af.status|bootstrap_horizontal }}
 | 
			
		||||
 | 
			
		||||
{#                                        <div class="hr-line-dashed"></div>#}
 | 
			
		||||
{#                                        {{ af.is_active|bootstrap_horizontal }}#}
 | 
			
		||||
 | 
			
		||||
                                        <div class="hr-line-dashed"></div>
 | 
			
		||||
                                        <div class="form-group"><label class="col-sm-2 control-label"> 是否激活<span class="red-fonts">*</span> </label>
 | 
			
		||||
| 
						 | 
				
			
			@ -96,9 +130,7 @@
 | 
			
		|||
                                        </div>
 | 
			
		||||
 | 
			
		||||
                                       <div class="hr-line-dashed"></div>
 | 
			
		||||
                                        <div class="form-group"><label class="col-sm-2 control-label"> 备注 </label>
 | 
			
		||||
                                            <div class="col-sm-8"><input type="text" value="{{ asset.comment }}" name="comment" class="form-control"></div>
 | 
			
		||||
                                        </div>
 | 
			
		||||
                                        {{ af.comment|bootstrap_horizontal }}
 | 
			
		||||
 | 
			
		||||
                                        <div class="hr-line-dashed"></div>
 | 
			
		||||
                                        <div class="form-group">
 | 
			
		||||
| 
						 | 
				
			
			@ -121,9 +153,8 @@
 | 
			
		|||
 | 
			
		||||
{% block self_footer_js %}
 | 
			
		||||
<script>
 | 
			
		||||
 | 
			
		||||
    $('document').ready(function(){
 | 
			
		||||
    $('#use_default').click(function(){
 | 
			
		||||
        $('#id_use_default_auth').click(function(){
 | 
			
		||||
            if ($(this).is(':checked')){
 | 
			
		||||
                $('#admin_account').css('display', 'none')
 | 
			
		||||
            }
 | 
			
		||||
| 
						 | 
				
			
			@ -133,6 +164,11 @@ $('document').ready(function(){
 | 
			
		|||
        })
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    var required_fields = ["id_ip", "id_port"];
 | 
			
		||||
    required_fields.forEach(function(field) {
 | 
			
		||||
        $('label[for="' + field + '"]').parent().addClass("required");
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    $('#assetForm').validator({
 | 
			
		||||
        timely: 2,
 | 
			
		||||
        theme: "yellow_right_effect",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,180 @@
 | 
			
		|||
<html>
 | 
			
		||||
    <head>
 | 
			
		||||
        <link href="/static/css/bootstrap.min.css" rel="stylesheet">
 | 
			
		||||
        <link href="/static/font-awesome/css/font-awesome.css" rel="stylesheet">
 | 
			
		||||
        <link href="/static/css/plugins/iCheck/custom.css" rel="stylesheet">
 | 
			
		||||
        <link href="/static/css/animate.css" rel="stylesheet">
 | 
			
		||||
        <link href="/static/css/style.css" rel="stylesheet">
 | 
			
		||||
 | 
			
		||||
        <script src="/static/js/jquery-2.1.1.js"></script>
 | 
			
		||||
{#        <style>#}
 | 
			
		||||
{#            body {background: #ffffff;}#}
 | 
			
		||||
{#        </style>#}
 | 
			
		||||
    </head>
 | 
			
		||||
 | 
			
		||||
{% load bootstrap %}
 | 
			
		||||
{% block content %}
 | 
			
		||||
 | 
			
		||||
<body>
 | 
			
		||||
<div class="wrapper wrapper-content animated fadeInRight">
 | 
			
		||||
    <div class="row">
 | 
			
		||||
        <div class="col-lg-10">
 | 
			
		||||
            <div class="ibox float-e-margins">
 | 
			
		||||
                <div class="ibox-title">
 | 
			
		||||
                    <h5 class="text-center"> 填写修改主机信息. </h5>
 | 
			
		||||
                    <div class="ibox-tools">
 | 
			
		||||
                        <a class="collapse-link">
 | 
			
		||||
                            <i class="fa fa-chevron-up"></i>
 | 
			
		||||
                        </a>
 | 
			
		||||
                        <a class="dropdown-toggle" data-toggle="dropdown" href="#">
 | 
			
		||||
                            <i class="fa fa-wrench"></i>
 | 
			
		||||
                        </a>
 | 
			
		||||
                        <ul class="dropdown-menu dropdown-user"></ul>
 | 
			
		||||
                        <a class="close-link">
 | 
			
		||||
                            <i class="fa fa-times"></i>
 | 
			
		||||
                        </a>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
 | 
			
		||||
            <div class="ibox-content">
 | 
			
		||||
                <form class="form-horizontal" action="" id="signupForm"  method="post" name="horizontal" role="form" autocomplete="off">
 | 
			
		||||
                {% csrf_token %}
 | 
			
		||||
                    <input id="ids" style="display: none">
 | 
			
		||||
                    {{ af.env|bootstrap_horizontal }}
 | 
			
		||||
 | 
			
		||||
                    <div class="hr-line-dashed"></div>
 | 
			
		||||
                    {{ af.idc|bootstrap_horizontal }}
 | 
			
		||||
 | 
			
		||||
                    <div class="hr-line-dashed"></div>
 | 
			
		||||
                    {{ af.port|bootstrap_horizontal }}
 | 
			
		||||
 | 
			
		||||
                    <div class="hr-line-dashed"></div>
 | 
			
		||||
                    <div class="form-group">
 | 
			
		||||
                        <label for="j_group" class="col-sm-2 control-label">管理账号</label>
 | 
			
		||||
                        <div class="col-sm-2">
 | 
			
		||||
                            <div class="radio i-checks">
 | 
			
		||||
                                <label>
 | 
			
		||||
                                    <input type="radio" checked="" value="no_action" name="use_default_auth"><span> 不修改 </span>
 | 
			
		||||
                                </label>
 | 
			
		||||
                            </div>
 | 
			
		||||
                            <div class="radio i-checks">
 | 
			
		||||
                                <label>
 | 
			
		||||
                                    <input type="radio" name="use_default_auth"><span> 使用默认 </span>
 | 
			
		||||
                                </label>
 | 
			
		||||
                            </div>
 | 
			
		||||
                            <div class="radio i-checks">
 | 
			
		||||
                                <label>
 | 
			
		||||
                                    <input type="radio" id="id_use_default_auth" name="use_default_auth"><span> 用户名密码 </span>
 | 
			
		||||
                                </label>
 | 
			
		||||
                            </div>
 | 
			
		||||
                        </div>
 | 
			
		||||
                    </div>
 | 
			
		||||
 | 
			
		||||
                    <div class="form-group" id="admin_account" style="display: none">
 | 
			
		||||
                        <label class="col-sm-2 control-label"> 管理用户名<span class="red-fonts"> *</span></label>
 | 
			
		||||
                        <div class="col-sm-3">
 | 
			
		||||
                            <input type="text" placeholder="Username" name="username" class="form-control">
 | 
			
		||||
                        </div>
 | 
			
		||||
 | 
			
		||||
                        <label class="col-sm-1 control-label"> 密码<span class="red-fonts">*</span> </label>
 | 
			
		||||
                        <div class="col-sm-4">
 | 
			
		||||
                            <input type="password" placeholder="Password" name="password" class="form-control">
 | 
			
		||||
                        </div>
 | 
			
		||||
                    </div>
 | 
			
		||||
 | 
			
		||||
                    <div class="hr-line-dashed"></div>
 | 
			
		||||
                    <div class="form-group">
 | 
			
		||||
                        <label for="groups" class="col-sm-2 control-label">所属主机组</label>
 | 
			
		||||
 | 
			
		||||
                        <div class="col-sm-3">
 | 
			
		||||
                            <select id="groups" size="10" class="form-control m-b" multiple>
 | 
			
		||||
                            {% for asset_group in asset_group_all %}
 | 
			
		||||
                                    <option value="{{ asset_group.id }}">{{ asset_group.name }}</option>
 | 
			
		||||
                            {% endfor %}
 | 
			
		||||
                            </select>
 | 
			
		||||
                        </div>
 | 
			
		||||
                        <div class="col-sm-1">
 | 
			
		||||
                            <div class="btn-group" style="margin-top: 50px;">
 | 
			
		||||
                                <button type="button" class="btn btn-white" onclick="move_right('groups', 'groups_selected')"><i class="fa fa-chevron-right"></i></button>
 | 
			
		||||
                                <button type="button" class="btn btn-white" onclick="move_left('groups_selected', 'groups')"><i class="fa fa-chevron-left"></i> </button>
 | 
			
		||||
                            </div>
 | 
			
		||||
                        </div>
 | 
			
		||||
                        <div class="col-sm-3">
 | 
			
		||||
                            <div>
 | 
			
		||||
                                <select id="groups_selected" name="project" class="form-control m-b" size="10"  multiple>
 | 
			
		||||
                                </select>
 | 
			
		||||
                            </div>
 | 
			
		||||
                        </div>
 | 
			
		||||
                    </div>
 | 
			
		||||
 | 
			
		||||
                    <div class="hr-line-dashed"></div>
 | 
			
		||||
                    {{ af.cabinet|bootstrap_horizontal }}
 | 
			
		||||
 | 
			
		||||
                    <div class="hr-line-dashed"></div>
 | 
			
		||||
                    {{ af.comment|bootstrap_horizontal }}
 | 
			
		||||
                    <div class="hr-line-dashed"></div>
 | 
			
		||||
 | 
			
		||||
                   <div class="form-group">
 | 
			
		||||
                       <div class="col-sm-4 col-sm-offset-5">
 | 
			
		||||
                           <button class="btn btn-white" type="submit"> 重置 </button>
 | 
			
		||||
                           <button class="btn btn-primary" id="host_edit"> 提交 </button>
 | 
			
		||||
                       </div>
 | 
			
		||||
                   </div>
 | 
			
		||||
                </form>
 | 
			
		||||
                </div>
 | 
			
		||||
            </div>
 | 
			
		||||
        </div>
 | 
			
		||||
    </div>
 | 
			
		||||
</div>
 | 
			
		||||
<script>
 | 
			
		||||
    $(document).ready(function() {
 | 
			
		||||
        $('#host_edit').click(function () {
 | 
			
		||||
            var args = {};
 | 
			
		||||
            var match = null;
 | 
			
		||||
            var uuid = decodeURIComponent(location.search.substring(1));
 | 
			
		||||
            var reg = /(?:([^&]+)=([^&]+))/g;
 | 
			
		||||
            while((match = reg.exec(uuid))!==null){
 | 
			
		||||
                args[match[1]] = match[2];
 | 
			
		||||
            }
 | 
			
		||||
            var ids = args['uuid'];
 | 
			
		||||
            $('#uuid').val(ids)
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        $('#id_use_default_auth').click(function(){
 | 
			
		||||
            if ($(this).is(':checked')){
 | 
			
		||||
                $('#admin_account').css('display', 'block')
 | 
			
		||||
            }
 | 
			
		||||
            else {
 | 
			
		||||
                $('#admin_account').css('display', 'none')
 | 
			
		||||
            }
 | 
			
		||||
        })
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    function move_left(from, to) {
 | 
			
		||||
        $("#"+from+" option").each(function(){
 | 
			
		||||
            if ( $(this).prop("selected") == true ) {
 | 
			
		||||
                $("#"+to).append(this);
 | 
			
		||||
                $(this).attr("selected",'false');
 | 
			
		||||
            }
 | 
			
		||||
            $(this).attr("selected",'true');
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
    function move_right(from, to) {
 | 
			
		||||
        $("#"+from+" option").each(function(){
 | 
			
		||||
            if ( $(this).prop("selected") == true ) {
 | 
			
		||||
                $("#"+to).append(this);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function move_all(from, to){
 | 
			
		||||
        $("#"+from).children().each(function(){
 | 
			
		||||
            $("#"+to).append(this);
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
</script>
 | 
			
		||||
{% endblock content %}
 | 
			
		||||
</body>
 | 
			
		||||
</html>
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,7 @@
 | 
			
		|||
<div class="col-md-12 column">
 | 
			
		||||
    <div class="alert alert-success alert-dismissable">
 | 
			
		||||
         <button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
 | 
			
		||||
        <h4>
 | 
			
		||||
        </h4> <strong>Nice!</strong>  excel文件已生成请点击 <a href="/static/files/excels/{{ file_name }}" target="_blank" class="alert-link">下载</a>
 | 
			
		||||
    </div>
 | 
			
		||||
</div>
 | 
			
		||||
| 
						 | 
				
			
			@ -23,36 +23,93 @@
 | 
			
		|||
                </div>
 | 
			
		||||
 | 
			
		||||
                <div class="ibox-content">
 | 
			
		||||
                    <div>
 | 
			
		||||
                        {% if session_role_id > 0 %}
 | 
			
		||||
                        <a target="_blank" href="/jasset/asset_add/" class="btn btn-sm btn-primary "> 添加 </a>
 | 
			
		||||
                        {% endif %}
 | 
			
		||||
                        <form id="search_form" method="get" action="" class="pull-right mail-search">
 | 
			
		||||
                    <form id="asset_form">
 | 
			
		||||
                        <div class="col-sm-2" style="padding-left: 0px">
 | 
			
		||||
                            <label>
 | 
			
		||||
                                <select name="idc" class="form-control m-b" onchange="change_info()">
 | 
			
		||||
                                    <option value="">IDC机房</option>
 | 
			
		||||
                                    {% for idc in idc_all %}
 | 
			
		||||
                                        {% ifequal idc.name idc_name %}
 | 
			
		||||
                                            <option value="{{idc.name}}" selected> {{ idc.name }}</option>
 | 
			
		||||
                                        {% else %}
 | 
			
		||||
                                            <option value="{{idc.name}}"> {{ idc.name }}</option>
 | 
			
		||||
                                        {% endifequal %}
 | 
			
		||||
                                    {% endfor %}
 | 
			
		||||
                                </select>
 | 
			
		||||
                            </label>
 | 
			
		||||
                        </div>
 | 
			
		||||
                        <div class="col-sm-2">
 | 
			
		||||
                            <label>
 | 
			
		||||
                                <select name="group" class="form-control m-b" onchange="change_info()">
 | 
			
		||||
                                    <option value="">主机组</option>
 | 
			
		||||
                                    {% for asset_group in asset_group_all %}
 | 
			
		||||
                                        {% ifequal asset_group.name group_name %}
 | 
			
		||||
                                            <option value="{{ asset_group.name }}" selected> {{ asset_group.name }} </option>
 | 
			
		||||
                                        {% else %}
 | 
			
		||||
                                            <option value="{{ asset_group.name }}"> {{ asset_group.name }} </option>
 | 
			
		||||
                                        {% endifequal %}
 | 
			
		||||
                                    {% endfor %}
 | 
			
		||||
                                </select>
 | 
			
		||||
                            </label>
 | 
			
		||||
                        </div>
 | 
			
		||||
 | 
			
		||||
                        <div class="col-sm-2">
 | 
			
		||||
                            <label>
 | 
			
		||||
                                <select name="asset_type" class="form-control m-b" onchange="change_info()">
 | 
			
		||||
                                    <option value="">所有类型</option>
 | 
			
		||||
                                    {% for type in asset_types %}
 | 
			
		||||
                                        {% ifequal type.0|int2str asset_type %}
 | 
			
		||||
                                            <option value="{{ type.0 }}" selected> {{ type.1 }}</option>
 | 
			
		||||
                                        {% else %}
 | 
			
		||||
                                            <option value="{{ type.0 }}"> {{ type.1 }}</option>
 | 
			
		||||
                                        {% endifequal %}
 | 
			
		||||
                                    {% endfor %}
 | 
			
		||||
                                </select>
 | 
			
		||||
                            </label>
 | 
			
		||||
                        </div>
 | 
			
		||||
                        <div class="col-sm-2">
 | 
			
		||||
                            <label>
 | 
			
		||||
                                <select name="status" class="form-control m-b" onchange="change_info()">
 | 
			
		||||
                                    <option value="">状态</option>
 | 
			
		||||
                                    {% for s in asset_status %}
 | 
			
		||||
                                        {% ifequal s.0|int2str status %}
 | 
			
		||||
                                            <option value="{{ s.0 }}" selected> {{ s.1 }}</option>
 | 
			
		||||
                                        {% else %}
 | 
			
		||||
                                            <option value="{{ s.0 }}"> {{ s.1 }}</option>
 | 
			
		||||
                                        {% endifequal %}
 | 
			
		||||
                                    {% endfor %}
 | 
			
		||||
                                </select>
 | 
			
		||||
                            </label>
 | 
			
		||||
                        </div>
 | 
			
		||||
                         <div class="col-sm-4">
 | 
			
		||||
                            <div class="input-group">
 | 
			
		||||
                                <input type="text" class="form-control input-sm" id="search_input" name="keyword" placeholder="Search">
 | 
			
		||||
                                <input type="text" class="form-control m-b" id="search_input" name="keyword" value="{{ keyword }}" placeholder="Search">
 | 
			
		||||
                                <input type="text" style="display: none">
 | 
			
		||||
                                <div class="input-group-btn">
 | 
			
		||||
                                    <button type="submit" class="btn btn-sm btn-primary">
 | 
			
		||||
                                    <button id='search_btn' href="/jasset/asset_list/?search=true" type="button" class="btn btn-xm btn-primary search-btn"  onclick="change_info()">
 | 
			
		||||
                                        - 搜索 -
 | 
			
		||||
                                    </button>
 | 
			
		||||
                                    <button type="button" href="/jasset/asset_list/?export=true" name="export" class="btn btn-xm btn-success search-btn-excel" onclick="return false">
 | 
			
		||||
                                        - 导出 -
 | 
			
		||||
                                    </button>
 | 
			
		||||
                                </div>
 | 
			
		||||
                            </div>
 | 
			
		||||
                        </form>
 | 
			
		||||
                        </div>
 | 
			
		||||
 | 
			
		||||
                    <form id="contents_form" name="contents_form">
 | 
			
		||||
                        <div id="export"></div>
 | 
			
		||||
                        <table class="table table-striped table-bordered table-hover " id="editable" name="editable">
 | 
			
		||||
                            <thead>
 | 
			
		||||
                                <tr>
 | 
			
		||||
                                    <th class="text-center">
 | 
			
		||||
                                    <input id="checkall" type="checkbox" class="i-checks" name="checkall" value="checkall" data-editable='false' onclick="check_all('contents_form')">
 | 
			
		||||
                                        <input id="checkall" type="checkbox" class="i-checks" name="checkall" value="checkall" data-editable='false' onclick="check_all('asset_form')">
 | 
			
		||||
                                    </th>
 | 
			
		||||
                                    <th class="text-center" name="ip"> IP地址 </th>
 | 
			
		||||
                                <th class="text-center"> 端口号 </th>
 | 
			
		||||
                                    <th class="text-center"> 主机名 </th>
 | 
			
		||||
                                    <th class="text-center"> IDC </th>
 | 
			
		||||
                                    <th class="text-center"> 所属主机组 </th>
 | 
			
		||||
{#                                    <th class="text-center"> 配置信息 </th>#}
 | 
			
		||||
                                    <th class="text-center"> 操作系统 </th>
 | 
			
		||||
                                    <th class="text-center"> 使用默认管理 </th>
 | 
			
		||||
                                <th class="text-center"> 激活 </th>
 | 
			
		||||
                                <th class="text-center" name="comment"> 备注 </th>
 | 
			
		||||
                                    <th class="text-center"> 操作 </th>
 | 
			
		||||
                                </tr>
 | 
			
		||||
                            </thead>
 | 
			
		||||
| 
						 | 
				
			
			@ -63,15 +120,17 @@
 | 
			
		|||
                                        <input name="id" value="{{ asset.id }}" type="checkbox" class="i-checks">
 | 
			
		||||
                                    </td>
 | 
			
		||||
                                    <td class="text-center"> {{ asset.ip }} </td>
 | 
			
		||||
                                <td class="text-center"> {{ asset.port }} </td>
 | 
			
		||||
                                <td class="text-center">{{ asset.port }}</td>
 | 
			
		||||
                                    <td class="text-center"> {{ asset.hostname }} </td>
 | 
			
		||||
                                    <td class="text-center"> {{ asset.idc.name }} </td>
 | 
			
		||||
                                    <td class="text-center">{{ asset.group.all|group_str2 }}</td>
 | 
			
		||||
{#                                    <td class="text-center">{{ asset.cpu }}|{{ asset.memory }}|{{ asset.disk }}</td>#}
 | 
			
		||||
                                    <td class="text-center">{{ asset.system_type }}{{ asset.system_version }}</td>
 | 
			
		||||
                                    <td class="text-center"> {{ asset.use_default_auth|bool2str }} </td>
 | 
			
		||||
                                <td class="text-center"> {{ asset.is_active|bool2str }} </td>
 | 
			
		||||
                                <td class="text-center"> {{ asset.comment }} </td>
 | 
			
		||||
                                    <td class="text-center" data-editable='false'>
 | 
			
		||||
                                        <a href="/jasset/asset_detail/?id={{ asset.id }}" class="btn btn-xs btn-primary">详情</a>
 | 
			
		||||
                                        {% ifnotequal session_role_id 0 %}
 | 
			
		||||
                                            <a href="/jasset/asset_edit/?id={{ asset.id }}" class="btn btn-xs btn-info">编辑</a>
 | 
			
		||||
                                            <a href="/jasset/asset_update/?id={{ asset.id }}" class="btn btn-xs btn-info">更新</a>
 | 
			
		||||
                                            <a value="/jasset/asset_del/?id={{ asset.id }}" class="btn btn-xs btn-danger asset_del">删除</a>
 | 
			
		||||
                                        {% endifnotequal %}
 | 
			
		||||
                                    </td>
 | 
			
		||||
| 
						 | 
				
			
			@ -81,8 +140,8 @@
 | 
			
		|||
                        </table>
 | 
			
		||||
                        <div class="row">
 | 
			
		||||
                            <div class="col-sm-6">
 | 
			
		||||
                            <input type="button" id="del_button" class="btn btn-danger btn-sm"  name="del_button" value="删除" onclick="del('contents_form')" />
 | 
			
		||||
                            <input type="button" id="alter_button" class="btn btn-warning btn-sm" name="alter_button" value="修改" onclick="alter('contents_form')" />
 | 
			
		||||
                                <input type="button" id="asset_del" class="btn btn-danger btn-sm"  name="del_button" value="删除"/>
 | 
			
		||||
                                <a value="/jasset/asset_edit_batch/" type="button" class="btn btn-sm btn-warning iframe">修改</a>
 | 
			
		||||
                            </div>
 | 
			
		||||
                            {% include 'paginator.html' %}
 | 
			
		||||
                        </div>
 | 
			
		||||
| 
						 | 
				
			
			@ -124,60 +183,70 @@
 | 
			
		|||
        })
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    function alter(form) {
 | 
			
		||||
        selectData = GetTableDataBox();
 | 
			
		||||
        console.log(selectData[0])
 | 
			
		||||
        if (selectData[1] != 0) {
 | 
			
		||||
            $.ajax({
 | 
			
		||||
                type: "post",
 | 
			
		||||
                url: "/jasset/host_edit/batch/",
 | 
			
		||||
                data: {"editable": selectData[0], "len_table": selectData[1]},
 | 
			
		||||
                success: function (data) {
 | 
			
		||||
                    alert("修改成功");
 | 
			
		||||
                    window.open("/jasset/host_list/", "_self");
 | 
			
		||||
                error: window.open("/jasset/host_list/", "_self");
 | 
			
		||||
    $(".iframe").on('click', function(){
 | 
			
		||||
        var ids = getIDall();
 | 
			
		||||
        if (ids == ''){
 | 
			
		||||
            alert("请至少选择一行!");
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        var url= $(this).attr("value") + '?id=' + ids;
 | 
			
		||||
            index = $.layer({
 | 
			
		||||
                type: 2,
 | 
			
		||||
                title: 'JumpServer - 批量修改主机',
 | 
			
		||||
                maxmin: true,
 | 
			
		||||
                shift: 'top',
 | 
			
		||||
                border: [2, 0.3, '#1AB394'],
 | 
			
		||||
                shade: [0.5, '#000000'],
 | 
			
		||||
                shadeClose: true,
 | 
			
		||||
                area : ['800px' , '600px'],
 | 
			
		||||
                iframe: {src: url},
 | 
			
		||||
                close: function(){
 | 
			
		||||
                    location.replace(location.href);
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    function del(form) {
 | 
			
		||||
        var checkboxes = document.getElementById(form);
 | 
			
		||||
        var id_list = {};
 | 
			
		||||
        var j = 0;
 | 
			
		||||
        for (var i = 0; i < checkboxes.elements.length; i++) {
 | 
			
		||||
            if (checkboxes.elements[i].type == "checkbox" && checkboxes.elements[i].checked == true && checkboxes.elements[i].value != "checkall") {
 | 
			
		||||
                id_list[j] = checkboxes.elements[i].value;
 | 
			
		||||
                j++;
 | 
			
		||||
    $('.search-btn-excel').unbind('click').bind('click',function(){
 | 
			
		||||
        var url= $(this).attr("href");
 | 
			
		||||
        console.log(url);
 | 
			
		||||
        $.ajax({
 | 
			
		||||
            type: "GET",
 | 
			
		||||
            url: url,
 | 
			
		||||
            data: $("#asset_form").serialize(),
 | 
			
		||||
            success: function (data) {
 | 
			
		||||
                $("#export").html(data);
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    $('#asset_del').click(function () {
 | 
			
		||||
        var asset_id_all = getIDall();
 | 
			
		||||
        console.log(asset_id_all);
 | 
			
		||||
        if (asset_id_all == ''){
 | 
			
		||||
            alert("请至少选择一行!");
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        if (confirm("确定删除")) {
 | 
			
		||||
            $.ajax({
 | 
			
		||||
                type: "POST",
 | 
			
		||||
                url: "/jasset/host_del/multi/",
 | 
			
		||||
                data: {"id_list": id_list, "len_list": j},
 | 
			
		||||
                success: function (data) {
 | 
			
		||||
                    window.open("/jasset/host_list/", "_self");
 | 
			
		||||
                type: "post",
 | 
			
		||||
                data: {asset_id_all: asset_id_all},
 | 
			
		||||
                url: "/jasset/asset_del/?arg=batch",
 | 
			
		||||
                success: function () {
 | 
			
		||||
                    parent.location.reload();
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
{#    function host_search(){#}
 | 
			
		||||
{#        $.ajax({#}
 | 
			
		||||
{#            type: "GET",#}
 | 
			
		||||
{#            url: "/jasset/search/",#}
 | 
			
		||||
{#            data: $("#search_form").serialize(),#}
 | 
			
		||||
{#            success: function (data) {#}
 | 
			
		||||
{#                $("#contents_form").html(data);#}
 | 
			
		||||
{#            }#}
 | 
			
		||||
{#        });#}
 | 
			
		||||
{#    }#}
 | 
			
		||||
 | 
			
		||||
    function change_info(){
 | 
			
		||||
        var args = $("#asset_form").serialize();
 | 
			
		||||
        window.location = "/jasset/asset_list/?" + args
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    $("#search_input").keydown(function(e){
 | 
			
		||||
        if(e.keyCode==13){
 | 
			
		||||
            host_search()
 | 
			
		||||
            change_info()
 | 
			
		||||
            }
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -187,7 +256,6 @@
 | 
			
		|||
        $.ajax({
 | 
			
		||||
            type: "GET",
 | 
			
		||||
            url: url,
 | 
			
		||||
//            data: $("#search_form").serialize(),
 | 
			
		||||
            success: function (data) {
 | 
			
		||||
                $("#j_group_" + id).html(data);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,13 @@
 | 
			
		|||
{% for field in af %}
 | 
			
		||||
<div class="alert alert-warning text-center"> {{ field.errors }}</div>
 | 
			
		||||
{{ field.label_tag }}: {{ field }}
 | 
			
		||||
{% endfor %}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
{% if af.errors %}
 | 
			
		||||
<ul>
 | 
			
		||||
{% for error in af.errors %}
 | 
			
		||||
<li><strong>{{ error }}</strong></li>
 | 
			
		||||
{% endfor %}
 | 
			
		||||
</ul>
 | 
			
		||||
{% endif %}
 | 
			
		||||
| 
						 | 
				
			
			@ -22,7 +22,7 @@
 | 
			
		|||
        <div class="col-lg-10">
 | 
			
		||||
            <div class="ibox float-e-margins">
 | 
			
		||||
                <div id="ibox-content" class="ibox-title">
 | 
			
		||||
                    <h5> 填写资产组基本信息 </h5>
 | 
			
		||||
                    <h5> 填写主机组基本信息 </h5>
 | 
			
		||||
                    <div class="ibox-tools">
 | 
			
		||||
                        <a class="collapse-link">
 | 
			
		||||
                            <i class="fa fa-chevron-up"></i>
 | 
			
		||||
| 
						 | 
				
			
			@ -30,37 +30,34 @@
 | 
			
		|||
                        <a class="dropdown-toggle" data-toggle="dropdown" href="#">
 | 
			
		||||
                            <i class="fa fa-wrench"></i>
 | 
			
		||||
                        </a>
 | 
			
		||||
                        <ul class="dropdown-menu dropdown-user">
 | 
			
		||||
                            <li><a href="#">未启用 1</a>
 | 
			
		||||
                            </li>
 | 
			
		||||
                            <li><a href="#">未启用 2</a>
 | 
			
		||||
                            </li>
 | 
			
		||||
                        </ul>
 | 
			
		||||
                        <a class="close-link">
 | 
			
		||||
                            <i class="fa fa-times"></i>
 | 
			
		||||
                        </a>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
 | 
			
		||||
{#                <select id="assets_total" name="assets" class="form-control m-b" size="12" multiple style="display: none">#}
 | 
			
		||||
{#                    {% for asset in assets_all %}#}
 | 
			
		||||
{#                        <option value="{{ asset.id }}">{{ asset.ip }}</option>#}
 | 
			
		||||
{#                    {% endfor %}#}
 | 
			
		||||
{#                </select>#}
 | 
			
		||||
{##}
 | 
			
		||||
{#                <select id="asset_select_total" name="j_hosts" class="form-control m-b" size="12"  multiple style="display: none">#}
 | 
			
		||||
{#                    {% for asset in eposts %}#}
 | 
			
		||||
{#                    <option value="{{ asset.id }}">{{ asset.ip }}</option>#}
 | 
			
		||||
{#                    {% endfor %}#}
 | 
			
		||||
{#                </select>#}
 | 
			
		||||
                <select id="assets_total" name="assets" class="form-control m-b" size="12" multiple style="display: none">
 | 
			
		||||
                    {% for asset in asset_all %}
 | 
			
		||||
                        <option value="{{ asset.id }}">{{ asset.ip }}</option>
 | 
			
		||||
                    {% endfor %}
 | 
			
		||||
                </select>
 | 
			
		||||
 | 
			
		||||
                <div class="ibox-content">
 | 
			
		||||
                    {% if error %}
 | 
			
		||||
                        <div class="alert alert-warning text-center">{{ error }}</div>
 | 
			
		||||
                    {% if emg %}
 | 
			
		||||
                        <div class="alert alert-warning text-center">{{ emg }}</div>
 | 
			
		||||
                    {% endif %}
 | 
			
		||||
                    {% if msg %}
 | 
			
		||||
                        <div class="alert alert-success text-center">{{ msg }}</div>
 | 
			
		||||
                    {% if smg %}
 | 
			
		||||
                        <div class="alert alert-success text-center">{{ smg }}</div>
 | 
			
		||||
                    {% endif %}
 | 
			
		||||
                    <form id="assetForm" method="post" class="form-horizontal">
 | 
			
		||||
                        <div class="form-group">
 | 
			
		||||
                            <label class="col-sm-2 control-label"> 主机组名<span class="red-fonts">*</span></label>
 | 
			
		||||
                            <div class="col-sm-8">
 | 
			
		||||
                                <input type="text" placeholder="Name" name="name" class="form-control">
 | 
			
		||||
                            </div>
 | 
			
		||||
                        <div class="form-group"><label class="col-sm-2 control-label"> 主机组名<span class="red-fonts">*</span></label>
 | 
			
		||||
                            <div class="col-sm-8" name="group_id" value="{{ post.id }}"><input type="text" value="{{ group.name }}" placeholder="Name" name="name" class="form-control"></div>
 | 
			
		||||
                        </div>
 | 
			
		||||
 | 
			
		||||
                        <div class="hr-line-dashed"></div>
 | 
			
		||||
| 
						 | 
				
			
			@ -92,7 +89,7 @@
 | 
			
		|||
                            <div class="col-sm-1">
 | 
			
		||||
                                <div class="btn-group" style="margin-top: 60px;">
 | 
			
		||||
                                    <button type="button" class="btn btn-white" onclick="move('assets', 'asset_select', 'assets_total', 'asset_select_total'  )"><i class="fa fa-chevron-right"></i></button>
 | 
			
		||||
                                    <button type="button" class="btn btn-white" onclick="move('asset_select', 'assets', 'asset_select_total', 'assets_total')"><i class="fa fa-chevron-left"></i> </button>
 | 
			
		||||
                                    <button type="button" class="btn btn-white" onclick="move_left('asset_select', 'assets', 'asset_select_total', 'assets_total')"><i class="fa fa-chevron-left"></i> </button>
 | 
			
		||||
                                </div>
 | 
			
		||||
                            </div>
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -104,18 +101,15 @@
 | 
			
		|||
                        </div>
 | 
			
		||||
 | 
			
		||||
                        <div class="hr-line-dashed"></div>
 | 
			
		||||
                        <div class="form-group">
 | 
			
		||||
                            <label class="col-sm-2 control-label"> 备注 </label>
 | 
			
		||||
                            <div class="col-sm-8">
 | 
			
		||||
                                <input type="text" placeholder="Comment" name="comment" class="form-control">
 | 
			
		||||
                            </div>
 | 
			
		||||
                        <div class="form-group"><label class="col-sm-2 control-label"> 备注 </label>
 | 
			
		||||
                            <div class="col-sm-8"><input type="text" value="" placeholder="comment" name="comment" class="form-control"></div>
 | 
			
		||||
                        </div>
 | 
			
		||||
 | 
			
		||||
                        <div class="hr-line-dashed"></div>
 | 
			
		||||
                        <div class="form-group">
 | 
			
		||||
                            <div class="col-sm-4 col-sm-offset-2">
 | 
			
		||||
                                <button class="btn btn-white" type="reset"> 重置 </button>
 | 
			
		||||
                                <button class="btn btn-primary" type="submit" onclick="on_submit('groups_selected')  "> 提交 </button>
 | 
			
		||||
                            <div class="col-sm-4 col-sm-offset-5">
 | 
			
		||||
                                <button class="btn btn-white" type="submit"> 重置 </button>
 | 
			
		||||
                                <button class="btn btn-primary" id="submit_button" type="submit" onclick="on_submit('groups_selected')  "> 提交 </button>
 | 
			
		||||
                            </div>
 | 
			
		||||
                        </div>
 | 
			
		||||
                    </form>
 | 
			
		||||
| 
						 | 
				
			
			@ -159,16 +153,6 @@
 | 
			
		|||
            })
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
//    $('#search').keyup(function() {
 | 
			
		||||
//        var $rows = $('#hosts option');
 | 
			
		||||
//        var val = $.trim($(this).val()).replace(/ +/g, ' ').toLowerCase();
 | 
			
		||||
//
 | 
			
		||||
//        $rows.show().filter(function() {
 | 
			
		||||
//            var text = $(this).text().replace(/\s+/g, ' ').toLowerCase();
 | 
			
		||||
//            return !~text.indexOf(val);
 | 
			
		||||
//        }).hide();
 | 
			
		||||
//    });
 | 
			
		||||
 | 
			
		||||
    function change_dept(dept_id){
 | 
			
		||||
    $.get('/jasset/dept_host_ajax/',
 | 
			
		||||
            {'id': dept_id},
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -30,7 +30,7 @@
 | 
			
		|||
 | 
			
		||||
                <div class="ibox-content">
 | 
			
		||||
                    <div class="">
 | 
			
		||||
                        <a target="_blank" href="/jasset/host_add" class="btn btn-sm btn-primary"> 添加主机 </a>
 | 
			
		||||
                        <a target="_blank" href="/jasset/asset_add" class="btn btn-sm btn-primary"> 添加主机 </a>
 | 
			
		||||
                        <b class="pull-right">提示: 此页面删除只从本主机组中剔除主机               </b>
 | 
			
		||||
                    </div>
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -41,9 +41,8 @@
 | 
			
		|||
                                <th class="text-center"><input id="checkall" type="checkbox" class="i-checks" name="checkall" value="checkall" data-editable='false' onclick="check_all('contents_form')"></th>
 | 
			
		||||
                                <th class="text-center" name="j_ip"> IP地址 </th>
 | 
			
		||||
                                <th class="text-center"> 端口号 </th>
 | 
			
		||||
                                <th class="text-center" name="j_type"> 登录方式 </th>
 | 
			
		||||
                                <th class="text-center" name="j_idc"> 所属IDC </th>
 | 
			
		||||
                                <th class="text-center" id="group_id" value="{{ group.id }}"> 所属业务组 </th>
 | 
			
		||||
                                <th class="text-center" id="group_id" value="{{ group.id }}"> 所属主机组 </th>
 | 
			
		||||
                                <th class="text-center"> 是否激活 </th>
 | 
			
		||||
                                <th class="text-center" name="j_time"> 添加时间 </th>
 | 
			
		||||
                                <th class="text-center" name="j_comment"> 备注 </th>
 | 
			
		||||
| 
						 | 
				
			
			@ -51,21 +50,20 @@
 | 
			
		|||
                            </tr>
 | 
			
		||||
                        </thead>
 | 
			
		||||
                        <tbody>
 | 
			
		||||
                        {% for post in contacts.object_list %}
 | 
			
		||||
                        {% for asset in contacts.object_list %}
 | 
			
		||||
                            <tr class="gradeX">
 | 
			
		||||
                                <td class="text-center" name="j_id" value="{{ post.id }}" data-editable='false'><input name="id" value="{{ post.id }}" type="checkbox" class="i-checks"></td>
 | 
			
		||||
                                <td class="text-center" name="j_ip"> {{ post.ip }} </td>
 | 
			
		||||
                                <td class="text-center" name="j_port"> {{ post.port }} </td>
 | 
			
		||||
                                <td class="text-center" name="j_type"> {{ post.login_type|get_login_type }} </td>
 | 
			
		||||
                                <td class="text-center" name="j_idc"> {{ post.idc.name }} </td>
 | 
			
		||||
                                <td class="text-center" name="j_group">{{ post.bis_group.all | group_str2 }}</td>
 | 
			
		||||
                                <td class="text-center" name="j_active"> {{ post.is_active|bool2str }} </td>
 | 
			
		||||
                                <td class="text-center"> {{ post.date_added|date:"Y-m-d H:i:s" }} </td>
 | 
			
		||||
                                <td class="text-center" name="j_comment"> {{ post.comment }} </td>
 | 
			
		||||
                                <td class="text-center" name="j_id" value="{{ asset.id }}" data-editable='false'><input name="id" value="{{ asset.id }}" type="checkbox" class="i-checks"></td>
 | 
			
		||||
                                <td class="text-center" name="j_ip"> {{ asset.ip }} </td>
 | 
			
		||||
                                <td class="text-center" name="j_port"> {{ asset.port }} </td>
 | 
			
		||||
                                <td class="text-center" name="j_idc"> {{ asset.idc.name }} </td>
 | 
			
		||||
                                <td class="text-center" name="j_group">{{ asset.bis_group.all | group_str2 }}</td>
 | 
			
		||||
                                <td class="text-center" name="j_active"> {{ asset.is_active|bool2str }} </td>
 | 
			
		||||
                                <td class="text-center"> {{ asset.date_added|date:"Y-m-d H:i:s" }} </td>
 | 
			
		||||
                                <td class="text-center" name="j_comment"> {{ asset.comment }} </td>
 | 
			
		||||
                                <td class="text-center" data-editable='false'>
 | 
			
		||||
                                    <a href="/jasset/host_detail/?id={{ post.id }}" class="iframe btn btn-xs btn-primary">详情</a>
 | 
			
		||||
                                    <a href="/jasset/host_edit/?id={{ post.id }}" class="btn btn-xs btn-info">编辑</a>
 | 
			
		||||
                                    <a href="/jasset/group_del_host/?id={{ post.id }}&gid={{ group.id }}" class="btn btn-xs btn-danger">删除</a>
 | 
			
		||||
                                    <a href="/jasset/host_detail/?id={{ asset.id }}" class="iframe btn btn-xs btn-primary">详情</a>
 | 
			
		||||
                                    <a href="/jasset/host_edit/?id={{ asset.id }}" class="btn btn-xs btn-info">编辑</a>
 | 
			
		||||
                                    <a href="/jasset/group_del_host/?id={{ asset.id }}&gid={{ group.id }}" class="btn btn-xs btn-danger">删除</a>
 | 
			
		||||
                                </td>
 | 
			
		||||
                            </tr>
 | 
			
		||||
                        {% endfor %}
 | 
			
		||||
| 
						 | 
				
			
			@ -165,7 +163,7 @@
 | 
			
		|||
        selectData = GetTableDataBox();
 | 
			
		||||
        if (selectData[1] != 0) {
 | 
			
		||||
            $.ajax({
 | 
			
		||||
                type: "post",
 | 
			
		||||
                type: "asset",
 | 
			
		||||
                url: "/jasset/host_edit/batch/",
 | 
			
		||||
                data: {"editable": selectData[0], "len_table": selectData[1]},
 | 
			
		||||
                success: function (data) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -43,13 +43,13 @@
 | 
			
		|||
                    </div>
 | 
			
		||||
 | 
			
		||||
                 <select id="assets_total" name="assets" class="form-control m-b" size="12" multiple style="display: none">
 | 
			
		||||
                    {% for asset in posts %}
 | 
			
		||||
                    {% for asset in asset_all %}
 | 
			
		||||
                        <option value="{{ asset.id }}">{{ asset.ip }}</option>
 | 
			
		||||
                    {% endfor %}
 | 
			
		||||
                </select>
 | 
			
		||||
 | 
			
		||||
                <select id="asset_select_total" name="j_hosts" class="form-control m-b" size="12"  multiple style="display: none">
 | 
			
		||||
                    {% for asset in eposts %}
 | 
			
		||||
                <select id="asset_select_total" name="asset_select" class="form-control m-b" size="12"  multiple style="display: none">
 | 
			
		||||
                    {% for asset in asset_select %}
 | 
			
		||||
                    <option value="{{ asset.id }}">{{ asset.ip }}</option>
 | 
			
		||||
                    {% endfor %}
 | 
			
		||||
                </select>
 | 
			
		||||
| 
						 | 
				
			
			@ -63,14 +63,7 @@
 | 
			
		|||
                    {% endif %}
 | 
			
		||||
                    <form id="assetForm" method="post" class="form-horizontal">
 | 
			
		||||
                        <div class="form-group"><label class="col-sm-2 control-label"> 主机组名<span class="red-fonts">*</span></label>
 | 
			
		||||
                            <div class="col-sm-8" name="group_id" value="{{ post.id }}"><input type="text" value="{{ group.name }}" placeholder="网站" name="j_group" class="form-control"></div>
 | 
			
		||||
                        </div>
 | 
			
		||||
 | 
			
		||||
                        <div class="hr-line-dashed"></div>
 | 
			
		||||
                        <div class="form-group">
 | 
			
		||||
                            <label for="j_dept" class="col-lg-2 control-label">所属部门<span class="red-fonts" style="">*</span></label>
 | 
			
		||||
                                <input type="text" name="j_dept" value="{{  group.dept.id }}" style="display: none">
 | 
			
		||||
                                <div class="col-sm-8"><input type="text"  value="{{  group.dept.name }}" class="form-control" readonly="readonly"></div>
 | 
			
		||||
                            <div class="col-sm-8" name="group_id" value="{{ group.id }}"><input type="text" value="{{ group.name }}" placeholder="Name" name="name" class="form-control"></div>
 | 
			
		||||
                        </div>
 | 
			
		||||
 | 
			
		||||
                       <div class="hr-line-dashed"></div>
 | 
			
		||||
| 
						 | 
				
			
			@ -92,8 +85,8 @@
 | 
			
		|||
                            <div class="col-sm-4">
 | 
			
		||||
                                <div>
 | 
			
		||||
                                    <select id="assets" name="assets" class="form-control m-b" size="12" multiple>
 | 
			
		||||
                                        {% for post in posts %}
 | 
			
		||||
                                        <option value="{{ post.id }}">{{ post.ip }}</option>
 | 
			
		||||
                                        {% for asset in asset_no_select %}
 | 
			
		||||
                                        <option value="{{ asset.id }}">{{ asset.ip }}</option>
 | 
			
		||||
                                        {% endfor %}
 | 
			
		||||
                                    </select>
 | 
			
		||||
                                </div>
 | 
			
		||||
| 
						 | 
				
			
			@ -108,8 +101,8 @@
 | 
			
		|||
 | 
			
		||||
                            <div class="col-sm-3">
 | 
			
		||||
                                <div>
 | 
			
		||||
                                    <select id="asset_select" name="j_hosts" class="form-control m-b" size="12"  multiple>
 | 
			
		||||
                                        {% for asset in eposts %}
 | 
			
		||||
                                    <select id="asset_select" name="asset_select" class="form-control m-b" size="12"  multiple>
 | 
			
		||||
                                        {% for asset in asset_select %}
 | 
			
		||||
                                            <option value="{{ asset.id }}">{{ asset.ip }}</option>
 | 
			
		||||
                                        {% endfor %}
 | 
			
		||||
                                    </select>
 | 
			
		||||
| 
						 | 
				
			
			@ -119,7 +112,7 @@
 | 
			
		|||
 | 
			
		||||
                        <div class="hr-line-dashed"></div>
 | 
			
		||||
                        <div class="form-group"><label class="col-sm-2 control-label"> 备注 </label>
 | 
			
		||||
                            <div class="col-sm-8"><input type="text" value="{{ group.comment }}" placeholder=包括web组所有主机 name="j_comment" class="form-control"></div>
 | 
			
		||||
                            <div class="col-sm-8"><input type="text" value="{{ group.comment }}" name="comment" class="form-control"></div>
 | 
			
		||||
                        </div>
 | 
			
		||||
 | 
			
		||||
                        <div class="hr-line-dashed"></div>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,95 @@
 | 
			
		|||
{% extends 'base.html' %}
 | 
			
		||||
{% block content %}
 | 
			
		||||
{% load bootstrap %}
 | 
			
		||||
{% include 'nav_cat_bar.html' %}
 | 
			
		||||
<div class="wrapper wrapper-content animated fadeInRight">
 | 
			
		||||
    <div class="row">
 | 
			
		||||
        <div class="col-lg-10">
 | 
			
		||||
            <div class="ibox float-e-margins">
 | 
			
		||||
                <div id="ibox-content" class="ibox-title">
 | 
			
		||||
                    <h5> 填写IDC基本信息 </h5>
 | 
			
		||||
                    <div class="ibox-tools">
 | 
			
		||||
                        <a class="collapse-link">
 | 
			
		||||
                            <i class="fa fa-chevron-up"></i>
 | 
			
		||||
                        </a>
 | 
			
		||||
                        <a class="dropdown-toggle" data-toggle="dropdown" href="#">
 | 
			
		||||
                            <i class="fa fa-wrench"></i>
 | 
			
		||||
                        </a>
 | 
			
		||||
                        <ul class="dropdown-menu dropdown-user">
 | 
			
		||||
                        </ul>
 | 
			
		||||
                        <a class="close-link">
 | 
			
		||||
                            <i class="fa fa-times"></i>
 | 
			
		||||
                        </a>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
 | 
			
		||||
                <div class="ibox-content">
 | 
			
		||||
                    {% if emg %}
 | 
			
		||||
                        <div class="alert alert-warning text-center">{{ emg }}</div>
 | 
			
		||||
                    {% endif %}
 | 
			
		||||
                    {% if smg %}
 | 
			
		||||
                        <div class="alert alert-success text-center">{{ smg }}</div>
 | 
			
		||||
                    {% endif %}
 | 
			
		||||
                    <form id="assetForm" method="post" class="form-horizontal">
 | 
			
		||||
                        {{ idc_form.name|bootstrap_horizontal }}
 | 
			
		||||
 | 
			
		||||
                        <div class="hr-line-dashed"></div>
 | 
			
		||||
                        {{ idc_form.bandwidth|bootstrap_horizontal }}
 | 
			
		||||
 | 
			
		||||
                        <div class="hr-line-dashed"></div>
 | 
			
		||||
                        {{ idc_form.operator|bootstrap_horizontal }}
 | 
			
		||||
 | 
			
		||||
                        <div class="hr-line-dashed"></div>
 | 
			
		||||
                        {{ idc_form.linkman|bootstrap_horizontal }}
 | 
			
		||||
 | 
			
		||||
                        <div class="hr-line-dashed"></div>
 | 
			
		||||
                        {{ idc_form.phone|bootstrap_horizontal }}
 | 
			
		||||
 | 
			
		||||
                        <div class="hr-line-dashed"></div>
 | 
			
		||||
                        {{ idc_form.address|bootstrap_horizontal }}
 | 
			
		||||
 | 
			
		||||
                        <div class="hr-line-dashed"></div>
 | 
			
		||||
                        {{ idc_form.network|bootstrap_horizontal }}
 | 
			
		||||
 | 
			
		||||
                        <div class="hr-line-dashed"></div>
 | 
			
		||||
                        {{ idc_form.comment|bootstrap_horizontal }}
 | 
			
		||||
 | 
			
		||||
                        <div class="hr-line-dashed"></div>
 | 
			
		||||
                        <div class="form-group">
 | 
			
		||||
                            <div class="col-sm-4 col-sm-offset-5">
 | 
			
		||||
                                <button class="btn btn-white" type="submit"> 重置 </button>
 | 
			
		||||
                                <button class="btn btn-primary" type="sumbit"> 提交 </button>
 | 
			
		||||
                            </div>
 | 
			
		||||
                        </div>
 | 
			
		||||
                    </form>
 | 
			
		||||
                </div>
 | 
			
		||||
            </div>
 | 
			
		||||
        </div>
 | 
			
		||||
    </div>
 | 
			
		||||
</div>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
    var required_fields = ["id_name"];
 | 
			
		||||
    required_fields.forEach(function(field) {
 | 
			
		||||
        $('label[for="' + field + '"]').parent().addClass("required");
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    $('#assetForm').validator({
 | 
			
		||||
        timely: 2,
 | 
			
		||||
        theme: "yellow_right_effect",
 | 
			
		||||
        fields: {
 | 
			
		||||
            "j_idc": {
 | 
			
		||||
                rule: "required",
 | 
			
		||||
                tip: "输入IDC名",
 | 
			
		||||
                ok: "",
 | 
			
		||||
                msg: {required: "IDC名必须填写!"},
 | 
			
		||||
                data: {'data-ok':"主机名可以使用", 'data-msg-required': '主机名已正确'}
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
        valid: function(form) {
 | 
			
		||||
            form.submit();
 | 
			
		||||
        }
 | 
			
		||||
    });
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
{% endblock %}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,229 @@
 | 
			
		|||
{% extends 'base.html' %}
 | 
			
		||||
{% load mytags %}
 | 
			
		||||
{% block content %}
 | 
			
		||||
{% include 'nav_cat_bar.html' %}
 | 
			
		||||
 | 
			
		||||
<div class="wrapper wrapper-content animated fadeInRight">
 | 
			
		||||
    <div class="row">
 | 
			
		||||
        <div class="col-lg-12">
 | 
			
		||||
            <div class="ibox float-e-margins" id="all">
 | 
			
		||||
                <div class="ibox-title">
 | 
			
		||||
                    <h5> IDC<span class="text-info"> {{ idc.name }} </span>详细信息列表 </h5>
 | 
			
		||||
                    <div class="ibox-tools">
 | 
			
		||||
                        <a class="collapse-link">
 | 
			
		||||
                            <i class="fa fa-chevron-up"></i>
 | 
			
		||||
                        </a>
 | 
			
		||||
                        <a class="dropdown-toggle" data-toggle="dropdown" href="#">
 | 
			
		||||
                            <i class="fa fa-wrench"></i>
 | 
			
		||||
                        </a>
 | 
			
		||||
                        <ul class="dropdown-menu dropdown-user">
 | 
			
		||||
                            <li><a href="#">未启用 1</a>
 | 
			
		||||
                            </li>
 | 
			
		||||
                            <li><a href="#">未启用 2</a>
 | 
			
		||||
                            </li>
 | 
			
		||||
                        </ul>
 | 
			
		||||
                        <a class="close-link">
 | 
			
		||||
                            <i class="fa fa-times"></i>
 | 
			
		||||
                        </a>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
 | 
			
		||||
                <div class="ibox-content">
 | 
			
		||||
                    {% if emg %}
 | 
			
		||||
                        <div class="alert alert-warning text-center">{{ emg }}</div>
 | 
			
		||||
                    {% endif %}
 | 
			
		||||
                    {% if smg %}
 | 
			
		||||
                        <div class="alert alert-success text-center">{{ smg }}</div>
 | 
			
		||||
                    {% endif %}
 | 
			
		||||
                    <div class="">
 | 
			
		||||
                    <a target="_blank" href="/jasset/host_add" class="btn btn-sm btn-primary "> 添加主机 </a>
 | 
			
		||||
                    </div>
 | 
			
		||||
 | 
			
		||||
                    <form id="asset_form" name="asset_form">
 | 
			
		||||
                    <table class="table table-striped table-bordered table-hover " id="editable" name="editable">
 | 
			
		||||
                        <thead>
 | 
			
		||||
                            <tr>
 | 
			
		||||
                                <th class="text-center">
 | 
			
		||||
                                    <input id="checkall" type="checkbox" class="i-checks" name="checkall" value="checkall" data-editable='false' onclick="check_all('asset_form')">
 | 
			
		||||
                                </th>
 | 
			
		||||
                                <th class="text-center" name="ip"> IP地址 </th>
 | 
			
		||||
                                <th class="text-center"> 主机名 </th>
 | 
			
		||||
                                <th class="text-center"> IDC </th>
 | 
			
		||||
                                <th class="text-center"> 所属主机组 </th>
 | 
			
		||||
                                <th class="text-center"> 配置信息 </th>
 | 
			
		||||
                                <th class="text-center"> 使用默认管理 </th>
 | 
			
		||||
                                <th class="text-center"> 操作 </th>
 | 
			
		||||
                            </tr>
 | 
			
		||||
                        </thead>
 | 
			
		||||
                        <tbody>
 | 
			
		||||
                        {% for asset in contact_list %}
 | 
			
		||||
                            <tr class="gradeX">
 | 
			
		||||
                                <td class="text-center" name="id" value="{{ asset.id }}" data-editable='false'>
 | 
			
		||||
                                    <input name="id" value="{{ asset.id }}" type="checkbox" class="i-checks">
 | 
			
		||||
                                </td>
 | 
			
		||||
                                <td class="text-center"> {{ asset.ip }} </td>
 | 
			
		||||
                                <td class="text-center"> {{ asset.hostname }} </td>
 | 
			
		||||
                                <td class="text-center"> {{ asset.idc.name }} </td>
 | 
			
		||||
                                <td class="text-center">{{ asset.group.all|group_str2 }}</td>
 | 
			
		||||
                                <td class="text-center">{{ asset.cpu }}|{{ asset.memory }}|{{ asset.disk }}</td>
 | 
			
		||||
                                <td class="text-center"> {{ asset.use_default_auth|bool2str }} </td>
 | 
			
		||||
                                <td class="text-center" data-editable='false'>
 | 
			
		||||
                                    <a href="/jasset/asset_detail/?id={{ asset.id }}" class="btn btn-xs btn-primary">详情</a>
 | 
			
		||||
                                    {% ifnotequal session_role_id 0 %}
 | 
			
		||||
                                        <a href="/jasset/asset_edit/?id={{ asset.id }}" class="btn btn-xs btn-info">编辑</a>
 | 
			
		||||
                                        <a value="/jasset/asset_del/?id={{ asset.id }}" class="btn btn-xs btn-danger asset_del">删除</a>
 | 
			
		||||
                                    {% endifnotequal %}
 | 
			
		||||
                                </td>
 | 
			
		||||
                            </tr>
 | 
			
		||||
                        {% endfor %}
 | 
			
		||||
                        </tbody>
 | 
			
		||||
                    </table>
 | 
			
		||||
                    <div class="row">
 | 
			
		||||
                        <div class="col-sm-6">
 | 
			
		||||
                            <input type="button" id="asset_del" class="btn btn-danger btn-sm"  name="del_button" value="删除" />
 | 
			
		||||
                            <a value="/jasset/asset_edit_batch/" type="button" class="btn btn-sm btn-warning iframe">修改</a>
 | 
			
		||||
                        </div>
 | 
			
		||||
                        <div class="col-sm-6">
 | 
			
		||||
                            <div class="dataTables_paginate paging_simple_numbers" id="editable_paginate">
 | 
			
		||||
                                <ul class="pagination" style="margin-top: 0; float: right">
 | 
			
		||||
                                {% if keyword %}
 | 
			
		||||
                                    {% if contacts.has_previous %}
 | 
			
		||||
                                        <li class="paginate_button previous" aria-controls="editable" tabindex="0" id="editable_previous">
 | 
			
		||||
                                            <a href="?keyword={{ keyword }}&page={{ contacts.previous_page_number }}">Previous</a>
 | 
			
		||||
                                        </li>
 | 
			
		||||
                                    {% else %}
 | 
			
		||||
                                        <li class="paginate_button previous disabled" aria-controls="editable" tabindex="0" id="editable_previous">
 | 
			
		||||
                                             <a href="#">Previous</a>
 | 
			
		||||
                                        </li>
 | 
			
		||||
                                    {% endif %}
 | 
			
		||||
                                    {% ifequal show_first 1 %}
 | 
			
		||||
                                        <li class="paginate_button" aria-controls="editable" tabindex="0"><a href="?keyword={{ keyword }}&page=1&id={{ idc.id }}"  title="第1页">1...</a></li>
 | 
			
		||||
                                    {% endifequal %}
 | 
			
		||||
                                    {% for page in page_range %}
 | 
			
		||||
                                        {% ifequal current_page page %}
 | 
			
		||||
                                            <li class="paginate_button active"  aria-controls="editable" tabindex="0"><a href="?keyword={{ keyword }}&page={{ page }}&id={{ idc.id }}"  title="第{{ page }}页">{{ page }}</a></li>
 | 
			
		||||
                                        {% else %}
 | 
			
		||||
                                            <li class="paginate_button" aria-controls="editable" tabindex="0"><a href="?keyword={{ keyword }}&page={{ page }}&id={{ idc.id }}"  title="第{{ page }}页">{{ page }}</a></li>
 | 
			
		||||
                                        {% endifequal %}
 | 
			
		||||
                                    {% endfor %}
 | 
			
		||||
                                    {% ifequal show_end 1 %}
 | 
			
		||||
                                        <li class="paginate_button" aria-controls="editable" tabindex="0"><a href="?keyword={{ keyword }}&page={{ p.num_pages }}&id={{ idc.id }}"  title="第{{ page }}页">...{{ p.num_pages }}</a></li>
 | 
			
		||||
                                    {% endifequal %}
 | 
			
		||||
                                    {% if contacts.has_next %}
 | 
			
		||||
                                        <li class="paginate_button next" aria-controls="editable" tabindex="0" id="editable_next">
 | 
			
		||||
                                            <a href="?keyword={{ keyword }}&page={{ contacts.next_page_number }}&id={{ idc.id }}">Next</a>
 | 
			
		||||
                                        </li>
 | 
			
		||||
                                    {% else %}
 | 
			
		||||
                                        <li class="paginate_button next disabled" aria-controls="editable" tabindex="0" id="editable_next">
 | 
			
		||||
                                            <a href="#">Next</a>
 | 
			
		||||
                                        </li>
 | 
			
		||||
                                    {% endif %}
 | 
			
		||||
 | 
			
		||||
                                {% else %}
 | 
			
		||||
                                    {% if contacts.has_previous %}
 | 
			
		||||
                                        <li class="paginate_button previous" aria-controls="editable" tabindex="0" id="editable_previous">
 | 
			
		||||
                                            <a href="?page={{ contacts.previous_page_number }}&id={{ idc.id }}">Previous</a>
 | 
			
		||||
                                        </li>
 | 
			
		||||
                                    {% else %}
 | 
			
		||||
                                        <li class="paginate_button previous disabled" aria-controls="editable" tabindex="0" id="editable_previous">
 | 
			
		||||
                                             <a href="#">Previous</a>
 | 
			
		||||
                                        </li>
 | 
			
		||||
                                    {% endif %}
 | 
			
		||||
                                    {% ifequal show_first 1 %}
 | 
			
		||||
                                        <li class="paginate_button" aria-controls="editable" tabindex="0"><a href="?page=1&id={{ idc.id }}"  title="第1页">1...</a></li>
 | 
			
		||||
                                    {% endifequal %}
 | 
			
		||||
                                    {% for page in page_range %}
 | 
			
		||||
                                        {% ifequal current_page page %}
 | 
			
		||||
                                            <li class="paginate_button active"  aria-controls="editable" tabindex="0"><a href="?page={{ page }}&id={{ idc.id }}"  title="第{{ page }}页">{{ page }}</a></li>
 | 
			
		||||
                                        {% else %}
 | 
			
		||||
                                            <li class="paginate_button" aria-controls="editable" tabindex="0"><a href="?page={{ page }}&id={{ idc.id }}"  title="第{{ page }}页">{{ page }}</a></li>
 | 
			
		||||
                                        {% endifequal %}
 | 
			
		||||
                                    {% endfor %}
 | 
			
		||||
                                    {% ifequal show_end 1 %}
 | 
			
		||||
                                        <li class="paginate_button" aria-controls="editable" tabindex="0"><a href="?page={{ p.num_pages }}&id={{ idc.id }}"  title="第{{ page }}页">...{{ p.num_pages }}</a></li>
 | 
			
		||||
                                    {% endifequal %}
 | 
			
		||||
                                    {% if contacts.has_next %}
 | 
			
		||||
                                        <li class="paginate_button next" aria-controls="editable" tabindex="0" id="editable_next">
 | 
			
		||||
                                            <a href="?page={{ contacts.next_page_number }}&id={{ idc.id }}">Next</a>
 | 
			
		||||
                                        </li>
 | 
			
		||||
                                    {% else %}
 | 
			
		||||
                                        <li class="paginate_button next disabled" aria-controls="editable" tabindex="0" id="editable_next">
 | 
			
		||||
                                            <a href="#">Next</a>
 | 
			
		||||
                                        </li>
 | 
			
		||||
                                    {% endif %}
 | 
			
		||||
                                {% endif %}
 | 
			
		||||
                                </ul>
 | 
			
		||||
                            </div>
 | 
			
		||||
                        </div>
 | 
			
		||||
                    </div>
 | 
			
		||||
                    </form>
 | 
			
		||||
                </div>
 | 
			
		||||
            </div>
 | 
			
		||||
        </div>
 | 
			
		||||
    </div>
 | 
			
		||||
</div>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
    $(document).ready(function(){
 | 
			
		||||
        $('#editable').editableTableWidget();
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    function alter(form) {
 | 
			
		||||
        selectData = GetTableDataBox();
 | 
			
		||||
        if (selectData[1] != 0) {
 | 
			
		||||
            $.ajax({
 | 
			
		||||
                type: "post",
 | 
			
		||||
                url: "/jasset/host_edit/batch/",
 | 
			
		||||
                data: {"editable": selectData[0], "len_table": selectData[1]},
 | 
			
		||||
                success: function (data) {
 | 
			
		||||
                    alert("修改成功");
 | 
			
		||||
                    window.open("/jasset/host_list/", "_self");
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    $(".iframe").on('click', function(){
 | 
			
		||||
        var ids = getIDall();
 | 
			
		||||
        if (ids == ''){
 | 
			
		||||
            alert("请至少选择一行!");
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        var url= $(this).attr("value") + '?id=' + ids;
 | 
			
		||||
            index = $.layer({
 | 
			
		||||
                type: 2,
 | 
			
		||||
                title: 'JumpServer - 批量修改主机',
 | 
			
		||||
                maxmin: true,
 | 
			
		||||
                shift: 'top',
 | 
			
		||||
                border: [2, 0.3, '#1AB394'],
 | 
			
		||||
                shade: [0.5, '#000000'],
 | 
			
		||||
                shadeClose: true,
 | 
			
		||||
                area : ['800px' , '600px'],
 | 
			
		||||
                iframe: {src: url},
 | 
			
		||||
                close: function(){
 | 
			
		||||
                    location.replace(location.href);
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
     $('#asset_del').click(function () {
 | 
			
		||||
        var asset_id_all = getIDall();
 | 
			
		||||
        console.log(asset_id_all);
 | 
			
		||||
        if (asset_id_all == ''){
 | 
			
		||||
            alert("请至少选择一行!");
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        if (confirm("确定删除")) {
 | 
			
		||||
            $.ajax({
 | 
			
		||||
                type: "post",
 | 
			
		||||
                data: {asset_id_all: asset_id_all},
 | 
			
		||||
                url: "/jasset/asset_del/?arg=batch",
 | 
			
		||||
                success: function () {
 | 
			
		||||
                    parent.location.reload();
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
     });
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
{% endblock %}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,99 @@
 | 
			
		|||
{% extends 'base.html' %}
 | 
			
		||||
{% block content %}
 | 
			
		||||
{% load bootstrap %}
 | 
			
		||||
{% include 'nav_cat_bar.html' %}
 | 
			
		||||
<div class="wrapper wrapper-content animated fadeInRight">
 | 
			
		||||
    <div class="row">
 | 
			
		||||
        <div class="col-lg-10">
 | 
			
		||||
            <div class="ibox float-e-margins">
 | 
			
		||||
                <div id="ibox-content" class="ibox-title">
 | 
			
		||||
                    <h5> 填写IDC基本信息 </h5>
 | 
			
		||||
                    <div class="ibox-tools">
 | 
			
		||||
                        <a class="collapse-link">
 | 
			
		||||
                            <i class="fa fa-chevron-up"></i>
 | 
			
		||||
                        </a>
 | 
			
		||||
                        <a class="dropdown-toggle" data-toggle="dropdown" href="#">
 | 
			
		||||
                            <i class="fa fa-wrench"></i>
 | 
			
		||||
                        </a>
 | 
			
		||||
                        <ul class="dropdown-menu dropdown-user">
 | 
			
		||||
                            <li><a href="#">未启用 1</a>
 | 
			
		||||
                            </li>
 | 
			
		||||
                            <li><a href="#">未启用 2</a>
 | 
			
		||||
                            </li>
 | 
			
		||||
                        </ul>
 | 
			
		||||
                        <a class="close-link">
 | 
			
		||||
                            <i class="fa fa-times"></i>
 | 
			
		||||
                        </a>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
 | 
			
		||||
                <div class="ibox-content">
 | 
			
		||||
                    {% if emg %}
 | 
			
		||||
                        <div class="alert alert-warning text-center">{{ emg }}</div>
 | 
			
		||||
                    {% endif %}
 | 
			
		||||
                    {% if smg %}
 | 
			
		||||
                        <div class="alert alert-success text-center">{{ smg }}</div>
 | 
			
		||||
                    {% endif %}
 | 
			
		||||
                    <form id="assetForm" method="post" class="form-horizontal">
 | 
			
		||||
                        {{ idc_form.name|bootstrap_horizontal }}
 | 
			
		||||
 | 
			
		||||
                        <div class="hr-line-dashed"></div>
 | 
			
		||||
                        {{ idc_form.bandwidth|bootstrap_horizontal }}
 | 
			
		||||
 | 
			
		||||
                        <div class="hr-line-dashed"></div>
 | 
			
		||||
                        {{ idc_form.operator|bootstrap_horizontal }}
 | 
			
		||||
 | 
			
		||||
                        <div class="hr-line-dashed"></div>
 | 
			
		||||
                        {{ idc_form.linkman|bootstrap_horizontal }}
 | 
			
		||||
 | 
			
		||||
                        <div class="hr-line-dashed"></div>
 | 
			
		||||
                        {{ idc_form.phone|bootstrap_horizontal }}
 | 
			
		||||
 | 
			
		||||
                        <div class="hr-line-dashed"></div>
 | 
			
		||||
                        {{ idc_form.address|bootstrap_horizontal }}
 | 
			
		||||
 | 
			
		||||
                        <div class="hr-line-dashed"></div>
 | 
			
		||||
                        {{ idc_form.network|bootstrap_horizontal }}
 | 
			
		||||
 | 
			
		||||
                        <div class="hr-line-dashed"></div>
 | 
			
		||||
                        {{ idc_form.comment|bootstrap_horizontal }}
 | 
			
		||||
 | 
			
		||||
                        <div class="hr-line-dashed"></div>
 | 
			
		||||
                        <div class="form-group">
 | 
			
		||||
                            <div class="col-sm-4 col-sm-offset-5">
 | 
			
		||||
                                <button class="btn btn-white" type="submit"> 重置 </button>
 | 
			
		||||
                                <button class="btn btn-primary" type="sumbit"> 提交 </button>
 | 
			
		||||
                            </div>
 | 
			
		||||
                        </div>
 | 
			
		||||
                    </form>
 | 
			
		||||
                </div>
 | 
			
		||||
            </div>
 | 
			
		||||
        </div>
 | 
			
		||||
    </div>
 | 
			
		||||
</div>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
    var required_fields = ["id_name"];
 | 
			
		||||
    required_fields.forEach(function(field) {
 | 
			
		||||
        $('label[for="' + field + '"]').parent().addClass("required");
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    $('#assetForm').validator({
 | 
			
		||||
        timely: 2,
 | 
			
		||||
        theme: "yellow_right_effect",
 | 
			
		||||
        fields: {
 | 
			
		||||
            "j_idc": {
 | 
			
		||||
                rule: "required",
 | 
			
		||||
                tip: "输入IDC名",
 | 
			
		||||
                ok: "",
 | 
			
		||||
                msg: {required: "IDC名必须填写!"},
 | 
			
		||||
                data: {'data-ok':"主机名可以使用", 'data-msg-required': '主机名已正确'}
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
        valid: function(form) {
 | 
			
		||||
            form.submit();
 | 
			
		||||
        }
 | 
			
		||||
    });
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
{% endblock %}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,115 @@
 | 
			
		|||
{% extends 'base.html' %}
 | 
			
		||||
{% load mytags %}
 | 
			
		||||
{% block content %}
 | 
			
		||||
{% include 'nav_cat_bar.html' %}
 | 
			
		||||
 | 
			
		||||
<div class="wrapper wrapper-content animated fadeInRight">
 | 
			
		||||
    <div class="row">
 | 
			
		||||
        <div class="col-lg-10">
 | 
			
		||||
            <div class="ibox float-e-margins">
 | 
			
		||||
                <div class="ibox-title">
 | 
			
		||||
                    <h5> IDC详细信息列表</h5>
 | 
			
		||||
                    <div class="ibox-tools">
 | 
			
		||||
                        <a class="collapse-link">
 | 
			
		||||
                            <i class="fa fa-chevron-up"></i>
 | 
			
		||||
                        </a>
 | 
			
		||||
                        <a class="dropdown-toggle" data-toggle="dropdown" href="#">
 | 
			
		||||
                            <i class="fa fa-wrench"></i>
 | 
			
		||||
                        </a>
 | 
			
		||||
                        <ul class="dropdown-menu dropdown-user">
 | 
			
		||||
                            <li><a href="#">未启用 1</a>
 | 
			
		||||
                            </li>
 | 
			
		||||
                            <li><a href="#">未启用 2</a>
 | 
			
		||||
                            </li>
 | 
			
		||||
                        </ul>
 | 
			
		||||
                        <a class="close-link">
 | 
			
		||||
                            <i class="fa fa-times"></i>
 | 
			
		||||
                        </a>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
                <div class="ibox-content">
 | 
			
		||||
                    <div class="">
 | 
			
		||||
                    <a target="_blank" href="/jasset/idc_add" class="btn btn-sm btn-primary "> 添加IDC </a>
 | 
			
		||||
                    <form id="search_form" method="get" action="" class="pull-right mail-search">
 | 
			
		||||
                        <div class="input-group">
 | 
			
		||||
                            <input type="text" class="form-control input-sm" id="search_input" name="keyword" placeholder="Search">
 | 
			
		||||
                            <input type="text" style="display: none">
 | 
			
		||||
                            <div class="input-group-btn">
 | 
			
		||||
                                <button id='search_btn' type="submit" class="btn btn-sm btn-primary">
 | 
			
		||||
                                    Search
 | 
			
		||||
                                </button>
 | 
			
		||||
                            </div>
 | 
			
		||||
                        </div>
 | 
			
		||||
                    </form>
 | 
			
		||||
                    </div>
 | 
			
		||||
 | 
			
		||||
                    <form id="contents_form" name="contents_form">
 | 
			
		||||
                    <table class="table table-striped table-bordered table-hover " id="editable" >
 | 
			
		||||
                        <thead>
 | 
			
		||||
                            <tr>
 | 
			
		||||
                                {% ifequal session_role_id 2 %}
 | 
			
		||||
                                    <th class="text-center"><input id="checkall" type="checkbox" class="i-checks" name="checkall" value="checkall" data-editable='false' onclick="check_all('contents_form')"></th>
 | 
			
		||||
                                {% endifequal %}
 | 
			
		||||
                                <th class="text-center"> 机房名 </th>
 | 
			
		||||
                                <th class="text-center"> 主机数量 </th>
 | 
			
		||||
                                <th class="text-center"> 备注 </th>
 | 
			
		||||
                                <th class="text-center"> 操作 </th>
 | 
			
		||||
                            </tr>
 | 
			
		||||
                        </thead>
 | 
			
		||||
                        <tbody>
 | 
			
		||||
                        {% for post in contacts.object_list  %}
 | 
			
		||||
                            <tr class="gradeX">
 | 
			
		||||
                                    <td class="text-center" name="j_id" value="{{ post.id }}" data-editable='false'><input name="id" value="{{ post.id }}" type="checkbox" class="i-checks"></td>
 | 
			
		||||
                                <td class="text-center"> {{ post.name }} </td>
 | 
			
		||||
                                    <td class="text-center"> <a href="/jasset/idc_detail/?id={{ post.id }}">{{ post.asset_set.count }}</a> </td>
 | 
			
		||||
                                <td class="text-center"> {{ post.comment }} </td>
 | 
			
		||||
                                <td class="text-center">
 | 
			
		||||
                                    <a href="/jasset/idc_detail/?id={{ post.id }}" class="iframe btn btn-xs btn-primary">详情</a>
 | 
			
		||||
                                        <a href="/jasset/idc_edit/?id={{ post.id }}" class="btn btn-xs btn-info">编辑</a>
 | 
			
		||||
                                        <a href="/jasset/idc_del/?id={{ post.id }}" class="btn btn-xs btn-danger">删除</a>
 | 
			
		||||
                                </td>
 | 
			
		||||
                            </tr>
 | 
			
		||||
                        {% endfor %}
 | 
			
		||||
                        </tbody>
 | 
			
		||||
                    </table>
 | 
			
		||||
                   <div class="row">
 | 
			
		||||
                        <div class="col-sm-6">
 | 
			
		||||
                            {% ifequal session_role_id 2 %}
 | 
			
		||||
                                <input type="button" id="del_button" class="btn btn-danger btn-sm"  name="del_button" value="删除" onclick="del('contents_form')" />
 | 
			
		||||
                                <!--<input type="button" id="alter_button" class="btn btn-warning btn-sm" name="alter_button" value="修改" onclick="alter('contents_form')" />-->
 | 
			
		||||
                            {% endifequal %}
 | 
			
		||||
                        </div>
 | 
			
		||||
                        {% include 'paginator.html' %}
 | 
			
		||||
                    </div>
 | 
			
		||||
                   </form>
 | 
			
		||||
                </div>
 | 
			
		||||
            </div>
 | 
			
		||||
        </div>
 | 
			
		||||
    </div>
 | 
			
		||||
</div>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
    function del(form) {
 | 
			
		||||
    var checkboxes = document.getElementById(form);
 | 
			
		||||
    var id_list = {};
 | 
			
		||||
    var j = 0;
 | 
			
		||||
    for (var i = 0; i < checkboxes.elements.length; i++) {
 | 
			
		||||
        if (checkboxes.elements[i].type == "checkbox" && checkboxes.elements[i].checked == true && checkboxes.elements[i].value != "checkall") {
 | 
			
		||||
            id_list[j] = checkboxes.elements[i].value;
 | 
			
		||||
            j++;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    if (confirm("确定删除")) {
 | 
			
		||||
        $.ajax({
 | 
			
		||||
            type: "POST",
 | 
			
		||||
            url: "/jasset/idc_del/?id=multi",
 | 
			
		||||
            data: {"id_list": id_list, "len_list": j},
 | 
			
		||||
            success: function (data) {
 | 
			
		||||
                window.open("/jasset/idc_list/", "_self");
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
    }
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
{% endblock %}
 | 
			
		||||
| 
						 | 
				
			
			@ -21,7 +21,9 @@
 | 
			
		|||
                    <li class="group_add"><a href="/jasset/group_add/">添加资产组</a></li>
 | 
			
		||||
                    <li class="group_list group_detail group_edit"><a href="/jasset/group_list/">查看资产组</a></li>
 | 
			
		||||
                    <li class="asset_add asset_add_multi"><a href="/jasset/asset_add/">添加资产</a></li>
 | 
			
		||||
                    <li class="host_list host_detail host_edit"><a href="/jasset/asset_list/">查看资产<span class="label label-info pull-right">{{ host_active_num }}/{{ host_total_num}}</span></a></li>
 | 
			
		||||
                    <li class="asset_list asset_detail asset_edit"><a href="/jasset/asset_list/">查看资产<span class="label label-info pull-right">{{ host_active_num }}/{{ host_total_num}}</span></a></li>
 | 
			
		||||
                    <li class="idc_add"><a href="/jasset/idc_add/">添加机房</a></li>
 | 
			
		||||
                    <li class="idc_list idc_detail idc_edit"><a href="/jasset/idc_list/">查看机房</a></li>
 | 
			
		||||
                </ul>
 | 
			
		||||
            </li>
 | 
			
		||||
            <li id="jperm">
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue