前言:运维开发建立于Iaas的蓝鲸之上,采用python作为开发语言,结合angularJS+django框架,mysql为数据库。
第一步:获取框架模板(系统获取来自于蓝鲸智云企业版-->开发者中心-->模板获取)
第二步:数据库的创建
class openStack_list(models.Model):
name = models.CharField(max_length=100)
created_by = models.CharField(max_length=100)
openStack_ip = models.CharField(max_length=100)
openStack_user = models.CharField(max_length=100)
openStack_pwd = models.CharField(max_length=100)
when_created = models.CharField(max_length=100, null=True, default="")
sync_status = models.CharField(max_length=100, default="", null=True)
# 同步状态:not_sync,syncing,sync_success,sync_fail
last_synctime = models.CharField(max_length=100, null=True, default="")
def toDic(self):
return dict([(attr, getattr(self, attr)) for attr in [f.name for f in self._meta.fields]])
创建完成后执行python manage.py makemigrations 和python manage.py migrate
python manage.py makemigrations这个命令是记录我们对models.py的所有改动,并且将这个改动迁移到migrations这个文件下生成一个文件例如:0001文件
python manage.py migrate 命令时 这条命令的主要作用就是把这些改动作用到数据库也就是执行migrations里面新改动的迁移文件更新数据库,比如创建数据表,或者增加字段属性
第三步:代码编写
site.js
{
displayName: "系统管理", iconClass: "fa fa-cogs fa-lg",
children: [
{displayName: "账号管理", url: "#/accountManagement"},
{displayName: "邮箱管理", url: "#/mailManagement"},
{displayName: "日志管理", url: "#/logManagement"}
]
}
//每段导航模块前面要加逗号作为分割
init.js
.state('accountManagement', {
url: "/accountManagement",
controller: "accountManagement",
templateUrl: static_url + "client/views/os_management/accountManagement.html"
})
.state('mailManagement', {
url: "/mailManagement",
controller: "mailManagement",
templateUrl: static_url + "client/views/os_management/mailManagement.html"
})
.state('logManagement', {
url: "/logManagement",
controller: "logManagement",
templateUrl: static_url + "client/views/os_management/logManagement.html"
})
//分别为每个模块设置跳转url
accountManagement.html(相同内容的页面和控制器分别放在一个文件夹中)
<div style="width: 100%; overflow-y: auto;min-height: 300px; padding: 5px;margin-top: 5px;">
<--嵌套式模块 每次刷新页面都会将所要加载的DIV模块加载到主页面的内容中-->
<div class="fieldset mb10" style="padding-top:5px;padding-bottom: 5px;">
<div class="legend">查询条件</div>
<div class="container-fluid" style="margin-top: 10px">
<div class="form-group" style="float:left;margin-left: 10px;">
<label style="float: left;margin-top: 5px">openstack服务器名:</label>
<input ng-model="args.openStack_name" type="text" style="width:150px;height: 30px;" class="form-control"/>
<--ng-model="args.openStack_name" 和控制台的数据进行绑定的标签-->
</div>
<div class="form-group" style="float:left;margin-left: 10px;">
<label style="float: left;margin-top: 5px">IP地址:</label>
<input ng-model="args.openStack_ip" type="text" style="width:150px;height: 30px;" class="form-control"/>
<!--span ng-if=" " class="text-danger">{{ ip_error }}</span-->
</div>
<div style="float: left;margin-left: 20px;">
<button ng-click="search_openStack()" class="king-btn-demo king-btn king-primary">
搜索
</button>
<--ng-click="search_openStack()" 跳转到对应控制模块中的函数方法的标签-->
</div>
<div style="float: right;margin-right: 20px">
<button class="king-btn-demo king-btn king-primary" ng-click="add_openStack()">
添加openStack服务器配置
</button>
</div>
</div>
</div>
<div style="width:100%;overflow-y: auto;overflow-x: hidden;">
<div ng-grid="gridOption" cw-adaptbody="108"
style="margin-top: 5px;overflow-y: auto;overflow-x: hidden;"></div>
</div>
<--ng-grid="gridOption" table标签 由控制模块创建后会再此生成对应的表格-->
</div>
accountManagement.js(html页面对应的js)
controllers.controller('accountManagement', ["$scope","$modal","sysService", "loading", "errorModal","confirmModal",
function ($scope, $modal,sysService, loading, errorModal,confirmModal) {
//上面的都是服务、内置的和自定义的服务
$scope.openstack_server_list = [];
$scope.args = {
openStack_name: "",
openStack_ip: ""
}
//数据绑定:前端的数据一致性
// $scope.is_syncing = false;
//显示
$scope.search_openStack = function () {
//loading服务,用于加载较长的数据添加等待功能
// loading.open();
//通过定义服务方法从而找到.py文件的控制层方法(参数分别为:传递方式get/post/body、数据、返回值)
sysService.search_openStack({}, $scope.args, function (res) {
//等待取消
// loading.close();
$scope.openstack_server_list = res.data;
$scope.pagingOptions.currentPage = 1;
$scope.getPagedDataAsync($scope.pagingOptions.pageSize, $scope.pagingOptions.currentPage);
// if ($scope.is_syncing)
// setTimeout($scope.search_openStack, 2000);
})
};
//自动0.1s的间隔刷新显示
setTimeout($scope.search_openStack, 100);
//添加
$scope.add_openStack = function () {
//1.请求跳转到添加页面,定义了跳转url,样式,控制器名,是否锁定点击其他位置
var modalInstance = $modal.open({
templateUrl: static_url + 'client/views/os_management/accountManagement_add.html',
windowClass: 'dialog_custom',
controller: 'accountManagement_add',
backdrop: 'static'
});
//3.返回数据进行分页显示处理
modalInstance.result.then(function (res) {
$scope.openstack_server_list.unshift(res);
$scope.getPagedDataAsync($scope.pagingOptions.pageSize, $scope.pagingOptions.currentPage);
})
};
//修改模块
$scope.modify_openStack = function (row) {
var modalInstance = $modal.open({
templateUrl: static_url + 'client/views/os_management/accountManagement_add.html',
windowClass: 'dialog_custom',
controller: 'accountManagement_modify',
backdrop: 'static',
resolve: {
objectItem: function () {
return row.entity;
}
}
});
modalInstance.result.then(function (res) {
row.entity.name = res.openStack_name;
row.entity.openStack_ip = res.openStack_ip;
row.entity.openStack_user = res.openStack_user;
row.entity.openStack_pwd = res.openStack_pwd;
})
};
//删除模块
$scope.delete_openStack = function (row) {
var id = row.entity.id;
confirmModal.open({
text: "确认删除openStack服务器配置吗?",
confirmClick: function () {
sysService.delete_openStack({id: id}, {}, function (res) {
if (res.result) {
$scope.openstack_server_list.splice(row.rowIndex, 1);
$scope.getPagedDataAsync($scope.pagingOptions.pageSize, $scope.pagingOptions.currentPage);
}
})
}
})
};
//分页
$scope.Pagingdata = [];
$scope.totalSerItems = 0;
$scope.pagingOptions = {
pageSizes: [5, 10, 25, 50, 100],
pageSize: 10,
currentPage: 1
};
$scope.getPagedDataAsync = function (pageSize, page) {
$scope.setPagingData($scope.openstack_server_list ? $scope.openstack_server_list : [], pageSize, page);
};
$scope.setPagingData = function (data, pageSize, page) {
$scope.Pagingdata = data.slice((page - 1) * pageSize, page * pageSize);
$scope.totalSerItems = data.length;
if (!$scope.$$phase) {
$scope.$apply();
}
};
$scope.$watch('pagingOptions', function (newVal, oldVal) {
$scope.getPagedDataAsync($scope.pagingOptions.pageSize, $scope.pagingOptions.currentPage);
}, true);
//表格
$scope.gridOption = {
data: "Pagingdata",
enablePaging: true,
showFooter: true,
pagingOptions: $scope.pagingOptions,
totalServerItems: 'totalSerItems',
columnDefs: [
{field: 'name', displayName: 'openStack服务器名', cellClass: 'textAlignCenter'},
{field: 'openStack_ip', displayName: 'IP地址', cellClass: 'textAlignCenter'},
{field: 'created_by', displayName: '添加者', cellClass: 'textAlignCenter'},
{field: 'when_created', displayName: '添加时间', cellClass: 'textAlignCenter'},
{field: 'last_synctime', displayName: '上一次成功同步时间', cellClass: 'textAlignCenter'},
{field: 'sync_status', displayName: '同步状态', cellClass: 'textAlignCenter'},
{
displayName: '操作', width: 180,
cellTemplate: "<div style='width:100%;padding-top: 5px;text-align:center'>" +
"<span title='同步' style='cursor: pointer;color: #254eaf' class='fa fa-refresh fa-lg onoperate' ng-click='sync_vc(row)'></span> " +
"<span title='编辑' style='cursor: pointer;color: #254eaf' class='fa fa-pencil-square-o fa-lg onoperate' ng-click='modify_openStack(row)'></span> " +
"<span title='删除' style='cursor: pointer;color: #d15b47 !important;' class='fa fa-trash fa-lg onoperate' ng-click='delete_openStack(row)'></span></div>"
}
]
};
}]);
Services.js(配置服务信息)
services = angular.module('webApiService', ['ngResource', 'utilServices']);
//生产代码
var POST = "POST";
var GET = "GET";
//测试代码
//var sourceRoute = "./Client/MockData";
//var fileType = ".html";
//var POST = "GET";
//var GET = "GET";
services.factory('sysService', ['$resource', function ($resource) {
return $resource(site_url + ':actionName/', {},
{
search_data:{method: POST, params: {actionName: 'search_data'}, isArray: false},
get_list:{method: POST, params: {actionName: 'get_data'}, isArray: false},
get_image:{method: POST, params: {actionName: 'get_image'}, isArray: false},
search_image:{method: POST, params: {actionName: 'search_image'}, isArray: false},
//定义服务方法,实现代码复用的功能
add_openStack: {method: POST, params: {actionName: 'add_openStack'}, isArray: false},
modify_openStack: {method: POST, params: {actionName: 'modify_openStack'}, isArray: false},
search_openStack: {method: POST, params: {actionName: 'search_openStack'}, isArray: false},
delete_openStack: {method: POST, params: {actionName: 'delete_openStack'}, isArray: false},
});
}])
;//这是结束符,请勿删除
accountManagement_add.html(数据添加页面)
<div>
<div dragable dialog-title="{{ title }}"></div>
<div style="width: 100%;padding: 20px 0 20px 40px;">
<div class="form-horizontal">
<div class="form-group">
<label class="col-sm-3 control-label">服务器名:</label>
<div class="col-sm-8">
<input class="form-control" style="width: 220px;" ng-model="args.openStack_name" input-hint="请输入服务器名称">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">IP地址:</label>
<div class="col-sm-8">
<input class="form-control" style="width: 220px;" ng-change="changeIp()" ng-model="args.openStack_ip"
input-hint="请输入ip地址">
<span ng-if="isShowIpError" class="text-danger">IP格式不正确!</span>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">用户名:</label>
<div class="col-sm-8">
<input class="form-control" style="width: 220px;" ng-model="args.openStack_user" input-hint="请输入用户名">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">密码:</label>
<div class="col-sm-8">
<input ng-disabled="isPwdNoChange" class="form-control" type="password" style="width: 220px;padding:6px 12px;display: inline-block;" ng-model="args.openStack_pwd" input-hint="请输入用户密码">
<span ng-if="isModify" ng-click="openChange()" style="cursor: pointer" class="fa fa-lg fa-pencil"></span>
</div>
</div>
</div>
<div style="text-align: center;margin-top: 10px;">
<button class="king-btn king-primary king-btn-small" ng-click="confirm()">
确认
</button>
<button style="margin-left: 20px;" class="king-btn-small king-btn king-default" ng-click="cancel()">
取消
</button>
</div>
</div>
</div>
accountManagement.js(对应accountManagement.html的控制器)
controllers.controller("accountManagement_add", ["$scope","$modalInstance","sysService","loading","msgModal","errorModal",
function ($scope,$modalInstance,sysService,loading,msgModal,errorModal) {
$scope.title = "添加openStack服务器配置"
$scope.args = {
openStack_name: "",
openStack_ip: "",
openStack_user: "",
openStack_pwd: ""
}
$scope.confirm = function () {
var errors = validateObj();
if (errors.length > 0) {
errorModal.open(errors);
return;
}
loading.open();
sysService.add_openStack({}, $scope.args, function (res) {
loading.close();
if (res.result) {
//2.将数据返回进行处理
$modalInstance.close(res.data);
}
else{
errorModal.open(res.data);
}
})
};
$scope.cancel = function () {
$modalInstance.dismiss("cancel");
};
$scope.isShowIpError = false;
$scope.changeIp = function () {
if (!CWApp.isIP($scope.args.openStack_ip)) {
$scope.isShowIpError = true;
}
else
$scope.isShowIpError = false;
};
var validateObj = function () {
var errors = [];
if ($scope.args.openStack_name == "" || $scope.args.openStack_user == "" || $scope.args.openStack_pwd == "") {
errors.push("请填写完整相关信息!");
}
else if (!CWApp.isIP($scope.args.openStack_ip)) {
errors.push("IP格式不正确!");
}
return errors;
}
}]);
urls.py(python和js相互匹配的配置)
# -*- coding: utf-8 -*-
from django.conf.urls import patterns
urlpatterns = patterns(
'home_application.views',
# 首页--your index
(r'^$', 'home'),
(r'^search_data$', 'search_data'),
(r'^get_data$', 'get_data'),
(r'^get_token$', 'get_token'),
(r'^db_update$', 'db_update'),
(r'^get_detail_data$', 'get_detail_data'),
(r'^vm_details$', 'vm_details'),
(r'^get_image$', 'get_image'),
(r'^search_image$', 'search_image'),
#系统管理
(r'^add_openStack$', 'add_openStack'),
(r'^search_openStack$', 'search_openStack'),
(r'^modify_openStack$', 'modify_openStack'),
(r'^delete_openStack$', 'delete_openStack'),
)
os_management.py(python后台)
# -*-coding:utf-8-*-
import datetime
from cmath import e
# from django.core.serializers import json
from django.db.models import Q
from common.log import logger
from common.mymako import render_json
from home_application.models import openStack_list
from aes_helper import *
import json
#新增openStack账号信息
def add_openStack(request):
//获取js中传递过来的参数json.loads(request.body) 同样作用
args = eval(request.body)
openstack_name = args["openStack_name"]
openstack_ip = args["openStack_ip"]
openstack_user = args["openStack_user"]
openstack_pwd = args["openStack_pwd"]
try:
//标志位 是否存在此条数据 数据库查找
openStack_len = openStack_list.objects.filter(Q(name=openstack_name) | Q(openStack_ip=openstack_ip)).count()
if openStack_len:
return render_json({"result": False, "data": [u"该openStack已存在,请检查名称或IP"]})
//获取当前登陆的用户名
current_user = request.user.username
//获取时间
now = str(datetime.datetime.now()).split('.')[0]
//数据库添加数据
openstack_date = openStack_list.objects.create(name=openstack_name, openStack_ip=openstack_ip, openStack_user=openstack_user,
openStack_pwd=openstack_pwd,
created_by=current_user, when_created=now)
//返回结果给js控制层
return render_json({'result': True, "data": openstack_date.toDic()})
except Exception, e:
logger.error(e.message)
return render_json({"result": False, "data": e.message})
accountManagement.js
$scope.add_openStack = function () {
var modalInstance = $modal.open({
templateUrl: static_url + 'client/views/os_management/accountManagement_add.html',
windowClass: 'dialog_custom',
controller: 'accountManagement_add',
backdrop: 'static'
});
//返回结果进行分页显示返回前端
modalInstance.result.then(function (res) {
$scope.openstack_server_list.unshift(res);
$scope.getPagedDataAsync($scope.pagingOptions.pageSize, $scope.pagingOptions.currentPage);
})
};
全部逻辑结束end。