mirror of https://github.com/jumpserver/jumpserver
				
				
				
			asset add batch
							parent
							
								
									ec7b543bf2
								
							
						
					
					
						commit
						0f29745bfa
					
				| 
						 | 
				
			
			@ -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,5 @@
 | 
			
		|||
# coding: utf-8
 | 
			
		||||
import ast
 | 
			
		||||
import xlrd
 | 
			
		||||
import xlsxwriter
 | 
			
		||||
from django.db.models import AutoField
 | 
			
		||||
from jumpserver.api import *
 | 
			
		||||
| 
						 | 
				
			
			@ -226,7 +226,7 @@ def asset_diff(before, after):
 | 
			
		|||
 | 
			
		||||
def asset_diff_one(before, after):
 | 
			
		||||
    print before.__dict__, after.__dict__
 | 
			
		||||
    fields =  Asset._meta.get_all_field_names()
 | 
			
		||||
    fields = Asset._meta.get_all_field_names()
 | 
			
		||||
    for field in fields:
 | 
			
		||||
        print before.field, after.field
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -270,7 +270,7 @@ def db_asset_alert(asset, username, alert_dic):
 | 
			
		|||
            else:
 | 
			
		||||
                name = asset.username
 | 
			
		||||
                alert_info = [field_name, u'默认', name] if unicode(value[0]) == 'True' else \
 | 
			
		||||
                                    [field_name, name, u'默认']
 | 
			
		||||
                    [field_name, name, u'默认']
 | 
			
		||||
 | 
			
		||||
        elif field in ['username', 'password']:
 | 
			
		||||
            continue
 | 
			
		||||
| 
						 | 
				
			
			@ -281,7 +281,7 @@ def db_asset_alert(asset, username, alert_dic):
 | 
			
		|||
                continue
 | 
			
		||||
            else:
 | 
			
		||||
                alert_info = [u'是否激活', u'激活', u'禁用'] if unicode(value[0]) == 'True' else \
 | 
			
		||||
                                    [u'是否激活', u'禁用', u'激活']
 | 
			
		||||
                    [u'是否激活', u'禁用', u'激活']
 | 
			
		||||
 | 
			
		||||
        else:
 | 
			
		||||
            alert_info = [field_name, unicode(value[0]), unicode(value[1])]
 | 
			
		||||
| 
						 | 
				
			
			@ -310,8 +310,10 @@ def write_excel(asset_all):
 | 
			
		|||
 | 
			
		||||
        group_all = '/'.join(group_list)
 | 
			
		||||
        status = asset.get_status_display()
 | 
			
		||||
        alter_dic = [asset.hostname, asset.ip, asset.idc.name, asset.mac, asset.remote_ip, asset.cpu, asset.memory,
 | 
			
		||||
                     asset.disk, asset.system_type, asset.cabinet, group_all, status, asset.comment]
 | 
			
		||||
        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)
 | 
			
		||||
| 
						 | 
				
			
			@ -342,6 +344,62 @@ def write_excel(asset_all):
 | 
			
		|||
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)
 | 
			
		||||
                    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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -80,7 +80,7 @@ class Asset(models.Model):
 | 
			
		|||
    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=32, blank=True, null=True, verbose_name=u"SN编号")
 | 
			
		||||
    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"备注")
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,151 +0,0 @@
 | 
			
		|||
# coding: utf-8
 | 
			
		||||
 | 
			
		||||
import datetime
 | 
			
		||||
from django.db import models
 | 
			
		||||
from juser.models import User, UserGroup
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class AssetGroup(models.Model):
 | 
			
		||||
    GROUP_TYPE = (
 | 
			
		||||
        ('P', 'PRIVATE'),
 | 
			
		||||
        ('A', 'ASSET'),
 | 
			
		||||
    )
 | 
			
		||||
    name = models.CharField(max_length=80, unique=True)
 | 
			
		||||
    comment = models.CharField(max_length=160, blank=True, null=True)
 | 
			
		||||
 | 
			
		||||
    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, unique=True)
 | 
			
		||||
    bandwidth = models.CharField(max_length=32, blank=True, null=True)
 | 
			
		||||
    linkman = models.CharField(max_length=16, blank=True, null=True)
 | 
			
		||||
    phone = models.CharField(max_length=32, blank=True, null=True)
 | 
			
		||||
    address = models.CharField(max_length=128, blank=True, null=True)
 | 
			
		||||
    network = models.TextField(blank=True, null=True)
 | 
			
		||||
    date_added = models.DateField(auto_now=True, default=datetime.datetime.now())
 | 
			
		||||
    operator = models.IntegerField(max_length=32, blank=True, null=True)
 | 
			
		||||
    comment = models.CharField(max_length=128, blank=True, null=True)
 | 
			
		||||
 | 
			
		||||
    def __unicode__(self):
 | 
			
		||||
        return self.name
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Asset(models.Model):
 | 
			
		||||
    """
 | 
			
		||||
    asset modle
 | 
			
		||||
    """
 | 
			
		||||
    ENVIRONMENT = (
 | 
			
		||||
        (0, U'生产环境'),
 | 
			
		||||
        (1, U'测试环境')
 | 
			
		||||
    )
 | 
			
		||||
    SERVER_STATUS = (
 | 
			
		||||
        (0, u"已使用"),
 | 
			
		||||
        (1, u"未使用"),
 | 
			
		||||
        (2, u"报废")
 | 
			
		||||
    )
 | 
			
		||||
    ASSET_TYPE = (
 | 
			
		||||
        (0, u"服务器"),
 | 
			
		||||
        (2, u"网络设备"),
 | 
			
		||||
        (3, u"其他")
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    ip = models.IPAddressField(unique=True)
 | 
			
		||||
    second_ip = models.CharField(max_length=255, blank=True, null=True)
 | 
			
		||||
    hostname = models.CharField(max_length=64, blank=True, null=True)
 | 
			
		||||
    port = models.IntegerField(max_length=6)
 | 
			
		||||
    group = models.ManyToManyField(AssetGroup, blank=True, null=True)
 | 
			
		||||
    username = models.CharField(max_length=16, blank=True, null=True)
 | 
			
		||||
    password = models.CharField(max_length=64, blank=True, null=True)
 | 
			
		||||
    use_default_auth = models.BooleanField(default=True)
 | 
			
		||||
    idc = models.ForeignKey(IDC, blank=True, null=True, on_delete=models.SET_NULL)
 | 
			
		||||
    mac = models.CharField(max_length=20, blank=True, null=True)
 | 
			
		||||
    remote_ip = models.IPAddressField(unique=True, blank=True, null=True)
 | 
			
		||||
    brand = models.CharField(max_length=64, blank=True, null=True)
 | 
			
		||||
    cpu = models.CharField(max_length=64, blank=True, null=True)
 | 
			
		||||
    memory = models.CharField(max_length=128, blank=True, null=True)
 | 
			
		||||
    disk = models.CharField(max_length=128, blank=True, null=True)
 | 
			
		||||
    system_type = models.CharField(max_length=32, blank=True, null=True)
 | 
			
		||||
    system_version = models.CharField(max_length=8, blank=True, null=True)
 | 
			
		||||
    cabinet = models.CharField(max_length=32, blank=True, null=True)
 | 
			
		||||
    position = models.IntegerField(max_length=2, blank=True, null=True)
 | 
			
		||||
    number = models.CharField(max_length=32, blank=True, null=True)
 | 
			
		||||
    status = models.IntegerField(max_length=2, choices=SERVER_STATUS, default=1)
 | 
			
		||||
    asset_type = models.IntegerField(max_length=2, choices=ASSET_TYPE, blank=True, null=True)
 | 
			
		||||
    env = models.CharField(max_length=32, choices=ENVIRONMENT, blank=True, null=True)
 | 
			
		||||
    sn = models.CharField(max_length=32, blank=True, null=True)
 | 
			
		||||
    date_added = models.DateTimeField(auto_now=True, default=datetime.datetime.now())
 | 
			
		||||
    is_active = models.BooleanField(default=True)
 | 
			
		||||
    comment = models.CharField(max_length=128, blank=True, null=True)
 | 
			
		||||
 | 
			
		||||
    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 AssetAlias(models.Model):
 | 
			
		||||
    user = models.ForeignKey(User)
 | 
			
		||||
    asset = models.ForeignKey(Asset)
 | 
			
		||||
    alias = models.CharField(max_length=100, null=True)
 | 
			
		||||
 | 
			
		||||
    def __unicode__(self):
 | 
			
		||||
        return self.alias
 | 
			
		||||
| 
						 | 
				
			
			@ -4,15 +4,14 @@ from jasset.views import *
 | 
			
		|||
 | 
			
		||||
urlpatterns = patterns('',
 | 
			
		||||
    url(r'^asset_add/$', asset_add),
 | 
			
		||||
    # url(r"^host_add_multi/$", host_add_batch),
 | 
			
		||||
    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_add/$', group_add),
 | 
			
		||||
    url(r'^group_list/$', group_list),
 | 
			
		||||
| 
						 | 
				
			
			@ -27,4 +26,5 @@ urlpatterns = patterns('',
 | 
			
		|||
    url(r'^idc_detail/$', idc_detail),
 | 
			
		||||
    url(r'^idc_edit/$', idc_edit),
 | 
			
		||||
    url(r'^idc_del/$', idc_del),
 | 
			
		||||
    url(r'^upload/$', asset_upload),
 | 
			
		||||
)
 | 
			
		||||
| 
						 | 
				
			
			@ -1,14 +1,13 @@
 | 
			
		|||
# coding:utf-8
 | 
			
		||||
 | 
			
		||||
import ast
 | 
			
		||||
 | 
			
		||||
from django.db.models import Q
 | 
			
		||||
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')
 | 
			
		||||
| 
						 | 
				
			
			@ -175,6 +174,12 @@ def asset_add(request):
 | 
			
		|||
    return my_render('jasset/asset_add.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')
 | 
			
		||||
def asset_del(request):
 | 
			
		||||
    """
 | 
			
		||||
| 
						 | 
				
			
			@ -207,8 +212,6 @@ def asset_edit(request):
 | 
			
		|||
 | 
			
		||||
    asset_id = request.GET.get('id', '')
 | 
			
		||||
    username = request.session.get('username', 'admin')
 | 
			
		||||
    # if not asset_id:
 | 
			
		||||
    #     return HttpResponse('没有该主机')
 | 
			
		||||
    asset = get_object(Asset, id=asset_id)
 | 
			
		||||
    asset_old = copy_model_instance(asset)
 | 
			
		||||
    af = AssetForm(instance=asset)
 | 
			
		||||
| 
						 | 
				
			
			@ -231,8 +234,8 @@ def asset_edit(request):
 | 
			
		|||
                    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)
 | 
			
		||||
                # 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)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -306,7 +309,7 @@ def asset_edit_batch(request):
 | 
			
		|||
@require_role('admin')
 | 
			
		||||
def asset_detail(request):
 | 
			
		||||
    """
 | 
			
		||||
    主机详情
 | 
			
		||||
    Asset detail view
 | 
			
		||||
    """
 | 
			
		||||
    header_title, path1, path2 = u'主机详细信息', u'资产管理', u'主机详情'
 | 
			
		||||
    asset_id = request.GET.get('id', '')
 | 
			
		||||
| 
						 | 
				
			
			@ -316,6 +319,53 @@ def asset_detail(request):
 | 
			
		|||
    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):
 | 
			
		||||
    """
 | 
			
		||||
| 
						 | 
				
			
			@ -343,6 +393,9 @@ def idc_add(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', '')
 | 
			
		||||
| 
						 | 
				
			
			@ -358,6 +411,10 @@ def idc_list(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':
 | 
			
		||||
| 
						 | 
				
			
			@ -372,7 +429,9 @@ def idc_edit(request):
 | 
			
		|||
 | 
			
		||||
@require_role('admin')
 | 
			
		||||
def idc_detail(request):
 | 
			
		||||
    """ IDC详情 """
 | 
			
		||||
    """
 | 
			
		||||
    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)
 | 
			
		||||
| 
						 | 
				
			
			@ -384,7 +443,25 @@ def idc_detail(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)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -415,12 +415,29 @@ 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(',')
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -27,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">
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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 %}
 | 
			
		||||
| 
						 | 
				
			
			@ -37,6 +37,20 @@
 | 
			
		|||
                                        <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>
 | 
			
		||||
| 
						 | 
				
			
			@ -77,11 +91,21 @@
 | 
			
		|||
                                    </tr>
 | 
			
		||||
                                    <tr>
 | 
			
		||||
                                        <td class="text-navy">内存</td>
 | 
			
		||||
                                        <td>{{ asset.memory }}</td>
 | 
			
		||||
                                        <td>{{ asset.memory }}M</td>
 | 
			
		||||
                                    </tr>
 | 
			
		||||
                                    <tr>
 | 
			
		||||
                                        <td class="text-navy">硬盘</td>
 | 
			
		||||
                                        <td>{{ asset.disk }}</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>
 | 
			
		||||
| 
						 | 
				
			
			@ -95,6 +119,10 @@
 | 
			
		|||
                                        <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>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -107,7 +107,8 @@
 | 
			
		|||
                                    <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"> 操作 </th>
 | 
			
		||||
                                </tr>
 | 
			
		||||
| 
						 | 
				
			
			@ -122,12 +123,14 @@
 | 
			
		|||
                                    <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.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" 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>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue