diff --git a/README.md b/README.md index 058c66a0..39b14343 100644 --- a/README.md +++ b/README.md @@ -15,9 +15,12 @@ travis & django TestCase
如果你关注:自动化运维、运维资源管理等内容 :star: 我,[分享](http://www.yolovelife.com)给其他的运维人员
如果你关注:django开发、rest-framework等内容 :star: 我,[分享](http://www.yolovelife.com)给其他的开发者
-求求你们 :star: 我吧!!!
+求求你们 :star: 我吧!!!求求你们 :star: 我吧!!!求求你们 :star: 我吧!!!
-*如果您有相关的问题或者建议请在issues和我讨论 :heart: 期待收到您的信息* +*关于我开发中遇到的问题 我会写在issues当中供有需要的朋友 :mag: 查询*
+*这些问题都是在查询了诸多资料并亲身尝试大量解决方案 :grimacing: 最后得出的结论*
+*您可以在issues中搜索question和help wanted查看我写的相关问题*
+*如果未找到您关注的问题或者您对我的项目有建议请在issues和我讨论 :heart: 期待收到您的信息*
## Contents * [介绍](#introduce) diff --git a/apps/deveops/urls.py b/apps/deveops/urls.py index 9ac7e989..38767f75 100644 --- a/apps/deveops/urls.py +++ b/apps/deveops/urls.py @@ -26,19 +26,20 @@ url(r'^404/',views.ErrorView.as_view(),name='404'), url(r'^permission/',views.PermissionView.as_view(),name='permission'), url(r'^validate/', include('validate.urls.views_urls', namespace='validate')), - # url(r'^manager/', include('manager.urls.views_urls', namespace='manager')), - # url(r'^operation/',include('operation.urls.views_urls',namespace='operation')), - # url(r'^timeline/',include('timeline.urls.views_urls',namespace='timeline')), - # url(r'^authority/',include('authority.urls.views_urls',namespace='authority')), - # url(r'^application/',include('application.urls.views_urls',namespace='application')), - # url(r'^concert/',include('concert.urls.views_urls',namespace='concert')), + url(r'^manager/', include('manager.urls.views_urls', namespace='manager')), + url(r'^operation/',include('operation.urls.views_urls',namespace='operation')), + url(r'^timeline/',include('timeline.urls.views_urls',namespace='timeline')), + url(r'^authority/',include('authority.urls.views_urls',namespace='authority')), + url(r'^application/',include('application.urls.views_urls',namespace='application')), + url(r'^concert/',include('concert.urls.views_urls',namespace='concert')), # API - # url(r'^api-manager/', include('manager.urls.api_urls', namespace='api-manager')), - # url(r'^api-operation/',include('operation.urls.api_urls',namespace='api-operation')), - # url(r'^api-authority/',include('authority.urls.api_urls',namespace='api-authority')), - # url(r'^api-application/',include('application.urls.api_urls',namespace='api-application')), - # url(r'^api-concert/',include('concert.urls.api_urls',namespace='api-concert')), + url(r'^api-manager/', include('manager.urls.api_urls', namespace='api-manager')), + url(r'^api-operation/',include('operation.urls.api_urls',namespace='api-operation')), + url(r'^api-authority/',include('authority.urls.api_urls',namespace='api-authority')), + url(r'^api-application/',include('application.urls.api_urls',namespace='api-application')), + url(r'^api-concert/',include('concert.urls.api_urls',namespace='api-concert')), + url(r'^api-execute/',include('execute.urls.api_urls',namespace='api-execute')), ] ''' diff --git a/apps/execute/api.py b/apps/execute/api.py new file mode 100644 index 00000000..d27d43ee --- /dev/null +++ b/apps/execute/api.py @@ -0,0 +1,16 @@ +# -*- coding:utf-8 -*- +import models,serializers +from rest_framework import generics +from rest_framework.permissions import IsAuthenticated +from execute.service.catch.basic import BasicAnsibleService +from operation.models import PlayBook +from manager.models import Host +from service.catch.basic import BasicAnsibleService +class UpdateHostAPI(generics.ListAPIView): + serializer_class = serializers.ExecuteSerializer + permission_classes = [IsAuthenticated] + def get(self, request, *args, **kwargs): + host = Host.objects.get(id=self.kwargs['pk']) + playbook = PlayBook.objects.get(id=1) + bas = BasicAnsibleService(hostlist=[host]) + bas.run(tasklist=playbook.tasks.all().order_by('-sort'),hostlist=[host]) \ No newline at end of file diff --git a/apps/execute/callback/__init__.py b/apps/execute/callback/__init__.py index 06906586..b8ae2f62 100644 --- a/apps/execute/callback/__init__.py +++ b/apps/execute/callback/__init__.py @@ -41,4 +41,7 @@ def v2_runner_on_unreachable(self, result): # str="h:%s r:unreach module:%s arvg:%s"%(host,json.dumps(result._result['invocation']["module_name"]),json.dumps(result._result['invocation']["module_args"])) # print(str) # print(json.dumps(result._result)) - return super(ResultCallback,self).v2_runner_on_unreachable(result) \ No newline at end of file + return super(ResultCallback,self).v2_runner_on_unreachable(result) + + def ResultExtract(self): + pass \ No newline at end of file diff --git a/apps/execute/callback/catch/basic.py b/apps/execute/callback/catch/basic.py index e36467ed..0d94df9a 100644 --- a/apps/execute/callback/catch/basic.py +++ b/apps/execute/callback/catch/basic.py @@ -8,6 +8,10 @@ class BasicResultCallback(ResultCallback): def v2_runner_on_ok(self, result, **kwargs): c = Callback() c.info=json.dumps(result._result) - c.history = History.objects.get(id=1) + self.result = result._result c.save() - return c.id \ No newline at end of file + self.c = c + return + + def ResultExtract(self): + return self.result['stdout_lines'] \ No newline at end of file diff --git a/apps/execute/serializers.py b/apps/execute/serializers.py new file mode 100644 index 00000000..fc8e69f3 --- /dev/null +++ b/apps/execute/serializers.py @@ -0,0 +1,6 @@ +import models +from rest_framework import serializers +class ExecuteSerializer(serializers.HyperlinkedModelSerializer): + class Meta: + model = models.Callback + fields = ('id') \ No newline at end of file diff --git a/apps/execute/service/__init__.py b/apps/execute/service/__init__.py index e934c0d5..ddd2fff0 100644 --- a/apps/execute/service/__init__.py +++ b/apps/execute/service/__init__.py @@ -1,26 +1,33 @@ # -*- coding:utf-8 -*- -from inventory.maker import Maker from yosible.tasks.tasks import Task from yosible.run.ansiblerun import Ansible from yosible.run.playbook import Playbook from yosible.tasks.tasks import Tasks +from operation.models import Script +__metaclass__ = type class AnsibleService(): - def __init__(self,name): - self.ansible = Ansible() - self.maker = Maker() - self.playbook = Playbook(pbname=name,pbfacts='no') + def __init__(self,filename): + self.ansible = Ansible(filename) + self.playbook = Playbook(pbname='null',pbfacts='no') self.tasks = Tasks() self.push_tasks() self.push_playbook() - def run(self,hostlist,tasklist): + def run(self,tasklist,maker): for task in tasklist : t = Task(module = task.module,args=task.args) + #如果为脚本 则单独将脚本文件写出来 + if task.module == u'script': + script = Script.objects.get(id=int(str(task.args))) + t.args = maker.script_maker(script_id=str(script.id),script=script.formatScript()) self.tasks.push_task(t) + result = self.ansible.run_playbook() + maker.inventory_clear() - self.maker.inventory_maker(hostlist) - self.ansible.run_playbook() - return + return result + + def push_makername(self): + return self.maker.filename def push_tasks(self): self.playbook.push_tasks(self.tasks) diff --git a/apps/execute/service/catch/basic.py b/apps/execute/service/catch/basic.py index 7ce17780..2a2219e1 100644 --- a/apps/execute/service/catch/basic.py +++ b/apps/execute/service/catch/basic.py @@ -1,14 +1,28 @@ # -*- coding:utf-8 -*- from execute.service import AnsibleService from execute.callback.catch import basic - +from execute.models import Callback +from inventory.maker import Maker +__metaclass__ = type class BasicAnsibleService(AnsibleService): - - def __init__(self,name): - super(BasicAnsibleService,self).__init__(self,name) + def __init__(self,hostlist): + maker = Maker() + self.maker = maker + self.maker.inventory_maker(hostlist) + super(BasicAnsibleService,self).__init__(maker.filename) def run(self,hostlist,tasklist): - self.push_callback(basic.BasicResultCallback()) - return super(BasicAnsibleService,self).run(hostlist,tasklist) + callback = basic.BasicResultCallback() + self.push_callback(callback) + super(BasicAnsibleService,self).run(tasklist,self.maker) + list = callback.ResultExtract() + self.update(list,hostlist) + def update(self,list,hostlist): + for host in hostlist: + host.coreness = list[0] + host.memory = list[1] + host.root_disk = list[2] + host.hostname = list[3] + host.save() diff --git a/apps/execute/urls/__init__.py b/apps/execute/urls/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/apps/execute/urls/api_urls.py b/apps/execute/urls/api_urls.py new file mode 100644 index 00000000..b83a33a1 --- /dev/null +++ b/apps/execute/urls/api_urls.py @@ -0,0 +1,6 @@ +from django.conf.urls import url +from .. import api +urlpatterns=[ + # Resource update api + url(r'^v1/update/host/(?P[0-9]+)/', api.UpdateHostAPI.as_view()), +] \ No newline at end of file diff --git a/apps/execute/urls/views_urls.py b/apps/execute/urls/views_urls.py new file mode 100644 index 00000000..8482133f --- /dev/null +++ b/apps/execute/urls/views_urls.py @@ -0,0 +1,11 @@ +# -*- coding:utf-8 -*- +# !/usr/bin/env python +# Time 10 15:38 +# Author Yo +# Email YoLoveLife@outlook.com +from django.conf.urls import url +from ..views import group,host,storage,dashboard +urlpatterns = [ + #Resource dashboard url + # url(r'^dashboard/$', dashboard.ManagerDashboardView.as_view(), name='dashboard'), +] \ No newline at end of file diff --git a/apps/manager/api.py b/apps/manager/api.py index b1b317e1..1d09e7b8 100644 --- a/apps/manager/api.py +++ b/apps/manager/api.py @@ -2,7 +2,6 @@ import models,serializers from rest_framework import generics from rest_framework.permissions import IsAuthenticated -from execute.service.catch.basic import BasicAnsibleService class GroupListAPI(generics.ListAPIView): module = models.Group serializer_class = serializers.GroupSerializer @@ -23,17 +22,6 @@ def get_queryset(self): queryset=models.Group.objects.get(id=self.kwargs['pk']).hosts return queryset -class HostFlushAPI(generics.ListAPIView): - serializer_class = serializers.HostSerializer - permission_classes = [IsAuthenticated] - def get(self, request, *args, **kwargs): - host = models.Host.objects.get(id=self.kwargs['pk']) - - bas = BasicAnsibleService('update host') - bas.run(hostlist=[host],tasklist=[]) - return self.list(request, *args, **kwargs) - - class StorageListAPI(generics.ListAPIView): module = models.Storage serializer_class = serializers.StorageSerializer diff --git a/apps/manager/templates/manager/host.html b/apps/manager/templates/manager/host.html index 8c07dcc6..4b8c7f91 100644 --- a/apps/manager/templates/manager/host.html +++ b/apps/manager/templates/manager/host.html @@ -50,6 +50,7 @@

主机列表

服务器位置 用途 细节 + 刷新 @@ -100,6 +101,10 @@

主机信息

var label_a=''+''+''; return [label_a].join(''); } + function flushFormatter(value,row,index) { + var label_a=''+''+''; + return [label_a].join(''); + } $(document).ready(function () { $('.select2').select2(); var table=$('#host_tb').bootstrapTable({ diff --git a/apps/manager/urls/api_urls.py b/apps/manager/urls/api_urls.py index 14ec1e07..cb2fb95f 100644 --- a/apps/manager/urls/api_urls.py +++ b/apps/manager/urls/api_urls.py @@ -6,7 +6,6 @@ # Resource host api url(r'^v1/hostbygroup/(?P[0-9]+)',api.HostListByGroupAPI.as_view()), - url(r'^v1/hostflush/(?P[0-9]+)',api.HostFlushAPI.as_view()), # Resource storage api url(r'^v1/storage/', api.StorageListAPI.as_view()), diff --git a/apps/operation/__init__.py b/apps/operation/__init__.py index 7b8a8230..ba7f17dd 100644 --- a/apps/operation/__init__.py +++ b/apps/operation/__init__.py @@ -1,4 +1,4 @@ -MUDULE_OPTION = { +MODULE_OPTION = { '0':'none', '1': 'shell', '2': 'copy', diff --git a/apps/operation/models.py b/apps/operation/models.py index 90487452..017f954b 100644 --- a/apps/operation/models.py +++ b/apps/operation/models.py @@ -25,7 +25,6 @@ def formatScript(self): kwargs[args.args_name] = args.args_value string = string + utils.bash_writer(self.author.email,'now',**kwargs) string = string + utils.html2bash(self.script) - print(string) return string class ScriptArgs(models.Model): @@ -55,7 +54,7 @@ class PlayBook(models.Model): class Task(models.Model): id = models.AutoField(primary_key=True) - mudule = models.CharField(default='hostname',max_length=20) + module = models.CharField(default='hostname',max_length=20) args = models.CharField(default='',max_length=100) sort = models.IntegerField(default=0) playbook = models.ForeignKey(PlayBook,default=1,related_name='tasks') diff --git a/apps/operation/serializers.py b/apps/operation/serializers.py index 6c694170..b3504cfe 100644 --- a/apps/operation/serializers.py +++ b/apps/operation/serializers.py @@ -25,4 +25,4 @@ class Meta: class TaskSerializer(serializers.HyperlinkedModelSerializer): class Meta: model = models.Task - fields= ('id','mudule','args','sort') + fields= ('id','module','args','sort') diff --git a/apps/operation/templates/operation/module/copy.html b/apps/operation/templates/operation/module/copy.html index bc1732dd..ac2f6f4b 100644 --- a/apps/operation/templates/operation/module/copy.html +++ b/apps/operation/templates/operation/module/copy.html @@ -9,8 +9,8 @@
- - + +
diff --git a/apps/operation/templates/operation/module/file.html b/apps/operation/templates/operation/module/file.html index 8cdf0818..3e6297fb 100644 --- a/apps/operation/templates/operation/module/file.html +++ b/apps/operation/templates/operation/module/file.html @@ -8,8 +8,8 @@
- - + +
diff --git a/apps/operation/templates/operation/module/script.html b/apps/operation/templates/operation/module/script.html index 99b4a564..fd85a447 100644 --- a/apps/operation/templates/operation/module/script.html +++ b/apps/operation/templates/operation/module/script.html @@ -9,8 +9,8 @@
- - + +
diff --git a/apps/operation/templates/operation/module/service.html b/apps/operation/templates/operation/module/service.html index 45cc56ef..d783ce16 100644 --- a/apps/operation/templates/operation/module/service.html +++ b/apps/operation/templates/operation/module/service.html @@ -9,8 +9,8 @@
- - + +
diff --git a/apps/operation/templates/operation/module/shell.html b/apps/operation/templates/operation/module/shell.html index 7869af30..c5358a52 100644 --- a/apps/operation/templates/operation/module/shell.html +++ b/apps/operation/templates/operation/module/shell.html @@ -9,8 +9,8 @@
- - + +
diff --git a/apps/operation/templates/operation/module/yum.html b/apps/operation/templates/operation/module/yum.html index 4171c7d2..33191377 100644 --- a/apps/operation/templates/operation/module/yum.html +++ b/apps/operation/templates/operation/module/yum.html @@ -9,8 +9,8 @@
- - + +
diff --git a/apps/operation/templates/operation/new_update_playbook.html b/apps/operation/templates/operation/new_update_playbook.html index 4de3bb71..1b8a1cbc 100644 --- a/apps/operation/templates/operation/new_update_playbook.html +++ b/apps/operation/templates/operation/new_update_playbook.html @@ -77,7 +77,7 @@

剧本内容

# 剧本顺序 - 模块名称 + 模块名称 模块参数 diff --git a/apps/operation/utils/utils.py b/apps/operation/utils/utils.py index 5b2a0235..a2a70ba9 100644 --- a/apps/operation/utils/utils.py +++ b/apps/operation/utils/utils.py @@ -39,5 +39,5 @@ def html2bash(str): if __name__ == "__main__": kwargs={} print(bash_writer(author='Yo',time='2017-8-11 16:44:13',**kwargs)) - string = "

#!/bin/bash
# Time 2017-9-12 17:32:27
# Author Yo
# Github github.com/YoLoveLife/scrRipt
# processor

hostname
cat /proc/cpuinfo |grep processor|wc -l
free -m|sed -n '2p' |awk '{ print $2 }'
df -h |grep '/$' |awk '{ print $2 }'

" + string = "

hostname
cat /proc/cpuinfo |grep processor|wc -l
free -m|sed -n '2p' |awk '{ print $2 }'
df -h |grep '/$' |awk '{ print $2 }'

" print(html2bash(string)) \ No newline at end of file diff --git a/apps/operation/views/playbook.py b/apps/operation/views/playbook.py index c1f853f3..641fbce0 100644 --- a/apps/operation/views/playbook.py +++ b/apps/operation/views/playbook.py @@ -9,7 +9,7 @@ from django.views.generic import TemplateView from django.views.generic.edit import CreateView,UpdateView from django.views.generic.detail import DetailView -from .. import MUDULE_OPTION +from .. import MODULE_OPTION class OperationPlaybookListView(LoginRequiredMixin,TemplateView): template_name= 'operation/playbook.html' @@ -88,7 +88,7 @@ def get_context_data(self, **kwargs): context.update({ 'scripts' : scripts }) - self.template_name = self.template_dir + MUDULE_OPTION[module]+self.postfix + self.template_name = self.template_dir + MODULE_OPTION[module]+self.postfix return context def get(self,request,*args, **kwargs): diff --git a/inventory/maker.py b/inventory/maker.py index 1b582947..8f151864 100644 --- a/inventory/maker.py +++ b/inventory/maker.py @@ -5,17 +5,17 @@ # Email YoLoveLife@outlook.com import os import time -FILE=r"/tmp/ansible.host" -DIR = r"/tmp/%s" +FILENAME = r"/tmp/%s%s" SSHPORT = "ansible_ssh_port=" SSHUSER = "ansible_ssh_user=" SUDOPASS = "ansible_sudo_pass=" class Maker(): def __init__(self): - self.filename=DIR%str(time.time()) + self.timestamp = str(time.time()) + self.filename=FILENAME%(self.timestamp,'') def set_filename(self,filename): - self.filename=DIR%filename + self.filename=FILENAME%(filename,'') def inventory_maker(self,hosts): if os.path.exists(self.filename): @@ -33,4 +33,15 @@ def inventory_maker(self,hosts): def inventory_clear(self): if os.path.exists(self.filename): os.remove(self.filename) - return self.filename \ No newline at end of file + return self.filename + + def script_maker(self,script_id,script): + if os.path.exists(self.filename): + os.remove(self.filename) + script_name = FILENAME%(self.timestamp,'-'+script_id) + output = open(script_name,'w') + output.writelines(script) + output.close() + return script_name + + diff --git a/yosible/run/ansiblerun.py b/yosible/run/ansiblerun.py index cc31ffe2..f96cbfb5 100644 --- a/yosible/run/ansiblerun.py +++ b/yosible/run/ansiblerun.py @@ -9,13 +9,13 @@ from yosible.vars.args import option, HOST_LIST class Ansible(): - def __init__(self): + def __init__(self,host_file): self.options = option self.variable_manager = VariableManager() self.loader = DataLoader() self.passwords = dict(vault_pass='') self.results_callback = ResultCallback() - self.inventory = Inventory(loader=self.loader, variable_manager=self.variable_manager, host_list=HOST_LIST) + self.inventory = Inventory(loader=self.loader, variable_manager=self.variable_manager, host_list=host_file) self.variable_manager.set_inventory(self.inventory) def add_extendvars(self,newext): @@ -27,10 +27,12 @@ def set_playbook(self,pb): def set_callback(self,callback): self.results_callback = callback + def run_playbook(self): tqm=pop_TaskqueueManager(self) try: result =tqm.run(Play().load(self.playbook.pop_playbook())) + return result finally: if tqm is not None: tqm.cleanup()