├── .idea ├── misc.xml ├── modules.xml ├── my_oms.iml └── vcs.xml ├── README.md ├── account ├── __init__.py ├── admin.py ├── models.py ├── templates │ └── registration │ │ ├── logged_out.html │ │ └── login.html ├── tests.py ├── urls.py └── views.py ├── asset ├── __init__.py ├── admin.py ├── form.py ├── migrations │ └── __init__.py ├── models.py ├── tests.py └── views.py ├── demo ├── dashboard.jpg ├── host_list.jpg ├── install_record.jpg ├── log.jpg ├── login.jpg ├── module.jpg ├── remote.jpg ├── saltkey_list.jpg └── system_install.jpg ├── deploy ├── __init__.py ├── admin.py ├── models.py ├── saltapi.py ├── tests.py └── views.py ├── install ├── installed ├── __init__.py ├── admin.py ├── cobbler_api.py ├── form.py ├── migrations │ └── __init__.py ├── models.py ├── tests.py └── views.py ├── manage.py ├── my_oms ├── __init__.py ├── models.py ├── mysql.py ├── settings.py ├── settings_local.py ├── urls.py ├── views.py └── wsgi.py ├── requirements.txt └── templates ├── base.html ├── host_list.html ├── host_manage.html ├── index.html ├── install_list.html ├── install_manage.html ├── install_record_list.html ├── record.html ├── salt_key_list.html ├── salt_module_deploy.html └── salt_remote_execution.html /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | Buildout 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 40 | 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /.idea/my_oms.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 28 | 29 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jwh5566/my_oms/ccfea7a2a5495c5e67c3b2e631ee4e6c0c3978b5/README.md -------------------------------------------------------------------------------- /account/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jwh5566/my_oms/ccfea7a2a5495c5e67c3b2e631ee4e6c0c3978b5/account/__init__.py -------------------------------------------------------------------------------- /account/admin.py: -------------------------------------------------------------------------------- 1 | # Register your models here. 2 | -------------------------------------------------------------------------------- /account/models.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from django.db import models 3 | 4 | 5 | class Users(models.Model): 6 | """ 7 | OMS User Manage 8 | """ 9 | username = models.CharField(max_length=30, verbose_name=u'用户名') 10 | password = models.CharField(max_length=30, verbose_name=u'密码') 11 | 12 | def __unicode__(self): 13 | return self.username 14 | 15 | class Meta: 16 | # verbose_name_plural = u'用户信息' 17 | verbose_name_plural = u'用户信息管理' 18 | 19 | 20 | class Message(models.Model): 21 | """ 22 | 平台审计信息 23 | """ 24 | audit_time = models.DateTimeField(auto_now_add=True, verbose_name=u'时间') 25 | type = models.CharField(max_length=10, verbose_name=u'类型') 26 | action = models.CharField(max_length=10, verbose_name=u'动作') 27 | action_ip = models.CharField(max_length=15, verbose_name=u'执行IP') 28 | content = models.CharField(max_length=50, verbose_name=u'内容') 29 | 30 | class Meta: 31 | # verbose_name = u'审计信息' 32 | verbose_name_plural = u'审计信息管理' 33 | -------------------------------------------------------------------------------- /account/templates/registration/logged_out.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 用户退出 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 |

您已经退出

16 | 17 |

您已经成功退出. 你可以 重新登陆.

18 |
19 | 20 | -------------------------------------------------------------------------------- /account/templates/registration/login.html: -------------------------------------------------------------------------------- 1 | {% load bootstrap %} 2 | 3 | 4 | 5 | 6 | 用户登陆 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 |

用户登陆

20 | 21 |
22 |
23 |
24 | {{ form|bootstrap }} 25 | {# {{ form.username.label|bootstrap }}#} 26 | {# #} 27 | {% csrf_token %} 28 | {# #} 29 |
30 |
31 |
32 | {#
#} 33 | 34 |
35 | 36 |
37 | 38 | -------------------------------------------------------------------------------- /account/tests.py: -------------------------------------------------------------------------------- 1 | # Create your tests here. 2 | -------------------------------------------------------------------------------- /account/urls.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from django.conf.urls import url 3 | 4 | urlpatterns = [ 5 | url(r'^login/$', 'django.contrib.auth.views.login', name='login'), 6 | url(r'^logout/$', 'django.contrib.auth.views.logout', name='logout'), 7 | ] 8 | -------------------------------------------------------------------------------- /account/views.py: -------------------------------------------------------------------------------- 1 | # Create your views here. 2 | -------------------------------------------------------------------------------- /asset/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jwh5566/my_oms/ccfea7a2a5495c5e67c3b2e631ee4e6c0c3978b5/asset/__init__.py -------------------------------------------------------------------------------- /asset/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from .models import HostList, Message 3 | 4 | # Register your models here. 5 | admin.site.register(HostList) 6 | 7 | admin.site.register(Message) 8 | -------------------------------------------------------------------------------- /asset/form.py: -------------------------------------------------------------------------------- 1 | from django import forms 2 | from .models import HostList 3 | 4 | class HostsListForm(forms.ModelForm): 5 | 6 | class Meta: 7 | model = HostList 8 | fields = ('ip', 'hostname', 'product', 'application', 'idc_jg', 'status', 'remark') 9 | widgets = { 10 | 'ip': forms.TextInput(attrs={'class': 'form-control'}), 11 | 'hostname': forms.TextInput(attrs={'class': 'form-control'}), 12 | 'product': forms.TextInput(attrs={'class': 'form-control'}), 13 | 'application': forms.TextInput(attrs={'class': 'form-control'}), 14 | 'idc_jg': forms.TextInput(attrs={'class': 'form-control'}), 15 | 'status': forms.TextInput(attrs={'class': 'form-control'}), 16 | 'remark': forms.TextInput(attrs={'class': 'form-control'}), 17 | } 18 | -------------------------------------------------------------------------------- /asset/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jwh5566/my_oms/ccfea7a2a5495c5e67c3b2e631ee4e6c0c3978b5/asset/migrations/__init__.py -------------------------------------------------------------------------------- /asset/models.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from django.db import models 3 | 4 | class HostList(models.Model): 5 | ip = models.CharField(max_length=20, verbose_name=u'IP地址') 6 | hostname = models.CharField(max_length=30, verbose_name=u'主机名') 7 | product = models.CharField(max_length=20, verbose_name=u'产品') 8 | application = models.CharField(max_length=20, verbose_name=u'应用') 9 | idc_jg = models.CharField(max_length=10, blank=True, verbose_name=u'机柜编号') 10 | status = models.CharField(max_length=10, verbose_name=u'使用状态', default=u'待装机') 11 | remark = models.TextField(max_length=50, blank=True, verbose_name=u'备注') 12 | 13 | def __unicode__(self): 14 | return u'%s - %s - %s' %(self.ip, self.hostname, self.application ) 15 | 16 | class Meta: 17 | # verbose_name = u'主机列表' 18 | verbose_name_plural = u'主机列表管理' 19 | 20 | class Message(models.Model): 21 | """ 22 | Platform audit information 23 | """ 24 | audit_time = models.DateTimeField(auto_now_add=True, verbose_name=u'时间') 25 | type = models.CharField(max_length=10, verbose_name=u'类型') 26 | action = models.CharField(max_length=10, verbose_name=u'动作') 27 | action_ip = models.CharField(max_length=15, verbose_name=u'执行IP') 28 | content = models.CharField(max_length=50, verbose_name=u'内容') 29 | 30 | class Meta: 31 | # verbose_name = u'审计信息' 32 | verbose_name_plural = u'审计信息管理' 33 | -------------------------------------------------------------------------------- /asset/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /asset/views.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from django.shortcuts import render, get_object_or_404 3 | from django.http import HttpResponseRedirect 4 | from django.core.urlresolvers import reverse 5 | from django.core.paginator import Paginator 6 | 7 | from .models import HostList, Message 8 | from my_oms.mysql import db_operate 9 | from my_oms import settings 10 | from .form import HostsListForm 11 | 12 | 13 | def host_list(request): 14 | """ 15 | List all Hosts 16 | """ 17 | user = request.user 18 | host_list = HostList.objects.all().order_by('-status') 19 | # host_list = HostList.objects.all() 20 | paginator = Paginator(host_list,10) 21 | 22 | try: 23 | page = int(request.GET.get('page','1')) 24 | except ValueError: 25 | page = 1 26 | 27 | try: 28 | host_list = paginator.page(page) 29 | except : 30 | all_host = paginator.page(paginator.num_pages) 31 | 32 | return render(request, 'host_list.html', {'host_list': host_list, 'page': page, 'paginator':paginator}) 33 | # return render(request, 'host_list.html',{'host_list': host_list}) 34 | 35 | def host_list_manage(request, id=None): # 负责添加和修改和删除主机,删除,修改主机需要提供id号 36 | if id: 37 | host_list = get_object_or_404(HostList, pk=id) 38 | action = 'edit' 39 | # page_name = '编辑主机' 40 | db = db_operate() 41 | sql = 'select ip from asset_hostlist where id = %s' % (id) 42 | ret = db.mysql_command(settings.OMS_MYSQL, sql) # settings.OMS_MYSQL 是mysql连接参数的字典 43 | # 这里ret 是ip 44 | else: 45 | host_list = HostList() 46 | action = 'add' 47 | # page_name = '新增主机' 48 | ret=[] 49 | 50 | if request.method == 'GET': 51 | delete = request.GET.get('delete') 52 | id = request.GET.get('id') 53 | if delete: 54 | Message.objects.create(type='host', action='manage', action_ip=ret, content='主机下架') 55 | host_list = get_object_or_404(HostList, pk=id) 56 | host_list.delete() 57 | return HttpResponseRedirect(reverse('host_list')) 58 | if request.method == 'POST': # 修改主机或者添加新主机 59 | form = HostsListForm(request.POST,instance=host_list) 60 | print request.POST 61 | operate = request.POST.get('operate') # 这里表示点击更新了按钮 62 | if form.is_valid(): 63 | if action == 'add': # 点击添加按钮 64 | form.save() 65 | ret.append(form.cleaned_data['ip']) 66 | Message.objects.create(type='host', action='manage', action_ip=ret, content='主机添加成功') 67 | return HttpResponseRedirect(reverse('host_list')) 68 | if operate: 69 | if operate == 'update': 70 | form.save() 71 | Message.objects.create(type='host', action='manage', action_ip=ret, content='主机信息更新') 72 | return HttpResponseRedirect(reverse('host_list')) 73 | else: 74 | pass 75 | else: 76 | form = HostsListForm(instance=host_list) 77 | 78 | return render(request, 'host_manage.html', 79 | {"form": form, 80 | # "page_name": page_name, 81 | "action": action, # 这里action 要注意 如果是edit 页面显示edit按钮 如果是add页面显示add按钮 82 | }) 83 | 84 | 85 | def record(request): 86 | message_list = Message.objects.all().order_by('-audit_time') 87 | paginator = Paginator(message_list, 10) 88 | 89 | try: 90 | page = int(request.GET.get('page', '1')) 91 | except ValueError: 92 | page = 1 93 | 94 | try: 95 | message_list = paginator.page(page) 96 | except: 97 | all_host = paginator.page(paginator.num_pages) 98 | 99 | return render(request, 'record.html', {'message_list': message_list, 'page': page, 'paginator': paginator}) -------------------------------------------------------------------------------- /demo/dashboard.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jwh5566/my_oms/ccfea7a2a5495c5e67c3b2e631ee4e6c0c3978b5/demo/dashboard.jpg -------------------------------------------------------------------------------- /demo/host_list.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jwh5566/my_oms/ccfea7a2a5495c5e67c3b2e631ee4e6c0c3978b5/demo/host_list.jpg -------------------------------------------------------------------------------- /demo/install_record.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jwh5566/my_oms/ccfea7a2a5495c5e67c3b2e631ee4e6c0c3978b5/demo/install_record.jpg -------------------------------------------------------------------------------- /demo/log.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jwh5566/my_oms/ccfea7a2a5495c5e67c3b2e631ee4e6c0c3978b5/demo/log.jpg -------------------------------------------------------------------------------- /demo/login.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jwh5566/my_oms/ccfea7a2a5495c5e67c3b2e631ee4e6c0c3978b5/demo/login.jpg -------------------------------------------------------------------------------- /demo/module.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jwh5566/my_oms/ccfea7a2a5495c5e67c3b2e631ee4e6c0c3978b5/demo/module.jpg -------------------------------------------------------------------------------- /demo/remote.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jwh5566/my_oms/ccfea7a2a5495c5e67c3b2e631ee4e6c0c3978b5/demo/remote.jpg -------------------------------------------------------------------------------- /demo/saltkey_list.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jwh5566/my_oms/ccfea7a2a5495c5e67c3b2e631ee4e6c0c3978b5/demo/saltkey_list.jpg -------------------------------------------------------------------------------- /demo/system_install.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jwh5566/my_oms/ccfea7a2a5495c5e67c3b2e631ee4e6c0c3978b5/demo/system_install.jpg -------------------------------------------------------------------------------- /deploy/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jwh5566/my_oms/ccfea7a2a5495c5e67c3b2e631ee4e6c0c3978b5/deploy/__init__.py -------------------------------------------------------------------------------- /deploy/admin.py: -------------------------------------------------------------------------------- 1 | # Register your models here. 2 | -------------------------------------------------------------------------------- /deploy/models.py: -------------------------------------------------------------------------------- 1 | # Create your models here. 2 | -------------------------------------------------------------------------------- /deploy/saltapi.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | """ 4 | """ 5 | __title__ = '' 6 | __author__ = 'JWH5566' 7 | __mtime__ = '2016/4/8' 8 | 9 | import urllib2 10 | import urllib 11 | import ssl 12 | 13 | ssl._create_default_https_context = ssl._create_unverified_context 14 | 15 | try: 16 | import json 17 | except ImportError: 18 | import simplejson as json 19 | 20 | 21 | class SaltAPI(object): 22 | __token_id = '' 23 | 24 | def __init__(self, url, username, password): 25 | self.__url = url.rstrip('/') 26 | self.__user = username 27 | self.__password = password 28 | 29 | def token_id(self): 30 | ''' user login and get token id ''' 31 | params = {'eauth': 'pam', 'username': self.__user, 'password': self.__password} 32 | encode = urllib.urlencode(params) 33 | obj = urllib.unquote(encode) 34 | content = self.postRequest(obj, prefix='/login') 35 | try: 36 | self.__token_id = content['return'][0]['token'] 37 | except KeyError: 38 | raise KeyError 39 | 40 | def postRequest(self, obj, prefix='/'): 41 | """ 42 | 返回json格式 43 | :param obj: 44 | :param prefix: 45 | :return: 46 | """ 47 | url = self.__url + prefix 48 | headers = {'X-Auth-Token': self.__token_id} 49 | req = urllib2.Request(url, obj, headers) 50 | opener = urllib2.urlopen(req) 51 | content = json.loads(opener.read()) 52 | return content 53 | 54 | def list_all_key(self): 55 | params = {'client': 'wheel', 'fun': 'key.list_all'} 56 | obj = urllib.urlencode(params) 57 | self.token_id() 58 | content = self.postRequest(obj) 59 | minions = content['return'][0]['data']['return']['minions'] 60 | minions_pre = content['return'][0]['data']['return']['minions_pre'] 61 | return minions, minions_pre # minions_pre代表没有接受的主机 62 | 63 | def delete_key(self, node_name): 64 | params = {'client': 'wheel', 'fun': 'key.delete', 'match': node_name} 65 | obj = urllib.urlencode(params) 66 | self.token_id() 67 | content = self.postRequest(obj) 68 | ret = content['return'][0]['data']['success'] 69 | return ret 70 | 71 | def accept_key(self, node_name): 72 | params = {'client': 'wheel', 'fun': 'key.accept', 'match': node_name} 73 | obj = urllib.urlencode(params) 74 | self.token_id() 75 | content = self.postRequest(obj) 76 | ret = content['return'][0]['data']['success'] 77 | return ret 78 | 79 | def remote_noarg_execution(self, tgt, fun): 80 | ''' Execute commands without parameters ''' 81 | params = {'client': 'local', 'tgt': tgt, 'fun': fun} 82 | obj = urllib.urlencode(params) 83 | self.token_id() 84 | content = self.postRequest(obj) 85 | ret = content['return'][0][tgt] 86 | return ret 87 | 88 | def remote_execution(self, tgt, fun, arg): 89 | ''' Command execution with parameters ''' 90 | params = {'client': 'local', 'tgt': tgt, 'fun': fun, 'arg': arg} 91 | obj = urllib.urlencode(params) 92 | self.token_id() 93 | content = self.postRequest(obj) 94 | ret = content['return'][0][tgt] 95 | return ret 96 | 97 | def target_remote_execution(self, tgt, fun, arg): 98 | ''' Use targeting for remote execution ''' 99 | params = {'client': 'local', 'tgt': tgt, 'fun': fun, 'arg': arg, 'expr_form': 'nodegroup'} 100 | obj = urllib.urlencode(params) 101 | self.token_id() 102 | content = self.postRequest(obj) 103 | jid = content['return'][0]['jid'] 104 | return jid 105 | 106 | def deploy(self, tgt, arg): 107 | ''' Module deployment ''' 108 | params = {'client': 'local', 'tgt': tgt, 'fun': 'state.sls', 'arg': arg} 109 | obj = urllib.urlencode(params) 110 | self.token_id() 111 | content = self.postRequest(obj) 112 | return content 113 | 114 | def async_deploy(self, tgt, arg=None): 115 | ''' Asynchronously send a command to connected minions ''' 116 | params = {'client': 'local_async', 'tgt': tgt, 'fun': 'state.sls', 'arg': arg} 117 | obj = urllib.urlencode(params) 118 | self.token_id() 119 | content = self.postRequest(obj) 120 | # print content 121 | jid = content['return'][0]['jid'] 122 | # print jid 123 | return jid 124 | 125 | def target_deploy(self, tgt, arg): 126 | ''' Based on the node group forms deployment ''' 127 | params = {'client': 'local_async', 'tgt': tgt, 'fun': 'state.sls', 'arg': arg, 'expr_form': 'nodegroup'} 128 | obj = urllib.urlencode(params) 129 | self.token_id() 130 | content = self.postRequest(obj) 131 | jid = content['return'][0]['jid'] 132 | return jid 133 | 134 | 135 | def main(): 136 | url = 'https://10.0.0.151:8000' 137 | # token = '204f7d1a4bd2e098be379b93a203fe84295f5256' 138 | sapi = SaltAPI(url=url, username='test', password='test') 139 | # sapi.token_id() 140 | # print sapi.list_all_key() 141 | # sapi.delete_key('test-01') 142 | # sapi.accept_key('test-01') 143 | # sapi.deploy_1('test-01','nginx') 144 | print sapi.async_deploy('zabbix-agent', 'nginx') 145 | 146 | 147 | if __name__ == '__main__': 148 | main() 149 | -------------------------------------------------------------------------------- /deploy/tests.py: -------------------------------------------------------------------------------- 1 | # Create your tests here. 2 | -------------------------------------------------------------------------------- /deploy/views.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from django.shortcuts import render 3 | from django.core.urlresolvers import reverse 4 | from django.http import HttpResponseRedirect 5 | 6 | from saltapi import SaltAPI 7 | from my_oms import settings 8 | from asset.models import Message 9 | from asset.models import HostList 10 | from my_oms.mysql import db_operate 11 | 12 | 13 | def salt_key_list(request): 14 | """ 15 | list all key 16 | """ 17 | 18 | user = request.user 19 | sapi = SaltAPI(url=settings.SALT_API['url'], username=settings.SALT_API['user'], 20 | password=settings.SALT_API['password']) 21 | minions, minions_pre = sapi.list_all_key() 22 | 23 | return render(request, 'salt_key_list.html', {'all_minions': minions, 'all_minions_pre': minions_pre}) 24 | 25 | 26 | def salt_accept_key(request): 27 | """ 28 | accept salt minions key 29 | """ 30 | 31 | node_name = request.GET.get('node_name') 32 | sapi = SaltAPI(url=settings.SALT_API['url'], username=settings.SALT_API['user'], 33 | password=settings.SALT_API['password']) 34 | ret = sapi.accept_key(node_name) 35 | Message.objects.create(type='salt', action='key', action_ip=node_name, content='saltstack accept node key') 36 | return HttpResponseRedirect(reverse('key_list')) 37 | 38 | 39 | def salt_delete_key(request): 40 | """ 41 | delete salt minions key 42 | """ 43 | 44 | node_name = request.GET.get('node_name') 45 | sapi = SaltAPI(url=settings.SALT_API['url'], username=settings.SALT_API['user'], 46 | password=settings.SALT_API['password']) 47 | ret = sapi.delete_key(node_name) 48 | Message.objects.create(type='salt', action='key', action_ip=node_name, content='saltstack delete node key') 49 | return HttpResponseRedirect(reverse('key_list')) 50 | 51 | 52 | def module_deploy(request): 53 | """ 54 | deploy (nginx/php/mysql..etc) module 55 | """ 56 | 57 | ret = [] 58 | jid = [] 59 | user = request.user 60 | if request.method == 'POST': 61 | action = request.get_full_path().split('=')[1] 62 | if action == 'deploy': 63 | tgt = request.POST.get('tgt') 64 | arg = request.POST.getlist('module') 65 | tgtcheck = HostList.objects.filter(hostname=tgt) 66 | if tgtcheck: 67 | Message.objects.create(type='salt', action='deploy', action_ip=tgt, 68 | content='saltstack %s module depoy' % (arg)) 69 | sapi = SaltAPI(url=settings.SALT_API['url'], username=settings.SALT_API['user'], 70 | password=settings.SALT_API['password']) 71 | db = db_operate() 72 | 73 | if 'sysinit' in arg: 74 | obj = sapi.async_deploy(tgt, arg[-1]) # 先执行初始化模块,其他任意 sysinit 在最后的模块 75 | sql = "insert INTO salt_returns VALUES(%s) " % obj 76 | print sql 77 | jid.append(obj) 78 | arg.remove('sysinit') 79 | if arg: 80 | for i in arg: 81 | obj = sapi.async_deploy(tgt, i) 82 | jid.append(obj) 83 | else: 84 | for i in arg: 85 | obj = sapi.async_deploy(tgt, i) 86 | sql = "insert INTO salt_returns VALUES(%s) " % obj 87 | db.mysql_command(settings.OMS_MYSQL, sql) 88 | jid.append(obj) 89 | msg = '%s deploy %s module success,jid is %s' % (tgt, i, obj) 90 | ret.append(msg) 91 | # db = db_operate() 92 | # for i in jid: 93 | # # time.sleep(10) 94 | # sql = 'select returns from salt_returns where returns=%s' 95 | # result=db.select_table(settings.OMS_MYSQL,sql,str(i)) #通过jid获取执行结果 96 | # print result 97 | # ret.extend(result) 98 | # sapi.async_deploy('test-01','zabbix.api') #调用zabbix.api执行模块监控 99 | else: 100 | ret = '亲,目标主机不对,请重新输入' 101 | 102 | return render(request, 'salt_module_deploy.html', {'ret': ret}) 103 | 104 | 105 | def remote_execution(request): 106 | """ 107 | remote command execution 108 | """ 109 | 110 | ret = '' 111 | tgtcheck = '' 112 | danger = ('rm', 'reboot', 'init ', 'shutdown', 'll') 113 | user = request.user 114 | if request.method == 'POST': 115 | action = request.get_full_path().split('=')[1] 116 | if action == 'exec': 117 | tgt = request.POST.get('tgt') 118 | arg = request.POST.get('arg') 119 | tgtcheck = HostList.objects.filter(hostname=tgt) 120 | argcheck = arg not in danger 121 | if tgtcheck and argcheck: 122 | sapi = SaltAPI(url=settings.SALT_API['url'], username=settings.SALT_API['user'], 123 | password=settings.SALT_API['password']) 124 | ret = sapi.remote_execution(tgt, 'cmd.run', arg) 125 | elif not tgtcheck: 126 | ret = '亲,目标主机不正确,请重新输入' 127 | elif not argcheck: 128 | ret = '亲,命令很危险, 你这样子老大会不开森' 129 | Message.objects.create(type='salt', action='execution', action_ip=tgt, 130 | content='saltstack execution command: %s ' % (arg)) 131 | 132 | return render(request, 'salt_remote_execution.html', 133 | {'ret': ret}) 134 | 135 | # def code_deploy(request): 136 | # """ 137 | # Pull code for building, pushed to the server 138 | # """ 139 | # 140 | # ret = '' 141 | # host = {'ga': 'test-01', 'beta': 'localhost.localdomain'} 142 | # user = request.user 143 | # if request.method == 'POST': 144 | # action = request.get_full_path().split('=')[1] 145 | # if action == 'push': 146 | # pro = request.POST.get('project') 147 | # url = request.POST.get('url') 148 | # ver = request.POST.get('version') 149 | # env = request.POST.get('env') 150 | # capi = Code_Work(pro=pro,url=url,ver=ver) 151 | # data = {pro:{'ver':ver}} 152 | # obj = capi.work() #构建rpm包 153 | # if obj['comment'][0]['result'] and obj['comment'][1]['result'] and obj['comment'][2]['result']: 154 | # json_api = BuildJson() 155 | # json_api.build_data(host[env],data) #刷新pillar数据,通过deploy下发SLS执行代码发布 156 | # sapi = SaltAPI(url=settings.SALT_API['url'],username=settings.SALT_API['user'],password=settings.SALT_API['password']) 157 | # if env == 'beta': 158 | # jid = sapi.target_deploy('beta','deploy_1.'+pro) 159 | # elif env == 'ga': 160 | # jid = sapi.target_deploy('tg','deploy_1.'+pro) 161 | # else: 162 | # jid = sapi.target_deploy('beta','deploy_1.'+pro) 163 | # time.sleep(8) 164 | # db = db_operate() 165 | # sql = 'select returns from salt_returns where jid=%s' 166 | # ret=db.select_table(settings.RETURNS_MYSQL,sql,str(jid)) #通过jid获取执行结果 167 | # return render_to_response('code_deploy.html', 168 | # {'ret': ret},context_instance=RequestContext(request)) 169 | -------------------------------------------------------------------------------- /install: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jwh5566/my_oms/ccfea7a2a5495c5e67c3b2e631ee4e6c0c3978b5/install -------------------------------------------------------------------------------- /installed/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jwh5566/my_oms/ccfea7a2a5495c5e67c3b2e631ee4e6c0c3978b5/installed/__init__.py -------------------------------------------------------------------------------- /installed/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | 3 | from .models import SystemInstall, InstallRecord 4 | 5 | admin.site.register(SystemInstall) 6 | admin.site.register(InstallRecord) 7 | -------------------------------------------------------------------------------- /installed/cobbler_api.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # import cobbler 3 | import xmlrpclib 4 | 5 | class CobblerAPI(object): 6 | def __init__(self,url,user,password): # 初始化cobbler api对象 7 | self.cobbler_user= user 8 | self.cobbler_pass = password 9 | self.cobbler_url = url 10 | 11 | def add_system(self,hostname,ip_add,mac_add,profile): 12 | ''' 13 | Add Cobbler System Infomation 14 | ''' 15 | ret = { 16 | "result": True, 17 | "comment": [], 18 | } 19 | hostname = '_'.join(hostname.split()) 20 | remote = xmlrpclib.Server(self.cobbler_url) 21 | token = remote.login(self.cobbler_user,self.cobbler_pass) 22 | system_id = remote.new_system(token) 23 | remote.modify_system(system_id,"name",hostname,token) 24 | remote.modify_system(system_id,"hostname",hostname,token) 25 | remote.modify_system(system_id,'modify_interface', { 26 | "macaddress-eth0" : mac_add, 27 | "ipaddress-eth0" : ip_add, 28 | "dnsname-eth0" : hostname, 29 | }, token) 30 | remote.modify_system(system_id,"profile",profile,token) 31 | remote.save_system(system_id, token) 32 | try: 33 | remote.sync(token) 34 | ret['comment'].append(' add system success') 35 | except Exception as e: 36 | ret['result'] = False 37 | ret['comment'].append(str(e)) 38 | return ret 39 | 40 | def main(): 41 | cobbler = CobblerAPI(url='http://10.0.0.151/cobbler_api',user='cobbler',password='cobbler',) 42 | ret = cobbler.add_system(hostname='test',ip_add='10.0.0.123',mac_add='00:0C:29:70:A1:16',profile='CentOS-6.6-mini-x86_64') 43 | print ret 44 | 45 | if __name__ == '__main__': 46 | main() 47 | -------------------------------------------------------------------------------- /installed/form.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from django import forms 3 | from .models import SystemInstall 4 | 5 | class SystemInstallForm(forms.ModelForm): 6 | class Meta: 7 | model = SystemInstall 8 | exclude = ('install_date',) 9 | widgets = { 10 | 'ip': forms.TextInput(attrs={'class': 'form-control'}), 11 | 'hostname': forms.TextInput(attrs={'class': 'form-control'}), 12 | 'macaddress': forms.TextInput(attrs={'class': 'form-control'}), 13 | 'system_version': forms.TextInput(attrs={'class': 'form-control'}), 14 | 'profile': forms.TextInput(attrs={'class': 'form-control'}), 15 | } 16 | -------------------------------------------------------------------------------- /installed/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jwh5566/my_oms/ccfea7a2a5495c5e67c3b2e631ee4e6c0c3978b5/installed/migrations/__init__.py -------------------------------------------------------------------------------- /installed/models.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from django.db import models 3 | 4 | class SystemInstall(models.Model): 5 | """ 6 | System Install Manage 7 | """ 8 | ip = models.CharField(max_length=20, verbose_name=u'待装机IP') 9 | hostname = models.CharField(max_length=30, verbose_name=u'主机名') 10 | macaddress = models.CharField(max_length=50, verbose_name=u'MAC地址') 11 | system_version = models.CharField(max_length=20, verbose_name=u'操作系统') 12 | install_date = models.DateTimeField(auto_now_add=True, verbose_name=u'安装时间') 13 | profile = models.CharField(max_length=50, verbose_name=u'profile文件名') 14 | 15 | def __unicode__(self): 16 | return u'%s -- %s' %(self.ip, self.install_date) 17 | 18 | class Meta: 19 | # verbose_name = u'装机列表' 20 | verbose_name_plural = u'装机列表管理' 21 | 22 | class InstallRecord(models.Model): 23 | """ 24 | Server Install Recored 25 | """ 26 | install_date = models.CharField(max_length=50, verbose_name=u'安装时间') 27 | ip = models.CharField(max_length=20, verbose_name=u'安装IP') 28 | system_version = models.CharField(max_length=50, verbose_name = '安装操作系统版本') 29 | 30 | def __unicode__(self): 31 | return u'%s - %s' %(self.ip, self.system_version) 32 | 33 | class Meta: 34 | # verbose_name = u'装机记录' 35 | verbose_name_plural = u'装机记录管理' 36 | -------------------------------------------------------------------------------- /installed/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /installed/views.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from django.shortcuts import render, get_object_or_404 3 | from django.http import HttpResponseRedirect 4 | from django.core.urlresolvers import reverse 5 | from django.core.paginator import Paginator 6 | 7 | from asset.models import HostList, Message 8 | from .models import SystemInstall, InstallRecord 9 | from cobbler_api import CobblerAPI 10 | from my_oms import settings 11 | from form import SystemInstallForm 12 | from my_oms.mysql import db_operate 13 | 14 | 15 | def system_install(request): 16 | """ 17 | 1.Add Some Info to Cobbler System 18 | 2.Remote starting up 19 | 3.screen put in System Install process //这块信息暂且空着,日后有IPMI实践补上 20 | """ 21 | 22 | cobbler = CobblerAPI(url=settings.Cobbler_API['url'],user=settings.Cobbler_API['user'],password=settings.Cobbler_API['password']) 23 | if request.method == 'GET': 24 | ip = request.GET.get('ip') 25 | hostname = request.GET.get('host') 26 | mac_add = request.GET.get('mac') 27 | version = request.GET.get('ver') 28 | profile = request.GET.get('profile') 29 | ret = cobbler.add_system(hostname=hostname,ip_add=ip,mac_add=mac_add,profile=profile) 30 | if ret['result']: 31 | data = SystemInstall.objects.filter(ip=ip) # data 表示一条安装信息 格式 ip--日期 32 | install_date = str(data[0]).split('--')[1].strip() 33 | InstallRecord.objects.create(ip=ip,system_version=profile,install_date=install_date) 34 | HostList.objects.filter(ip=ip).update(status='已使用') #主机信息加入cobbler system,主机列表的状态变更为已使用状态,不再是待装机状态! 35 | SystemInstall.objects.filter(ip=ip).delete() #安装后,装机列表此IP信息删除,转让到安装记录里供审计 36 | Message.objects.create(type='system', action='install', action_ip=ip, content='主机信息添加至cobbler,进入安装模式') 37 | return HttpResponseRedirect(reverse('install_list')) 38 | 39 | 40 | def system_install_list(request): 41 | """ 42 | List all waiting for the host operating system is installed 43 | """ 44 | user = request.user 45 | 46 | #获取待装机的信息,从数据库中查询是否存在,未存在的插入到列表 47 | result = HostList.objects.filter(status='待装机') 48 | # print result 49 | install_list = [] 50 | for i in range(len(result)): 51 | ip = str(result[i]).split('-')[0] 52 | hostname = str(result[i]).split('-')[1].strip() 53 | ret = SystemInstall.objects.filter(ip=ip) 54 | if ret: 55 | message = ip + ' 已经在待安装列表' 56 | # else: 57 | # data = {'ip': ip, 'hostname': hostname, 'macaddress':ret['macaddress'], 'system_version':ret['system_version']} 58 | # install_list.append(data) 59 | 60 | # #列表数据插入数据库 61 | # for i in range(len(install_list)): 62 | # p = SystemInstall(ip=install_list[i]['ip'],hostname=install_list[i]['hostname'],macaddress=install_list[i]['macaddress'],system_version=install_list[i]['system_version']) 63 | # p.save() 64 | 65 | all_system_list = SystemInstall.objects.all().order_by('-install_date') 66 | # print all_system_list 67 | paginator = Paginator(all_system_list,10) 68 | 69 | try: 70 | page = int(request.GET.get('page','1')) 71 | except ValueError: 72 | page = 1 73 | 74 | try: 75 | all_system_list = paginator.page(page) 76 | except : 77 | all_system_list = paginator.page(paginator.num_pages) 78 | 79 | return render(request, 'install_list.html', {'all_system_list': all_system_list }) 80 | 81 | 82 | def system_install_managed(request,id=None): 83 | """ 84 | Management host to be installed 85 | """ 86 | user = request.user 87 | if id: 88 | system_install = get_object_or_404(SystemInstall, pk=id) 89 | action = 'edit' 90 | # page_name = '编辑主机' 91 | else: 92 | system_install = SystemInstall() 93 | action = 'add' 94 | # page_name = '添加主机' 95 | if request.method == 'POST': 96 | operate = request.POST.get('operate') 97 | form = SystemInstallForm(request.POST,instance=system_install) 98 | if form.is_valid(): 99 | if action == 'add': 100 | form.save() 101 | ret = form.cleaned_data['ip'] 102 | Message.objects.create(type='system', action='install', action_ip=ret, content='主机信息已添加(macadd、system_version),准备装机') 103 | return HttpResponseRedirect(reverse('install_list')) 104 | if operate: 105 | if operate == 'update': 106 | form.save() 107 | db = db_operate() 108 | sql = 'select ip from installed_systeminstall where id = %s' % (id) 109 | ret = db.mysql_command(settings.OMS_MYSQL,sql) 110 | Message.objects.create(type='system', action='install', action_ip=ret, content='主机信息已更新(macadd、system_version),准备装机') 111 | return HttpResponseRedirect(reverse('install_list')) 112 | else: 113 | pass 114 | else: 115 | form = SystemInstallForm(instance=system_install) 116 | action = 'add' 117 | 118 | return render(request, 'install_manage.html', 119 | {"form": form, 120 | 'action':action 121 | # "page_name": page_name, 122 | }) 123 | 124 | def system_install_record(request): 125 | """ 126 | List all operating system installation records 127 | """ 128 | 129 | user = request.user 130 | 131 | record = InstallRecord.objects.all().order_by('-install_date') 132 | paginator = Paginator(record,10) 133 | 134 | try: 135 | page = int(request.GET.get('page','1')) 136 | except ValueError: 137 | page = 1 138 | 139 | try: 140 | record = paginator.page(page) 141 | except : 142 | record = paginator.page(paginator.num_pages) 143 | 144 | return render(request, 'install_record_list.html', {'record': record, 'page': page, 'paginator':paginator}) -------------------------------------------------------------------------------- /manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import os 3 | import sys 4 | 5 | if __name__ == "__main__": 6 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "my_oms.settings") 7 | 8 | from django.core.management import execute_from_command_line 9 | 10 | execute_from_command_line(sys.argv) 11 | -------------------------------------------------------------------------------- /my_oms/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jwh5566/my_oms/ccfea7a2a5495c5e67c3b2e631ee4e6c0c3978b5/my_oms/__init__.py -------------------------------------------------------------------------------- /my_oms/models.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | -------------------------------------------------------------------------------- /my_oms/mysql.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import MySQLdb 3 | 4 | class db_operate: 5 | def mysql_command(self,conn,sql_cmd): # 执行sql 6 | try: 7 | ret = [] 8 | conn=MySQLdb.connect(host=conn["host"],user=conn["user"],passwd=conn["password"],db=conn["database"],port=conn["port"],charset="utf8") 9 | cursor = conn.cursor() 10 | n = cursor.execute(sql_cmd) 11 | for row in cursor.fetchall(): 12 | for i in row: 13 | ret.append(i) 14 | conn.commit() 15 | cursor.close() 16 | conn.close() 17 | except MySQLdb.Error,e: 18 | ret.append(e) 19 | 20 | return ret 21 | 22 | def select_table(self,conn,sql_cmd,parmas): # 执行带参数的sql 23 | try: 24 | ret = [] 25 | conn=MySQLdb.connect(host=conn["host"],user=conn["user"],passwd=conn["password"],db=conn["database"],port=conn["port"],charset="utf8") 26 | cursor = conn.cursor() 27 | n = cursor.execute(sql_cmd,parmas) 28 | for row in cursor.fetchall(): 29 | for i in row: 30 | ret.append(i) 31 | conn.commit() 32 | cursor.close() 33 | conn.close() 34 | except MySQLdb.Error,e: 35 | ret.append(e) 36 | 37 | return ret -------------------------------------------------------------------------------- /my_oms/settings.py: -------------------------------------------------------------------------------- 1 | """ 2 | Django settings for my_oms project. 3 | 4 | Generated by 'django-admin startproject' using Django 1.8.7. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/1.8/topics/settings/ 8 | 9 | For the full list of settings and their values, see 10 | https://docs.djangoproject.com/en/1.8/ref/settings/ 11 | """ 12 | 13 | # Build paths inside the project like this: os.path.join(BASE_DIR, ...) 14 | import os 15 | 16 | from django.core.urlresolvers import reverse_lazy 17 | 18 | BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 19 | 20 | 21 | # Quick-start development settings - unsuitable for production 22 | # See https://docs.djangoproject.com/en/1.8/howto/deployment/checklist/ 23 | 24 | # SECURITY WARNING: keep the secret key used in production secret! 25 | SECRET_KEY = 'xuu5qnp)=yshydz_^$pa(kfz4&g1oikn549vre)3^r4+-aln6)' 26 | 27 | # SECURITY WARNING: don't run with debug turned on in production! 28 | DEBUG = True 29 | 30 | ALLOWED_HOSTS = [] 31 | 32 | 33 | # Application definition 34 | 35 | INSTALLED_APPS = ( 36 | 'account', 37 | 'django.contrib.auth', 38 | 'django.contrib.admin', 39 | 'django.contrib.contenttypes', 40 | 'django.contrib.sessions', 41 | 'django.contrib.messages', 42 | 'django.contrib.staticfiles', 43 | 'asset', 44 | 'installed', 45 | 'bootstrapform', 46 | ) 47 | 48 | MIDDLEWARE_CLASSES = ( 49 | 'django.contrib.sessions.middleware.SessionMiddleware', 50 | 'django.middleware.common.CommonMiddleware', 51 | 'django.middleware.csrf.CsrfViewMiddleware', 52 | 'django.contrib.auth.middleware.AuthenticationMiddleware', 53 | 'django.contrib.auth.middleware.SessionAuthenticationMiddleware', 54 | 'django.contrib.messages.middleware.MessageMiddleware', 55 | 'django.middleware.clickjacking.XFrameOptionsMiddleware', 56 | 'django.middleware.security.SecurityMiddleware', 57 | ) 58 | 59 | ROOT_URLCONF = 'my_oms.urls' 60 | 61 | TEMPLATES = [ 62 | { 63 | 'BACKEND': 'django.template.backends.django.DjangoTemplates', 64 | 'DIRS': [os.path.join(BASE_DIR, 'templates')] 65 | , 66 | 'APP_DIRS': True, 67 | 'OPTIONS': { 68 | 'context_processors': [ 69 | 'django.template.context_processors.debug', 70 | 'django.template.context_processors.request', 71 | 'django.contrib.auth.context_processors.auth', 72 | 'django.contrib.messages.context_processors.messages', 73 | ], 74 | }, 75 | }, 76 | ] 77 | 78 | WSGI_APPLICATION = 'my_oms.wsgi.application' 79 | 80 | 81 | # Database 82 | # https://docs.djangoproject.com/en/1.8/ref/settings/#databases 83 | 84 | DATABASES = { 85 | 'default': { 86 | 'ENGINE': 'django.db.backends.mysql', 87 | 'NAME': 'oms', 88 | 'USER': 'root', 89 | 'PORT': 3306, 90 | 'PASSWORD': 'abc@123', 91 | } 92 | } 93 | 94 | 95 | # Internationalization 96 | # https://docs.djangoproject.com/en/1.8/topics/i18n/ 97 | 98 | LANGUAGE_CODE = 'zh-CN' 99 | 100 | TIME_ZONE = 'Asia/Shanghai' 101 | 102 | USE_I18N = True 103 | 104 | USE_L10N = True 105 | 106 | USE_TZ = True 107 | 108 | 109 | # Static files (CSS, JavaScript, Images) 110 | # https://docs.djangoproject.com/en/1.8/howto/static-files/ 111 | 112 | STATIC_URL = '/static/' 113 | 114 | LOGIN_REDIRECT_URL = reverse_lazy('index') 115 | LOGIN_URL = reverse_lazy('login') 116 | LOGOUT_URL = reverse_lazy('logout') 117 | 118 | try: 119 | from settings_local import * 120 | except ImportError: 121 | pass 122 | -------------------------------------------------------------------------------- /my_oms/settings_local.py: -------------------------------------------------------------------------------- 1 | OMS_MYSQL = {"host": "localhost", 2 | "port": 3306, 3 | "database": "oms", 4 | "user": "root", 5 | "password": "abc@123" 6 | } 7 | 8 | Cobbler_API = {"url": "http://10.0.0.151/cobbler_api", 9 | "user": "cobbler", 10 | "password": "cobbler" 11 | } 12 | 13 | SALT_API = {"url": "https://10.0.0.151:8000", 14 | "user": "test", 15 | "password": "test" 16 | } 17 | -------------------------------------------------------------------------------- /my_oms/urls.py: -------------------------------------------------------------------------------- 1 | """my_oms URL Configuration 2 | 3 | The `urlpatterns` list routes URLs to views. For more information please see: 4 | https://docs.djangoproject.com/en/1.8/topics/http/urls/ 5 | Examples: 6 | Function views 7 | 1. Add an import: from my_app import views 8 | 2. Add a URL to urlpatterns: url(r'^$', views.home, name='home') 9 | Class-based views 10 | 1. Add an import: from other_app.views import Home 11 | 2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home') 12 | Including another URLconf 13 | 1. Add an import: from blog import urls as blog_urls 14 | 2. Add a URL to urlpatterns: url(r'^blog/', include(blog_urls)) 15 | """ 16 | from django.conf.urls import include, url 17 | from django.contrib import admin 18 | 19 | from asset.views import * 20 | from installed.views import * 21 | from .views import * 22 | from deploy.views import * 23 | 24 | urlpatterns = [ 25 | url(r'^admin/', include(admin.site.urls)), 26 | url(r'^$', index, name='index'), 27 | 28 | # url(r'^$', 'django.contrib.auth.views.login', name='login'), 29 | url(r'^account/', include('account.urls')), 30 | 31 | url(r'^asset/record$', record, name='record'), 32 | url(r'^asset/host_list/$', host_list, name='host_list'), 33 | url(r'^asset/add_host/$', host_list_manage, name='add_host'), 34 | url(r'^asset/host_manage/(?P\d+)/$', host_list_manage, name='host_manage'), 35 | url(r'^asset/delete_host/$', host_list_manage, name='host_delete'), 36 | 37 | url(r'^install/install_list/$', system_install_list, name='install_list'), 38 | url(r'^install/install_manage/(?P\d+)/$', system_install_managed, name='install_manage'), 39 | url(r'^install/install_manage/$', system_install_managed, name='system_manage'), 40 | url(r'^install/system_install/$',system_install, name='system_install'), 41 | url(r'^install/install_record/$',system_install_record, name='install_record'), 42 | 43 | url(r'^deploy/key_list/$', salt_key_list, name='key_list'), 44 | url(r'^deploy/key_delete/$', salt_delete_key, name='delete_key'), 45 | url(r'^deploy/key_accept/$', salt_accept_key, name='accept_key'), 46 | url(r'^deploy/module_deploy/$', module_deploy, name='module_deploy'), 47 | url(r'^deploy/remote_execution/$', remote_execution, name='remote_execution'), 48 | # url(r'^deploy_1/code_deploy/$', code_deploy, name='code_deploy'), 49 | ] 50 | -------------------------------------------------------------------------------- /my_oms/views.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from django.shortcuts import render 3 | from django.contrib.auth.decorators import login_required 4 | 5 | 6 | @login_required() 7 | def index(request): 8 | return render(request, 'index.html') 9 | -------------------------------------------------------------------------------- /my_oms/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for my_oms project. 3 | 4 | It exposes the WSGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/1.8/howto/deployment/wsgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.wsgi import get_wsgi_application 13 | 14 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "my_oms.settings") 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | 组件要求: 2 | 1.Django1.8.X 3 | 2.Cobbler 4 | 3.Saltstack 2015.8.8 5 | 4.Salt API 2015.8.8.2 6 | 5.MySQL-python、MySQL 7 | 6.Python 2.7 8 | 9 | -------------------------------------------------------------------------------- /templates/base.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {% block title %}{% endblock %} 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 35 | 36 | 37 | 38 | 39 | 40 | 41 |
42 |
43 |
44 | 93 |
94 |
95 | {% block content %}{% endblock %} 96 |
97 |
98 |
99 | 100 | 101 | -------------------------------------------------------------------------------- /templates/host_list.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block title %}主机列表{% endblock %} 4 | 5 | 6 | {% block content %} 7 |

添加主机

8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | {% for host in host_list %} 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 37 | 38 | {% endfor %} 39 |
IDIP地址主机名产品应用机柜编号使用状态备注操作
{{ forloop.counter }}{{ host.ip }}{{ host.hostname }}{{ host.product }}{{ host.application }}{{ host.idc_jg }}{{ host.status }}{{ host.remark }}编辑 35 | 删除 36 |
40 | 41 | 42 |
43 | {#
#} 44 | {# #} 45 | {#
#} 46 | 47 |
48 |
49 | 50 | {% if host_list.has_previous %} 51 | 上一页 52 | {% endif %} 53 | 54 | 第{{ host_list.number }}页,共{{ host_list.paginator.num_pages }}页 55 | 56 | {% if host_list.has_next %} 57 | 下一页 58 | {% endif %} 59 |
60 |
61 |
62 | 63 | 64 | {% endblock %} 65 | -------------------------------------------------------------------------------- /templates/host_manage.html: -------------------------------------------------------------------------------- 1 | {% extends "host_list.html" %} 2 | {% block title %}{% endblock %} 3 | {% block content %} 4 | 5 | 6 | 7 |
8 | {% csrf_token %} 9 |
10 | 11 |
12 | {{ form.ip }} 13 | {{ form.ip.errors }} 14 |
15 |
16 |
17 | 18 |
19 | {{ form.hostname }} 20 | {{ form.hostname.errors }} 21 |
22 |
23 |
24 | 25 |
26 | {{ form.product }} 27 | {{ form.product.errors }} 28 |
29 |
30 |
31 | 32 |
33 | {{ form.application }} 34 | {{ form.application.errors }} 35 |
36 |
37 |
38 | 39 |
40 | {{ form.idc_jg }} 41 | {{ form.idc_jg.errors }} 42 |
43 |
44 |
45 | 46 |
47 | {{ form.status }} 48 | {{ form.status.errors }} 49 |
50 |
51 |
52 | 53 |
54 | {{ form.remark }} 55 | {{ form.remark.errors }} 56 |
57 |
58 |
59 | {% ifequal action 'add' %} 60 | 61 | {% endifequal %} 62 | {% ifequal action 'edit' %} 63 | 64 | {% endifequal %} 65 |
66 | 67 |
68 | 69 | 70 | {% endblock %} 71 | -------------------------------------------------------------------------------- /templates/index.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block title %}Dashboard{% endblock %} 4 | 5 | {% block content %} 6 |

欢迎使用我的运维平台

7 |

QQ:419288922

8 | {% endblock %} -------------------------------------------------------------------------------- /templates/install_list.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | {% block title%} 装机列表{% endblock %} 3 | 4 | {% block content %} 5 |

添加系统

6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | {% for system_list in all_system_list %} 20 | 21 | 22 | 23 | 24 | 25 | 26 | 29 | 30 | {% endfor %} 31 | 32 |
IDIP地址主机名MAC地址操作系统操作
{{ forloop.counter }}{{ system_list.ip }}{{ system_list.hostname }}{{ system_list.macaddress }}{{ system_list.system_version }}编辑 27 | 安装 28 |
33 | 34 |
35 | {#
#} 36 | {# #} 37 | {#
#} 38 | 39 |
40 |
41 | {% if all_system_list.has_previous %} 42 | 上一页 43 | {% endif %} 44 | 45 | 第{{ all_system_list.number }}页,共{{ all_system_list.paginator.num_pages }}页 46 | 47 | {% if all_system_list.has_next %} 48 | 下一页 49 | {% endif %} 50 |
51 |
52 |
53 | {% endblock %} -------------------------------------------------------------------------------- /templates/install_manage.html: -------------------------------------------------------------------------------- 1 | {% extends "host_list.html" %} 2 | {% block content %} 3 | 4 | 5 |
6 |
7 |
8 |
9 |
10 | {% csrf_token %} 11 |
12 | 13 |
14 | {{ form.ip }} 15 | {{ form.ip.errors }} 16 |
17 |
18 |
19 | 20 |
21 | {{ form.hostname }} 22 | {{ form.hostname.errors }} 23 |
24 |
25 |
26 | 27 |
28 | {{ form.macaddress }} 29 | {{ form.macaddress.errors }} 30 |
31 |
32 |
33 | 34 |
35 | {{ form.system_version }} 36 | {{ form.system_version.errors }} 37 |
38 |
39 |
40 | 41 |
42 | {{ form.profile }} 43 | {{ form.profile.errors }} 44 |
45 |
46 |
47 | {% ifequal action 'add' %} 48 | 49 | {% endifequal %} 50 | {% ifequal action 'edit' %} 51 | 52 | {% endifequal %} 53 |
54 | 55 | 56 | 57 |
58 | 59 |
60 |
61 |
62 |
63 | 64 | {% endblock %} 65 | -------------------------------------------------------------------------------- /templates/install_record_list.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block title %}系统安装记录{% endblock %} 4 | 5 | {% block content %} 6 |
7 |
8 |
9 |
10 | {% if record %} 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | {% for each_record in record %} 23 | 24 | 25 | 26 | 27 | 28 | 29 | {% endfor %} 30 | 31 |
ID安装时间IP操作系统
{{ forloop.counter }}{{ each_record.install_date }}{{ each_record.ip }}{{ each_record.system_version }}
32 | {% endif %} 33 |
34 | {#
#} 35 | {# #} 36 | {#
#} 37 | 38 |
39 |
40 | {% if record.has_previous %} 41 | 上一页 42 | {% endif %} 43 | 44 | 第{{ record.number }}页,共{{ record.paginator.num_pages }}页 45 | 46 | {% if record.has_next %} 47 | 下一页 48 | {% endif %} 49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 | 57 | {% endblock %} -------------------------------------------------------------------------------- /templates/record.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block title %}审计记录{% endblock %} 4 | 5 | {% block content %} 6 |
7 |
8 |
9 |
10 | {% if message_list %} 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | {% for msg in message_list %} 23 | 24 | 25 | 26 | 27 | 28 | 29 | {% endfor %} 30 | 31 |
类型动作执行主机动作
{{ msg.type }}{{ msg.action }}{{ msg.action_ip }}{{ msg.content }}
32 | {% endif %} 33 |
34 | {#
#} 35 | {# #} 36 | {#
#} 37 | 38 |
39 |
40 | {% if message_list.has_previous %} 41 | 上一页 42 | {% endif %} 43 | 44 | 第{{ message_list.number }}页,共{{ message_list.paginator.num_pages }}页 45 | 46 | {% if message_list.has_next %} 47 | 下一页 48 | {% endif %} 49 |
50 |
51 |
52 | 53 |
54 |
55 |
56 |
57 | {% endblock %} -------------------------------------------------------------------------------- /templates/salt_key_list.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block title %}Salt key管理{% endblock %} 4 | 5 | {% block content %} 6 |
7 |
8 |
9 |
10 |
11 | 12 | 13 | 14 | 15 |
所有salt-key列表
16 |

未允许的key

17 | 18 | 19 | {% for each_pre in all_minions_pre %} 20 | 21 | 23 | {% endfor %} 24 | 25 |
{{ each_pre }}允许
26 |

已管理的key

27 | 28 | 29 | {% for each_minion in all_minions %} 30 | 31 | 32 | 34 | 35 | {% endfor %} 36 | 37 |
{{ each_minion }}删除
38 |
39 |
40 | 42 |
43 |
44 |
45 |
46 |
47 |
48 | 49 |
50 |
51 |
52 |
53 |
54 | {% endblock %} -------------------------------------------------------------------------------- /templates/salt_module_deploy.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | {% block title %}模块部署{% endblock %} 3 | {% block content %} 4 | 5 |
6 |
7 |
8 |
9 |
11 | {% csrf_token %} 12 |
13 | 14 | 15 |
16 | 17 |
18 |
19 |
20 | 21 | 22 |
23 | 25 | 27 | 29 | 31 | 34 | 36 | 38 | 40 |
41 |
42 |
43 | 44 | 45 |
46 | 47 |
48 |
49 |
50 | 51 | 52 |
53 | 54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 | 62 | 63 | {% endblock %} 64 | -------------------------------------------------------------------------------- /templates/salt_remote_execution.html: -------------------------------------------------------------------------------- 1 | {% extends "index.html" %} 2 | {% block title %}远程管理{% endblock %} 3 | {% block content %} 4 |
5 |
6 |
7 |
8 |
10 | {% csrf_token %} 11 |
12 | 13 | 14 |
15 | 16 |
17 |
18 |
19 | 20 | 21 |
22 | 23 |
24 |
25 |
26 |
27 | 28 |
29 |
30 |
31 | 32 | 33 |
34 | 35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 | 43 | 44 | {% endblock %} 45 | --------------------------------------------------------------------------------