diff --git a/.gitignore b/.gitignore index 9f5ded8b2..4861567b4 100644 --- a/.gitignore +++ b/.gitignore @@ -21,3 +21,4 @@ migrations/ host_rsa_key *.bat tags +tmp/* diff --git a/apps/applications/api.py b/apps/applications/api.py index d30f9667c..9cc75ca8a 100644 --- a/apps/applications/api.py +++ b/apps/applications/api.py @@ -95,9 +95,6 @@ class TerminateConnectionView(APIView): proxy_log_id = d.get('proxy_log_id') proxy_log = get_object_or_404(ProxyLog, id=proxy_log_id) terminal_id = proxy_log.terminal - proxy_log.is_finished = True - proxy_log.date_finished = timezone.now() - proxy_log.save() if terminal_id in tasks: tasks[terminal_id].append({'name': 'kill_proxy', 'proxy_log_id': proxy_log_id}) diff --git a/apps/applications/templates/applications/terminal_list.html b/apps/applications/templates/applications/terminal_list.html index 33a04c009..9574d72d5 100644 --- a/apps/applications/templates/applications/terminal_list.html +++ b/apps/applications/templates/applications/terminal_list.html @@ -29,7 +29,7 @@ {% trans 'Name' %} {% trans 'IP' %} {% trans 'Type' %} - {% trans 'proxy online' %} + {% trans 'Session online' %} {% trans 'Active' %} {% trans 'Alive' %} {% trans 'Action' %} diff --git a/apps/assets/api.py b/apps/assets/api.py index 0d427b91f..37ed15c5c 100644 --- a/apps/assets/api.py +++ b/apps/assets/api.py @@ -12,7 +12,7 @@ from django.shortcuts import get_object_or_404 from common.mixins import IDInFilterMixin from common.utils import get_object_or_none, signer from .hands import IsSuperUser, IsAppUser -from .models import AssetGroup, Asset, IDC, SystemUser, AdminUser, Tag +from .models import AssetGroup, Asset, IDC, SystemUser, AdminUser from . import serializers @@ -25,14 +25,11 @@ class AssetViewSet(IDInFilterMixin, BulkModelViewSet): def get_queryset(self): queryset = super(AssetViewSet, self).get_queryset() idc_id = self.request.query_params.get('idc_id', '') - tags_id = self.request.query_params.get('tag_id', '') system_users_id = self.request.query_params.get('system_user_id', '') asset_group_id = self.request.query_params.get('asset_group_id', '') admin_user_id = self.request.query_params.get('admin_user_id', '') if idc_id: queryset = queryset.filter(idc__id=idc_id) - if tags_id: - queryset = queryset.filter(tags__id=tags_id) if system_users_id: queryset = queryset.filter(system_users__id=system_users_id) if admin_user_id: @@ -147,16 +144,3 @@ class SystemUserAuthInfoApi(generics.RetrieveAPIView): } return Response(data) - -class TagViewSet(IDInFilterMixin, BulkModelViewSet): - queryset = Tag.objects.all() - serializer_class = serializers.TagSerializer - permission_classes = (IsSuperUser,) - - -## update the IDC, and add or delete the assets to the IDC -class TagUpdateAssetsApi(generics.RetrieveUpdateAPIView): - queryset = Tag.objects.all() - serializer_class = serializers.TagUpdateAssetsSerializer - permission_classes = (IsSuperUser,) - diff --git a/apps/assets/forms.py b/apps/assets/forms.py index 0c1a12625..66da29afd 100644 --- a/apps/assets/forms.py +++ b/apps/assets/forms.py @@ -2,7 +2,7 @@ from django import forms from django.utils.translation import gettext_lazy as _ -from .models import IDC, Asset, AssetGroup, AdminUser, SystemUser, Tag +from .models import IDC, Asset, AssetGroup, AdminUser, SystemUser from common.utils import validate_ssh_private_key, ssh_pubkey_gen, ssh_key_gen, get_logger @@ -10,20 +10,6 @@ logger = get_logger(__file__) class AssetCreateForm(forms.ModelForm): - - def __init__(self, *args, **kwargs): - instance = kwargs.get('instance', None) - if instance: - initial = kwargs.get('initial', {}) - initial['tags'] = [t.pk for t in kwargs['instance'].tags.all()] - super(AssetCreateForm, self).__init__(*args, **kwargs) - - def _save_m2m(self): - super(AssetCreateForm, self)._save_m2m() - tags = self.cleaned_data['tags'] - self.instance.tags.clear() - self.instance.tags.add(*tuple(tags)) - def clean_admin_user(self): if not self.cleaned_data['admin_user']: raise forms.ValidationError(_('Select admin user')) @@ -31,16 +17,13 @@ class AssetCreateForm(forms.ModelForm): class Meta: model = Asset - tags = forms.ModelMultipleChoiceField(queryset=Tag.objects.all()) fields = [ 'hostname', 'ip', 'public_ip', 'port', 'type', 'comment', 'admin_user', - 'idc', 'groups', 'status', 'env', 'tags', 'is_active' + 'idc', 'groups', 'status', 'env', 'is_active' ] widgets = { 'groups': forms.SelectMultiple(attrs={'class': 'select2', 'data-placeholder': _('Select asset groups')}), - 'tags': forms.SelectMultiple(attrs={'class': 'select2', - 'data-placeholder': _('Select asset tags')}), 'admin_user': forms.Select(attrs={'class': 'select2', 'data-placeholder': _('Select asset admin user')}), } help_texts = { @@ -48,24 +31,20 @@ class AssetCreateForm(forms.ModelForm): 'ip': '* required', 'system_users': _('System user will be granted for user to login assets (using ansible create automatic)'), 'admin_user': _('Admin user should be exist on asset already, And have sudo ALL permission'), - 'tags': '最多5个标签,单个标签最长8个汉字,按回车确认' } class AssetUpdateForm(AssetCreateForm): class Meta: model = Asset - tags = forms.ModelMultipleChoiceField(queryset=Tag.objects.all()) fields = [ 'hostname', 'ip', 'port', 'groups', 'admin_user', 'idc', 'is_active', 'type', 'env', 'status', 'public_ip', 'remote_card_ip', 'cabinet_no', - 'cabinet_pos', 'number', 'comment', 'tags' + 'cabinet_pos', 'number', 'comment' ] widgets = { 'groups': forms.SelectMultiple(attrs={'class': 'select2', 'data-placeholder': _('Select asset groups')}), - 'tags': forms.SelectMultiple(attrs={'class': 'select2', - 'data-placeholder': _('Select asset tags')}), 'admin_user': forms.Select(attrs={'class': 'select2', 'data-placeholder': _('Select asset admin user')}), } help_texts = { @@ -73,18 +52,18 @@ class AssetUpdateForm(AssetCreateForm): 'ip': '* required', 'system_users': _('System user will be granted for user to login assets (using ansible create automatic)'), 'admin_user': _('Admin user should be exist on asset already, And have sudo ALL permission'), - 'tags': '最多5个标签,单个标签最长8个汉字,按回车确认' } class AssetGroupForm(forms.ModelForm): # See AdminUserForm comment same it - assets = forms.ModelMultipleChoiceField(queryset=Asset.objects.all(), - label=_('Asset'), - required=False, - widget=forms.SelectMultiple( - attrs={'class': 'select2', 'data-placeholder': _('Select assets')}) - ) + assets = forms.ModelMultipleChoiceField( + queryset=Asset.objects.all(), + label=_('Asset'), + required=False, + widget=forms.SelectMultiple( + attrs={'class': 'select2', 'data-placeholder': _('Select assets')}) + ) def __init__(self, *args, **kwargs): if kwargs.get('instance', None): @@ -297,39 +276,5 @@ class SystemUserForm(forms.ModelForm): } -class AssetTagForm(forms.ModelForm): - assets = forms.ModelMultipleChoiceField(queryset=Asset.objects.all(), - label=_('Asset'), - required=False, - widget=forms.SelectMultiple( - attrs={'class': 'select2', 'data-placeholder': _('Select assets')}) - ) - - def __init__(self, *args, **kwargs): - if kwargs.get('instance', None): - initial = kwargs.get('initial', {}) - initial['assets'] = kwargs['instance'].asset_set.all() - super(AssetTagForm, self).__init__(*args, **kwargs) - - def _save_m2m(self): - assets = self.cleaned_data['assets'] - self.instance.assets.clear() - self.instance.assets.add(*tuple(assets)) - super(AssetTagForm, self)._save_m2m() - - class Meta: - model = Tag - fields = [ - "name", - ] - widgets = { - 'name': forms.TextInput(attrs={}), - - } - help_texts = { - 'name': '* required', - } - - class FileForm(forms.Form): file = forms.FileField() diff --git a/apps/assets/models/asset.py b/apps/assets/models/asset.py index 068f41aa2..54a2d4820 100644 --- a/apps/assets/models/asset.py +++ b/apps/assets/models/asset.py @@ -10,7 +10,7 @@ from django.utils.translation import ugettext_lazy as _ from . import IDC, AssetGroup, AdminUser, SystemUser -__all__ = ['Asset', 'Tag'] +__all__ = ['Asset'] logger = logging.getLogger(__name__) @@ -83,7 +83,6 @@ class Asset(models.Model): created_by = models.CharField(max_length=32, null=True, blank=True, verbose_name=_('Created by')) date_created = models.DateTimeField(auto_now_add=True, null=True, blank=True, verbose_name=_('Date added')) comment = models.TextField(max_length=128, default='', blank=True, verbose_name=_('Comment')) - tags = models.ManyToManyField('Tag', related_name='assets', blank=True, verbose_name=_('Tags')) def __unicode__(self): return '%s <%s: %s>' % (self.hostname, self.ip, self.port) @@ -112,7 +111,12 @@ class Asset(models.Model): 'groups': [group.name for group in self.groups.all()], 'username': self.admin_user.username if self.admin_user else '', 'password': self.admin_user.password if self.admin_user else '', - 'private_key': self.admin_user.private_key if self.admin_user else None, + 'private_key': self.admin_user.private_key_file if self.admin_user else None, + 'become': { + 'method': self.admin_user.become_method, + 'user': self.admin_user.become_user, + 'pass': self.admin_user.become_pass, + } if self.admin_user.become else {}, } class Meta: @@ -141,16 +145,3 @@ class Asset(models.Model): print('Error continue') continue - -class Tag(models.Model): - name = models.CharField(max_length=64, unique=True, verbose_name=_('Name')) - created_time = models.DateTimeField(auto_now_add=True, verbose_name=_('Create time')) - created_by = models.CharField(max_length=32, null=True, blank=True, verbose_name=_('Created by')) - - def __unicode__(self): - return self.name - - __str__ = __unicode__ - - class Meta: - db_table = 'tag' diff --git a/apps/assets/models/user.py b/apps/assets/models/user.py index ee2a156ab..48d0f4029 100644 --- a/apps/assets/models/user.py +++ b/apps/assets/models/user.py @@ -3,12 +3,14 @@ # from __future__ import unicode_literals - +import os import logging +from hashlib import md5 from django.core.exceptions import ValidationError from django.db import models from django.utils.translation import ugettext_lazy as _ +from django.conf import settings from common.utils import signer, validate_ssh_private_key, ssh_key_string_to_obj @@ -38,7 +40,7 @@ class AdminUser(models.Model): become = models.BooleanField(default=True) become_method = models.CharField(choices=BECOME_METHOD_CHOICES, default='sudo', max_length=4) become_user = models.CharField(default='root', max_length=64) - become_password = models.CharField(default='', max_length=128) + become_pass = models.CharField(default='', max_length=128) _public_key = models.CharField( max_length=4096, blank=True, verbose_name=_('SSH public key')) comment = models.TextField(blank=True, verbose_name=_('Comment')) @@ -74,6 +76,18 @@ class AdminUser(models.Model): def private_key(self, private_key_raw): self._private_key = signer.sign(private_key_raw) + @property + def private_key_file(self): + if not self.private_key: + return None + project_dir = settings.PROJECT_DIR + tmp_dir = os.path.join(project_dir, 'tmp') + key_name = md5(self._private_key).hexdigest() + key_path = os.path.join(tmp_dir, key_name) + if not os.path.exists(key_path): + self.private_key.write_private_key_file(key_path) + return key_path + @property def public_key(self): return signer.unsign(self._public_key) diff --git a/apps/assets/serializers.py b/apps/assets/serializers.py index aae1c4b13..50e7188f3 100644 --- a/apps/assets/serializers.py +++ b/apps/assets/serializers.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- from django.utils.translation import ugettext_lazy as _ from rest_framework import viewsets, serializers, generics -from .models import AssetGroup, Asset, IDC, AdminUser, SystemUser, Tag +from .models import AssetGroup, Asset, IDC, AdminUser, SystemUser from common.mixins import IDInFilterMixin from rest_framework_bulk import BulkListSerializer, BulkSerializerMixin @@ -61,20 +61,6 @@ class IDCUpdateAssetsSerializer(serializers.ModelSerializer): fields = ['id', 'assets'] -class TagSerializer(BulkSerializerMixin, serializers.ModelSerializer): - assets_amount = serializers.SerializerMethodField() - assets = serializers.PrimaryKeyRelatedField(many=True, queryset=Asset.objects.all()) - - class Meta: - model = Tag - list_serializer_class = BulkListSerializer - fields = '__all__' - - @staticmethod - def get_assets_amount(obj): - return obj.assets.count() - - class AdminUserSerializer(serializers.ModelSerializer): assets = serializers.PrimaryKeyRelatedField(many=True, queryset=Asset.objects.all()) @@ -189,10 +175,3 @@ class IDCSerializer(BulkSerializerMixin, serializers.ModelSerializer): fields.append('assets_amount') return fields - -class TagUpdateAssetsSerializer(serializers.ModelSerializer): - assets = serializers.PrimaryKeyRelatedField(many=True, queryset=Asset.objects.all()) - - class Meta: - model = Tag - fields = ['id', 'assets'] \ No newline at end of file diff --git a/apps/assets/tasks.py b/apps/assets/tasks.py index 89e2e410e..b716dc644 100644 --- a/apps/assets/tasks.py +++ b/apps/assets/tasks.py @@ -12,8 +12,7 @@ def update_assets_hardware_info(assets): task_tuple = ( ('setup', ''), ) - task_name = ','.join([asset.hostname for asset in assets]) - summary, result = run_AdHoc(task_tuple, assets, record=True, task_name=task_name) + summary, result = run_AdHoc(task_tuple, assets, record=False) for hostname, info in result['contacted'].items(): if info: info = info[0]['ansible_facts'] diff --git a/apps/assets/templates/assets/_asset_bulk_update_modal.html b/apps/assets/templates/assets/_asset_bulk_update_modal.html index 9ff3d2973..df012f619 100644 --- a/apps/assets/templates/assets/_asset_bulk_update_modal.html +++ b/apps/assets/templates/assets/_asset_bulk_update_modal.html @@ -61,22 +61,6 @@ - -
- -
- -

- 最多5个标签,单个标签最长8个汉字,按回车确认 -

-
- -
- {% endblock %} {% block modal_confirm_id %}btn_asset_bulk_update{% endblock %} \ No newline at end of file diff --git a/apps/assets/templates/assets/asset_create.html b/apps/assets/templates/assets/asset_create.html index a1fa33705..5535f2b64 100644 --- a/apps/assets/templates/assets/asset_create.html +++ b/apps/assets/templates/assets/asset_create.html @@ -29,7 +29,6 @@

{% trans 'Other' %}

- {{ form.tags|bootstrap_horizontal }} {{ form.comment|bootstrap_horizontal }} {{ form.is_active|bootstrap_horizontal }} diff --git a/apps/assets/templates/assets/asset_list.html b/apps/assets/templates/assets/asset_list.html index 38c6a9c0a..4c6927088 100644 --- a/apps/assets/templates/assets/asset_list.html +++ b/apps/assets/templates/assets/asset_list.html @@ -104,37 +104,6 @@ function tagShow() { } } //onload; -function objDelete(obj, name, url) { - function doDelete() { - var body = {}; - var success = function() { - swal('Deleted!', "[ "+name+"]"+" has been deleted ", "success"); - $(obj).parent().parent().remove(); - }; - var fail = function() { - swal("Failed", "Delete"+"[ "+name+" ]"+"failed", "error"); - }; - APIUpdateAttr({ - url: url, - body: JSON.stringify(body), - method: 'DELETE', - success: success, - error: fail - }); - } - swal({ - title: 'Are you sure delete ?', - text: " [" + name + "] ", - type: "warning", - showCancelButton: true, - cancelButtonText: 'Cancel', - confirmButtonColor: "#DD6B55", - confirmButtonText: 'Confirm', - closeOnConfirm: false - }, function () { - doDelete() - }); -} $(document).ready(function(){ var options = { diff --git a/apps/assets/urls/api_urls.py b/apps/assets/urls/api_urls.py index 42839bdfa..0abe9db6f 100644 --- a/apps/assets/urls/api_urls.py +++ b/apps/assets/urls/api_urls.py @@ -13,7 +13,6 @@ router.register(r'v1/assets', api.AssetViewSet, 'asset') router.register(r'v1/idc', api.IDCViewSet, 'idc') router.register(r'v1/admin-user', api.AdminUserViewSet, 'admin-user') router.register(r'v1/system-user', api.SystemUserViewSet, 'system-user') -router.register(r'v1/tags', api.TagViewSet, 'asset-tag') urlpatterns = [ url(r'^v1/assets_bulk/$', api.AssetListUpdateApi.as_view(), name='asset-bulk-update'), @@ -45,8 +44,6 @@ urlpatterns = [ url(r'^v1/idc/(?P\d+)/assets/$', api.IDCupdateAssetsApi.as_view(), name='idc-update-assets'), - url(r'v1/tag/(?P\d+)/assets/$', - api.TagUpdateAssetsApi.as_view(), name='tag-update-assets'), ] urlpatterns += router.urls diff --git a/apps/assets/urls/views_urls.py b/apps/assets/urls/views_urls.py index a2b4537a3..e583f3b6a 100644 --- a/apps/assets/urls/views_urls.py +++ b/apps/assets/urls/views_urls.py @@ -24,13 +24,6 @@ urlpatterns = [ url(r'^asset-group/(?P[0-9]+)/update/$', views.AssetGroupUpdateView.as_view(), name='asset-group-update'), url(r'^asset-group/(?P[0-9]+)/delete/$', views.AssetGroupDeleteView.as_view(), name='asset-group-delete'), - url(r'^tags/$', views.TagsListView.as_view(), name='asset-tag-list'), - url(r'^asset-by-tag/(?P[0-9]+)/$', views.TagView.as_view(), name='asset-tags'), - url(r'^tags/create/$', views.AssetTagCreateView.as_view(), name='asset-tag-create'), - url(r'^asset-tag/(?P[0-9]+)/$', views.AssetTagDetailView.as_view(), name='asset-tag-detail'), - url(r'^asset-tag/(?P[0-9]+)/update/$', views.AssetTagUpdateView.as_view(), name='asset-tag-update'), - url(r'^asset-tag/(?P[0-9]+)/delete/$', views.AssetTagDeleteView.as_view(), name='asset-tag-delete'), - # Resource idc url url(r'^idc/$', views.IDCListView.as_view(), name='idc-list'), url(r'^idc/create/$', views.IDCCreateView.as_view(), name='idc-create'), diff --git a/apps/assets/utils.py b/apps/assets/utils.py index 4eeb3ed65..cd064e942 100644 --- a/apps/assets/utils.py +++ b/apps/assets/utils.py @@ -1,40 +1,3 @@ # ~*~ coding: utf-8 ~*~ # -from rest_framework import serializers -from models import Tag -from django.views.generic.edit import CreateView - -class CreateAssetTagsMiXin(CreateView): - def get_form_kwargs(self): - tags_list = self.request.POST.getlist('tags') - kwargs = { - 'initial': self.get_initial(), - 'prefix': self.get_prefix(), - } - if self.request.method in ('POST', 'PUT'): - post_data = self.request.POST.copy() - if post_data.has_key('tags'): - post_data.pop('tags') - for t in tags_list: - try: - oTag = Tag.objects.get(pk=int(t)) - except (Tag.DoesNotExist, UnicodeEncodeError): - oTag = Tag(name=t, created_by=self.request.user.username or 'Admin') - oTag.save() - post_data.update({'tags':oTag.pk}) - else: - post_data.update({'tags':int(t)}) - kwargs.update({ - 'data': post_data, - 'files': self.request.FILES, - }) - return kwargs - - -class UpdateAssetTagsMiXin(CreateAssetTagsMiXin): - def get_form_kwargs(self): - kwargs = super(UpdateAssetTagsMiXin, self).get_form_kwargs() - if hasattr(self, 'object'): - kwargs.update({'instance': self.object}) - return kwargs \ No newline at end of file diff --git a/apps/assets/views.py b/apps/assets/views.py index e89500c75..51850a5d6 100644 --- a/apps/assets/views.py +++ b/apps/assets/views.py @@ -25,9 +25,8 @@ from django.utils import timezone from common.mixins import JSONResponseMixin from common.utils import get_object_or_none -from .utils import CreateAssetTagsMiXin, UpdateAssetTagsMiXin from . import forms -from .models import Asset, AssetGroup, AdminUser, IDC, SystemUser, Tag +from .models import Asset, AssetGroup, AdminUser, IDC, SystemUser from .hands import AdminUserRequiredMixin @@ -40,16 +39,13 @@ class AssetListView(AdminUserRequiredMixin, TemplateView): 'action': 'asset list', 'groups': AssetGroup.objects.all(), 'system_users': SystemUser.objects.all(), - 'tag_list': [(i.id, i.name, i.assets.all().count())for i in Tag.objects.all().order_by('name')], - 'tags': Tag.objects.all().order_by('name') } kwargs.update(context) return super(AssetListView, self).get_context_data(**kwargs) -class AssetCreateView(AdminUserRequiredMixin, CreateAssetTagsMiXin, CreateView): +class AssetCreateView(AdminUserRequiredMixin, CreateView): model = Asset - tag_type = 'asset' form_class = forms.AssetCreateForm template_name = 'assets/asset_create.html' success_url = reverse_lazy('assets:asset-list') @@ -69,7 +65,7 @@ class AssetCreateView(AdminUserRequiredMixin, CreateAssetTagsMiXin, CreateView): return super(AssetCreateView, self).get_context_data(**kwargs) -class AssetModalCreateView(AdminUserRequiredMixin, CreateAssetTagsMiXin, ListView): +class AssetModalCreateView(AdminUserRequiredMixin, ListView): model = Asset form_class = forms.AssetCreateForm template_name = 'assets/asset_modal_update.html' @@ -97,31 +93,11 @@ class AssetModalCreateView(AdminUserRequiredMixin, CreateAssetTagsMiXin, ListVie return super(AssetModalCreateView, self).get_context_data(**kwargs) -class AssetUpdateView(AdminUserRequiredMixin, UpdateAssetTagsMiXin, UpdateView): +class AssetUpdateView(AdminUserRequiredMixin, UpdateView): model = Asset form_class = forms.AssetUpdateForm template_name = 'assets/asset_update.html' success_url = reverse_lazy('assets:asset-list') - # new_form = '' - # assets_ids = '' - - # def post(self, request, *args, **kwargs): - # default_keys = [ - # 'csrfmiddlewaretoken', - # 'assets_ids', - # 'ip', - # 'number', - # 'hostname', - # 'system_users', - # 'admin_user', - # ] - # self.assets_ids = self.request.POST.getlist('assets_ids') - # self.new_form = self.request.POST.copy() - # for i in default_keys: - # if self.new_form.has_key(i): - # self.new_form.pop(i) - - # return super(AssetUpdateView, self).post(request, *args, **kwargs) def get_context_data(self, **kwargs): context = { @@ -135,26 +111,6 @@ class AssetUpdateView(AdminUserRequiredMixin, UpdateAssetTagsMiXin, UpdateView): print(form.errors) return super(AssetUpdateView, self).form_invalid(form) - # def form_valid(self, form): - # asset = form.save(commit=False) - # - # def prn_obj_key(obj_form): - # return obj_form.clean().keys() - # - # for i in prn_obj_key(form): - # if i not in self.new_form.keys(): - # print i - - #delattr(asset, '"%s" % i') - #del asset.i - # asset.save() - # asset.id = 27 - # # asset.created_by = self.request.user.username or 'Admin' - # asset.save() - # asset.id = 28 - # asset.save() - # return super(AssetUpdateView, self).form_valid(form) - class AssetDeleteView(DeleteView): model = Asset @@ -192,7 +148,6 @@ class AssetModalListView(AdminUserRequiredMixin, ListView): def get_context_data(self, **kwargs): group_id = self.request.GET.get('group_id') - tag_id = self.request.GET.get('tag_id') plain_id_lists = self.request.GET.get('plain_id_lists') self.s = self.request.GET.get('plain_id_lists') assets = Asset.objects.all() @@ -208,24 +163,15 @@ class AssetModalListView(AdminUserRequiredMixin, ListView): plain_id_lists = [int(self.s)] context = { 'all_assets': plain_id_lists, - 'assets': assets } kwargs.update(context) if group_id: group = AssetGroup.objects.get(id=group_id) - print group context = { 'all_assets': [x.id for x in group.assets.all()], 'assets': assets } kwargs.update(context) - if tag_id: - tag = Tag.objects.get(id=tag_id) - context = { - 'all_assets': [x.id for x in tag.asset_set.all()], - 'assets': assets - } - kwargs.update(context) else: context = { 'assets': assets @@ -315,7 +261,6 @@ class AssetGroupUpdateView(AdminUserRequiredMixin, UpdateView): 'assets_on_list': assets_all, 'assets_count': len(assets_all), 'group_id': self.object.id, - 'tags': Tag.objects.all() } kwargs.update(context) return super(AssetGroupUpdateView, self).get_context_data(**kwargs) @@ -401,7 +346,6 @@ class IDCAssetsView(AdminUserRequiredMixin, DetailView): 'action': _('Asset detail'), 'groups': AssetGroup.objects.all(), 'system_users': SystemUser.objects.all(), - 'tags': Tag.objects.all(), 'assets_remain': assets_remain, 'assets': [asset for asset in Asset.objects.all() if asset not in assets_remain], } @@ -626,123 +570,8 @@ class SystemUserAssetView(AdminUserRequiredMixin, SingleObjectMixin, ListView): return super(SystemUserAssetView, self).get_context_data(**kwargs) -class TagView(ListView): - context_object_name = 'asset_list' - template_name = 'assets/asset_list.html' - - def get_queryset(self): - asset_list = Asset.objects.filter(tags=self.kwargs['tag_id']) - return asset_list - - def get_context_data(self, **kwargs): - kwargs['app'] = 'Assets' - kwargs['action']='asset list' - kwargs['tag_list'] = [(i.id,i.name,i.asset_set.all().count() )for i in Tag.objects.all().order_by('name')] - kwargs['tag_id'] = self.kwargs['tag_id'] - return super(TagView, self).get_context_data(**kwargs) - - -class TagsListView(AdminUserRequiredMixin, ListView): - model = Tag - paginate_by = settings.CONFIG.DISPLAY_PER_PAGE - context_object_name = 'asset_tags_list' - template_name = 'assets/asset_tags_list.html' - ordering = '-id' - - def get_context_data(self, **kwargs): - context = { - 'app': _('Tag'), - 'action': _('Asset Tags list'), - 'keyword': self.request.GET.get('keyword', '') - } - kwargs.update(context) - return super(TagsListView, self).get_context_data(**kwargs) - - -class AssetTagCreateView(AdminUserRequiredMixin, CreateAssetTagsMiXin, CreateView): - model = Tag - form_class = forms.AssetTagForm - template_name = 'assets/asset_tag_create.html' - success_url = reverse_lazy('assets:asset-tag-list') - #ordering = '-id' - - # Todo: Asset group create template select assets so hard, need be resolve next - - def get_context_data(self, **kwargs): - context = { - 'app': _('Tag'), - 'action': _('Asset Tags list'), - 'assets_count': 0, - } - kwargs.update(context) - return super(AssetTagCreateView, self).get_context_data(**kwargs) - - def form_valid(self, form): - asset_tag = form.save() - assets_id_list = self.request.POST.getlist('assets', []) - assets = [get_object_or_404(Asset, id=int(asset_id)) for asset_id in assets_id_list] - asset_tag.created_by = self.request.user.username or 'Admin' - asset_tag.assets.add(*tuple(assets)) - asset_tag.save() - return super(AssetTagCreateView, self).form_valid(form) - - -class AssetTagDetailView(SingleObjectMixin, AdminUserRequiredMixin, ListView): - template_name = 'assets/asset_tag_detail.html' - paginate_by = settings.CONFIG.DISPLAY_PER_PAGE - - def get(self, request, *args, **kwargs): - self.object = self.get_object(queryset=Tag.objects.all()) - return super(AssetTagDetailView, self).get(request, *args, **kwargs) - - def get_queryset(self): - return self.object.assets.all() - - def get_context_data(self, **kwargs): - assets_remain = Asset.objects.exclude(id__in=self.object.assets.all()) - context = { - 'app': _('Tag'), - 'action': _('Asset Tags detail'), - 'asset_tag': self.object, - 'assets_remain': assets_remain, - 'assets': [asset for asset in Asset.objects.all() if asset not in assets_remain] - } - kwargs.update(context) - return super(AssetTagDetailView, self).get_context_data(**kwargs) - - -class AssetTagUpdateView(AdminUserRequiredMixin, UpdateView): - model = Tag - form_class = forms.AssetTagForm - template_name = 'assets/asset_tag_create.html' - success_url = reverse_lazy('assets:asset-tag-list') - - def get(self, request, *args, **kwargs): - self.object = self.get_object(queryset=Tag.objects.all()) - return super(AssetTagUpdateView, self).get(request, *args, **kwargs) - - def get_context_data(self, **kwargs): - assets_all = self.object.assets.all() - context = { - 'app': _('Tag'), - 'action': _('Asset Tags detail'), - 'assets_count': len(assets_all), - 'assets_on_list': assets_all, - 'tag_id':self.object.id, - } - kwargs.update(context) - return super(AssetTagUpdateView, self).get_context_data(**kwargs) - - -class AssetTagDeleteView(AdminUserRequiredMixin, DeleteView): - template_name = 'assets/delete_confirm.html' - model = Tag - success_url = reverse_lazy('assets:asset-tag-list') - - @method_decorator(csrf_exempt, name='dispatch') class AssetExportView(View): - @staticmethod def get_asset_attr(asset, attr): if attr in ['admin_user', 'idc']: diff --git a/apps/audits/api.py b/apps/audits/api.py index 302fc3a69..d8a7b21de 100644 --- a/apps/audits/api.py +++ b/apps/audits/api.py @@ -90,8 +90,3 @@ class RecordLogViewSet(BulkModelViewSet): else: return record_store.all() - - - - - diff --git a/apps/audits/templates/audits/command_log_list.html b/apps/audits/templates/audits/command_log_list.html index 3ed7d5d0b..04bb976fb 100644 --- a/apps/audits/templates/audits/command_log_list.html +++ b/apps/audits/templates/audits/command_log_list.html @@ -23,18 +23,18 @@
- {% for u in user_list %} - + {% endfor %}
- {% for a in asset_list %} - + {% endfor %}
diff --git a/apps/audits/templates/audits/proxy_log_detail.html b/apps/audits/templates/audits/proxy_log_detail.html index 909d66fe6..0fa28b517 100644 --- a/apps/audits/templates/audits/proxy_log_detail.html +++ b/apps/audits/templates/audits/proxy_log_detail.html @@ -1,6 +1,7 @@ {% extends 'base.html' %} {% load static %} {% load i18n %} +{% load common_tags %} {% block custom_head_css_js %} diff --git a/apps/audits/templates/audits/proxy_log_offline_list.html b/apps/audits/templates/audits/proxy_log_offline_list.html new file mode 100644 index 000000000..ffe695662 --- /dev/null +++ b/apps/audits/templates/audits/proxy_log_offline_list.html @@ -0,0 +1,159 @@ +{% extends '_base_list.html' %} +{% load i18n %} +{% load static %} +{% block content_left_head %} + + +{% endblock %} + + +{% block table_search %} +
+
+
+ + + to + +
+
+
+ +
+
+ +
+
+ +
+
+ +
+
+
+ +
+
+
+{% endblock %} + +{% block table_head %} + + {% trans 'ID' %} + {% trans 'User' %} + {% trans 'Asset' %} + {% trans 'System user' %} + {% trans 'Terminal' %} + {% trans 'Command' %} + {% trans 'Success' %} + {% trans 'Finished' %} + {% trans 'Play' %} + {% trans 'Date start' %} + {% trans 'Time' %} +{% endblock %} + +{% block table_body %} + {% for proxy_log in proxy_log_list %} + + + + {{ proxy_log.id }} + + {{ proxy_log.user }} + {{ proxy_log.asset }} + {{ proxy_log.system_user }} + {{ proxy_log.terminal }} + {{ proxy_log.commands.all|length}} + + {% if proxy_log.is_failed %} + + {% else %} + + {% endif %} + + {% if proxy_log.is_finished %} + + + + + + + {% else %} + + + + + + + {% endif %} + {{ proxy_log.date_start }} + {{ proxy_log.date_finished|timeuntil:proxy_log.date_start }} + + {% endfor %} +{% endblock %} + + +{% block custom_foot_js %} + + +{% endblock %} + diff --git a/apps/audits/templates/audits/proxy_log_list.html b/apps/audits/templates/audits/proxy_log_online_list.html similarity index 94% rename from apps/audits/templates/audits/proxy_log_list.html rename to apps/audits/templates/audits/proxy_log_online_list.html index 6a3c815b0..500fe68b3 100644 --- a/apps/audits/templates/audits/proxy_log_list.html +++ b/apps/audits/templates/audits/proxy_log_online_list.html @@ -24,16 +24,16 @@
@@ -68,7 +68,7 @@ {% trans 'Command' %} {% trans 'Success' %} {% trans 'Finished' %} - {% trans 'R/M' %} + {% trans 'Monitor' %} {% trans 'Date start' %} {% trans 'Time' %} {% endblock %} diff --git a/apps/audits/urls/views_urls.py b/apps/audits/urls/views_urls.py index d28882704..1ad6439b3 100644 --- a/apps/audits/urls/views_urls.py +++ b/apps/audits/urls/views_urls.py @@ -4,14 +4,16 @@ from .. import views app_name = 'audits' urlpatterns = [ - url(r'^proxy-log$', views.ProxyLogListView.as_view(), - name='proxy-log-list'), - url(r'^proxy-log/(?P\d+)$', views.ProxyLogDetailView.as_view(), + url(r'^proxy-log-offline/$', views.ProxyLogOfflineListView.as_view(), + name='proxy-log-offline-list'), + url(r'^proxy-log-online/$', views.ProxyLogOnlineListView.as_view(), + name='proxy-log-online-list'), + url(r'^proxy-log/(?P\d+)/$', views.ProxyLogDetailView.as_view(), name='proxy-log-detail'), # url(r'^proxy-log/(?P\d+)/commands$', views.ProxyLogCommandsListView.as_view(), name='proxy-log-commands-list'), - url(r'^command-log$', views.CommandLogListView.as_view(), + url(r'^command-log/$', views.CommandLogListView.as_view(), name='command-log-list'), - url(r'^login-log$', views.LoginLogListView.as_view(), + url(r'^login-log/$', views.LoginLogListView.as_view(), name='login-log-list'), ] diff --git a/apps/audits/views.py b/apps/audits/views.py index 20bc3f8aa..de7cc9421 100644 --- a/apps/audits/views.py +++ b/apps/audits/views.py @@ -3,7 +3,6 @@ import time from datetime import datetime -import pytz from django.views.generic import ListView, UpdateView, DeleteView, DetailView, TemplateView from django.views.generic.edit import SingleObjectMixin from django.utils.translation import ugettext as _ @@ -22,10 +21,10 @@ from audits.backends import CommandLogSerializer class ProxyLogListView(AdminUserRequiredMixin, ListView): model = ProxyLog - template_name = 'audits/proxy_log_list.html' + template_name = 'audits/proxy_log_online_list.html' context_object_name = 'proxy_log_list' paginate_by = settings.CONFIG.DISPLAY_PER_PAGE - keyword = user = asset = system_user = date_from_s = date_to_s = '' + keyword = username = hostname = system_user = date_from_s = date_to_s = '' ordering = ['is_finished', '-id'] date_format = '%m/%d/%Y' @@ -37,8 +36,8 @@ class ProxyLogListView(AdminUserRequiredMixin, ListView): self.queryset = super(ProxyLogListView, self).get_queryset() self.keyword = self.request.GET.get('keyword', '') - self.user = self.request.GET.get('user') - self.asset = self.request.GET.get('asset') + self.username = self.request.GET.get('username') + self.ip = self.request.GET.get('ip') self.system_user = self.request.GET.get('system_user') self.date_from_s = self.request.GET.get('date_from', date_from_default) self.date_to_s = self.request.GET.get('date_to', date_to_default) @@ -53,10 +52,10 @@ class ProxyLogListView(AdminUserRequiredMixin, ListView): self.date_to_s + ' 23:59:59', '%m/%d/%Y %H:%M:%S') date_to = date_to.replace(tzinfo=timezone.get_current_timezone()) filter_kwargs['date_start__lt'] = date_to - if self.user: - filter_kwargs['user'] = self.user - if self.asset: - filter_kwargs['asset'] = self.asset + if self.username: + filter_kwargs['user'] = self.username + if self.ip: + filter_kwargs['ip'] = self.ip if self.system_user: filter_kwargs['system_user'] = self.system_user if self.keyword: @@ -81,14 +80,46 @@ class ProxyLogListView(AdminUserRequiredMixin, ListView): 'keyword': self.keyword, 'date_from': self.date_from_s, 'date_to': self.date_to_s, - 'user': self.user, - 'asset': self.asset, + 'username': self.username, + 'ip': self.ip, 'system_user': self.system_user, } kwargs.update(context) return super(ProxyLogListView, self).get_context_data(**kwargs) +class ProxyLogOfflineListView(ProxyLogListView): + template_name = 'audits/proxy_log_offline_list.html' + + def get_queryset(self): + queryset = super(ProxyLogOfflineListView, self).get_queryset() + queryset = queryset.filter(is_finished=True) + return queryset + + def get_context_data(self, **kwargs): + context = { + 'action': _('Proxy log offline list'), + } + kwargs.update(context) + return super(ProxyLogOfflineListView, self).get_context_data(**kwargs) + + +class ProxyLogOnlineListView(ProxyLogListView): + template_name = 'audits/proxy_log_online_list.html' + + def get_queryset(self): + queryset = super(ProxyLogOnlineListView, self).get_queryset() + queryset = queryset.filter(is_finished=False) + return queryset + + def get_context_data(self, **kwargs): + context = { + 'action': _('Proxy log online list'), + } + kwargs.update(context) + return super(ProxyLogOnlineListView, self).get_context_data(**kwargs) + + class ProxyLogDetailView(AdminUserRequiredMixin, SingleObjectMixin, ListView): @@ -131,7 +162,7 @@ class CommandLogListView(AdminUserRequiredMixin, ListView): template_name = 'audits/command_log_list.html' paginate_by = settings.CONFIG.DISPLAY_PER_PAGE context_object_name = 'command_list' - user = asset = system_user = command = date_from_s = date_to_s = '' + username = ip = system_user = command = date_from_s = date_to_s = '' date_format = '%m/%d/%Y' ordering = ['-id'] @@ -141,8 +172,8 @@ class CommandLogListView(AdminUserRequiredMixin, ListView): date_from_default = (date_now - timezone.timedelta(7)) \ .strftime(self.date_format) self.command = self.request.GET.get('command', '') - self.user = self.request.GET.get('user') - self.asset = self.request.GET.get('asset') + self.username = self.request.GET.get('username') + self.ip = self.request.GET.get('ip') self.system_user = self.request.GET.get('system_user') self.date_from_s = \ self.request.GET.get('date_from', date_from_default) @@ -162,10 +193,10 @@ class CommandLogListView(AdminUserRequiredMixin, ListView): .replace(tzinfo=timezone.get_current_timezone()) date_to_ts = time.mktime(date_to.timetuple()) filter_kwargs['date_to_ts'] = date_to_ts - if self.user: - filter_kwargs['user'] = self.user - if self.asset: - filter_kwargs['asset'] = self.asset + if self.username: + filter_kwargs['user'] = self.username + if self.ip: + filter_kwargs['asset'] = self.ip if self.system_user: filter_kwargs['system_user'] = self.system_user if self.command: @@ -183,8 +214,8 @@ class CommandLogListView(AdminUserRequiredMixin, ListView): 'command': self.command, 'date_from': self.date_from_s, 'date_to': self.date_to_s, - 'user': self.user, - 'asset': self.asset, + 'username': self.username, + 'ip': self.ip, 'system_user': self.system_user, } kwargs.update(context) diff --git a/apps/common/utils.py b/apps/common/utils.py index 3e543a107..1fa8e3915 100644 --- a/apps/common/utils.py +++ b/apps/common/utils.py @@ -2,6 +2,7 @@ # from __future__ import unicode_literals +from collections import OrderedDict from six import string_types import base64 import os @@ -53,6 +54,7 @@ def get_object_or_none(model, **kwargs): class Signer(object): + """用来加密,解密,和基于时间戳的方式验证token""" def __init__(self, secret_key=SECRET_KEY): self.secret_key = secret_key @@ -330,13 +332,13 @@ def encrypt_password(password): return None -from collections import OrderedDict def capacity_convert(size, expect='auto', rate=1000): """ - :param cap: '100MB', '1G' + :param size: '100MB', '1G' :param expect: 'K, M, G, T + :param rate: Default 1000, may be 1024 :return: """ rate_mapping = ( diff --git a/apps/jumpserver/settings.py b/apps/jumpserver/settings.py index 758a93221..ed919cb47 100644 --- a/apps/jumpserver/settings.py +++ b/apps/jumpserver/settings.py @@ -320,8 +320,9 @@ CACHES = { } # Captcha settings, more see https://django-simple-captcha.readthedocs.io/en/latest/advanced.html -CAPTCHA_IMAGE_SIZE = (75, 33) +CAPTCHA_IMAGE_SIZE = (80, 33) CAPTCHA_FOREGROUND_COLOR = '#001100' +CAPTCHA_NOISE_FUNCTIONS = ('captcha.helpers.noise_dots',) COMMAND_STORE_BACKEND = 'audits.backends.command.db' RECORD_STORE_BACKEND = 'audits.backends.record.db' diff --git a/apps/ops/ansible/inventory.py b/apps/ops/ansible/inventory.py index e9b2496d8..5c421e916 100644 --- a/apps/ops/ansible/inventory.py +++ b/apps/ops/ansible/inventory.py @@ -21,16 +21,16 @@ class JMSHost(Host): # 添加密码和秘钥 if asset.get('password'): self.set_variable('ansible_ssh_pass', asset['password']) - if asset.get('key'): + if asset.get('private_key'): self.set_variable('ansible_ssh_private_key_file', asset['private_key']) # 添加become支持 - become = asset.get("become", None) - if become is not None: + become = asset.get("become", False) + if become: self.set_variable("ansible_become", True) - self.set_variable("ansible_become_method", become.get('method')) - self.set_variable("ansible_become_user", become.get('user')) - self.set_variable("ansible_become_pass", become.get('pass')) + self.set_variable("ansible_become_method", become.get('method', 'sudo')) + self.set_variable("ansible_become_user", become.get('user', 'root')) + self.set_variable("ansible_become_pass", become.get('pass', '')) else: self.set_variable("ansible_become", False) diff --git a/apps/ops/ansible/runner.py b/apps/ops/ansible/runner.py index 1af3d7a0d..6496c4202 100644 --- a/apps/ops/ansible/runner.py +++ b/apps/ops/ansible/runner.py @@ -265,8 +265,10 @@ class AdHocRunner(object): result['success'].append(host) for host, msgs in self.results_callback.result_q['dark'].items(): - msg = '\n'.join(['{}: {}'.format(msg.get('invocation', {}).get('module_name'), - msg.get('msg', '')) for msg in msgs]) + msg = '\n'.join(['{} {}: {}'.format( + msg.get('module_stdout', ''), + msg.get('invocation', {}).get('module_name'), + msg.get('msg', '')) for msg in msgs]) result['failed'].append((host, msg)) return result diff --git a/apps/ops/api.py b/apps/ops/api.py new file mode 100644 index 000000000..3a9e45b25 --- /dev/null +++ b/apps/ops/api.py @@ -0,0 +1,15 @@ +# ~*~ coding: utf-8 ~*~ + + +from rest_framework import viewsets + +from .hands import IsSuperUser +from .models import Task +from .serializers import TaskSerializer + + +class TaskViewSet(viewsets.ModelViewSet): + queryset = Task.objects.all() + serializer_class = TaskSerializer + permission_classes = (IsSuperUser,) + diff --git a/apps/ops/api/__init__.py b/apps/ops/api/__init__.py deleted file mode 100644 index c8b15abe0..000000000 --- a/apps/ops/api/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from views import * \ No newline at end of file diff --git a/apps/ops/api/exc.py b/apps/ops/api/exc.py deleted file mode 100644 index 81deb805c..000000000 --- a/apps/ops/api/exc.py +++ /dev/null @@ -1,16 +0,0 @@ -# ~*~ coding: utf-8 ~*~ -from __future__ import unicode_literals, print_function - -from rest_framework.exceptions import APIException -from django.utils.translation import ugettext as _ - - -class ServiceUnavailable(APIException): - status_code = default_code = 503 - default_detail = _('Service temporarily unavailable, try again later.') - - -class ServiceNotImplemented(APIException): - status_code = default_code = 501 - default_detail = _('This service maybe implemented in the future, but now not implemented!') - diff --git a/apps/ops/api/permissions.py b/apps/ops/api/permissions.py deleted file mode 100644 index 0fc0d0861..000000000 --- a/apps/ops/api/permissions.py +++ /dev/null @@ -1,19 +0,0 @@ -# ~*~ coding: utf-8 ~*~ -from __future__ import unicode_literals - -from rest_framework import permissions - - -class AdminUserRequired(permissions.BasePermission): - """ - Custom permission to only allow admin user to access the resource. - """ - - def has_object_permission(self, request, view, obj): - # Read permissions are allowed to any request, - # so we'll always allow GET, HEAD or OPTIONS requests. - if request.method in permissions.SAFE_METHODS: - return True - - # Write permissions are only allowed to the admin role. - return request.user.is_staff diff --git a/apps/ops/api/serializers.py b/apps/ops/api/serializers.py deleted file mode 100644 index af472b3cb..000000000 --- a/apps/ops/api/serializers.py +++ /dev/null @@ -1,4 +0,0 @@ -# ~*~ coding: utf-8 ~*~ -from __future__ import unicode_literals - - diff --git a/apps/ops/api/views.py b/apps/ops/api/views.py deleted file mode 100644 index affa9cdc7..000000000 --- a/apps/ops/api/views.py +++ /dev/null @@ -1,7 +0,0 @@ -# ~*~ coding: utf-8 ~*~ -from __future__ import unicode_literals -from rest_framework import viewsets - -from serializers import * -from permissions import * - diff --git a/apps/ops/hands.py b/apps/ops/hands.py new file mode 100644 index 000000000..d7175db18 --- /dev/null +++ b/apps/ops/hands.py @@ -0,0 +1,4 @@ +# ~*~ coding: utf-8 ~*~ + +from users.permissions import IsSuperUser + diff --git a/apps/ops/serializers.py b/apps/ops/serializers.py new file mode 100644 index 000000000..986ee66e6 --- /dev/null +++ b/apps/ops/serializers.py @@ -0,0 +1,13 @@ +# ~*~ coding: utf-8 ~*~ +from __future__ import unicode_literals +from rest_framework import serializers + +from .models import Task + + +class TaskSerializer(serializers.ModelSerializer): + class Meta: + model = Task + fields = '__all__' + + diff --git a/apps/ops/templates/ops/task_detail.html b/apps/ops/templates/ops/task_detail.html index a0f38e86c..bc8fbf682 100644 --- a/apps/ops/templates/ops/task_detail.html +++ b/apps/ops/templates/ops/task_detail.html @@ -68,7 +68,17 @@ {% trans 'Is success ' %}: + {% if object.is_finished %} {{ object.is_success|yesno:"Yes,No,Unkown" }} + {% else %} + +
+
+ 40% Complete (success) +
+
+ + {% endif %} {% trans 'Assets ' %}: @@ -84,6 +94,31 @@ + +
+
+ Result +
+ + + + + + + + + + +
+
+
+
+{{ object.result }}
+                                    
+
+
+
diff --git a/apps/ops/templates/ops/task_list.html b/apps/ops/templates/ops/task_list.html index cb64849a4..dac614805 100644 --- a/apps/ops/templates/ops/task_list.html +++ b/apps/ops/templates/ops/task_list.html @@ -35,7 +35,7 @@ {% endblock %} {% block table_head %} - + {% trans 'Name' %} {% trans 'Asset' %} {% trans 'Success' %} @@ -69,6 +69,7 @@ {{ object.timedelta }} s {% trans "Run again" %} + {% trans "Delete" %} {% endfor %} @@ -92,45 +93,14 @@ forceParse: false, autoclose: true }); + + }).on('click', '.btn-del', function () { + var $this = $(this); + var name = $(this).closest("tr").find(":nth-child(2)").children('a').html(); + var uid = $this.data('uid'); + var the_url = '{% url "api-ops:task-detail" pk=99991937 %}'.replace('99991937', uid); + objectDelete($this, name, the_url); }) -{# function terminateConnection(data) {#} -{# function success() {#} -{# window.setTimeout(function () {#} -{# window.location.reload()#} -{# }, 300)#} -{# }#} -{# var the_url = "{% url 'api-applications:terminate-connection' %}";#} -{# APIUpdateAttr({url: the_url, method: 'POST', body: JSON.stringify(data), success: success, success_message: 'Terminate success'});#} -{# }#} -{# $(document).ready(function() {#} -{# $('table').DataTable({#} -{# "searching": false,#} -{# "paging": false,#} -{# "bInfo" : false,#} -{# "order": []#} -{# });#} -{# $('.select2').select2();#} -{# $('#date .input-daterange').datepicker({#} -{# dateFormat: 'mm/dd/yy',#} -{# keyboardNavigation: false,#} -{# forceParse: false,#} -{# autoclose: true#} -{# });#} -{# }).on('click', '.btn-term', function () {#} -{# var $this = $(this);#} -{# var proxy_log_id = $this.attr('value');#} -{# var data = {#} -{# proxy_log_id: proxy_log_id#} -{# };#} -{# terminateConnection(data)#} -{# }).on('click', '#btn_bulk_update', function () {#} -{# var data = [];#} -{# $('.cbx-term:checked').each(function () {#} -{# data.push({proxy_log_id: $(this).attr('value')})#} -{# });#} -{# terminateConnection(data)#} -{# })#} -{# #} {% endblock %} diff --git a/apps/ops/urls/api_urls.py b/apps/ops/urls/api_urls.py index d97d28a4a..c96bfb926 100644 --- a/apps/ops/urls/api_urls.py +++ b/apps/ops/urls/api_urls.py @@ -2,6 +2,12 @@ from __future__ import unicode_literals from rest_framework.routers import DefaultRouter +from .. import api -urlpatterns = [] \ No newline at end of file +router = DefaultRouter() +router.register(r'v1/tasks', api.TaskViewSet, 'task') + +urlpatterns = [] + +urlpatterns += router.urls diff --git a/apps/ops/utils.py b/apps/ops/utils.py index d1b5190dd..0c3cbbc99 100644 --- a/apps/ops/utils.py +++ b/apps/ops/utils.py @@ -18,7 +18,7 @@ logger = get_logger(__file__) def run_AdHoc(task_tuple, assets, task_name='Ansible AdHoc runner', task_id=None, pattern='all', - record=True, verbose=False): + record=True, verbose=True): """ :param task_tuple: (('module_name', 'module_args'), ('module_name', 'module_args')) :param assets: [asset1, asset2] @@ -51,6 +51,11 @@ def run_AdHoc(task_tuple, assets, else: record = Task.objects.get(uuid=task_id) record.date_start = timezone.now() + record.date_finished = None + record.timedelta = None + record.is_finished = False + record.is_success = False + record.save() ts_start = time.time() if verbose: logger.debug('Start runner {}'.format(task_name)) @@ -61,7 +66,7 @@ def run_AdHoc(task_tuple, assets, record.date_finished = timezone.now() record.is_finished = True if verbose: - record.result = json.dumps(result) + record.result = json.dumps(result, indent=4, sort_keys=True) record.summary = json.dumps(summary) record.timedelta = timedelta if len(summary['failed']) == 0: diff --git a/apps/ops/views.py b/apps/ops/views.py index dadf71faf..145f72534 100644 --- a/apps/ops/views.py +++ b/apps/ops/views.py @@ -1,5 +1,6 @@ # ~*~ coding: utf-8 ~*~ from __future__ import unicode_literals +import time import json from datetime import datetime @@ -81,4 +82,5 @@ class TaskRunView(View): def get(self, request, *args, **kwargs): pk = kwargs.get(self.pk_url_kwarg) rerun_task.delay(pk) + time.sleep(0.5) return redirect(reverse('ops:task-detail', kwargs={'pk': pk})) diff --git a/apps/perms/tasks.py b/apps/perms/tasks.py index 50ced1ee3..6bef200cd 100644 --- a/apps/perms/tasks.py +++ b/apps/perms/tasks.py @@ -35,10 +35,10 @@ def push_users(self, assets, users): ('authorized_key', "user={} state=present key='{}'".format( user['username'], user['public_key'])), ('lineinfile', - "name=/etc/sudoers state=present regexp='^{0} ALL=(ALL)' " + "dest=/etc/sudoers state=present regexp='^{0} ALL=' " "line='{0} ALL=(ALL) NOPASSWD: {1}' " "validate='visudo -cf %s'".format( - user['username'], user.get('sudo', '/bin/whoami') + user['username'], user.get('sudo', '/sbin/ifconfig') )) ]) task_name = 'Push user {}'.format(','.join([user['name'] for user in users])) diff --git a/apps/templates/_footer.html b/apps/templates/_footer.html index c43bda248..95f0f82d3 100644 --- a/apps/templates/_footer.html +++ b/apps/templates/_footer.html @@ -1,8 +1,9 @@ \ No newline at end of file diff --git a/apps/templates/_nav.html b/apps/templates/_nav.html index 6792a22b2..d0a2b9073 100644 --- a/apps/templates/_nav.html +++ b/apps/templates/_nav.html @@ -23,7 +23,6 @@
  • {% trans 'IDC' %}
  • {% trans 'Admin user' %}
  • {% trans 'System user' %}
  • -
  • {% trans 'Label' %}
  • @@ -56,8 +55,11 @@
  • {% trans 'Audits' %}
  • -
  • - - {% trans 'File' %} - - -
  • -
  • - - {% trans 'Settings' %} - -
  • +{#
  • #} +{# #} +{# {% trans 'File' %}#} +{# #} +{# #} +{#
  • #} +{#
  • #} +{# #} +{# {% trans 'Settings' %}#} +{# #} +{#
  • #}