package maker import ( "context" "fmt" "os" "path/filepath" "gitea.loveuer.com/yizhisec/pkg3/logger" "github.com/samber/lo" "yizhisec.com/hsv2/forge/internal/opt" "yizhisec.com/hsv2/forge/pkg/resource" ) type NginxOpt func(*nginxOpt) type nginxOpt struct { WithoutSeafile bool Replica int } func WithNginxReplica(replica int) NginxOpt { return func(o *nginxOpt) { if replica >= 0 { o.Replica = replica } } } func WithoutNginxSeafile() NginxOpt { return func(o *nginxOpt) { o.WithoutSeafile = true } } func (m *maker) AppNginx(ctx context.Context, opts ...NginxOpt) error { const ( _upsert = `#!/bin/bash kubectl create configmap nginx-main --namespace hsv2 --from-file=nginx.conf=./conf/nginx.conf --dry-run=client -o yaml | kubectl apply -f - kubectl create configmap nginx-user --namespace hsv2 --from-file=user.conf=./conf/user.conf --dry-run=client -o yaml | kubectl apply -f - kubectl create configmap nginx-gateway --namespace hsv2 --from-file=gateway.conf=./conf/gateway.conf --dry-run=client -o yaml | kubectl apply -f - kubectl create configmap nginx-web --namespace hsv2 --from-file=web.conf=./conf/web.conf --dry-run=client -o yaml | kubectl apply -f - kubectl create configmap nginx-client --namespace hsv2 --from-file=client.conf=./conf/client.conf --dry-run=client -o yaml | kubectl apply -f - kubectl create configmap nginx-common --namespace hsv2 --from-file=common.conf=./conf/common.conf --dry-run=client -o yaml | kubectl apply -f - %s kubectl create configmap ssl-ca-crt --namespace hsv2 --from-file=ca.crt=./ssl/ca.crt --dry-run=client -o yaml | kubectl apply -f - kubectl create configmap ssl-ffdhe2048 --namespace hsv2 --from-file=ffdhe2048.txt=./ssl/ffdhe2048.txt --dry-run=client -o yaml | kubectl apply -f - kubectl create configmap ssl-server-crt --namespace hsv2 --from-file=server.crt=./ssl/server.crt --dry-run=client -o yaml | kubectl apply -f - kubectl create configmap ssl-server-key --namespace hsv2 --from-file=server.key=./ssl/server.key --dry-run=client -o yaml | kubectl apply -f - kubectl create configmap ssl-mqtt-crt --namespace hsv2 --from-file=mqtt.server.crt=./ssl/mqtt.server.crt --dry-run=client -o yaml | kubectl apply -f - kubectl create configmap ssl-mqtt-key --namespace hsv2 --from-file=mqtt.server.key=./ssl/mqtt.server.key --dry-run=client -o yaml | kubectl apply -f - kubectl create configmap ssl-client-server-crt --namespace hsv2 --from-file=client.server.crt=./ssl/client.server.crt --dry-run=client -o yaml | kubectl apply -f - kubectl create configmap ssl-client-server-key --namespace hsv2 --from-file=client.server.key=./ssl/client.server.key --dry-run=client -o yaml | kubectl apply -f - kubectl create configmap ssl-web-server-crt --namespace hsv2 --from-file=web.server.crt=./ssl/web.server.crt --dry-run=client -o yaml | kubectl apply -f - kubectl create configmap ssl-web-server-key --namespace hsv2 --from-file=web.server.key=./ssl/web.server.key --dry-run=client -o yaml | kubectl apply -f - kubectl apply -f deployment.yaml kubectl rollout restart deployment nginx-deployment -n hsv2` ) var ( err error workdir = filepath.Join(opt.Cfg.Make.Dir, "app", "nginx") o = nginxOpt{ WithoutSeafile: false, Replica: 2, } applySeafile = "kubectl create configmap nginx-seafile --namespace hsv2 --from-file=seafile.conf=./conf/seafile.conf --dry-run=client -o yaml | kubectl apply -f -" ) logger.Info(" ☑️ maker.AppNginx: 开始构建 nginx, workdir = %s", workdir) for _, fn := range opts { fn(&o) } logger.Debug(" ☑️ maker.AppNginx: 创建工作目录 = %s", workdir) if err = os.MkdirAll(workdir, 0755); err != nil { return err } logger.Debug("✅ maker.AppNginx: 创建工作目录成功 = %s", workdir) // 子目录: conf 与 ssl confDir := filepath.Join(workdir, "conf") sslDir := filepath.Join(workdir, "ssl") logger.Debug(" ☑️ maker.AppNginx: 创建 conf 与 ssl 子目录") if err = os.MkdirAll(confDir, 0755); err != nil { logger.Debug("❌ maker.AppNginx: 创建 conf 目录失败: %v", err) return err } if err = os.MkdirAll(sslDir, 0755); err != nil { logger.Debug("❌ maker.AppNginx: 创建 ssl 目录失败: %v", err) return err } logger.Debug("✅ maker.AppNginx: 创建 conf 与 ssl 子目录成功") // 写入 nginx 配置文件到 conf 子目录(列表 + for 循环) logger.Debug(" ☑️ maker.AppNginx: 写入 nginx 配置文件到 conf 子目录") confFiles := []struct { name string content []byte }{ {"nginx.conf", resource.NGINXMain}, {"user.conf", resource.NGINXUser}, {"gateway.conf", resource.NGINXGateway}, {"web.conf", resource.NGINXWeb}, {"client.conf", resource.NGINXClient}, {"common.conf", resource.NGINXCommon}, } // 过滤 seafile.conf 文件 if !o.WithoutSeafile { confFiles = append(confFiles, struct { name string content []byte }{ "seafile.conf", resource.NGINXSeafile, }) } for _, f := range confFiles { dest := filepath.Join(confDir, f.name) if err = os.WriteFile(dest, f.content, 0644); err != nil { logger.Debug("❌ maker.AppNginx: 写入 %s 失败: %v", f.name, err) return err } logger.Debug("✅ maker.AppNginx: 写入 %s 成功, dest = %s", f.name, dest) } logger.Debug("✅ maker.AppNginx: 写入 nginx 配置文件成功") // 写入 ssl 文件到 ssl 子目录 logger.Debug(" ☑️ maker.AppNginx: 写入 SSL 证书与密钥到 ssl 子目录") sslFiles := []struct{ name, content string }{ {"ffdhe2048.txt", resource.SSLFFDHE2048}, {"ca.crt", resource.SSLCaCrt}, {"server.crt", resource.SSLServerCrt}, {"server.key", resource.SSLServerKey}, {"mqtt.server.crt", resource.SSLMQTTServerCrt}, {"mqtt.server.key", resource.SSLMQTTServerKey}, {"client.server.crt", resource.SSLClientServerCrt}, {"client.server.key", resource.SSLClientServerKey}, {"web.server.crt", resource.SSLWebServerCrt}, {"web.server.key", resource.SSLWebServerKey}, } for _, f := range sslFiles { dest := filepath.Join(sslDir, f.name) if err = os.WriteFile(dest, []byte(f.content), 0644); err != nil { logger.Debug("❌ maker.AppNginx: 写入 %s 失败: %v", f.name, err) return err } logger.Debug("✅ maker.AppNginx: 写入 %s 成功, dest = %s", f.name, dest) } // write nginx deployment yaml dest := filepath.Join(workdir, "nginx.yaml") content := []byte(fmt.Sprintf(resource.YAMLAppNGINX, o.Replica)) if err = os.WriteFile(dest, content, 0644); err != nil { logger.Debug("❌ maker.AppNginx: 写入 nginx.yaml 失败: %v", err) return err } logger.Debug("✅ maker.AppNginx: 写入 nginx.yaml 成功, dest = %s", dest) // write nginx upsert script dest = filepath.Join(workdir, "upsert.sh") content = []byte(fmt.Sprintf(_upsert, lo.If(o.WithoutSeafile, "").Else(applySeafile))) if err = os.WriteFile(dest, content, 0755); err != nil { logger.Debug("❌ maker.AppNginx: 写入 upsert.sh 失败: %v", err) return err } logger.Debug("✅ maker.AppNginx: 写入 upsert.sh 成功, dest = %s", dest) logger.Info("✅ maker.AppNginx: nginx 构建完成") return nil }