mirror of https://github.com/jumpserver/jumpserver
[Stash] Test case 通不过,import error
parent
27a1849b1d
commit
18fd04d63c
|
@ -0,0 +1,2 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#
|
|
@ -1,9 +1,10 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
#
|
||||
print("Import assets model")
|
||||
|
||||
from .user import AdminUser, SystemUser
|
||||
from .cluster import *
|
||||
from .user import *
|
||||
from .group import *
|
||||
from .asset import *
|
||||
from .utils import *
|
||||
|
|
|
@ -2,15 +2,15 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import uuid
|
||||
|
||||
from django.db import models
|
||||
import logging
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from . import Cluster, AssetGroup, AdminUser, SystemUser
|
||||
from .cluster import Cluster
|
||||
from .group import AssetGroup
|
||||
from .user import AdminUser, SystemUser
|
||||
|
||||
__all__ = ['Asset']
|
||||
logger = logging.getLogger(__name__)
|
||||
|
|
|
@ -10,7 +10,7 @@ from django.db import models
|
|||
import logging
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from . import SystemUser
|
||||
from .user import SystemUser
|
||||
|
||||
__all__ = ['AssetGroup']
|
||||
logger = logging.getLogger(__name__)
|
||||
|
|
|
@ -321,7 +321,7 @@ $(document).ready(function () {
|
|||
var body = {};
|
||||
var success = function() {
|
||||
swal('Deleted!', "[ "+name+"]"+" has been deleted ", "success");
|
||||
window.location.href="{% url 'assets:idc-list' %}";
|
||||
window.location.href="{% url 'assets:cluster-list' %}";
|
||||
};
|
||||
var fail = function() {
|
||||
swal("Failed", "Delete"+"[ "+name+" ]"+"failed", "error");
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
|
||||
<div class="hr-line-dashed"></div>
|
||||
<h3>{% trans 'Group' %}</h3>
|
||||
{% bootstrap_field form.idc layout="horizontal" %}
|
||||
{% bootstrap_field form.cluster layout="horizontal" %}
|
||||
{% bootstrap_field form.groups layout="horizontal" %}
|
||||
|
||||
<div class="hr-line-dashed"></div>
|
||||
|
|
|
@ -7,15 +7,15 @@
|
|||
{% block table_search %}{% endblock %}
|
||||
{% block table_container %}
|
||||
<div class="uc pull-left m-l-5 m-r-5">
|
||||
<a href="{% url "assets:idc-create" %}" class="btn btn-sm btn-primary"> {% trans "Create Cluster" %} </a>
|
||||
<a href="{% url "assets:cluster-create" %}" class="btn btn-sm btn-primary"> {% trans "Create Cluster" %} </a>
|
||||
</div>
|
||||
<table class="table table-striped table-bordered table-hover " id="idc_list_table" >
|
||||
<table class="table table-striped table-bordered table-hover " id="cluster_list_table" >
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="text-center">
|
||||
<input type="checkbox" id="check_all" class="ipt_check_all" >
|
||||
</th>
|
||||
<th class="text-center"><a href="{% url 'assets:idc-list' %}?sort=name">{% trans 'Name' %}</a></th>
|
||||
<th class="text-center"><a href="{% url 'assets:cluster-list' %}?sort=name">{% trans 'Name' %}</a></th>
|
||||
<th class="text-center">{% trans 'Asset num' %}</th>
|
||||
<th class="text-center">{% trans 'Contact' %}</th>
|
||||
<th class="text-center">{% trans 'Phone' %}</th>
|
||||
|
@ -44,19 +44,19 @@
|
|||
<script>
|
||||
$(document).ready(function(){
|
||||
var options = {
|
||||
ele: $('#idc_list_table'),
|
||||
ele: $('#cluster_list_table'),
|
||||
columnDefs: [
|
||||
{targets: 1, createdCell: function (td, cellData, rowData) {
|
||||
var detail_btn = '<a href="{% url "assets:idc-detail" pk=99991937 %}">' + cellData + '</a>';
|
||||
var detail_btn = '<a href="{% url "assets:cluster-detail" pk=99991937 %}">' + cellData + '</a>';
|
||||
$(td).html(detail_btn.replace('99991937', rowData.id));
|
||||
}},
|
||||
|
||||
{targets: 6, createdCell: function (td, cellData, rowData) {
|
||||
var update_btn = '<a href="{% url "assets:idc-update" pk=99991937 %}" class="btn btn-xs btn-info">{% trans "Update" %}</a>'.replace('99991937', cellData);
|
||||
var del_btn = '<a class="btn btn-xs btn-danger m-l-xs btn_idc_delete" data-uid="99991937">{% trans "Delete" %}</a>'.replace('99991937', cellData);
|
||||
var update_btn = '<a href="{% url "assets:cluster-update" pk=99991937 %}" class="btn btn-xs btn-info">{% trans "Update" %}</a>'.replace('99991937', cellData);
|
||||
var del_btn = '<a class="btn btn-xs btn-danger m-l-xs btn_cluster_delete" data-uid="99991937">{% trans "Delete" %}</a>'.replace('99991937', cellData);
|
||||
$(td).html(update_btn + del_btn)
|
||||
}}],
|
||||
ajax_url: '{% url "api-assets:idc-list" %}',
|
||||
ajax_url: '{% url "api-assets:cluster-list" %}',
|
||||
columns: [{data: function(){return ""}}, {data: "name" }, {data: "assets_amount" }, {data: "contact" }, {data: "phone" },
|
||||
{data: "operator" }, {data: "id" }],
|
||||
op_html: $('#actions').html()
|
||||
|
@ -64,12 +64,12 @@ $(document).ready(function(){
|
|||
jumpserver.initDataTable(options);
|
||||
})
|
||||
|
||||
.on('click', '.btn_idc_delete', function () {
|
||||
.on('click', '.btn_cluster_delete', function () {
|
||||
var $this = $(this);
|
||||
var $data_table = $('#idc_list_table').DataTable();
|
||||
var $data_table = $('#cluster_list_table').DataTable();
|
||||
var name = $(this).closest("tr").find(":nth-child(2)").children('a').html();
|
||||
var uid = $this.data('uid');
|
||||
var the_url = '{% url "api-assets:idc-detail" pk=99991937 %}'.replace('99991937', uid);
|
||||
var the_url = '{% url "api-assets:cluster-detail" pk=99991937 %}'.replace('99991937', uid);
|
||||
objectDelete($this, name, the_url);
|
||||
setTimeout( function () {
|
||||
$data_table.ajax.reload();
|
||||
|
@ -78,7 +78,7 @@ $(document).ready(function(){
|
|||
|
||||
.on('click', '#btn_bulk_update', function () {
|
||||
var action = $('#slct_bulk_update').val();
|
||||
var $data_table = $('#idc_list_table').DataTable();
|
||||
var $data_table = $('#cluster_list_table').DataTable();
|
||||
var id_list = [];
|
||||
var plain_id_list = [];
|
||||
$data_table.rows({selected: true}).every(function(){
|
||||
|
@ -88,11 +88,11 @@ $(document).ready(function(){
|
|||
if (id_list === []) {
|
||||
return false;
|
||||
}
|
||||
var the_url = "{% url 'api-assets:idc-list' %}";
|
||||
var the_url = "{% url 'api-assets:cluster-list' %}";
|
||||
function doDelete() {
|
||||
swal({
|
||||
title: "{% trans 'Are you sure?' %}",
|
||||
text: "{% trans 'This will delete the selected idc' %}",
|
||||
text: "{% trans 'This will delete the selected cluster' %}",
|
||||
type: "warning",
|
||||
showCancelButton: true,
|
||||
confirmButtonColor: "#DD6B55",
|
||||
|
@ -102,7 +102,7 @@ $(document).ready(function(){
|
|||
var success = function() {
|
||||
var msg = "{% trans 'Cluster Deleted.' %}";
|
||||
swal("{% trans 'Cluster Delete' %}", msg, "success");
|
||||
$('#idc_list_table').DataTable().ajax.reload();
|
||||
$('#cluster_list_table').DataTable().ajax.reload();
|
||||
};
|
||||
var fail = function() {
|
||||
var msg = "{% trans 'Cluster Deleting failed.' %}";
|
||||
|
|
|
@ -30,11 +30,12 @@ from ..hands import AdminUserRequiredMixin
|
|||
from ..tasks import update_assets_hardware_info
|
||||
|
||||
|
||||
__all__ = ['AssetListView', 'AssetCreateView', 'AssetUpdateView',
|
||||
'UserAssetListView', 'AssetBulkUpdateView', 'AssetDetailView',
|
||||
'AssetModalListView', 'AssetDeleteView', 'AssetExportView',
|
||||
'BulkImportAssetView',
|
||||
]
|
||||
__all__ = [
|
||||
'AssetListView', 'AssetCreateView', 'AssetUpdateView',
|
||||
'UserAssetListView', 'AssetBulkUpdateView', 'AssetDetailView',
|
||||
'AssetModalListView', 'AssetDeleteView', 'AssetExportView',
|
||||
'BulkImportAssetView',
|
||||
]
|
||||
|
||||
|
||||
class AssetListView(AdminUserRequiredMixin, TemplateView):
|
||||
|
@ -282,7 +283,7 @@ class BulkImportAssetView(AdminUserRequiredMixin, JSONResponseMixin, FormView):
|
|||
|
||||
asset = get_object_or_none(Asset, id=id_)
|
||||
for k, v in asset_dict.items():
|
||||
if k == 'idc':
|
||||
if k == 'cluster':
|
||||
v = get_object_or_none(Cluster, name=v)
|
||||
elif k == 'is_active':
|
||||
v = bool(v)
|
||||
|
|
|
@ -1108,7 +1108,7 @@ msgid "Create Cluster"
|
|||
msgstr "创建Cluster"
|
||||
|
||||
#: assets/templates/assets/idc_list.html:95
|
||||
msgid "This will delete the selected idc"
|
||||
msgid "This will delete the selected cluster"
|
||||
msgstr "删除选择Cluster"
|
||||
|
||||
#: assets/templates/assets/idc_list.html:103
|
||||
|
|
|
@ -18,7 +18,8 @@ class AdHoc(models.Model):
|
|||
id = models.UUIDField(default=uuid.uuid4, primary_key=True)
|
||||
name = models.CharField(max_length=128, blank=True, verbose_name=_('Name'))
|
||||
is_deleted = models.BooleanField(default=False)
|
||||
date_create = models.DateTimeField(auto_created=True)
|
||||
created_by = models.CharField(max_length=128, blank=True, default='')
|
||||
date_create = models.DateTimeField(auto_now_add=True)
|
||||
|
||||
@property
|
||||
def short_id(self):
|
||||
|
@ -45,7 +46,7 @@ class AdHocData(models.Model):
|
|||
_become_pass = models.CharField(default='', max_length=128)
|
||||
pattern = models.CharField(max_length=64, default='', verbose_name=_('Pattern'))
|
||||
created_by = models.CharField(max_length=64, verbose_name=_('Create by'))
|
||||
date_created = models.DateTimeField(auto_created=True)
|
||||
date_created = models.DateTimeField(auto_now_add=True)
|
||||
|
||||
@property
|
||||
def tasks(self):
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
|
||||
import sys
|
||||
import os
|
||||
from django.test import TestCase
|
||||
|
||||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "jumpserver.settings")
|
||||
from ops.models import AdHoc, AdHocData
|
||||
from ops.utils import run_adhoc
|
||||
|
||||
|
||||
class TestRunAdHoc(TestCase):
|
||||
def setUp(self):
|
||||
adhoc = AdHoc(name="Test run adhoc")
|
||||
adhoc.save()
|
||||
|
||||
self.data = AdHocData(subject=adhoc, run_as_admin=True, pattern='all')
|
||||
self.data.tasks = [
|
||||
{'name': 'run ls', 'action': {'module': 'shell', 'args': 'ls'}},
|
||||
{'name': 'echo ', 'action': {'module': 'shell', 'args': 'echo 123'}},
|
||||
]
|
||||
self.data.hosts = [
|
||||
"testserver"
|
||||
]
|
||||
|
||||
def test_run(self):
|
||||
pass
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -1,16 +1,13 @@
|
|||
# ~*~ coding: utf-8 ~*~
|
||||
|
||||
from __future__ import absolute_import, unicode_literals
|
||||
|
||||
import json
|
||||
import re
|
||||
import time
|
||||
import uuid
|
||||
|
||||
import time
|
||||
from django.utils import timezone
|
||||
|
||||
from common.utils import get_logger, get_object_or_none
|
||||
from .ansible import AdHocRunner
|
||||
from .ansible.exceptions import AnsibleError
|
||||
from .models import AdHocRunHistory
|
||||
from assets.utils import get_assets_by_hostname_list
|
||||
|
||||
logger = get_logger(__file__)
|
||||
|
@ -82,16 +79,43 @@ def hosts_add_become(hosts, adhoc_data):
|
|||
return hosts
|
||||
|
||||
|
||||
def run_adhoc(adhoc_data, forks=10):
|
||||
tasks = adhoc_data.tasks
|
||||
def run_adhoc(adhoc_data, **options):
|
||||
"""
|
||||
:param adhoc_data: Instance of AdHocData
|
||||
:param options: ansible support option, like forks ...
|
||||
:return:
|
||||
"""
|
||||
name = adhoc_data.subject.name
|
||||
hostname_list = adhoc_data.hosts
|
||||
adhoc_name = adhoc_data.subject.name
|
||||
|
||||
if adhoc_data.run_as_admin:
|
||||
hosts = get_hosts_with_admin(adhoc_data.hosts)
|
||||
hosts = get_hosts_with_admin(hostname_list)
|
||||
else:
|
||||
hosts = get_hosts_with_run_user(hostname_list, adhoc_data.run_as)
|
||||
hosts_add_become(hosts, adhoc_data) # admin user 自带become
|
||||
|
||||
runner = AdHocRunner(hosts)
|
||||
runner.set_option('forks', forks)
|
||||
for k, v in options:
|
||||
runner.set_option(k, v)
|
||||
|
||||
record = AdHocRunHistory(adhoc=adhoc_data)
|
||||
time_start = time.time()
|
||||
try:
|
||||
result = runner.run(adhoc_data.tasks, adhoc_data.pattern, name)
|
||||
record.is_finished = True
|
||||
if result.results_summary.get('dark'):
|
||||
record.is_success = False
|
||||
else:
|
||||
record.is_success = True
|
||||
record.result = result.results_raw
|
||||
record.summary = result.results_summary
|
||||
return result
|
||||
except AnsibleError as e:
|
||||
logger.error("Failed run adhoc {}, {}".format(name, e))
|
||||
raise
|
||||
finally:
|
||||
record.date_finished = timezone.now()
|
||||
record.timedelta = time.time() - time_start
|
||||
record.save()
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,18 +1,15 @@
|
|||
from __future__ import unicode_literals, absolute_import
|
||||
import functools
|
||||
import uuid
|
||||
|
||||
from django.db import models
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.utils import timezone
|
||||
from django.db.models.signals import m2m_changed
|
||||
|
||||
from users.models import User, UserGroup
|
||||
from assets.models import Asset, AssetGroup, SystemUser
|
||||
from common.utils import date_expired_default, combine_seq
|
||||
|
||||
|
||||
class AssetPermission(models.Model):
|
||||
from users.models import User, UserGroup
|
||||
from assets.models import Asset, AssetGroup, SystemUser
|
||||
# PRIVATE_FOR_CHOICE = (
|
||||
# ('N', 'None'),
|
||||
# ('U', 'user'),
|
||||
|
|
|
@ -6,7 +6,7 @@ import uuid
|
|||
from django.db import models
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from rest_framework.authtoken.models import Token
|
||||
from . import User
|
||||
from .user import User
|
||||
|
||||
__all__ = ['AccessKey', 'PrivateToken', 'LoginLog']
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ from django.utils.translation import ugettext_lazy as _
|
|||
from django.utils import timezone
|
||||
from django.shortcuts import reverse
|
||||
|
||||
from . import UserGroup
|
||||
from .group import UserGroup
|
||||
from common.utils import signer, date_expired_default
|
||||
|
||||
|
||||
|
|
|
@ -2,7 +2,8 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
|
||||
from . import User, UserGroup
|
||||
from .user import User
|
||||
from .group import UserGroup
|
||||
|
||||
|
||||
def init_model():
|
||||
|
|
|
@ -1,24 +0,0 @@
|
|||
# ~*~ coding: utf-8 ~*~
|
||||
|
||||
|
||||
from random import choice
|
||||
import forgery_py
|
||||
|
||||
from users.models import User, UserGroup, init_all_models
|
||||
|
||||
|
||||
def gen_username():
|
||||
return forgery_py.internet.user_name(True)
|
||||
|
||||
|
||||
def gen_email():
|
||||
return forgery_py.internet.email_address()
|
||||
|
||||
|
||||
def gen_name():
|
||||
return forgery_py.name.full_name()
|
||||
|
||||
|
||||
def get_role():
|
||||
role = choice(dict(User.ROLE_CHOICES).keys())
|
||||
return role
|
|
@ -1,95 +0,0 @@
|
|||
# ~*~ coding: utf-8 ~*~
|
||||
|
||||
|
||||
from django.utils import timezone
|
||||
from django.shortcuts import reverse
|
||||
from django.test import TestCase, TransactionTestCase
|
||||
from django.db import IntegrityError
|
||||
from users.models import User, UserGroup, init_all_models
|
||||
from django.contrib.auth.models import Permission
|
||||
|
||||
from .base import gen_name, gen_username, gen_email, get_role
|
||||
|
||||
|
||||
class UserModelTest(TransactionTestCase):
|
||||
def setUp(self):
|
||||
init_all_models()
|
||||
|
||||
# 创建一个用户用于测试
|
||||
role = get_role()
|
||||
user = User(name='test', username='test', email='test@email.org', role=role)
|
||||
user.save()
|
||||
|
||||
def test_initial(self):
|
||||
self.assertEqual(User.objects.all().count(), 2)
|
||||
|
||||
@property
|
||||
def role(self):
|
||||
return get_role()
|
||||
|
||||
# 创建一个姓名一致的用户, 应该创建成功
|
||||
def test_user_name_duplicate(self):
|
||||
user1 = User(name='test', username=gen_username(), password_raw=gen_username(),
|
||||
email=gen_email())
|
||||
try:
|
||||
user1.save()
|
||||
user1.delete()
|
||||
except IntegrityError:
|
||||
self.assertTrue(0, 'Duplicate <name> not allowed.')
|
||||
|
||||
# 创建一个用户名一致的用户, 应该创建不成功
|
||||
def test_user_username_duplicate(self):
|
||||
user2 = User(username='test', email=gen_email(), role=self.role)
|
||||
|
||||
with self.assertRaises(IntegrityError):
|
||||
user2.save()
|
||||
|
||||
# 创建一个Email一致的用户,应该创建不成功
|
||||
def test_user_email_duplicate(self):
|
||||
user3 = User(username=gen_username(), email='test@email.org', role=self.role)
|
||||
|
||||
with self.assertRaises(IntegrityError):
|
||||
user3.save()
|
||||
|
||||
# 用户过期测试
|
||||
def test_user_was_expired(self):
|
||||
date = timezone.now() - timezone.timedelta(days=1)
|
||||
user = User(name=gen_name(), username=gen_username(),
|
||||
email=gen_email(), role=self.role, date_expired=date)
|
||||
|
||||
self.assertTrue(user.is_expired)
|
||||
|
||||
# 测试用户默认会输入All用户组
|
||||
def test_user_with_default_group(self):
|
||||
role = get_role()
|
||||
user = User(username=gen_username(), email=gen_email(), role=role)
|
||||
user.save()
|
||||
|
||||
self.assertEqual(user.groups.count(), 1)
|
||||
self.assertEqual(user.groups.first().name, 'Default')
|
||||
|
||||
def test_user_password_authenticated(self):
|
||||
password = gen_username() * 3
|
||||
user = User(username=gen_username(), password_raw=password, role=self.role)
|
||||
user.save()
|
||||
self.assertTrue(user.check_password(password))
|
||||
self.assertFalse(user.check_password(password*2))
|
||||
|
||||
def test_user_reset_password(self):
|
||||
user = User.objects.first()
|
||||
token = User.generate_reset_token(user.email)
|
||||
new_password = gen_username()
|
||||
User.reset_password(token, new_password)
|
||||
user_ = User.objects.get(id=user.id)
|
||||
self.assertTrue(user_.check_password(new_password))
|
||||
|
||||
def tearDown(self):
|
||||
User.objects.all().delete()
|
||||
UserGroup.objects.all().delete()
|
||||
|
||||
|
||||
class UserGroupModelTestCase(TransactionTestCase):
|
||||
pass
|
||||
|
||||
|
||||
|
|
@ -1,66 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
|
||||
from users.models import User, UserGroup, init_all_models
|
||||
from django.shortcuts import reverse
|
||||
from django.test import TestCase, Client, TransactionTestCase
|
||||
|
||||
from .base import gen_username, gen_name, gen_email, get_role
|
||||
|
||||
|
||||
class UserListViewTests(TransactionTestCase):
|
||||
def setUp(self):
|
||||
init_all_models()
|
||||
self.client.login(username='admin', password='admin')
|
||||
|
||||
def test_a_new_user_in_list(self):
|
||||
username = gen_username()
|
||||
user = User(username=username, email=gen_email(), role=get_role())
|
||||
user.save()
|
||||
response = self.client.get(reverse('users:user-list'))
|
||||
|
||||
self.assertContains(response, username)
|
||||
|
||||
def test_list_view_with_admin_user(self):
|
||||
response = self.client.get(reverse('users:user-list'))
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertContains(response, 'Admin')
|
||||
self.assertEqual(response.context['user_list'].count(), User.objects.all().count())
|
||||
|
||||
def test_pagination(self):
|
||||
User.generate_fake(count=20)
|
||||
response = self.client.get(reverse('users:user-list'))
|
||||
self.assertEqual(response.context['is_paginated'], True)
|
||||
|
||||
def tearDown(self):
|
||||
self.client.logout()
|
||||
|
||||
|
||||
class UserAddTests(TestCase):
|
||||
def setUp(self):
|
||||
init_all_models()
|
||||
self.client.login(username='admin', password='admin')
|
||||
|
||||
def test_add_a_new_user(self):
|
||||
username = gen_username()
|
||||
data = {
|
||||
'username': username,
|
||||
'comment': '',
|
||||
'name': gen_name(),
|
||||
'email': gen_email(),
|
||||
'groups': [UserGroup.objects.first().id, ],
|
||||
'role': get_role(),
|
||||
'date_expired': '2086-08-06 19:12:22',
|
||||
}
|
||||
|
||||
response = self.client.post(reverse('users:user-create'), data)
|
||||
self.assertEqual(response.status_code, 302)
|
||||
self.assertEqual(response['location'], reverse('users:user-list'))
|
||||
|
||||
response = self.client.get(reverse('users:user-list'))
|
||||
self.assertContains(response, username)
|
||||
|
||||
def tearDown(self):
|
||||
self.client.logout()
|
||||
|
Loading…
Reference in New Issue