作者 刘锟

合并分支 'akun' 到 'master'

update



查看合并请求 !755
  1 +<?php
  2 +
  3 +namespace App\Console\Commands\Domain;
  4 +
  5 +use App\Models\Project\Project;
  6 +use App\Models\Project\ProjectServerBackup;
  7 +use Illuminate\Console\Command;
  8 +
  9 +class EmergencyRelieve extends Command
  10 +{
  11 + protected $signature = 'emergency_relieve';
  12 + protected $description = '危机解除,恢复项目服务器';
  13 +
  14 + public function handle()
  15 + {
  16 + $backup_list = ProjectServerBackup::where('status', ProjectServerBackup::STATUS_NO)->get();
  17 +
  18 + $project_model = new Project();
  19 + if ($backup_list->count() > 0) {
  20 + foreach ($backup_list as $item) {
  21 + $project_model->edit(['serve_id' => $item->serve_id], ['id' => $item->project_id]);
  22 + $item->status = ProjectServerBackup::STATUS_YES;
  23 + $item->save();
  24 +
  25 + $this->output('项目ID:' . $item->project_id . ',恢复成功');
  26 + }
  27 + }
  28 + }
  29 +
  30 + /**
  31 + * 输出处理日志
  32 + * @param $message
  33 + */
  34 + public function output($message)
  35 + {
  36 + echo date('Y-m-d H:i:s') . ' | ' . $message . PHP_EOL;
  37 + }
  38 +}
  1 +<?php
  2 +
  3 +namespace App\Console\Commands\Domain;
  4 +
  5 +use App\Models\Com\Notify;
  6 +use App\Models\Devops\ServersIp;
  7 +use App\Models\Domain\DomainCreateTask;
  8 +use App\Models\Project\Project;
  9 +use App\Models\Project\ProjectServerBackup;
  10 +use App\Models\Domain\DomainInfo;
  11 +use Illuminate\Console\Command;
  12 +use Symfony\Component\Process\Process;
  13 +
  14 +class EmergencyRenewSite extends Command
  15 +{
  16 + protected $signature = 'emergency_renew_site';
  17 + protected $description = '紧急重建站点';
  18 +
  19 + public function handle()
  20 + {
  21 + //目标服务器
  22 + $target_server_id = 1;
  23 + $target_server = ServersIp::select(['id', 'ip', 'domain'])->where('servers_id', $target_server_id)->first()->toArray();
  24 +
  25 + //受灾服务器
  26 + $server_ids = [9, 13];
  27 + $server_ip_ids = ServersIp::whereIn('servers_id', $server_ids)->get()->pluck('id')->toArray();
  28 +
  29 + //获取所有受灾项目
  30 + $project_list = Project::select(['id', 'serve_id', 'title'])->whereIn('serve_id', $server_ip_ids)->get();
  31 + $domain_model = new DomainInfo();
  32 + $create_model = new DomainCreateTask();
  33 + $notify_model = new Notify();
  34 + $backup_model = new ProjectServerBackup();
  35 + foreach ($project_list as $value) {
  36 + $domain_info = $domain_model->read(['project_id' => $value->id, 'status' => 1], ['id', 'domain']);
  37 + if (!$domain_info) {
  38 + //过滤未绑定正式域名的项目
  39 + continue;
  40 + }
  41 +
  42 + //判断域名是否已经解析到目标服务器
  43 + if (!$this->check_cname($domain_info['domain'], $target_server)) {
  44 + $this->output($domain_info['domain'] . ' | 未解析到目标服务器');
  45 + }
  46 +
  47 + //获取站点其他域名
  48 + $other_domain = [];
  49 + if (strpos($domain_info['domain'], 'www.') === 0) {
  50 + $other_domain[] = str_replace('www', '*', $domain_info['domain']);
  51 +
  52 + $top_domain = str_replace('www.', '', $domain_info['domain']);
  53 + if ($this->check_cname($top_domain, $target_server)) {
  54 + $other_domain[] = $top_domain;
  55 + }
  56 + }
  57 +
  58 + //创建目标服务器建站任务
  59 + $map_create = [
  60 + 'type' => DomainCreateTask::TYPE_MAIN,
  61 + 'server_id' => $target_server_id,
  62 + 'project_id' => $value->id,
  63 + 'domain_id' => $domain_info['id'],
  64 + 'status' => DomainCreateTask::STATUS_UN,
  65 + ];
  66 + $task_info = $create_model->read($map_create, ['id']);
  67 + if (!$task_info) {
  68 + $map_create['other_domain'] = json_encode($other_domain);
  69 + $create_model->add($map_create);
  70 + }
  71 +
  72 + //创建目标服务器站点页面生成任务
  73 + $map_notify = [
  74 + 'type' => Notify::TYPE_MASTER,
  75 + 'server_id' => $target_server_id,
  76 + 'project_id' => $value->id,
  77 + 'status' => Notify::STATUS_INIT,
  78 + 'route' => Notify::ROUTE_ALL,
  79 + ];
  80 + $notify_info = $notify_model->read($map_notify);
  81 + if (!$notify_info) {
  82 + $map_notify['data'] = json_encode(['domain' => $domain_info['domain'], 'url' => [], 'language' => []]);
  83 + $map_notify['sort'] = 9;
  84 + $notify_model->add($map_notify);
  85 + }
  86 +
  87 + //备份项目原始服务器
  88 + $backup_info = $backup_model->read(['project_id' => $value->id, 'status' => ProjectServerBackup::STATUS_NO], ['id']);
  89 + if ($backup_info) {
  90 + $backup_model->edit(['serve_id' => $value->serve_id], ['id' => $backup_info['id']]);
  91 + } else {
  92 + $backup_model->add(['project_id' => $value->id, 'serve_id' => $value->serve_id]);
  93 + }
  94 +
  95 + //更改项目服务器
  96 + $value->serve_id = $target_server_id;
  97 + $value->save();
  98 +
  99 + $this->output($domain_info['domain'] . ' | success');
  100 + }
  101 + }
  102 +
  103 + /**
  104 + * 验证是否cname或者A记录解析到目标服务器
  105 + * @param $domain
  106 + * @param $server_info
  107 + * @return mixed
  108 + * @author zbj
  109 + * @date 2023/11/13
  110 + */
  111 + public function check_cname($domain, $server_info)
  112 + {
  113 + $process = new Process(['nslookup', '-qt=a', $domain]);
  114 + $process->run();
  115 + $output = explode(PHP_EOL, $process->getOutput());
  116 + foreach ($output as $line) {
  117 + if ($line) {
  118 + $checkA = strpos($line, $server_info['ip']) !== false;
  119 + if ($checkA) {
  120 + return $domain;
  121 + }
  122 + }
  123 + }
  124 +
  125 + //是否cname
  126 + $process = new Process(['nslookup', '-qt=cname', $domain]);
  127 + $process->run();
  128 + $output = explode(PHP_EOL, $process->getOutput());
  129 + foreach ($output as $line) {
  130 + if ($line) {
  131 + $checkCname = (strpos($line, $server_info['domain']) !== false);
  132 + if ($checkCname) {
  133 + return $domain;
  134 + }
  135 + }
  136 + }
  137 + return false;
  138 + }
  139 +
  140 + /**
  141 + * 输出处理日志
  142 + * @param $message
  143 + */
  144 + public function output($message)
  145 + {
  146 + echo date('Y-m-d H:i:s') . ' | ' . $message . PHP_EOL;
  147 + }
  148 +}
  1 +<?php
  2 +namespace App\Models\Project;
  3 +
  4 +use App\Models\Base;
  5 +
  6 +class ProjectServerBackup extends Base
  7 +{
  8 + protected $table = 'gl_project_server_backup';
  9 +
  10 + const STATUS_NO = 0;
  11 + const STATUS_YES = 1;
  12 +}