作者 刘锟

灾备

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