130 lines
3.3 KiB
PHP
130 lines
3.3 KiB
PHP
<?php
|
|
|
|
namespace App\Console\Commands;
|
|
|
|
use Illuminate\Console\Command;
|
|
use Illuminate\Support\Facades\File;
|
|
use Symfony\Component\Process\Process;
|
|
|
|
class DeployStaticSite extends Command
|
|
{
|
|
protected $signature = 'deploy:static-site {name} {host} {id}';
|
|
protected $description = 'Generate K8s manifests, copy files with Ansible, and deploy to cluster';
|
|
|
|
public function handle()
|
|
{
|
|
$name = $this->argument('name');
|
|
$host = $this->argument('host');
|
|
$id = $this->argument('id');
|
|
$namespace = 'hosting-deploy';
|
|
$kubeDir = storage_path("app/kube/{$name}");
|
|
File::ensureDirectoryExists($kubeDir);
|
|
|
|
// 1. Generate K8s YAMLs
|
|
File::put("{$kubeDir}/deployment.yaml", $this->deployment($name,$id, $namespace));
|
|
File::put("{$kubeDir}/service.yaml", $this->service($name,$id, $namespace));
|
|
File::put("{$kubeDir}/ingress.yaml", $this->ingress($name,$host,$id, $namespace));
|
|
|
|
$this->info("✅ K8s manifests generated.");
|
|
|
|
// 2. Run Ansible to copy files and apply kube
|
|
$ansiblePlaybook = base_path("ansible/deploy_site.yml");
|
|
$process = new Process([
|
|
'ansible-playbook',
|
|
$ansiblePlaybook,
|
|
'-i', base_path('ansible/inventory/hosts.ini'),
|
|
'--extra-vars', "sitename={$name}",'--extra-vars', "siteid={$id}"
|
|
]);
|
|
$process->setTimeout(300);
|
|
$process->run(function ($type, $buffer) {
|
|
echo $buffer;
|
|
});
|
|
|
|
if ($process->isSuccessful()) {
|
|
$this->info("🚀 Site '{$name}' deployed successfully.");
|
|
} else {
|
|
$this->error("❌ Ansible deployment failed.");
|
|
}
|
|
}
|
|
|
|
private function deployment(string $name,string $id, string $namespace): string
|
|
{
|
|
return <<<YAML
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: {$name}-{$id}-deployment
|
|
namespace: {$namespace}
|
|
labels:
|
|
app: {$name}-{$id}
|
|
spec:
|
|
replicas: 1
|
|
selector:
|
|
matchLabels:
|
|
app: {$name}-{$id}
|
|
template:
|
|
metadata:
|
|
labels:
|
|
app: {$name}-{$id}
|
|
spec:
|
|
containers:
|
|
- name: {$name}-{$id}
|
|
image: nginx:alpine
|
|
ports:
|
|
- containerPort: 80
|
|
volumeMounts:
|
|
- name: static-content
|
|
mountPath: /usr/share/nginx/html
|
|
volumes:
|
|
- name: static-content
|
|
hostPath:
|
|
path: /var/www/{$name}/{$id}
|
|
type: Directory
|
|
YAML;
|
|
}
|
|
|
|
private function service(string $name, string $id, string $namespace): string
|
|
{
|
|
return <<<YAML
|
|
apiVersion: v1
|
|
kind: Service
|
|
metadata:
|
|
name: {$name}-{$id}-service
|
|
namespace: {$namespace}
|
|
spec:
|
|
selector:
|
|
app: {$name}-{$id}
|
|
ports:
|
|
- protocol: TCP
|
|
port: 80
|
|
targetPort: 80
|
|
type: ClusterIP
|
|
YAML;
|
|
}
|
|
|
|
private function ingress(string $name,string $host,string $id, string $namespace): string
|
|
{
|
|
return <<<YAML
|
|
apiVersion: networking.k8s.io/v1
|
|
kind: Ingress
|
|
metadata:
|
|
name: {$name}-{$id}-ingress
|
|
namespace: {$namespace}
|
|
annotations:
|
|
traefik.ingress.kubernetes.io/router.entrypoints: web
|
|
spec:
|
|
rules:
|
|
- host: {$host}
|
|
http:
|
|
paths:
|
|
- path: /
|
|
pathType: Prefix
|
|
backend:
|
|
service:
|
|
name: {$name}-{$id}-service
|
|
port:
|
|
number: 80
|
|
YAML;
|
|
}
|
|
}
|