Operation and maintenance development is based on the blue whale of Iaas, using python as the development language, combining angularJS+django framework, mysql as the database.
Step 1: get the framework template (system get from Blue whale smart cloud Enterprise Edition -->Developer Center > template acquisition)
Step 2: create database
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) # Synchronization status: 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]])
Execute Python manage.py-makemigrations and python manage.py-migrate after creation
python manage.py makemigrations this command records all our changes to models.py, and migrates the changes to the migrations file to generate a file, for example: 0001 file
When executing the python manage.py migrate command, the main function of this command is to apply these changes to the database, that is, to update the database by executing the newly changed migration files in migrations, such as creating data tables or adding field attributes
Step 3: Code
site.js
{ displayName: "system management", iconClass: "fa fa-cogs fa-lg", children: [ {displayName: "account management", url: "#/accountManagement"}, {displayName: "Mailbox Management", url: "#/mailManagement"}, {displayName: "Log management", url: "#/logManagement"} ] } //Each navigation module should be separated by commas
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" }) //Set the jump url for each module separately
accountManagement.html (pages with the same content and controllers are placed in a folder)
<div style="width: 100%; overflow-y: auto;min-height: 300px; padding: 5px;margin-top: 5px;"> <--The nested module will load the DIV Module loaded into main page content--> <div class="fieldset mb10" style="padding-top:5px;padding-bottom: 5px;"> <div class="legend">query criteria</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 Server name:</label> <input ng-model="args.openStack_name" type="text" style="width:150px;height: 30px;" class="form-control"/> <--ng-model="args.openStack_name" Tags bound to console data--> </div> <div class="form-group" style="float:left;margin-left: 10px;"> <label style="float: left;margin-top: 5px">IP Address:</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"> search </button> <--ng-click="search_openStack()" Label to jump to the function method in the corresponding control module--> </div> <div style="float: right;margin-right: 20px"> <button class="king-btn-demo king-btn king-primary" ng-click="add_openStack()"> Add to openStack Server configuration </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 The corresponding table will be generated after the label is created by the control module--> </div>
accountManagement.js (JS corresponding to html page)
controllers.controller('accountManagement', ["$scope","$modal","sysService", "loading", "errorModal","confirmModal", function ($scope, $modal,sysService, loading, errorModal,confirmModal) { //Above are services, built-in and custom services $scope.openstack_server_list = []; $scope.args = { openStack_name: "", openStack_ip: "" } //Data binding: data consistency on the front end // $scope.is_syncing = false; //display $scope.search_openStack = function () { //loading service, used to load long data adding waiting function // loading.open(); //Find the control layer method of. py file by defining the service method (parameters are: transfer method get/post/body, data, return value) sysService.search_openStack({}, $scope.args, function (res) { //Waiting for cancellation // 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); }) }; //Refresh display automatically at 0.1s interval setTimeout($scope.search_openStack, 100); //Add to $scope.add_openStack = function () { //1. Request to jump to the add page, define the jump url, style, controller name, and whether to lock and click other locations var modalInstance = $modal.open({ templateUrl: static_url + 'client/views/os_management/accountManagement_add.html', windowClass: 'dialog_custom', controller: 'accountManagement_add', backdrop: 'static' }); //3. Return data for pagination display modalInstance.result.then(function (res) { $scope.openstack_server_list.unshift(res); $scope.getPagedDataAsync($scope.pagingOptions.pageSize, $scope.pagingOptions.currentPage); }) }; //Modify module $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; }) }; //remove module $scope.delete_openStack = function (row) { var id = row.entity.id; confirmModal.open({ text: "confirm deletion openStack Server configuration?", 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); } }) } }) }; //paging $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); //form $scope.gridOption = { data: "Pagingdata", enablePaging: true, showFooter: true, pagingOptions: $scope.pagingOptions, totalServerItems: 'totalSerItems', columnDefs: [ {field: 'name', displayName: 'openStack server name', cellClass: 'textAlignCenter'}, {field: 'openStack_ip', displayName: 'IP address', cellClass: 'textAlignCenter'}, {field: 'created_by', displayName: 'Additive', cellClass: 'textAlignCenter'}, {field: 'when_created', displayName: 'Adding time', cellClass: 'textAlignCenter'}, {field: 'last_synctime', displayName: 'Last successful synchronization time', cellClass: 'textAlignCenter'}, {field: 'sync_status', displayName: 'Synchronization state', cellClass: 'textAlignCenter'}, { displayName: 'operation', width: 180, cellTemplate: "<div style='width:100%;padding-top: 5px;text-align:center'>" + "<span title='synchronization' style='cursor: pointer;color: #254eaf' class='fa fa-refresh fa-lg onoperate' ng-click='sync_vc(row)'></span> " + "<span title='edit' style='cursor: pointer;color: #254eaf' class='fa fa-pencil-square-o fa-lg onoperate' ng-click='modify_openStack(row)'></span> " + "<span title='delete' style='cursor: pointer;color: #d15b47 !important;' class='fa fa-trash fa-lg onoperate' ng-click='delete_openStack(row)'></span></div>" } ] }; }]);
Services.js (configure service information)
services = angular.module('webApiService', ['ngResource', 'utilServices']); //Production code var POST = "POST"; var GET = "GET"; //Test code //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}, //Define service methods and realize the function of code reuse 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}, }); }]) ;//This is the ending character. Please do not delete it
Accountmanagement? Add.html (data add page)
<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">Server name:</label> <div class="col-sm-8"> <input class="form-control" style="width: 220px;" ng-model="args.openStack_name" input-hint="Please enter the server name"> </div> </div> <div class="form-group"> <label class="col-sm-3 control-label">IP Address:</label> <div class="col-sm-8"> <input class="form-control" style="width: 220px;" ng-change="changeIp()" ng-model="args.openStack_ip" input-hint="Please input ip address"> <span ng-if="isShowIpError" class="text-danger">IP Incorrect format!</span> </div> </div> <div class="form-group"> <label class="col-sm-3 control-label">User name:</label> <div class="col-sm-8"> <input class="form-control" style="width: 220px;" ng-model="args.openStack_user" input-hint="enter one user name"> </div> </div> <div class="form-group"> <label class="col-sm-3 control-label">Password:</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="Please enter the user password"> <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()"> confirm </button> <button style="margin-left: 20px;" class="king-btn-small king-btn king-default" ng-click="cancel()"> cancel </button> </div> </div> </div>
accountManagement.js (controller corresponding to accountManagement.html)
controllers.controller("accountManagement_add", ["$scope","$modalInstance","sysService","loading","msgModal","errorModal", function ($scope,$modalInstance,sysService,loading,msgModal,errorModal) { $scope.title = "Add to openStack Server configuration" $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. Return data for processing $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("Please fill in the relevant information!"); } else if (!CWApp.isIP($scope.args.openStack_ip)) { errors.push("IP Incorrect format!"); } return errors; } }]);
urls.py (matching configuration of python and js)
# -*- coding: utf-8 -*- from django.conf.urls import patterns urlpatterns = patterns( 'home_application.views', # Home page - 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'), #system management (r'^add_openStack$', 'add_openStack'), (r'^search_openStack$', 'search_openStack'), (r'^modify_openStack$', 'modify_openStack'), (r'^delete_openStack$', 'delete_openStack'), )
os_management.py (python background)
# -*-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 #Add openStack account information def add_openStack(request): //Getting the parameter json.loads(request.body) passed from js also works 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: //Whether this data database lookup exists for flag bit 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"The openStack Already exists, please check the name or IP"]}) //Get the current login user name current_user = request.user.username //Acquisition time now = str(datetime.datetime.now()).split('.')[0] //Database add data 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) //Return the result to js control layer 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' }); //Return the results for pagination display and return to the front end modalInstance.result.then(function (res) { $scope.openstack_server_list.unshift(res); $scope.getPagedDataAsync($scope.pagingOptions.pageSize, $scope.pagingOptions.currentPage); }) };
end of all logic.