mirror of https://github.com/jumpserver/jumpserver
asset update batch and crontab
parent
b8cb6f4246
commit
5a3c11f619
|
@ -1,459 +0,0 @@
|
|||
# -*- 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
|
||||
|
||||
|
|
@ -4,6 +4,8 @@ import xlsxwriter
|
|||
from django.db.models import AutoField
|
||||
from jumpserver.api import *
|
||||
from jasset.models import ASSET_STATUS, ASSET_TYPE, ASSET_ENV, IDC, AssetRecord
|
||||
from jperm.ansible_api import MyRunner
|
||||
from jperm.perm_api import gen_resource
|
||||
|
||||
|
||||
def group_add_asset(group, asset_id=None, asset_ip=None):
|
||||
|
@ -406,3 +408,64 @@ def excel_to_db(excel_file):
|
|||
asset.group = group_instance
|
||||
asset.save()
|
||||
return True
|
||||
|
||||
|
||||
def get_ansible_asset_info(asset_ip, setup_info):
|
||||
disk_all = setup_info.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")
|
||||
|
||||
all_ip = setup_info.get("ansible_all_ipv4_addresses")
|
||||
other_ip_list = all_ip.remove(asset_ip) if asset_ip in all_ip else []
|
||||
other_ip = ','.join(other_ip_list) if other_ip_list else ''
|
||||
# hostname = setup_info.get("ansible_hostname")
|
||||
# ip = setup_info.get("ansible_default_ipv4").get("address")
|
||||
mac = setup_info.get("ansible_default_ipv4").get("macaddress")
|
||||
brand = setup_info.get("ansible_product_name")
|
||||
cpu_type = setup_info.get("ansible_processor")[1]
|
||||
cpu_cores = setup_info.get("ansible_processor_count")
|
||||
cpu = cpu_type + ' * ' + unicode(cpu_cores)
|
||||
memory = setup_info.get("ansible_memtotal_mb")
|
||||
disk = disk_need
|
||||
system_type = setup_info.get("ansible_distribution")
|
||||
system_version = setup_info.get("ansible_distribution_version")
|
||||
# asset_type = setup_info.get("ansible_system")
|
||||
sn = setup_info.get("ansible_product_serial")
|
||||
asset_info = [other_ip, mac, cpu, memory, disk, sn, system_type, system_version, brand]
|
||||
|
||||
return asset_info
|
||||
|
||||
|
||||
def asset_ansible_update(obj_list, name=''):
|
||||
resource = gen_resource(obj_list)
|
||||
ansible_instance = MyRunner(resource)
|
||||
ansible_asset_info = ansible_instance.run(module_name='setup', pattern='*')
|
||||
for asset in obj_list:
|
||||
try:
|
||||
setup_info = ansible_asset_info['contacted'][asset.hostname]['ansible_facts']
|
||||
except KeyError:
|
||||
continue
|
||||
else:
|
||||
asset_info = get_ansible_asset_info(asset.ip, setup_info)
|
||||
other_ip, mac, cpu, memory, disk, sn, system_type, system_version, brand = asset_info
|
||||
asset_dic = {"other_ip": other_ip,
|
||||
"mac": mac,
|
||||
"cpu": cpu,
|
||||
"memory": memory,
|
||||
"disk": disk,
|
||||
"sn": sn,
|
||||
"system_type": system_type,
|
||||
"system_version": system_version,
|
||||
"brand": brand
|
||||
}
|
||||
|
||||
ansible_record(asset, asset_dic, name)
|
||||
|
||||
|
||||
def asset_ansible_update_all():
|
||||
name = u'定时更新'
|
||||
asset_all = Asset.objects.all()
|
||||
asset_ansible_update(asset_all, name)
|
||||
|
||||
|
|
|
@ -73,7 +73,7 @@ class Asset(models.Model):
|
|||
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"版本号")
|
||||
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(blank=True, null=True, verbose_name=u'机器位置')
|
||||
number = models.CharField(max_length=32, blank=True, null=True, verbose_name=u'资产编号')
|
||||
|
|
|
@ -11,6 +11,7 @@ urlpatterns = patterns('',
|
|||
url(r"^asset_detail/$", asset_detail),
|
||||
url(r'^asset_edit/$', asset_edit),
|
||||
url(r'^asset_update/$', asset_update),
|
||||
url(r'^asset_update_batch/$', asset_update_batch),
|
||||
# url(r'^search/$', host_search),
|
||||
# url(r"^show_all_ajax/$", show_all_ajax),
|
||||
url(r'^group_add/$', group_add),
|
||||
|
|
|
@ -6,7 +6,8 @@ from jumpserver.api import *
|
|||
from jumpserver.models import Setting
|
||||
from jasset.forms import AssetForm, IdcForm
|
||||
from jasset.models import Asset, IDC, AssetGroup, ASSET_TYPE, ASSET_STATUS
|
||||
from ansible_api import Tasks
|
||||
from jperm.ansible_api import Tasks, MyRunner
|
||||
from jperm.perm_api import gen_resource
|
||||
|
||||
|
||||
@require_role('admin')
|
||||
|
@ -197,7 +198,7 @@ def asset_edit(request):
|
|||
header_title, path1, path2 = u'修改资产', u'资产管理', u'修改资产'
|
||||
|
||||
asset_id = request.GET.get('id', '')
|
||||
username = request.session.get('username', 'admin')
|
||||
username = request.user.username
|
||||
asset = get_object(Asset, id=asset_id)
|
||||
if asset:
|
||||
password_old = asset.password
|
||||
|
@ -311,7 +312,7 @@ def asset_list(request):
|
|||
@require_role('admin')
|
||||
def asset_edit_batch(request):
|
||||
af = AssetForm()
|
||||
name = request.session.get('username', 'admin')
|
||||
name = request.user.username
|
||||
asset_group_all = AssetGroup.objects.all()
|
||||
|
||||
if request.method == 'POST':
|
||||
|
@ -409,55 +410,30 @@ def asset_update(request):
|
|||
"""
|
||||
asset_id = request.GET.get('id', '')
|
||||
asset = get_object(Asset, id=asset_id)
|
||||
name = request.session.get('username', 'admin')
|
||||
name = request.user.username
|
||||
if not asset:
|
||||
return HttpResponseRedirect('/jasset/asset_detail/?id=%s' % asset_id)
|
||||
if asset.use_default_auth:
|
||||
default = Setting.objects.all()
|
||||
if default:
|
||||
default = default[0]
|
||||
username = default.default_user
|
||||
password = CRYPTOR.decrypt(default.default_password)
|
||||
port = default.default_port
|
||||
else:
|
||||
return HttpResponse(u'没有设置默认用户名和密码!')
|
||||
else:
|
||||
username = asset.username
|
||||
password = CRYPTOR.decrypt(asset.password)
|
||||
port = asset.port
|
||||
|
||||
resource = [{"hostname": asset.ip, "port": 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')
|
||||
all_ip = asset_info.get('other_ip')
|
||||
other_ip_list = all_ip.remove(asset.ip) if asset.ip in all_ip else []
|
||||
other_ip = ','.join(other_ip_list) if other_ip_list else ''
|
||||
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)
|
||||
|
||||
asset_ansible_update(asset_list, name)
|
||||
return HttpResponseRedirect('/jasset/asset_detail/?id=%s' % asset_id)
|
||||
|
||||
|
||||
@require_role('admin')
|
||||
def asset_update_batch(request):
|
||||
if request.method == 'POST':
|
||||
asset_list = []
|
||||
name = unicode(request.user.username) + ' - ' + u'自动更新'
|
||||
asset_id_all = unicode(request.POST.get('asset_id_all', ''))
|
||||
asset_id_all = asset_id_all.split(',')
|
||||
for asset_id in asset_id_all:
|
||||
asset = get_object(Asset, id=asset_id)
|
||||
if asset:
|
||||
asset_list.append(asset)
|
||||
asset_ansible_update(asset_list, name)
|
||||
return HttpResponse(u'批量更新成功!')
|
||||
return HttpResponse(u'批量更新成功!')
|
||||
|
||||
|
||||
@require_role('admin')
|
||||
def idc_add(request):
|
||||
"""
|
||||
|
@ -478,9 +454,7 @@ def idc_add(request):
|
|||
return HttpResponseRedirect("/jasset/idc_list/")
|
||||
else:
|
||||
idc_form = IdcForm()
|
||||
return render_to_response('jasset/idc_add.html',
|
||||
locals(),
|
||||
context_instance=RequestContext(request))
|
||||
return my_render('jasset/idc_add.html', locals(), request)
|
||||
|
||||
|
||||
@require_role('admin')
|
||||
|
@ -496,9 +470,7 @@ def idc_list(request):
|
|||
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))
|
||||
return my_render('jasset/idc_list.html', locals(), request)
|
||||
|
||||
|
||||
@require_role('admin')
|
||||
|
|
|
@ -66,6 +66,7 @@ INSTALLED_APPS = (
|
|||
'django.contrib.messages',
|
||||
'django.contrib.staticfiles',
|
||||
'django.contrib.humanize',
|
||||
'django_crontab',
|
||||
'bootstrapform',
|
||||
'jumpserver',
|
||||
'juser',
|
||||
|
@ -149,3 +150,7 @@ USE_TZ = False
|
|||
STATIC_URL = '/static/'
|
||||
|
||||
BOOTSTRAP_COLUMN_COUNT = 10
|
||||
|
||||
CRONJOBS = [
|
||||
('0 1 * * *', 'jasset.asset_api.asset_ansible_update_all')
|
||||
]
|
||||
|
|
|
@ -11,9 +11,15 @@
|
|||
<div class="ibox-title">
|
||||
<span class="text text-primary"><b>{{ asset.ip }}</b></span>
|
||||
<div class="ibox-tools">
|
||||
<a class="" href="/jasset/asset_update/?id={{ asset.id }}">
|
||||
<i class="fa fa-refresh"></i>
|
||||
</a>
|
||||
<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">
|
||||
|
|
|
@ -96,6 +96,12 @@
|
|||
<div class="hr-line-dashed"></div>
|
||||
{{ af.memory|bootstrap_horizontal }}
|
||||
|
||||
<div class="hr-line-dashed"></div>
|
||||
{{ af.system_type|bootstrap_horizontal }}
|
||||
|
||||
<div class="hr-line-dashed"></div>
|
||||
{{ af.system_version|bootstrap_horizontal }}
|
||||
|
||||
<div class="hr-line-dashed"></div>
|
||||
{{ af.disk|bootstrap_horizontal }}
|
||||
|
||||
|
|
|
@ -54,29 +54,17 @@
|
|||
<div class="col-sm-2">
|
||||
<div class="radio i-checks">
|
||||
<label>
|
||||
<<<<<<< HEAD
|
||||
<input type="radio" checked="" value="no_action" id="no" name="use_default_auth" class="auth"><span> 不修改 </span>
|
||||
=======
|
||||
<input type="radio" checked="" value="" id="no" name="use_default_auth" class="auth"><span> 不修改 </span>
|
||||
>>>>>>> cmdb
|
||||
</label>
|
||||
</div>
|
||||
<div class="radio i-checks">
|
||||
<label>
|
||||
<<<<<<< HEAD
|
||||
<input type="radio" id="default" name="use_default_auth" class="auth"><span> 使用默认 </span>
|
||||
=======
|
||||
<input type="radio" id="default" name="use_default_auth" class="auth" value="default"><span> 使用默认 </span>
|
||||
>>>>>>> cmdb
|
||||
</label>
|
||||
</div>
|
||||
<div class="radio i-checks">
|
||||
<label>
|
||||
<<<<<<< HEAD
|
||||
<input type="radio" id="pass" name="use_default_auth" class="auth"><span> 用户名密码 </span>
|
||||
=======
|
||||
<input type="radio" id="pass" name="use_default_auth" class="auth" value="user_passwd"><span> 用户名密码 </span>
|
||||
>>>>>>> cmdb
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -138,21 +126,6 @@
|
|||
</div>
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
<<<<<<< HEAD
|
||||
$('#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)
|
||||
});
|
||||
|
||||
=======
|
||||
>>>>>>> cmdb
|
||||
$('.auth').click(function(){
|
||||
if ($(this).attr('id') == 'pass'){
|
||||
$('#admin_account').css('display', 'block')
|
||||
|
|
|
@ -130,7 +130,6 @@
|
|||
<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>
|
||||
|
@ -142,7 +141,7 @@
|
|||
<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>
|
||||
<a value="/jasset/asset_update_batch/" type="button" class="btn btn-sm btn-info">更新</a>
|
||||
<input type="button" id="asset_update" class="btn btn-info btn-sm" name="update_button" value="更新"/>
|
||||
</div>
|
||||
{% include 'paginator.html' %}
|
||||
</div>
|
||||
|
@ -156,23 +155,10 @@
|
|||
|
||||
{% block self_footer_js %}
|
||||
<script>
|
||||
$('table td').on('change', function(env, id){
|
||||
var url = "/jasset/show_all_ajax/?env=" + env + "&id=" + id;
|
||||
console.log(url);
|
||||
$.ajax({
|
||||
type: "GET",
|
||||
url: url,
|
||||
// data: $("#search_form").serialize(),
|
||||
success: function (data) {
|
||||
$("#j_dept_"+id).html(data);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$(document).ready(function(){
|
||||
$('.asset_del').click(function(){
|
||||
var row = $(this).closest('tr');
|
||||
if (confirm("确定删除")) {
|
||||
if (confirm("确定删除?")) {
|
||||
$.get(
|
||||
$(this).attr('value'),
|
||||
{},
|
||||
|
@ -222,12 +208,11 @@
|
|||
|
||||
$('#asset_del').click(function () {
|
||||
var asset_id_all = getIDall();
|
||||
console.log(asset_id_all);
|
||||
if (asset_id_all == ''){
|
||||
alert("请至少选择一行!");
|
||||
return false;
|
||||
}
|
||||
if (confirm("确定删除")) {
|
||||
if (confirm("确定删除?")) {
|
||||
$.ajax({
|
||||
type: "post",
|
||||
data: {asset_id_all: asset_id_all},
|
||||
|
@ -239,6 +224,23 @@
|
|||
}
|
||||
});
|
||||
|
||||
$('#asset_update').click(function () {
|
||||
var asset_id_all = getIDall();
|
||||
if (asset_id_all == ''){
|
||||
alert("请至少选择一行!");
|
||||
return false;
|
||||
}
|
||||
layer.msg('玩命更新中...', {time: 200000});
|
||||
$.ajax({
|
||||
type: "post",
|
||||
data: {asset_id_all: asset_id_all},
|
||||
url: "/jasset/asset_update_batch/",
|
||||
success: function () {
|
||||
parent.location.reload();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
function change_info(){
|
||||
var args = $("#asset_form").serialize();
|
||||
|
@ -250,19 +252,6 @@
|
|||
change_info()
|
||||
}
|
||||
});
|
||||
|
||||
function show_all(env, id) {
|
||||
var url = "/jasset/show_all_ajax/?env=" + env + "&id=" + id;
|
||||
console.log(url);
|
||||
$.ajax({
|
||||
type: "GET",
|
||||
url: url,
|
||||
success: function (data) {
|
||||
$("#j_group_" + id).html(data);
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
{% endblock %}
|
Loading…
Reference in New Issue