[Change] 修改idc => cluster

pull/828/merge
ibuler 7 years ago
parent 32fd9bb42f
commit 27a1849b1d

@ -24,7 +24,7 @@ from common.mixins import IDInFilterMixin
from common.utils import get_object_or_none from common.utils import get_object_or_none
from .hands import IsSuperUser, IsAppUser, IsValidUser, \ from .hands import IsSuperUser, IsAppUser, IsValidUser, \
get_user_granted_assets, push_users get_user_granted_assets, push_users
from .models import AssetGroup, Asset, IDC, SystemUser, AdminUser from .models import AssetGroup, Asset, Cluster, SystemUser, AdminUser
from . import serializers from . import serializers
from .tasks import update_assets_hardware_info from .tasks import update_assets_hardware_info
from .utils import test_admin_user_connective_manual from .utils import test_admin_user_connective_manual
@ -41,12 +41,12 @@ class AssetViewSet(IDInFilterMixin, BulkModelViewSet):
queryset = super(AssetViewSet, self).get_queryset() queryset = super(AssetViewSet, self).get_queryset()
else: else:
queryset = get_user_granted_assets(self.request.user) queryset = get_user_granted_assets(self.request.user)
idc_id = self.request.query_params.get('idc_id', '') cluster_id = self.request.query_params.get('cluster_id', '')
system_users_id = self.request.query_params.get('system_user_id', '') system_users_id = self.request.query_params.get('system_user_id', '')
asset_group_id = self.request.query_params.get('asset_group_id', '') asset_group_id = self.request.query_params.get('asset_group_id', '')
admin_user_id = self.request.query_params.get('admin_user_id', '') admin_user_id = self.request.query_params.get('admin_user_id', '')
if idc_id: if cluster_id:
queryset = queryset.filter(idc__id=idc_id) queryset = queryset.filter(cluster__id=cluster_id)
if system_users_id: if system_users_id:
queryset = queryset.filter(system_users__id=system_users_id) queryset = queryset.filter(system_users__id=system_users_id)
if admin_user_id: if admin_user_id:
@ -84,17 +84,17 @@ class AssetGroupUpdateSystemUserApi(generics.RetrieveUpdateAPIView):
permission_classes = (IsSuperUser,) permission_classes = (IsSuperUser,)
class IDCUpdateAssetsApi(generics.RetrieveUpdateAPIView): class ClusterUpdateAssetsApi(generics.RetrieveUpdateAPIView):
"""IDC update asset member""" """Cluster update asset member"""
queryset = IDC.objects.all() queryset = Cluster.objects.all()
serializer_class = serializers.IDCUpdateAssetsSerializer serializer_class = serializers.ClusterUpdateAssetsSerializer
permission_classes = (IsSuperUser,) permission_classes = (IsSuperUser,)
class IDCViewSet(IDInFilterMixin, BulkModelViewSet): class ClusterViewSet(IDInFilterMixin, BulkModelViewSet):
"""IDC api set, for add,delete,update,list,retrieve resource""" """Cluster api set, for add,delete,update,list,retrieve resource"""
queryset = IDC.objects.all() queryset = Cluster.objects.all()
serializer_class = serializers.IDCSerializer serializer_class = serializers.ClusterSerializer
permission_classes = (IsSuperUser,) permission_classes = (IsSuperUser,)

@ -2,7 +2,7 @@
from django import forms from django import forms
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from .models import IDC, Asset, AssetGroup, AdminUser, SystemUser from .models import Cluster, Asset, AssetGroup, AdminUser, SystemUser
from common.utils import validate_ssh_private_key, ssh_pubkey_gen, ssh_key_gen, get_logger from common.utils import validate_ssh_private_key, ssh_pubkey_gen, ssh_key_gen, get_logger
@ -14,7 +14,7 @@ class AssetCreateForm(forms.ModelForm):
model = Asset model = Asset
fields = [ fields = [
'hostname', 'ip', 'public_ip', 'port', 'type', 'comment', 'hostname', 'ip', 'public_ip', 'port', 'type', 'comment',
'admin_user', 'idc', 'groups', 'status', 'env', 'is_active' 'admin_user', "cluster", 'groups', 'status', 'env', 'is_active'
] ]
widgets = { widgets = {
'groups': forms.SelectMultiple( 'groups': forms.SelectMultiple(
@ -43,7 +43,7 @@ class AssetUpdateForm(forms.ModelForm):
class Meta: class Meta:
model = Asset model = Asset
fields = [ fields = [
'hostname', 'ip', 'port', 'groups', 'admin_user', 'idc', 'is_active', 'hostname', 'ip', 'port', 'groups', 'admin_user', "cluster", 'is_active',
'type', 'env', 'status', 'public_ip', 'remote_card_ip', 'cabinet_no', 'type', 'env', 'status', 'public_ip', 'remote_card_ip', 'cabinet_no',
'cabinet_pos', 'number', 'comment' 'cabinet_pos', 'number', 'comment'
] ]
@ -83,7 +83,7 @@ class AssetBulkUpdateForm(forms.ModelForm):
class Meta: class Meta:
model = Asset model = Asset
fields = [ fields = [
'assets', 'port', 'groups', 'admin_user', 'idc', 'assets', 'port', 'groups', 'admin_user', "cluster",
'type', 'env', 'status', 'type', 'env', 'status',
] ]
widgets = { widgets = {
@ -139,7 +139,7 @@ class AssetGroupForm(forms.ModelForm):
} }
class IDCForm(forms.ModelForm): class ClusterForm(forms.ModelForm):
# See AdminUserForm comment same it # See AdminUserForm comment same it
assets = forms.ModelMultipleChoiceField( assets = forms.ModelMultipleChoiceField(
queryset=Asset.objects.all(), queryset=Asset.objects.all(),
@ -153,16 +153,16 @@ class IDCForm(forms.ModelForm):
if kwargs.get('instance'): if kwargs.get('instance'):
initial = kwargs.get('initial', {}) initial = kwargs.get('initial', {})
initial['assets'] = kwargs['instance'].assets.all() initial['assets'] = kwargs['instance'].assets.all()
super(IDCForm, self).__init__(*args, **kwargs) super(ClusterForm, self).__init__(*args, **kwargs)
def _save_m2m(self): def _save_m2m(self):
super(IDCForm, self)._save_m2m() super(ClusterForm, self)._save_m2m()
assets = self.cleaned_data['assets'] assets = self.cleaned_data['assets']
self.instance.assets.clear() self.instance.assets.clear()
self.instance.assets.add(*tuple(assets)) self.instance.assets.add(*tuple(assets))
class Meta: class Meta:
model = IDC model = Cluster
fields = ['name', "bandwidth", "operator", 'contact', fields = ['name', "bandwidth", "operator", 'contact',
'phone', 'address', 'intranet', 'extranet', 'comment'] 'phone', 'address', 'intranet', 'extranet', 'comment']
widgets = { widgets = {
@ -356,6 +356,5 @@ class SystemUserUpdateForm(forms.ModelForm):
} }
class FileForm(forms.Form): class FileForm(forms.Form):
file = forms.FileField() file = forms.FileField()

@ -2,7 +2,7 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# #
from .idc import * from .cluster import *
from .user import * from .user import *
from .group import * from .group import *
from .asset import * from .asset import *

@ -10,14 +10,14 @@ from django.db import models
import logging import logging
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from . import IDC, AssetGroup, AdminUser, SystemUser from . import Cluster, AssetGroup, AdminUser, SystemUser
__all__ = ['Asset'] __all__ = ['Asset']
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
def get_default_idc(): def get_default_cluster():
return IDC.initial() return Cluster.initial()
class Asset(models.Model): class Asset(models.Model):
@ -47,7 +47,7 @@ class Asset(models.Model):
groups = models.ManyToManyField(AssetGroup, blank=True, related_name='assets', verbose_name=_('Asset groups')) groups = models.ManyToManyField(AssetGroup, blank=True, related_name='assets', verbose_name=_('Asset groups'))
admin_user = models.ForeignKey(AdminUser, null=True, blank=True, related_name='assets', on_delete=models.SET_NULL, verbose_name=_("Admin user")) admin_user = models.ForeignKey(AdminUser, null=True, blank=True, related_name='assets', on_delete=models.SET_NULL, verbose_name=_("Admin user"))
system_users = models.ManyToManyField(SystemUser, blank=True, related_name='assets', verbose_name=_("System User")) system_users = models.ManyToManyField(SystemUser, blank=True, related_name='assets', verbose_name=_("System User"))
idc = models.ForeignKey(IDC, blank=True, null=True, related_name='assets', on_delete=models.SET_NULL, verbose_name=_('IDC'),) cluster = models.ForeignKey(Cluster, blank=True, null=True, related_name='assets', on_delete=models.SET_NULL, verbose_name=_('Cluster'),)
is_active = models.BooleanField(default=True, verbose_name=_('Is active')) is_active = models.BooleanField(default=True, verbose_name=_('Is active'))
type = models.CharField(choices=TYPE_CHOICES, max_length=16, blank=True, null=True, default='Server', verbose_name=_('Asset type'),) type = models.CharField(choices=TYPE_CHOICES, max_length=16, blank=True, null=True, default='Server', verbose_name=_('Asset type'),)
env = models.CharField(choices=ENV_CHOICES, max_length=8, blank=True, null=True, default='Prod', verbose_name=_('Asset environment'),) env = models.CharField(choices=ENV_CHOICES, max_length=8, blank=True, null=True, default='Prod', verbose_name=_('Asset environment'),)
@ -100,18 +100,16 @@ class Asset(models.Model):
'hostname': self.hostname, 'hostname': self.hostname,
'ip': self.ip, 'ip': self.ip,
'port': self.port, 'port': self.port,
'groups': [group.name for group in self.groups.all()],
} }
def _to_secret_json(self): def _to_secret_json(self):
"""Ansible use it create inventory""" """
data = { Ansible use it create inventory
'id': self.id,
'hostname': self.hostname,
'ip': self.ip,
'port': self.port,
'groups': [group.name for group in self.groups.all()],
}
Todo: May be move to ops implements it
"""
data = self.to_json()
if self.admin_user: if self.admin_user:
data.update({ data.update({
'username': self.admin_user.username, 'username': self.admin_user.username,
@ -139,7 +137,7 @@ class Asset(models.Model):
asset = cls(ip='%s.%s.%s.%s' % (i, i, i, i), asset = cls(ip='%s.%s.%s.%s' % (i, i, i, i),
hostname=forgery_py.internet.user_name(True), hostname=forgery_py.internet.user_name(True),
admin_user=choice(AdminUser.objects.all()), admin_user=choice(AdminUser.objects.all()),
idc=choice(IDC.objects.all()), cluster=choice(Cluster.objects.all()),
port=22, port=22,
created_by='Fake') created_by='Fake')
try: try:

@ -0,0 +1,63 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
from __future__ import unicode_literals
import logging
import uuid
from django.db import models
from django.utils.translation import ugettext_lazy as _
__all__ = ['Cluster']
logger = logging.getLogger(__name__)
class Cluster(models.Model):
id = models.UUIDField(default=uuid.uuid4, primary_key=True)
name = models.CharField(max_length=32, verbose_name=_('Name'))
bandwidth = models.CharField(max_length=32, blank=True, verbose_name=_('Bandwidth'))
contact = models.CharField(max_length=128, blank=True, verbose_name=_('Contact'))
phone = models.CharField(max_length=32, blank=True, verbose_name=_('Phone'))
address = models.CharField(max_length=128, blank=True, verbose_name=_("Address"))
intranet = models.TextField(blank=True, verbose_name=_('Intranet'))
extranet = models.TextField(blank=True, verbose_name=_('Extranet'))
date_created = models.DateTimeField(auto_now_add=True, null=True, verbose_name=_('Date created'))
operator = models.CharField(max_length=32, blank=True, verbose_name=_('Operator'))
created_by = models.CharField(max_length=32, blank=True, verbose_name=_('Created by'))
comment = models.TextField(blank=True, verbose_name=_('Comment'))
def __str__(self):
return self.name
@classmethod
def initial(cls):
return cls.objects.get_or_create(name=_('Default'), created_by=_('System'), comment=_('Default Cluster'))[0]
class Meta:
ordering = ['name']
@classmethod
def generate_fake(cls, count=5):
from random import seed, choice
import forgery_py
from django.db import IntegrityError
seed()
for i in range(count):
cluster = cls(name=forgery_py.name.full_name(),
bandwidth='200M',
contact=forgery_py.name.full_name(),
phone=forgery_py.address.phone(),
address=forgery_py.address.city() + forgery_py.address.street_address(),
operator=choice(['北京联通', '北京电信', 'BGP全网通']),
comment=forgery_py.lorem_ipsum.sentence(),
created_by='Fake')
try:
cluster.save()
logger.debug('Generate fake asset group: %s' % cluster.name)
except IntegrityError:
print('Error continue')
continue

@ -1,71 +0,0 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
from __future__ import unicode_literals
import logging
import uuid
from django.db import models
from django.utils.translation import ugettext_lazy as _
__all__ = ['IDC']
logger = logging.getLogger(__name__)
class IDC(models.Model):
id = models.UUIDField(default=uuid.uuid4, primary_key=True)
name = models.CharField(max_length=32, verbose_name=_('Name'))
bandwidth = models.CharField(
max_length=32, blank=True, verbose_name=_('Bandwidth'))
contact = models.CharField(
max_length=128, blank=True, verbose_name=_('Contact'))
phone = models.CharField(max_length=32, blank=True,
verbose_name=_('Phone'))
address = models.CharField(
max_length=128, blank=True, verbose_name=_("Address"))
intranet = models.TextField(blank=True, verbose_name=_('Intranet'))
extranet = models.TextField(blank=True, verbose_name=_('Extranet'))
date_created = models.DateTimeField(
auto_now_add=True, null=True, verbose_name=_('Date created'))
operator = models.CharField(
max_length=32, blank=True, verbose_name=_('Operator'))
created_by = models.CharField(
max_length=32, blank=True, verbose_name=_('Created by'))
comment = models.TextField(blank=True, verbose_name=_('Comment'))
def __unicode__(self):
return self.name
__str__ = __unicode__
@classmethod
def initial(cls):
return cls.objects.get_or_create(name=_('Default'), created_by=_('System'), comment=_('Default IDC'))[0]
class Meta:
ordering = ['name']
@classmethod
def generate_fake(cls, count=5):
from random import seed, choice
import forgery_py
from django.db import IntegrityError
seed()
for i in range(count):
idc = cls(name=forgery_py.name.full_name(),
bandwidth='200M',
contact=forgery_py.name.full_name(),
phone=forgery_py.address.phone(),
address=forgery_py.address.city() + forgery_py.address.street_address(),
operator=choice(['北京联通', '北京电信', 'BGP全网通']),
comment=forgery_py.lorem_ipsum.sentence(),
created_by='Fake')
try:
idc.save()
logger.debug('Generate fake asset group: %s' % idc.name)
except IntegrityError:
print('Error continue')
continue

@ -29,7 +29,7 @@ def private_key_validator(value):
class AdminUser(models.Model): class AdminUser(models.Model):
""" """
Ansible use admin user as devops user to run adHoc and Playbook A privileged user that ansible can use it to push system user and so on
""" """
BECOME_METHOD_CHOICES = ( BECOME_METHOD_CHOICES = (
('sudo', 'sudo'), ('sudo', 'sudo'),
@ -43,7 +43,7 @@ class AdminUser(models.Model):
become = models.BooleanField(default=True) become = models.BooleanField(default=True)
become_method = models.CharField(choices=BECOME_METHOD_CHOICES, default='sudo', max_length=4) become_method = models.CharField(choices=BECOME_METHOD_CHOICES, default='sudo', max_length=4)
become_user = models.CharField(default='root', max_length=64) become_user = models.CharField(default='root', max_length=64)
become_pass = models.CharField(default='', max_length=128) _become_pass = models.CharField(default='', max_length=128)
_public_key = models.TextField(max_length=4096, blank=True, verbose_name=_('SSH public key')) _public_key = models.TextField(max_length=4096, blank=True, verbose_name=_('SSH public key'))
comment = models.TextField(blank=True, verbose_name=_('Comment')) comment = models.TextField(blank=True, verbose_name=_('Comment'))
date_created = models.DateTimeField(auto_now_add=True, null=True) date_created = models.DateTimeField(auto_now_add=True, null=True)
@ -95,6 +95,15 @@ class AdminUser(models.Model):
def public_key(self, public_key_raw): def public_key(self, public_key_raw):
self._public_key = signer.sign(public_key_raw) self._public_key = signer.sign(public_key_raw)
@property
def become_pass(self):
return signer.unsign(self._become_pass)
@become_pass.setter
def become_pass(self, password):
self._become_pass = signer.sign(password)
@property @property
def assets_amount(self): def assets_amount(self):
return self.assets.count() return self.assets.count()

@ -2,19 +2,19 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# #
from . import IDC, SystemUser, AdminUser, AssetGroup, Asset from . import Cluster, SystemUser, AdminUser, AssetGroup, Asset
__all__ = ['init_model', 'generate_fake'] __all__ = ['init_model', 'generate_fake']
def init_model(): def init_model():
for cls in [IDC, SystemUser, AdminUser, AssetGroup, Asset]: for cls in [Cluster, SystemUser, AdminUser, AssetGroup, Asset]:
if hasattr(cls, 'initial'): if hasattr(cls, 'initial'):
cls.initial() cls.initial()
def generate_fake(): def generate_fake():
for cls in [IDC, SystemUser, AdminUser, AssetGroup, Asset]: for cls in [Cluster, SystemUser, AdminUser, AssetGroup, Asset]:
if hasattr(cls, 'generate_fake'): if hasattr(cls, 'generate_fake'):
cls.generate_fake() cls.generate_fake()

@ -2,7 +2,7 @@
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from django.core.cache import cache from django.core.cache import cache
from rest_framework import viewsets, serializers, generics from rest_framework import viewsets, serializers, generics
from .models import AssetGroup, Asset, IDC, AdminUser, SystemUser from .models import AssetGroup, Asset, Cluster, AdminUser, SystemUser
from common.mixins import IDInFilterMixin from common.mixins import IDInFilterMixin
from rest_framework_bulk import BulkListSerializer, BulkSerializerMixin from rest_framework_bulk import BulkListSerializer, BulkSerializerMixin
@ -54,11 +54,11 @@ class AssetGroupUpdateSystemUserSerializer(serializers.ModelSerializer):
fields = ['id', 'system_users'] fields = ['id', 'system_users']
class IDCUpdateAssetsSerializer(serializers.ModelSerializer): class ClusterUpdateAssetsSerializer(serializers.ModelSerializer):
assets = serializers.PrimaryKeyRelatedField(many=True, queryset=Asset.objects.all()) assets = serializers.PrimaryKeyRelatedField(many=True, queryset=Asset.objects.all())
class Meta: class Meta:
model = IDC model = Cluster
fields = ['id', 'assets'] fields = ['id', 'assets']
@ -180,12 +180,12 @@ class MyAssetGrantedSerializer(AssetGrantedSerializer):
"is_active", "system_users_join", "comment") "is_active", "system_users_join", "comment")
class IDCSerializer(BulkSerializerMixin, serializers.ModelSerializer): class ClusterSerializer(BulkSerializerMixin, serializers.ModelSerializer):
assets_amount = serializers.SerializerMethodField() assets_amount = serializers.SerializerMethodField()
assets = serializers.PrimaryKeyRelatedField(many=True, queryset=Asset.objects.all()) assets = serializers.PrimaryKeyRelatedField(many=True, queryset=Asset.objects.all())
class Meta: class Meta:
model = IDC model = Cluster
fields = '__all__' fields = '__all__'
@staticmethod @staticmethod
@ -193,7 +193,7 @@ class IDCSerializer(BulkSerializerMixin, serializers.ModelSerializer):
return obj.assets.count() return obj.assets.count()
def get_field_names(self, declared_fields, info): def get_field_names(self, declared_fields, info):
fields = super(IDCSerializer, self).get_field_names(declared_fields, info) fields = super(ClusterSerializer, self).get_field_names(declared_fields, info)
fields.append('assets_amount') fields.append('assets_amount')
return fields return fields

@ -21,7 +21,7 @@
<div class="hr-line-dashed"></div> <div class="hr-line-dashed"></div>
<h3>{% trans 'Group' %}</h3> <h3>{% trans 'Group' %}</h3>
{% bootstrap_field form.idc layout="horizontal" %} {% bootstrap_field form.cluster layout="horizontal" %}
{% bootstrap_field form.groups layout="horizontal" %} {% bootstrap_field form.groups layout="horizontal" %}
<div class="hr-line-dashed"></div> <div class="hr-line-dashed"></div>

@ -82,8 +82,8 @@
<td><b>{{ asset.remote_card_ip }}</b></td> <td><b>{{ asset.remote_card_ip }}</b></td>
</tr> </tr>
<tr> <tr>
<td>{% trans 'IDC' %}:</td> <td>{% trans 'Cluster' %}:</td>
<td><b>{{ asset.idc.name }}</b></td> <td><b>{{ asset.cluster.name }}</b></td>
</tr> </tr>
<tr> <tr>
<td>{% trans 'Cabinet number' %}:</td> <td>{% trans 'Cabinet number' %}:</td>

@ -17,10 +17,10 @@
<div class="panel-options"> <div class="panel-options">
<ul class="nav nav-tabs"> <ul class="nav nav-tabs">
<li> <li>
<a href="{% url 'assets:idc-detail' pk=idc.id %}" class="text-center"><i class="fa fa-laptop"></i> {% trans 'Detail' %} </a> <a href="{% url 'assets:cluster-detail' pk=cluster.id %}" class="text-center"><i class="fa fa-laptop"></i> {% trans 'Detail' %} </a>
</li> </li>
<li class="active"><a href="{% url 'assets:idc-assets' pk=idc.id %}" class="text-center"> <li class="active"><a href="{% url 'assets:cluster-assets' pk=cluster.id %}" class="text-center">
<i class="fa fa-bar-chart-o"></i> {% trans 'IDC assets' %}</a> <i class="fa fa-bar-chart-o"></i> {% trans 'Cluster assets' %}</a>
</li> </li>
</ul> </ul>
</div> </div>
@ -28,7 +28,7 @@
<div class="col-sm-7" style="padding-left: 0;"> <div class="col-sm-7" style="padding-left: 0;">
<div class="ibox float-e-margins"> <div class="ibox float-e-margins">
<div class="ibox-title"> <div class="ibox-title">
<span style="float: left">{% trans 'IDC assets' %} <b>{{ idc.name }} </b><span class="badge"></span></span> <span style="float: left">{% trans 'Cluster assets' %} <b>{{ cluster.name }} </b><span class="badge"></span></span>
<div class="ibox-tools"> <div class="ibox-tools">
<a class="collapse-link"> <a class="collapse-link">
<i class="fa fa-chevron-up"></i> <i class="fa fa-chevron-up"></i>
@ -45,7 +45,7 @@
</div> </div>
<div class="ibox-content"> <div class="ibox-content">
<table class="table table-striped table-bordered table-hover " id="idc_assets_table" > <table class="table table-striped table-bordered table-hover " id="cluster_assets_table" >
<thead> <thead>
<tr> <tr>
<th class="text-center"> <th class="text-center">
@ -80,7 +80,7 @@
<div class="col-sm-5" style="padding-left: 0;padding-right: 0"> <div class="col-sm-5" style="padding-left: 0;padding-right: 0">
<div class="panel panel-primary"> <div class="panel panel-primary">
<div class="panel-heading"> <div class="panel-heading">
<i class="fa fa-info-circle"></i> {% trans 'Add assets to' %} {{ idc.name }} <i class="fa fa-info-circle"></i> {% trans 'Add assets to' %} {{ cluster.name }}
</div> </div>
<div class="panel-body"> <div class="panel-body">
<table class="table"> <table class="table">
@ -125,12 +125,12 @@ Array.prototype.remove = function(val) {
} }
}; };
function updateIDCAssets(assets) { function updateClusterAssets(assets) {
var the_url = "{% url 'api-assets:idc-update-assets' pk=idc.id %}"; var the_url = "{% url 'api-assets:cluster-update-assets' pk=cluster.id %}";
var body = { var body = {
assets: Object.assign([], assets) assets: Object.assign([], assets)
}; };
var $data_table = $("#idc_assets_table").DataTable(); var $data_table = $("#cluster_assets_table").DataTable();
var success = function(data) { var success = function(data) {
$('.select2-selection__rendered').empty(); $('.select2-selection__rendered').empty();
$.map(jumpserver.assets_selected, function(asset_ip, index) { $.map(jumpserver.assets_selected, function(asset_ip, index) {
@ -147,12 +147,12 @@ function updateIDCAssets(assets) {
}); });
} }
function deleteIDCAssets(assets) { function deleteClusterAssets(assets) {
var the_url = "{% url 'api-assets:idc-update-assets' pk=idc.id %}"; var the_url = "{% url 'api-assets:cluster-update-assets' pk=cluster.id %}";
var body = { var body = {
assets: Object.assign([], assets) assets: Object.assign([], assets)
}; };
var $data_table = $("#idc_assets_table").DataTable(); var $data_table = $("#cluster_assets_table").DataTable();
var success = function(data) { var success = function(data) {
$data_table.ajax.reload(); $data_table.ajax.reload();
}; };
@ -175,7 +175,7 @@ $(document).ready(function () {
delete jumpserver.assets_selected[data.id]; delete jumpserver.assets_selected[data.id];
}); });
var options = { var options = {
ele: $('#idc_assets_table'), ele: $('#cluster_assets_table'),
buttons: [], buttons: [],
order: [], order: [],
columnDefs: [ columnDefs: [
@ -190,7 +190,7 @@ $(document).ready(function () {
$(td).html('<i class="fa fa-check text-navy"></i>') $(td).html('<i class="fa fa-check text-navy"></i>')
} }
}}], }}],
ajax_url: '{% url "api-assets:asset-list" %}?idc_id={{ idc.id }}', ajax_url: '{% url "api-assets:asset-list" %}?cluster_id={{ cluster.id }}',
columns: [{data: function(){return ""}}, {data: "hostname" }, {data: "ip" }, {data: "port" }, columns: [{data: function(){return ""}}, {data: "hostname" }, {data: "ip" }, {data: "port" },
{data: "type" }, {data: "is_active" }], {data: "type" }, {data: "is_active" }],
op_html: $('#actions').html() op_html: $('#actions').html()
@ -204,11 +204,11 @@ $(document).ready(function () {
return false; return false;
} }
var assets=[]; var assets=[];
var $data_table = $("#idc_assets_table").DataTable(); var $data_table = $("#cluster_assets_table").DataTable();
$.ajax({ $.ajax({
url: '{% url "api-assets:asset-list" %}', url: '{% url "api-assets:asset-list" %}',
method: 'GET', method: 'GET',
data: {"idc_id": {{ idc.id }}}, data: {"cluster_id": {{ cluster.id }}},
dataType: 'json', dataType: 'json',
success: function (result) { success: function (result) {
for(var i in result){ for(var i in result){
@ -219,7 +219,7 @@ $(document).ready(function () {
$.map(jumpserver.assets_selected, function(value, index) { $.map(jumpserver.assets_selected, function(value, index) {
assets.push(parseInt(index)); assets.push(parseInt(index));
}); });
updateIDCAssets(assets); updateClusterAssets(assets);
} }
}); });
@ -227,7 +227,7 @@ $(document).ready(function () {
.on('click', '#btn_bulk_update', function () { .on('click', '#btn_bulk_update', function () {
var action = $("#slct_bulk_update").val(); var action = $("#slct_bulk_update").val();
var $data_table = $("#idc_assets_table").DataTable(); var $data_table = $("#cluster_assets_table").DataTable();
var id_list = []; var id_list = [];
var plain_id_list = []; var plain_id_list = [];
var assets = []; var assets = [];
@ -240,7 +240,7 @@ $(document).ready(function () {
} }
$.ajax({ $.ajax({
url: '{% url "api-assets:asset-list" %}', url: '{% url "api-assets:asset-list" %}',
data: {"idc_id": {{ idc.id }}}, data: {"cluster_id": {{ cluster.id }}},
dataType: 'json', dataType: 'json',
method: 'GET', method: 'GET',
success: function (result) { success: function (result) {
@ -265,13 +265,13 @@ $(document).ready(function () {
var success = function() { var success = function() {
var msg = "{% trans 'Asset Deleted.' %}"; var msg = "{% trans 'Asset Deleted.' %}";
swal("{% trans 'Asset Delete' %}", msg, "success"); swal("{% trans 'Asset Delete' %}", msg, "success");
$('#idc_assets_table').DataTable().ajax.reload(); $('#cluster_assets_table').DataTable().ajax.reload();
}; };
var fail = function() { var fail = function() {
var msg = "{% trans 'Asset Deleting failed.' %}"; var msg = "{% trans 'Asset Deleting failed.' %}";
swal("{% trans 'Asset Delete' %}", msg, "error"); swal("{% trans 'Asset Delete' %}", msg, "error");
}; };
var url_delete = "{% url 'api-assets:idc-update-assets' pk=idc.id %}"; var url_delete = "{% url 'api-assets:cluster-update-assets' pk=cluster.id %}";
var body = { var body = {
assets: Object.assign([], assets) assets: Object.assign([], assets)
}; };

@ -31,7 +31,7 @@
<div class="panel-body"> <div class="panel-body">
<div class="tab-content"> <div class="tab-content">
<div id="tab-1" class="ibox float-e-margins tab-pane active"></div> <div id="tab-1" class="ibox float-e-margins tab-pane active"></div>
<form id="IDCForm" method="post" class="form-horizontal"> <form id="ClusterForm" method="post" class="form-horizontal">
{% csrf_token %} {% csrf_token %}
<h3 class="widget-head-color-box">基本信息</h3> <h3 class="widget-head-color-box">基本信息</h3>
{% bootstrap_field form.name layout="horizontal" %} {% bootstrap_field form.name layout="horizontal" %}

@ -14,18 +14,18 @@
<div class="panel-options"> <div class="panel-options">
<ul class="nav nav-tabs"> <ul class="nav nav-tabs">
<li class="active"> <li class="active">
<a href="{% url 'assets:idc-detail' pk=idc.id %}" class="text-center"><i class="fa fa-laptop"></i> {% trans 'Detail' %} </a> <a href="{% url 'assets:cluster-detail' pk=cluster.id %}" class="text-center"><i class="fa fa-laptop"></i> {% trans 'Detail' %} </a>
</li> </li>
<li> <li>
<a href="{% url 'assets:idc-assets' pk=idc.id %}" class="text-center"> <a href="{% url 'assets:cluster-assets' pk=cluster.id %}" class="text-center">
<i class="fa fa-bar-chart-o"></i> {% trans 'IDC assets' %} <i class="fa fa-bar-chart-o"></i> {% trans 'Cluster assets' %}
</a> </a>
</li> </li>
<li class="pull-right"> <li class="pull-right">
<a class="btn btn-outline btn-default" href="{% url 'assets:idc-update' pk=idc.id %}"><i class="fa fa-edit"></i>Update</a> <a class="btn btn-outline btn-default" href="{% url 'assets:cluster-update' pk=cluster.id %}"><i class="fa fa-edit"></i>Update</a>
</li> </li>
<li class="pull-right"> <li class="pull-right">
<a class="btn btn-outline btn-danger btn-delete-idc"> <a class="btn btn-outline btn-danger btn-delete-cluster">
<i class="fa fa-edit"></i>Delete <i class="fa fa-edit"></i>Delete
</a> </a>
</li> </li>
@ -35,7 +35,7 @@
<div class="col-sm-7" style="padding-left: 0;"> <div class="col-sm-7" style="padding-left: 0;">
<div class="ibox float-e-margins"> <div class="ibox float-e-margins">
<div class="ibox-title"> <div class="ibox-title">
<span class="label"><b>{{ idc.name }}</b></span> <span class="label"><b>{{ cluster.name }}</b></span>
<div class="ibox-tools"> <div class="ibox-tools">
<a class="collapse-link"> <a class="collapse-link">
<i class="fa fa-chevron-up"></i> <i class="fa fa-chevron-up"></i>
@ -55,35 +55,35 @@
<tbody> <tbody>
<tr class="no-borders-tr"> <tr class="no-borders-tr">
<td width="20%">{% trans 'Name' %}:</td> <td width="20%">{% trans 'Name' %}:</td>
<td><b>{{ idc.name }}</b></td> <td><b>{{ cluster.name }}</b></td>
</tr> </tr>
<tr> <tr>
<td>{% trans 'Bandwidth' %}:</td> <td>{% trans 'Bandwidth' %}:</td>
<td><b>{{ idc.bandwidth }}</b></td> <td><b>{{ cluster.bandwidth }}</b></td>
</tr> </tr>
<tr> <tr>
<td>{% trans 'Contact' %}:</td> <td>{% trans 'Contact' %}:</td>
<td><b>{{ idc.contact }}</b></td> <td><b>{{ cluster.contact }}</b></td>
</tr> </tr>
<tr> <tr>
<td>{% trans 'Phone' %}:</td> <td>{% trans 'Phone' %}:</td>
<td><b>{{ idc.phone }}</b></td> <td><b>{{ cluster.phone }}</b></td>
</tr> </tr>
<tr> <tr>
<td>{% trans 'Address' %}:</td> <td>{% trans 'Address' %}:</td>
<td><b>{{ idc.address }}</b></td> <td><b>{{ cluster.address }}</b></td>
</tr> </tr>
<tr> <tr>
<td>{% trans 'Intranet' %}:</td> <td>{% trans 'Intranet' %}:</td>
<td><b>{{ idc.Intranet }}</b></td> <td><b>{{ cluster.Intranet }}</b></td>
</tr> </tr>
<tr> <tr>
<td>{% trans 'Extranet' %}:</td> <td>{% trans 'Extranet' %}:</td>
<td><b>{{ idc.extranet }}</b></td> <td><b>{{ cluster.extranet }}</b></td>
</tr> </tr>
<tr> <tr>
<td>{% trans 'Operator' %}:</td> <td>{% trans 'Operator' %}:</td>
<td><b>{{ idc.operator }}</b></td> <td><b>{{ cluster.operator }}</b></td>
</tr> </tr>
<tr> <tr>
<td>{% trans 'Date created' %}:</td> <td>{% trans 'Date created' %}:</td>
@ -111,12 +111,12 @@
{% endblock %} {% endblock %}
{% block custom_foot_js %} {% block custom_foot_js %}
<script> <script>
function idcDelete(name, url) { function clusterDelete(name, url) {
function doDelete() { function doDelete() {
var body = {}; var body = {};
var success = function() { var success = function() {
swal('Deleted!', "[ "+name+"]"+" has been deleted ", "success"); swal('Deleted!', "[ "+name+"]"+" has been deleted ", "success");
window.location.href="{% url 'assets:idc-list' %}"; window.location.href="{% url 'assets:cluster-list' %}";
}; };
var fail = function() { var fail = function() {
swal("Failed", "Delete"+"[ "+name+" ]"+"failed", "error"); swal("Failed", "Delete"+"[ "+name+" ]"+"failed", "error");
@ -146,11 +146,11 @@ function idcDelete(name, url) {
$(document).ready(function () { $(document).ready(function () {
$('.select2').select2(); $('.select2').select2();
}) })
.on('click', '.btn-delete-idc', function () { .on('click', '.btn-delete-cluster', function () {
var name = $('.idc-details > tbody > tr').attr("data-name"); var name = $('.cluster-details > tbody > tr').attr("data-name");
var id = {{ idc.id }}; var id = {{ cluster.id }};
var the_url = '{% url "api-assets:idc-detail" pk=99991937 %}'.replace(99991937, id); var the_url = '{% url "api-assets:cluster-detail" pk=99991937 %}'.replace(99991937, id);
idcDelete(name, the_url); clusterDelete(name, the_url);
}); });
</script> </script>
{% endblock %} {% endblock %}

@ -7,7 +7,7 @@
{% block table_search %}{% endblock %} {% block table_search %}{% endblock %}
{% block table_container %} {% block table_container %}
<div class="uc pull-left m-l-5 m-r-5"> <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 IDC" %} </a> <a href="{% url "assets:idc-create" %}" class="btn btn-sm btn-primary"> {% trans "Create Cluster" %} </a>
</div> </div>
<table class="table table-striped table-bordered table-hover " id="idc_list_table" > <table class="table table-striped table-bordered table-hover " id="idc_list_table" >
<thead> <thead>
@ -100,13 +100,13 @@ $(document).ready(function(){
closeOnConfirm: false closeOnConfirm: false
}, function() { }, function() {
var success = function() { var success = function() {
var msg = "{% trans 'IDC Deleted.' %}"; var msg = "{% trans 'Cluster Deleted.' %}";
swal("{% trans 'IDC Delete' %}", msg, "success"); swal("{% trans 'Cluster Delete' %}", msg, "success");
$('#idc_list_table').DataTable().ajax.reload(); $('#idc_list_table').DataTable().ajax.reload();
}; };
var fail = function() { var fail = function() {
var msg = "{% trans 'IDC Deleting failed.' %}"; var msg = "{% trans 'Cluster Deleting failed.' %}";
swal("{% trans 'IDC Delete' %}", msg, "error"); swal("{% trans 'Cluster Delete' %}", msg, "error");
}; };
var url_delete = the_url + '?id__in=' + JSON.stringify(plain_id_list); var url_delete = the_url + '?id__in=' + JSON.stringify(plain_id_list);
APIUpdateAttr({url: url_delete, method: 'DELETE', success: success, error: fail}); APIUpdateAttr({url: url_delete, method: 'DELETE', success: success, error: fail});

@ -69,7 +69,7 @@ $(document).ready(function(){
.on('click', '.btn_admin_user_delete', function () { .on('click', '.btn_admin_user_delete', function () {
var $this = $(this); 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 name = $(this).closest("tr").find(":nth-child(2)").children('a').html();
var uid = $this.data('uid'); var uid = $this.data('uid');
var the_url = '{% url "api-assets:system-user-detail" pk=99991937 %}'.replace('99991937', uid); var the_url = '{% url "api-assets:system-user-detail" pk=99991937 %}'.replace('99991937', uid);

@ -10,7 +10,7 @@ app_name = 'assets'
router = BulkRouter() router = BulkRouter()
router.register(r'v1/groups', api.AssetGroupViewSet, 'asset-group') router.register(r'v1/groups', api.AssetGroupViewSet, 'asset-group')
router.register(r'v1/assets', api.AssetViewSet, 'asset') router.register(r'v1/assets', api.AssetViewSet, 'asset')
router.register(r'v1/idc', api.IDCViewSet, 'idc') router.register(r'v1/clusters', api.ClusterViewSet, 'cluster')
router.register(r'v1/admin-user', api.AdminUserViewSet, 'admin-user') router.register(r'v1/admin-user', api.AdminUserViewSet, 'admin-user')
router.register(r'v1/system-user', api.SystemUserViewSet, 'system-user') router.register(r'v1/system-user', api.SystemUserViewSet, 'system-user')
@ -47,9 +47,9 @@ urlpatterns = [
url(r'^v1/groups/(?P<pk>[0-9a-zA-Z\-]+)/system-users/$', url(r'^v1/groups/(?P<pk>[0-9a-zA-Z\-]+)/system-users/$',
api.AssetGroupUpdateSystemUserApi.as_view(), name='asset-groups-update-systemusers'), api.AssetGroupUpdateSystemUserApi.as_view(), name='asset-groups-update-systemusers'),
# update the IDC, and add or delete the assets to the IDC # update the Cluster, and add or delete the assets to the Cluster
url(r'^v1/idc/(?P<pk>[0-9a-zA-Z\-]+)/assets/$', url(r'^v1/cluster/(?P<pk>[0-9a-zA-Z\-]+)/assets/$',
api.IDCUpdateAssetsApi.as_view(), name='idc-update-assets'), api.ClusterUpdateAssetsApi.as_view(), name='cluster-update-assets'),
] ]

@ -27,13 +27,13 @@ urlpatterns = [
url(r'^asset-group/(?P<pk>[0-9a-zA-Z\-]+)/update/$', views.AssetGroupUpdateView.as_view(), name='asset-group-update'), url(r'^asset-group/(?P<pk>[0-9a-zA-Z\-]+)/update/$', views.AssetGroupUpdateView.as_view(), name='asset-group-update'),
url(r'^asset-group/(?P<pk>[0-9a-zA-Z\-]+)/delete/$', views.AssetGroupDeleteView.as_view(), name='asset-group-delete'), url(r'^asset-group/(?P<pk>[0-9a-zA-Z\-]+)/delete/$', views.AssetGroupDeleteView.as_view(), name='asset-group-delete'),
# Resource idc url # Resource cluster url
url(r'^idc/$', views.IDCListView.as_view(), name='idc-list'), url(r'^cluster/$', views.ClusterListView.as_view(), name='cluster-list'),
url(r'^idc/create/$', views.IDCCreateView.as_view(), name='idc-create'), url(r'^cluster/create/$', views.ClusterCreateView.as_view(), name='cluster-create'),
url(r'^idc/(?P<pk>[0-9a-zA-Z\-]+)/$', views.IDCDetailView.as_view(), name='idc-detail'), url(r'^cluster/(?P<pk>[0-9a-zA-Z\-]+)/$', views.ClusterDetailView.as_view(), name='cluster-detail'),
url(r'^idc/(?P<pk>[0-9a-zA-Z\-]+)/update/', views.IDCUpdateView.as_view(), name='idc-update'), url(r'^cluster/(?P<pk>[0-9a-zA-Z\-]+)/update/', views.ClusterUpdateView.as_view(), name='cluster-update'),
url(r'^idc/(?P<pk>[0-9a-zA-Z\-]+)/delete/$', views.IDCDeleteView.as_view(), name='idc-delete'), url(r'^cluster/(?P<pk>[0-9a-zA-Z\-]+)/delete/$', views.ClusterDeleteView.as_view(), name='cluster-delete'),
url(r'^idc/(?P<pk>[0-9a-zA-Z\-]+)/assets/$', views.IDCAssetsView.as_view(), name='idc-assets'), url(r'^cluster/(?P<pk>[0-9a-zA-Z\-]+)/assets/$', views.ClusterAssetsView.as_view(), name='cluster-assets'),
# Resource admin user url # Resource admin user url
url(r'^admin-user/$', views.AdminUserListView.as_view(), name='admin-user-list'), url(r'^admin-user/$', views.AdminUserListView.as_view(), name='admin-user-list'),

@ -1,7 +1,7 @@
# coding:utf-8 # coding:utf-8
from .asset import * from .asset import *
from .group import * from .group import *
from .idc import * from .cluster import *
from .system_user import * from .system_user import *
from .admin_user import * from .admin_user import *

@ -9,7 +9,7 @@ from django.contrib.messages.views import SuccessMessageMixin
from django.views.generic.detail import DetailView, SingleObjectMixin from django.views.generic.detail import DetailView, SingleObjectMixin
from .. import forms from .. import forms
from ..models import Asset, AssetGroup, AdminUser, IDC, SystemUser from ..models import Asset, AssetGroup, AdminUser, Cluster, SystemUser
from ..hands import AdminUserRequiredMixin from ..hands import AdminUserRequiredMixin
__all__ = ['AdminUserCreateView', 'AdminUserDetailView', __all__ = ['AdminUserCreateView', 'AdminUserDetailView',

@ -25,7 +25,7 @@ from django.shortcuts import get_object_or_404, redirect, reverse
from common.mixins import JSONResponseMixin from common.mixins import JSONResponseMixin
from common.utils import get_object_or_none from common.utils import get_object_or_none
from .. import forms from .. import forms
from ..models import Asset, AssetGroup, AdminUser, IDC, SystemUser from ..models import Asset, AssetGroup, AdminUser, Cluster, SystemUser
from ..hands import AdminUserRequiredMixin from ..hands import AdminUserRequiredMixin
from ..tasks import update_assets_hardware_info from ..tasks import update_assets_hardware_info
@ -283,7 +283,7 @@ class BulkImportAssetView(AdminUserRequiredMixin, JSONResponseMixin, FormView):
asset = get_object_or_none(Asset, id=id_) asset = get_object_or_none(Asset, id=id_)
for k, v in asset_dict.items(): for k, v in asset_dict.items():
if k == 'idc': if k == 'idc':
v = get_object_or_none(IDC, name=v) v = get_object_or_none(Cluster, name=v)
elif k == 'is_active': elif k == 'is_active':
v = bool(v) v = bool(v)
elif k == 'admin_user': elif k == 'admin_user':

@ -0,0 +1,101 @@
# coding:utf-8
from __future__ import absolute_import, unicode_literals
from django.utils.translation import ugettext as _
from django.views.generic import TemplateView, ListView, View
from django.views.generic.edit import CreateView, DeleteView, FormView, UpdateView
from django.urls import reverse_lazy
from django.views.generic.detail import DetailView, SingleObjectMixin
from .. import forms
from ..models import Asset, AssetGroup, AdminUser, Cluster, SystemUser
from ..hands import AdminUserRequiredMixin
__all__ = ['ClusterListView', 'ClusterCreateView', 'ClusterUpdateView',
'ClusterDetailView', 'ClusterDeleteView', 'ClusterAssetsView']
class ClusterListView(AdminUserRequiredMixin, TemplateView):
template_name = 'assets/cluster_list.html'
def get_context_data(self, **kwargs):
context = {
'app': _('Assets'),
'action': _('Cluster list'),
# 'keyword': self.request.GET.get('keyword', '')
}
kwargs.update(context)
return super(ClusterListView, self).get_context_data(**kwargs)
class ClusterCreateView(AdminUserRequiredMixin, CreateView):
model = Cluster
form_class = forms.ClusterForm
template_name = 'assets/cluster_create_update.html'
success_url = reverse_lazy('assets:cluster-list')
def get_context_data(self, **kwargs):
context = {
'app': _('assets'),
'action': _('Create Cluster'),
}
kwargs.update(context)
return super(ClusterCreateView, self).get_context_data(**kwargs)
def form_valid(self, form):
cluster = form.save(commit=False)
cluster.created_by = self.request.user.username or 'System'
cluster.save()
return super(ClusterCreateView, self).form_valid(form)
class ClusterUpdateView(AdminUserRequiredMixin, UpdateView):
model = Cluster
form_class = forms.ClusterForm
template_name = 'assets/cluster_create_update.html'
context_object_name = 'cluster'
success_url = reverse_lazy('assets:cluster-list')
def form_valid(self, form):
cluster = form.save(commit=False)
cluster.save()
return super(ClusterUpdateView, self).form_valid(form)
def get_context_data(self, **kwargs):
context = {
'app': _('assets'),
'action': _('Update Cluster'),
}
kwargs.update(context)
return super(ClusterUpdateView, self).get_context_data(**kwargs)
class ClusterDetailView(AdminUserRequiredMixin, DetailView):
model = Cluster
template_name = 'assets/cluster_detail.html'
context_object_name = 'cluster'
class ClusterAssetsView(AdminUserRequiredMixin, DetailView):
model = Cluster
template_name = 'assets/cluster_assets.html'
context_object_name = 'cluster'
def get_context_data(self, **kwargs):
assets_remain = Asset.objects.exclude(id__in=self.object.assets.all())
context = {
'app': _('Assets'),
'action': _('Asset detail'),
'groups': AssetGroup.objects.all(),
'system_users': SystemUser.objects.all(),
'assets_remain': assets_remain,
'assets': [asset for asset in Asset.objects.all() if asset not in assets_remain],
}
kwargs.update(context)
return super(ClusterAssetsView, self).get_context_data(**kwargs)
class ClusterDeleteView(AdminUserRequiredMixin, DeleteView):
model = Cluster
template_name = 'assets/delete_confirm.html'
success_url = reverse_lazy('assets:cluster-list')

@ -9,7 +9,7 @@ from django.views.generic.detail import DetailView, SingleObjectMixin
from django.shortcuts import get_object_or_404, reverse, redirect from django.shortcuts import get_object_or_404, reverse, redirect
from .. import forms from .. import forms
from ..models import Asset, AssetGroup, AdminUser, IDC, SystemUser from ..models import Asset, AssetGroup, AdminUser, Cluster, SystemUser
from ..hands import AdminUserRequiredMixin from ..hands import AdminUserRequiredMixin

@ -1,101 +0,0 @@
# coding:utf-8
from __future__ import absolute_import, unicode_literals
from django.utils.translation import ugettext as _
from django.views.generic import TemplateView, ListView, View
from django.views.generic.edit import CreateView, DeleteView, FormView, UpdateView
from django.urls import reverse_lazy
from django.views.generic.detail import DetailView, SingleObjectMixin
from .. import forms
from ..models import Asset, AssetGroup, AdminUser, IDC, SystemUser
from ..hands import AdminUserRequiredMixin
__all__ = ['IDCListView', 'IDCCreateView', 'IDCUpdateView',
'IDCDetailView', 'IDCDeleteView', 'IDCAssetsView']
class IDCListView(AdminUserRequiredMixin, TemplateView):
template_name = 'assets/idc_list.html'
def get_context_data(self, **kwargs):
context = {
'app': _('Assets'),
'action': _('IDC list'),
# 'keyword': self.request.GET.get('keyword', '')
}
kwargs.update(context)
return super(IDCListView, self).get_context_data(**kwargs)
class IDCCreateView(AdminUserRequiredMixin, CreateView):
model = IDC
form_class = forms.IDCForm
template_name = 'assets/idc_create_update.html'
success_url = reverse_lazy('assets:idc-list')
def get_context_data(self, **kwargs):
context = {
'app': _('assets'),
'action': _('Create IDC'),
}
kwargs.update(context)
return super(IDCCreateView, self).get_context_data(**kwargs)
def form_valid(self, form):
idc = form.save(commit=False)
idc.created_by = self.request.user.username or 'System'
idc.save()
return super(IDCCreateView, self).form_valid(form)
class IDCUpdateView(AdminUserRequiredMixin, UpdateView):
model = IDC
form_class = forms.IDCForm
template_name = 'assets/idc_create_update.html'
context_object_name = 'idc'
success_url = reverse_lazy('assets:idc-list')
def form_valid(self, form):
idc = form.save(commit=False)
idc.save()
return super(IDCUpdateView, self).form_valid(form)
def get_context_data(self, **kwargs):
context = {
'app': _('assets'),
'action': _('Update IDC'),
}
kwargs.update(context)
return super(IDCUpdateView, self).get_context_data(**kwargs)
class IDCDetailView(AdminUserRequiredMixin, DetailView):
model = IDC
template_name = 'assets/idc_detail.html'
context_object_name = 'idc'
class IDCAssetsView(AdminUserRequiredMixin, DetailView):
model = IDC
template_name = 'assets/idc_assets.html'
context_object_name = 'idc'
def get_context_data(self, **kwargs):
assets_remain = Asset.objects.exclude(id__in=self.object.assets.all())
context = {
'app': _('Assets'),
'action': _('Asset detail'),
'groups': AssetGroup.objects.all(),
'system_users': SystemUser.objects.all(),
'assets_remain': assets_remain,
'assets': [asset for asset in Asset.objects.all() if asset not in assets_remain],
}
kwargs.update(context)
return super(IDCAssetsView, self).get_context_data(**kwargs)
class IDCDeleteView(AdminUserRequiredMixin, DeleteView):
model = IDC
template_name = 'assets/delete_confirm.html'
success_url = reverse_lazy('assets:idc-list')

File diff suppressed because one or more lines are too long

@ -1 +1 @@
[{"model": "users.usergroup", "pk": "0460a32e-59c9-42cc-81a5-7e0a13fc0085", "fields": {"is_discard": false, "discard_time": null, "name": "Default", "comment": "Default user group", "date_created": "2017-11-23T03:59:09.875Z", "created_by": "System"}}, {"model": "assets.idc", "pk": "937922e3-e2b7-42aa-b460-6b276901f53a", "fields": {"name": "Default", "bandwidth": "", "contact": "", "phone": "", "address": "", "intranet": "", "extranet": "", "date_created": "2017-11-23T03:59:09.882Z", "operator": "", "created_by": "System", "comment": "Default IDC"}}, {"model": "assets.assetgroup", "pk": "f758dc94-b979-4edf-9afc-f9171f9d2d6a", "fields": {"name": "Default", "created_by": "", "date_created": "2017-11-23T03:59:09.883Z", "comment": "Default asset group", "system_users": []}}, {"model": "users.user", "pk": "bb318c48-4f50-483e-a165-89d7f18e9e95", "fields": {"password": "pbkdf2_sha256$36000$kHqN5uCVaAk9$SXWzKLwBg68/2W8NLSNJIaVBJc60F26p8RO9E3oSskI=", "last_login": null, "first_name": "", "last_name": "", "is_active": true, "date_joined": "2017-11-23T03:59:09.828Z", "username": "admin", "name": "Administrator", "email": "admin@jumpserver.org", "role": "Admin", "avatar": "", "wechat": "", "phone": null, "enable_otp": false, "secret_key_otp": "", "_private_key": "", "_public_key": "", "comment": "Administrator is the super user of system", "is_first_login": false, "date_expired": "2087-11-06T03:59:09.829Z", "created_by": "System", "user_permissions": [], "groups": ["0460a32e-59c9-42cc-81a5-7e0a13fc0085"]}}] [{"model": "users.usergroup", "pk": "2e0b2a25-b32f-44a0-b087-f0f17de66e26", "fields": {"is_discard": false, "discard_time": null, "name": "Default", "comment": "Default user group", "date_created": "2017-12-07T08:20:09.593Z", "created_by": "System"}}, {"model": "assets.cluster", "pk": "c0df1aa0-bde7-4226-a69a-d02976888456", "fields": {"name": "Default", "bandwidth": "", "contact": "", "phone": "", "address": "", "intranet": "", "extranet": "", "date_created": "2017-12-07T08:20:09.606Z", "operator": "", "created_by": "System", "comment": "Default Cluster"}}, {"model": "assets.assetgroup", "pk": "881a0460-7989-42af-a588-957efe57fb8e", "fields": {"name": "Default", "created_by": "", "date_created": "2017-12-07T08:20:09.610Z", "comment": "Default asset group", "system_users": []}}, {"model": "users.user", "pk": "edc529d5-0377-4456-831f-ec42cf5b34d2", "fields": {"password": "pbkdf2_sha256$36000$3VcSL8Ap6zHd$14Y4+uZHRU8gwFgEXdIEZZ2+NWV15sRBV2YWgWbdyhY=", "last_login": null, "first_name": "", "last_name": "", "is_active": true, "date_joined": "2017-12-07T08:20:09.494Z", "username": "admin", "name": "Administrator", "email": "admin@jumpserver.org", "role": "Admin", "avatar": "", "wechat": "", "phone": null, "enable_otp": false, "secret_key_otp": "", "_private_key": "", "_public_key": "", "comment": "Administrator is the super user of system", "is_first_login": false, "date_expired": "2087-11-20T08:20:09.494Z", "created_by": "System", "user_permissions": [], "groups": ["2e0b2a25-b32f-44a0-b087-f0f17de66e26"]}}]

@ -467,7 +467,7 @@ msgstr "系统用户"
#: assets/models/asset.py:52 assets/templates/assets/asset_detail.html:85 #: assets/models/asset.py:52 assets/templates/assets/asset_detail.html:85
#: templates/_nav.html:23 #: templates/_nav.html:23
msgid "IDC" msgid "Cluster"
msgstr "机房" msgstr "机房"
#: assets/models/asset.py:53 assets/templates/assets/asset_detail.html:129 #: assets/models/asset.py:53 assets/templates/assets/asset_detail.html:129
@ -618,8 +618,8 @@ msgid "System"
msgstr "系统" msgstr "系统"
#: assets/models/idc.py:43 #: assets/models/idc.py:43
msgid "Default IDC" msgid "Default Cluster"
msgstr "默认IDC" msgstr "默认Cluster"
#: assets/models/user.py:24 #: assets/models/user.py:24
#, python-format #, python-format
@ -1080,8 +1080,8 @@ msgstr "您确定删除吗?"
#: assets/templates/assets/idc_assets.html:23 #: assets/templates/assets/idc_assets.html:23
#: assets/templates/assets/idc_assets.html:31 #: assets/templates/assets/idc_assets.html:31
#: assets/templates/assets/idc_detail.html:21 #: assets/templates/assets/idc_detail.html:21
msgid "IDC assets" msgid "Cluster assets"
msgstr "IDC资产" msgstr "Cluster资产"
#: assets/templates/assets/idc_assets.html:68 #: assets/templates/assets/idc_assets.html:68
#, fuzzy #, fuzzy
@ -1104,25 +1104,25 @@ msgid "Asset Updated"
msgstr "更新" msgstr "更新"
#: assets/templates/assets/idc_list.html:10 assets/views/idc.py:39 #: assets/templates/assets/idc_list.html:10 assets/views/idc.py:39
msgid "Create IDC" msgid "Create Cluster"
msgstr "创建IDC" msgstr "创建Cluster"
#: assets/templates/assets/idc_list.html:95 #: assets/templates/assets/idc_list.html:95
msgid "This will delete the selected idc" msgid "This will delete the selected idc"
msgstr "删除选择IDC" msgstr "删除选择Cluster"
#: assets/templates/assets/idc_list.html:103 #: assets/templates/assets/idc_list.html:103
msgid "IDC Deleted." msgid "Cluster Deleted."
msgstr "已被删除" msgstr "已被删除"
#: assets/templates/assets/idc_list.html:104 #: assets/templates/assets/idc_list.html:104
#: assets/templates/assets/idc_list.html:109 #: assets/templates/assets/idc_list.html:109
msgid "IDC Delete" msgid "Cluster Delete"
msgstr "删除" msgstr "删除"
#: assets/templates/assets/idc_list.html:108 #: assets/templates/assets/idc_list.html:108
msgid "IDC Deleting failed." msgid "Cluster Deleting failed."
msgstr "IDC删除失败" msgstr "Cluster删除失败"
#: assets/templates/assets/system_user_asset.html:20 #: assets/templates/assets/system_user_asset.html:20
#: assets/templates/assets/system_user_detail.html:22 #: assets/templates/assets/system_user_detail.html:22
@ -1208,8 +1208,8 @@ msgid "Asset group detail"
msgstr "资产组详情" msgstr "资产组详情"
#: assets/views/idc.py:23 #: assets/views/idc.py:23
msgid "IDC list" msgid "Cluster list"
msgstr "IDC列表" msgstr "Cluster列表"
#: assets/views/idc.py:38 assets/views/idc.py:65 #: assets/views/idc.py:38 assets/views/idc.py:65
#: ops/templates/ops/task_detail.html:84 #: ops/templates/ops/task_detail.html:84
@ -1217,8 +1217,8 @@ msgid "assets"
msgstr "资产管理" msgstr "资产管理"
#: assets/views/idc.py:66 #: assets/views/idc.py:66
msgid "Update IDC" msgid "Update Cluster"
msgstr "更新IDC" msgstr "更新Cluster"
#: assets/views/system_user.py:31 #: assets/views/system_user.py:31
msgid "System user list" msgid "System user list"

@ -29,7 +29,7 @@ Options = namedtuple('Options', [
'ssh_common_args', 'ssh_extra_args', 'sftp_extra_args', 'ssh_common_args', 'ssh_extra_args', 'sftp_extra_args',
'scp_extra_args', 'become', 'become_method', 'become_user', 'scp_extra_args', 'become', 'become_method', 'become_user',
'verbosity', 'check', 'extra_vars', 'playbook_path', 'passwords', 'verbosity', 'check', 'extra_vars', 'playbook_path', 'passwords',
'diff', 'diff', 'gathering'
]) ])
@ -58,6 +58,7 @@ def get_default_options():
playbook_path='/etc/ansible/', playbook_path='/etc/ansible/',
passwords=None, passwords=None,
diff=False, diff=False,
gathering='implicit',
) )
return options return options

@ -6,8 +6,9 @@ import uuid
from django.db import models from django.db import models
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from common.utils import signer
__all__ = ["AdHoc", "History"] __all__ = ["AdHoc", "AdHocRunHistory"]
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -16,6 +17,8 @@ logger = logging.getLogger(__name__)
class AdHoc(models.Model): class AdHoc(models.Model):
id = models.UUIDField(default=uuid.uuid4, primary_key=True) id = models.UUIDField(default=uuid.uuid4, primary_key=True)
name = models.CharField(max_length=128, blank=True, verbose_name=_('Name')) name = models.CharField(max_length=128, blank=True, verbose_name=_('Name'))
is_deleted = models.BooleanField(default=False)
date_create = models.DateTimeField(auto_created=True)
@property @property
def short_id(self): def short_id(self):
@ -39,7 +42,7 @@ class AdHocData(models.Model):
become = models.BooleanField(default=False, verbose_name=_("Become")) become = models.BooleanField(default=False, verbose_name=_("Become"))
become_method = models.CharField(choices=BECOME_METHOD_CHOICES, default='sudo', max_length=4) become_method = models.CharField(choices=BECOME_METHOD_CHOICES, default='sudo', max_length=4)
become_user = models.CharField(default='root', max_length=64) become_user = models.CharField(default='root', max_length=64)
become_pass = models.CharField(default='', max_length=128) _become_pass = models.CharField(default='', max_length=128)
pattern = models.CharField(max_length=64, default='', verbose_name=_('Pattern')) pattern = models.CharField(max_length=64, default='', verbose_name=_('Pattern'))
created_by = models.CharField(max_length=64, verbose_name=_('Create by')) created_by = models.CharField(max_length=64, verbose_name=_('Create by'))
date_created = models.DateTimeField(auto_created=True) date_created = models.DateTimeField(auto_created=True)
@ -60,15 +63,29 @@ class AdHocData(models.Model):
def hosts(self, item): def hosts(self, item):
self._hosts = json.dumps(item) self._hosts = json.dumps(item)
@property
def become_pass(self):
return signer.unsign(self._become_pass)
@become_pass.setter
def become_pass(self, password):
self._become_pass = signer.sign(password)
@property @property
def short_version(self): def short_version(self):
return str(self.version).split('-')[-1] return str(self.version).split('-')[-1]
def run(self):
pass
def __str__(self): def __str__(self):
return "{} of {}".format(self.subject.name, self.short_version) return "{} of {}".format(self.subject.name, self.short_version)
class Meta:
db_table = "ops_adhoc_data"
class AdHocHistory(models.Model): class AdHocRunHistory(models.Model):
uuid = models.UUIDField(default=uuid.uuid4, primary_key=True) uuid = models.UUIDField(default=uuid.uuid4, primary_key=True)
adhoc = models.ForeignKey(AdHocData, on_delete=models.CASCADE) adhoc = models.ForeignKey(AdHocData, on_delete=models.CASCADE)
date_start = models.DateTimeField(auto_now_add=True, verbose_name=_('Start time')) date_start = models.DateTimeField(auto_now_add=True, verbose_name=_('Start time'))
@ -85,3 +102,6 @@ class AdHocHistory(models.Model):
def __str__(self): def __str__(self):
return self.short_id return self.short_id
class Meta:
db_table = "ops_adhoc_history"

@ -9,77 +9,16 @@ import uuid
from django.utils import timezone from django.utils import timezone
from assets.models import Asset from common.utils import get_logger, get_object_or_none
from common.utils import get_logger from .ansible import AdHocRunner
from .ansible.runner import AdHocRunner from assets.utils import get_assets_by_hostname_list
logger = get_logger(__file__) logger = get_logger(__file__)
UUID_PATTERN = re.compile(r'[0-9a-zA-Z\-]{36}')
def run_AdHoc(task_tuple, assets, def run_AdHoc():
task_name='Ansible AdHoc runner', pass
task_id=None, pattern='all',
record=True, verbose=True):
"""
:param task_tuple: (('module_name', 'module_args'), ('module_name', 'module_args'))
:param assets: [asset1, asset2]
:param task_name:
:param task_id:
:param pattern:
:param record:
:param verbose:
:return: summary: {'success': [], 'failed': [{'192.168.1.1': 'msg'}]}
result: {'contacted': {'hostname': [{''}, {''}], 'dark': []}
"""
if not assets:
logger.warning('Empty assets, runner cancel')
return
if isinstance(assets[0], Asset):
assets = [asset._to_secret_json() for asset in assets]
if task_id is None:
task_id = str(uuid.uuid4())
runner = AdHocRunner(assets)
if record:
from .models import Playbook
if not Playbook.objects.filter(uuid=task_id):
record = Playbook(uuid=task_id,
name=task_name,
assets=','.join(str(asset['id']) for asset in assets),
module_args=task_tuple,
pattern=pattern)
record.save()
else:
record = Playbook.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))
result = runner.run(task_tuple, pattern=pattern, task_name=task_name)
timedelta = round(time.time() - ts_start, 2)
summary = runner.clean_result()
if record:
record.date_finished = timezone.now()
record.is_finished = True
if verbose:
record.result = json.dumps(result, indent=4, sort_keys=True)
record.summary = json.dumps(summary)
record.timedelta = timedelta
if len(summary['failed']) == 0:
record.is_success = True
else:
record.is_success = False
record.save()
return summary, result
UUID_PATTERN = re.compile(r'[0-9a-zA-Z\-]{36}')
def is_uuid(s): def is_uuid(s):
@ -99,3 +38,60 @@ def asset_to_dict_with_credential(asset):
def system_user_to_dict_with_credential(system_user): def system_user_to_dict_with_credential(system_user):
return system_user._to_secret_json() return system_user._to_secret_json()
def get_hosts_with_admin(hostname_list):
assets = get_assets_by_hostname_list(hostname_list)
return [asset._to_secret_json for asset in assets]
def get_hosts(hostname_list):
assets = get_assets_by_hostname_list(hostname_list)
return [asset.to_json for asset in assets]
def get_run_user(name):
from assets.models import SystemUser
system_user = get_object_or_none(SystemUser, name=name)
if system_user is None:
return {}
else:
return system_user._to_secret_json()
def get_hosts_with_run_user(hostname_list, run_as):
hosts_dict = get_hosts(hostname_list)
system_user_dct = get_run_user(run_as)
for host in hosts_dict:
host.update(system_user_dct)
return hosts_dict
def hosts_add_become(hosts, adhoc_data):
if adhoc_data.become:
become_data = {
"become": {
"method": adhoc_data.become_method,
"user": adhoc_data.become_user,
"pass": adhoc_data.become_pass,
}
}
for host in hosts:
host.update(become_data)
return hosts
def run_adhoc(adhoc_data, forks=10):
tasks = adhoc_data.tasks
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)
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)

@ -9,7 +9,7 @@ from django.views.generic import ListView, DetailView, View
from django.utils import timezone from django.utils import timezone
from django.shortcuts import redirect, reverse from django.shortcuts import redirect, reverse
from .models import AdHoc, AdHocData, AdHocHistory from .models import AdHoc, AdHocData, AdHocRunHistory
from ops.tasks import rerun_task from ops.tasks import rerun_task
@ -63,7 +63,7 @@ class TaskListView(ListView):
class TaskDetailView(DetailView): class TaskDetailView(DetailView):
model = AdHocHistory model = AdHocRunHistory
template_name = 'ops/task_detail.html' template_name = 'ops/task_detail.html'
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):

@ -21,7 +21,7 @@
<ul class="nav nav-second-level"> <ul class="nav nav-second-level">
<li id="asset"><a href="{% url 'assets:asset-list' %}">{% trans 'Asset' %}</a></li> <li id="asset"><a href="{% url 'assets:asset-list' %}">{% trans 'Asset' %}</a></li>
<li id="asset-group"><a href="{% url 'assets:asset-group-list' %}">{% trans 'Asset group' %}</a></li> <li id="asset-group"><a href="{% url 'assets:asset-group-list' %}">{% trans 'Asset group' %}</a></li>
<li id="idc"><a href="{% url 'assets:idc-list' %}">{% trans 'IDC' %}</a></li> <li id="cluster"><a href="{% url 'assets:cluster-list' %}">{% trans 'Cluster' %}</a></li>
<li id="admin-user"><a href="{% url 'assets:admin-user-list' %}">{% trans 'Admin user' %}</a></li> <li id="admin-user"><a href="{% url 'assets:admin-user-list' %}">{% trans 'Admin user' %}</a></li>
<li id="system-user"><a href="{% url 'assets:system-user-list' %}">{% trans 'System user' %}</a></li> <li id="system-user"><a href="{% url 'assets:system-user-list' %}">{% trans 'System user' %}</a></li>
</ul> </ul>

@ -9,8 +9,8 @@ generate_fake()
EOF EOF
python ../apps/manage.py dbshell << EOF python ../apps/manage.py dbshell << EOF
delete from django_content_type;
delete from auth_permission; delete from auth_permission;
delete from django_content_type;
EOF EOF

@ -8,14 +8,11 @@ init_model()
from assets.models import * from assets.models import *
init_model() init_model()
from audits.models import LoginLog
LoginLog.objects.all().delete()
EOF EOF
python ../apps/manage.py dbshell << EOF python ../apps/manage.py dbshell << EOF
delete from django_content_type;
delete from auth_permission; delete from auth_permission;
delete from django_content_type;
EOF EOF
python ../apps/manage.py dumpdata > ../apps/fixtures/init.json python ../apps/manage.py dumpdata > ../apps/fixtures/init.json

Loading…
Cancel
Save