作者 赵彬吉

update

<?php
namespace App\Console\Commands;
use App\Models\Devops\DevopsTaskLog;
use App\Models\Project;
use Illuminate\Console\Command;
use App\Models\Devops\DevopsTask as DevopsTaskModel;
/**
* Class DevopsTask
* @package App\Console\Commands
* @author zbj
* @date 2023/4/25
*/
class DevopsTask extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'devops_task';
/**
* The console command description.
*
* @var string
*/
protected $description = '运维任务执行';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* @return bool
*/
public function handle()
{
while (true){
$tasks = DevopsTaskModel::where('status', DevopsTaskModel::STATUS_PENDING)->get();
foreach ($tasks as $task){
echo "Start task " . $task->id . PHP_EOL;
if($task->type == DevopsTaskModel::TYPE_MYSQL){
$this->updateTable($task);
}
echo "End task " . $task->id . PHP_EOL;
}
sleep(10);
}
}
public function updateTable($task){
$projects = Project::all();
foreach ($projects as $project){
echo "project " . $project->id;
$log = DevopsTaskLog::addLog($task->id, $project->id);
if($log->status == DevopsTaskModel::STATUS_ACTIVE){
continue;
}
if(!$project->mysqlConfig){
$log->status = DevopsTaskLog::STATUS_ERROR;
$log->remark = '未配置数据库';
$log->save();
continue;
}
//DB类是单例模式,生命周期内修改配置不会生效
$conn = new \mysqli(
$project->mysqlConfig->host,
$project->mysqlConfig->user,
$project->mysqlConfig->password,
$project->databaseName(),
$project->mysqlConfig->port,
);
$res = $conn->query($task->sql);
$log->status = $res ? DevopsTaskLog::STATUS_ACTIVE : DevopsTaskLog::STATUS_ERROR;
$log->remark = $res ? '成功' : 'sql执行失败';
$log->save();
echo '-->' . $log->remark . PHP_EOL;
}
$task->status = DevopsTaskModel::STATUS_ACTIVE;
$task->save();
}
}
... ...
<?php
/**
* Created by PhpStorm.
* User: zhl
* Date: 2023/4/19
* Time: 15:04
*/
namespace App\Console\Commands;
use App\Models\Project;
use App\Services\ProjectServer;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
/**
* Class ProjectDatabaseUpdate
* @package App\Console\Commands
*/
class ProjectDatabaseUpdate extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'project:database_update';
/**
* The console command description.
*
* @var string
*/
protected $description = '项目数据库更新';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* @return bool
*/
public function handle()
{
#TODO 未处理更新 更新对象(base, project) 更新内容
return true;
}
/**
* 主库内容更新
* @param $sql
* @return array
*/
public function baseUpdate($sql)
{
return DB::select($sql);
}
/**
* 客户数据表更新
* @param $sql
* @return bool
*/
public function projectDatabaseUpdate($sql)
{
$project = Project::get();
foreach ($project as $val) {
ProjectServer::useProject($val->id);
DB::connection('custom_mysql')->select($sql);
}
return true;
}
/**
* 指定项目数据库更新
* @param $project_id
* @param $sql
*/
public function appointProjectUpdate($project_id, $sql)
{
ProjectServer::useProject($project_id);
DB::connection('custom_mysql')->select($sql);
}
}
\ No newline at end of file
<?php
/**
* Created by PhpStorm.
* User: zhl
* Date: 2023/4/12
* Time: 15:33
*/
namespace App\Console\Commands;
use App\Models\Project;
use App\Services\ProjectServer;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
/**
* Class ProjectInitDatabase
* @package App\Console\Commands
*/
class ProjectInit extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'project:init';
/**
* The console command description.
*
* @var string
*/
protected $description = '项目数据库初始化';
protected $connect = null;
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* @return bool
*/
public function handle()
{
#TODO 通过项目ID获取项目部署数据库配置, 创建数据库, 同步数据表
$project_id = 102;
$project = Project::getProjectById($project_id);
if (empty($project) || empty($project->mysqlConfig()))
return true;
$this->initDatabase($project);
return true;
}
/**
* @param Project $project
* @return bool
*/
public function initDatabase($project)
{
$create_flag = $this->createDatabase($project);
if (!$create_flag) {
// 创建数据库失败 添加通知以及再次处理
}
// 设置 database.connections.custom_mysql 数据
ProjectServer::useProject($project->id);
// TODO 创建对应库 初始化数据表
$this->initTable();
return true;
}
/**
* @return bool
*/
public function initTable()
{
$database_name = DB::connection('custom_tmp_mysql')->getDatabaseName();
$table = Schema::connection('custom_tmp_mysql')->getAllTables();
$table = array_column($table, 'Tables_in_' . $database_name);
foreach ($table as $v) {
$has_table = Schema::connection('custom_mysql')->hasTable($v);
if ($has_table)
continue;
$connection = DB::connection('custom_tmp_mysql');
$sql = $connection->getDoctrineSchemaManager()
->getDatabasePlatform()
->getCreateTableSQL($connection->getDoctrineSchemaManager()->listTableDetails($v));
DB::connection('custom_mysql')->select($sql[0]);
}
return true;
}
/**
* 创建数据库
* 链接mysql 查询数据库是否存在 创建数据库
* @param Project $project
* @return bool|\mysqli_result|null
*/
public function createDatabase($project)
{
# 该方法需要:composer require parity-bit/laravel-db-commands
// $result = Artisan::call('db:create', [
// '--database' => $database_name,
// ]);
//
// return $result;
if ($this->connect)
return $this->connect;
//连接到 MySQL 服务器
$servername = $project->mysqlConfig()->host;
$username = $project->mysqlConfig()->user;
$password = $project->mysqlConfig()->password;
$conn = new \mysqli($servername, $username, $password);
//检查连接是否成功
if ($conn->connect_error) {
die("连接失败: " . $conn->connect_error);
}
$this->connect = $conn;
// $result = $conn->query('SHOW DATABASES LIKE \'' . $database_name . '\';');
// if ($result)
// return true;
$result = $conn->query('CREATE DATABASE ' . $project->databaseName() . ';');
return $result;
}
}
<?php
namespace App\Console\Commands;
namespace App\Console\Commands\Test;
... ...
... ... @@ -38,16 +38,6 @@ class BaseController extends Controller
$this->get_param();
}
/**
* admin端用渲染 不走接口
* @return mixed
* @author zbj
* @date 2023/4/19
*/
public function manage(){
return Session::get('manage');
}
/**
* 成功返回
... ...
... ... @@ -2,7 +2,7 @@
namespace App\Http\Controllers\Aside\Devops;
use App\Http\Controllers\Bside\BaseController;
use App\Http\Controllers\Aside\BaseController;
use App\Http\Logic\Aside\Devops\ServerConfigLogic;
use App\Http\Requests\Aside\Devops\ServerConfigRequest;
... ...
... ... @@ -31,7 +31,7 @@ class LoginController extends BaseController
return $this->success();
}
if($this->manage()){
if($logic->manage()){
return redirect(route('admin.home.white'));
}
return view('admin.login');
... ...
... ... @@ -3,7 +3,6 @@
namespace App\Http\Controllers\Aside;
use App\Enums\Common\Code;
use App\Http\Controllers\Bside\BaseController;
use App\Models\Project as ProjectModel;
... ...
... ... @@ -6,8 +6,9 @@ namespace App\Http\Logic\Aside\Devops;
use App\Http\Logic\Aside\BaseLogic;
use App\Http\Logic\Aside\Project\ProjectLogic;
use App\Models\Devops\DevopsTask;
use App\Models\Project;
use App\Models\ServerConfig;
use App\Models\Devops\ServerConfig;
use App\Services\ProjectServer;
use Illuminate\Support\Facades\DB;
... ... @@ -29,25 +30,29 @@ class ServerConfigLogic extends BaseLogic
public function save($param)
{
$project = ProjectServer::useProject($param['project_id']);
$project_logic = new ProjectLogic();
$project = $project_logic->getCacheInfo($param['project_id']);
if(!$project){
$this->fail('项目不存在或者已经删');
$this->fail('项目不存在或者已经删');
}
DB::beginTransaction();
try {
//保存配置
$res = parent::save($param);
//关联到项目
$data['id'] = $param['project_id'];
if ($param['type'] == ServerConfig::TYPE_SERVER) {
$data['serve_id'] = $res['id'];
}else{
$data['mysql_id'] = $res['id'];
}
(new ProjectLogic())->save($data);
$project_logic->save($data);
//初始化数据库
if ($param['type'] == ServerConfig::TYPE_MYSQL) {
//切换数据库配置
$project = ProjectServer::useProject($param['project_id']);
//创建数据库
ProjectServer::createDatabase($project);
//创建表
... ... @@ -73,9 +78,8 @@ class ServerConfigLogic extends BaseLogic
public function updateTable($param){
$project = ProjectServer::useProject($param['project_id']);
if(!$project){
$this->fail('项目不存在或者已经删');
$this->fail('项目不存在或数据库未配置');
}
ProjectServer::useProject($param['project_id']);
DB::connection('custom_mysql')->statement($param['sql']);
return $this->success();
}
... ... @@ -100,19 +104,7 @@ class ServerConfigLogic extends BaseLogic
* @date 2023/4/24
*/
public function updateAllTable($param){
$projects = Project::all();
foreach ($projects as $project){
//DB类是单例模式,不能用哈 切换配置不会生效
$conn = new \mysqli(
$project->mysqlConfig->host,
$project->mysqlConfig->user,
$project->mysqlConfig->password,
$project->databaseName(),
$project->mysqlConfig->port,
);
$conn->query($param['sql']);
}
DevopsTask::addTask($param['sql']);
return $this->success();
}
}
... ...
... ... @@ -48,4 +48,12 @@ class LoginLogic extends BaseLogic
Session::forget('manage');
return redirect(route('admin.login'));
}
public static function manage($field = ''){
$manage = Session::get('manage');
if($field){
return $manage[$field] ?? '';
}
return $manage;
}
}
... ...
... ... @@ -5,6 +5,7 @@ namespace App\Http\Middleware\Bside;
use App\Enums\Common\Code;
use App\Models\User\ProjectMenu;
use App\Models\User\ProjectRole as ProjectRoleModel;
use App\Services\ProjectServer;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
... ... @@ -29,7 +30,10 @@ class LoginAuthMiddleware
return response(['code'=>Code::USER_ERROR,'msg'=>'当前用户未登录']);
}
// 设置数据信息
// ProjectServer::useProject($info['project_id']);
$project = ProjectServer::useProject($info['project_id']);
if($project){
return response(['code'=>Code::USER_ERROR,'msg'=>'数据库未配置']);
}
//操作权限设置
$projectRoleModel = new ProjectRoleModel();
$role_info = $projectRoleModel->read(['id'=>$info['role_id']]);
... ...
... ... @@ -2,7 +2,7 @@
namespace App\Http\Requests\Aside\Devops;
use App\Models\ServerConfig;
use App\Models\Devops\ServerConfig;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;
... ...
<?php
namespace App\Models\Devops;
use App\Http\Logic\Aside\LoginLogic;
use App\Models\Base;
/**
* 运维任务
* Class DevopsTask
* @package App\Models\Devops
* @author zbj
* @date 2023/4/25
*/
class DevopsTask extends Base
{
/**
* @var string
*/
protected $table = 'gl_devops_task';
/**
* 1:数据库更新, 2:代码更新
*/
const TYPE_MYSQL = 1;
const TYPE_CODE = 2;
const STATUS_PENDING = 0;
const STATUS_ACTIVE = 1;
/**
* @param $sql
* @param int $type
* @return mixed
* @author zbj
* @date 2023/4/25
*/
public static function addTask($sql, int $type = self::TYPE_MYSQL){
$model = new static();
$model->type = $type;
$model->sql = $sql;
$model->manage_id = intval(LoginLogic::manage('id'));
$model->save();
return $model->id;
}
}
... ...
<?php
namespace App\Models\Devops;
use App\Http\Logic\Aside\LoginLogic;
use App\Models\Base;
/**
* 运维任务
* Class DevopsTask
* @package App\Models\Devops
* @author zbj
* @date 2023/4/25
*/
class DevopsTaskLog extends Base
{
/**
* @var string
*/
protected $table = 'gl_devops_task_log';
const STATUS_PENDING = 0;
const STATUS_ACTIVE = 1;
const STATUS_ERROR = 2;
/**
* @param $task_id
* @param $project_id
* @return mixed
* @author zbj
* @date 2023/4/25
*/
public static function addLog($task_id, $project_id)
{
$log = self::where('task_id', $task_id)->where('project_id', $project_id)->first();
if (!$log) {
$log = new self();
$log->task_id = $task_id;
$log->project_id = $project_id;
$log->save();
}
return $log;
}
}
... ...
... ... @@ -6,7 +6,9 @@
* Time: 10:04
*/
namespace App\Models;
namespace App\Models\Devops;
use App\Models\Base;
/**
* 服务账户信息
... ...
... ... @@ -27,6 +27,10 @@ class ProjectServer extends BaseService
$project = Project::getProjectById($project_id);
if (empty($project))
return false;
if(!$project->mysqlConfig){
return false;
}
// 设置 database.connections.custom_mysql 配置
config(['database.connections.custom_mysql.host' => $project->mysqlConfig->host]);
config(['database.connections.custom_mysql.port' => $project->mysqlConfig->port]);
... ...