一 最终版本 split
脚本需求
- 批量删除Gitlab仓库中的前端项目使用configmap暴露服务
源文件内容
app: fe-freight-admin
appType: nginx
replicaCount: 2
ingress:
enabled: true
class: alb
internal:
enabled: false
internet:
enabled: true
tlsEnabled: true
host: xxxx.xxxx.cn
service:
type: ClusterIP
port: 80
configs:
enabled: true
type: file
path: /etc/nginx/conf.d
data:
default.conf: |-
server {
listen 80;
server_name localhost;
resolver kube-dns.kube-system.svc.cluster.local valid=30s;
resolver_timeout 3s;
root /opt/dist;
index index.html;
location ^~ /oms {
set $URL http://fe-freight-oms-admin.fe-freight-oms-admin.svc.cluster.local;
rewrite ^/oms(.*) /$1 break;
proxy_set_header X-real-ip $remote_addr;
proxy_pass $URL;
}
location ^~ /tms {
set $URL http://fe-freight-tms-admin.fe-freight-tms-admin.svc.cluster.local;
rewrite ^/tms(.*) /$1 break;
proxy_set_header X-real-ip $remote_addr;
proxy_pass $URL;
}
location ^~ /bms {
set $URL http://fe-freight-bms-admin.fe-freight-bms-admin.svc.cluster.local;
rewrite ^/bms(.*) /$1 break;
proxy_set_header X-real-ip $remote_addr;
proxy_pass $URL;
}
location ^~ /base {
set $URL http://fe-freight-base-admin.fe-freight-base-admin.svc.cluster.local;
rewrite ^/base(.*) /$1 break;
proxy_set_header X-real-ip $remote_addr;
proxy_pass $URL;
}
location ^~ /v1 {
set $URL http://fe-freight-v1-admin.fe-freight-v1-admin.svc.cluster.local;
rewrite ^/v1(.*) /$1 break;
proxy_set_header X-real-ip $remote_addr;
proxy_pass $URL;
}
location ^~/hope-saas-auth-web/ {
set $URL http://hope-saas-auth-web.hope-saas-auth-web.svc.cluster.local:8080;
rewrite ^/hope-saas-auth-web/(.*) /$1 break;
proxy_set_header X-real-ip $remote_addr;
proxy_pass $URL;
}
location ^~ /hope-saas-tms-web/ {
set $URL http://hope-saas-tms-web.hope-saas-tms-web.svc.cluster.local:8080;
rewrite ^/hope-saas-tms-web/(.*) /$1 break;
proxy_set_header X-real-ip $remote_addr;
proxy_pass $URL;
}
location ^~ /tms_plus_waybill/ {
set $URL http://otms-web-plus.otms-web-plus.svc.cluster.local:8080;
rewrite ^/tms_plus_waybill/(.*) /$1 break;
proxy_set_header X-real-ip $remote_addr;
proxy_pass $URL;
}
location ^~ /hope-saas-tcs-web/ {
set $URL http://hope-saas-tcs-web.hope-saas-tcs-web.svc.cluster.local:8080;
rewrite ^/hope-saas-tcs-web/(.*) /$1 break;
proxy_set_header X-real-ip $remote_addr;
proxy_pass $URL;
}
location ^~ /tms_plus {
set $URL http://otms-web-plus.otms-web-plus.svc.cluster.local:8080;
proxy_set_header X-real-ip $remote_addr;
proxy_pass $URL;
}
location = /index.html {
add_header Cache-Control "no-store";
}
location / {
expires -1;
}
location ~ \.(jpg|png|jpeg|gif)$ {
expires 30d;
}
location ~ \.(js|css)$ {
expires 2h;
}
location ^~ /.git {
deny all;
}
}
resources:
requests:
cpu: 100m
memory: 512Mi
limits:
cpu: 2000m
memory: 512Mi
lifecycle:
preStop:
enabled: true
command:
- /bin/sh
- -c
- sleep 15
设计思路
- 1 首先检测文件是否以backup为开头,如果是,文件为备份文件不需要替换
- 2 检测文件是否以 yaml或者yml为结尾,如果是yml文件,则进行下一步操作
- 3 判断文件内容是否包含 appType: nginx,如果包含这个才是前端文件
- 4 判断文件中是否有我们需要去除的app名字
- 5 确认文件是我们需要修改的文件后,开始进行split分段操作
- 6 以default.conf:分段,作为文件中独一无二的部分
- 7 对location部分split,设置一个切片,最后使用strings.join拼接切片
- 8 写入修改后的文本内容
package main
import (
"flag"
"fmt"
"io/ioutil"
"os"
"regexp"
"strings"
)
var (
app string
)
const (
rule1 = "default.conf:"
)
func checkFile(filename string) {
//检测文件是否以backup为开头
if !strings.HasPrefix(filename, "./backup") {
//检测文件是否以 yaml或者yml为结尾
if strings.HasSuffix(filename, "ymal") || strings.HasSuffix(filename, "yml") {
bytes, err := os.ReadFile(filename)
if err != nil {
panic(err.Error())
}
//判断文件内容是否包含 appType: nginx,如果包含这个才是前端文件
if regexp.MustCompile(rule1).MatchString(string(bytes)) {
if regexp.MustCompile(app).MatchString(string(bytes)) {
updateFile(filename,string(bytes))
}
}
}
}
}
func addFile(dirName string) []string {
var ret []string
fileInfo, err := ioutil.ReadDir(dirName)
if err != nil {
fmt.Println(err)
return ret
}
for _, fi := range fileInfo {
fileName := dirName + "/" + fi.Name()
//fmt.Printf("%s%s\n", s, fileName)
if fi.IsDir() {
tmpRes := addFile(fileName)
ret = append(ret, tmpRes...)
} else {
ret = append(ret, fileName)
}
}
return ret
}
func updateFile(filename,data string) {
var result string
var head []string
confSplit := strings.Split(data, "default.conf:")
result =result + confSplit[0] + "default.conf:"
locationSplit := strings.Split(confSplit[1], "location")
result = result + locationSplit[0]
head = []string{""}
for _,v := range locationSplit[1:]{
head = append(head, v)
}
data = strings.Join(head, "location")
splits := strings.Split(data, "}")
rule2 := fmt.Sprintf("location.*/%s-.*{", app)
rule3 := fmt.Sprintf("location.*/%s.*{", app)
var ret []string
for _,v := range splits {
if regexp.MustCompile(rule3).MatchString(v) {
if regexp.MustCompile(rule2).MatchString(v){
ret = append(ret, v)
}
} else {
ret = append(ret, v)
}
}
join := strings.Join(ret, "}")
result = result + join
_ = os.Remove(filename)
file, err := os.OpenFile(filename, os.O_RDWR|os.O_APPEND|os.O_CREATE, 0666)
if err != nil {
panic(err.Error())
}
file.WriteString(result)
file.Close()
fmt.Printf("修改 %s 文件成功\n",filename)
}
func main() {
flag.StringVar(&app, "app", "", "请输入要替换的location名字")
flag.Parse()
if app == "" {
fmt.Println("请输入要替换的location,并再次执行 ./yunlizhi_change_file --app=你想删除的location名字")
return
}
fileList := addFile(".")
for _, filename := range fileList {
checkFile(filename)
}
//checkFile("values.yml")
}
第二种思路 使用viper去提取yaml格式
失败原因提取的yaml未经过格式化,大小写区分错误
package main
import (
"fmt"
"github.com/spf13/viper"
"strings"
)
func main() {
viper.SetConfigType("yaml")
viper.SetConfigFile("fe-bms-admin_prod_values.yml")
//判断文件的前缀 fmt.Println(strings.HasPrefix(a, "go"))
//判断文件的后缀 fmt.Println(strings.HasSuffix(a, "ng")) //true
err := viper.ReadInConfig()
if err != nil {
panic(err.Error())
}
data := viper.GetStringMap("configs.data")
confData := data["default.conf"].(string)
splitN := strings.Split(confData, "location")
//fmt.Println(splitN[0])
s := strings.Join(splitN,"location")
fmt.Println(s)
}
package main
import (
"flag"
"fmt"
"github.com/spf13/viper"
"io/ioutil"
"os"
"regexp"
"strings"
)
var (
app string
)
const (
rule1 = "appType: nginx"
)
func checkFile(filename string) {
//检测文件是否以backup为开头
if !strings.HasPrefix(filename, "backup") {
//检测文件是否以 yaml或者yml为结尾
if strings.HasSuffix(filename, "ymal") || strings.HasSuffix(filename, "yml") {
bytes, err := os.ReadFile(filename)
if err != nil {
panic(err.Error())
}
//判断文件内容是否包含 appType: nginx,如果包含这个才是前端文件
if regexp.MustCompile(rule1).MatchString(string(bytes)) {
updateFile(filename)
}
}
}
}
func addFile(dirName string) []string {
var ret []string
fileInfo, err := ioutil.ReadDir(dirName)
if err != nil {
fmt.Println(err)
return ret
}
for _, fi := range fileInfo {
fileName := dirName + "/" + fi.Name()
//fmt.Printf("%s%s\n", s, fileName)
if fi.IsDir() {
tmpRes := addFile(fileName)
ret = append(ret, tmpRes...)
} else {
ret = append(ret, fileName)
}
}
return ret
}
func replaceStr(filename,old,new string) {
bytes, err := os.ReadFile(filename)
if err != nil {
panic(err.Error())
}
var result string
for _,v := range bytes{
result = result + string(v)
}
replace := strings.Replace(result, old, new, -1)
os.Remove(filename)
//创建新文件
file, err := os.OpenFile(filename, os.O_RDWR|os.O_APPEND|os.O_CREATE, 0666)
if err != nil {
panic(err.Error())
}
file.WriteString(replace)
//fmt.Printf("修改文件 %s 成功========================================\n", filename)
defer file.Close()
}
func updateFile(filename string) {
replaceStr(filename,"default.conf","default-conf")
viper.SetConfigType("yaml")
viper.SetConfigFile(filename)
err := viper.ReadInConfig()
if err != nil {
panic(err.Error())
}
keys := viper.AllKeys()
for _,v := range keys{
if regexp.MustCompile("configs.data.default-conf").MatchString(v){
data := viper.GetString("configs.data.default-conf")
locations := strings.Split(data, "}")
rule2 := fmt.Sprintf("location.*/%s-.*", app)
rule3 := fmt.Sprintf("location.*/%s", app)
var ret []string
for _,v := range locations{
if regexp.MustCompile(rule3).MatchString(v) {
if regexp.MustCompile(rule2).MatchString(v){
ret = append(ret, v)
}
} else {
ret = append(ret,v)
}
}
result := strings.Join(ret, "}")
fmt.Println(result)
viper.Set("configs.data.default-conf",result)
viper.WriteConfig()
replaceStr(filename,"default-conf","default.conf")
}
}
}
func main() {
flag.StringVar(&app, "app", "", "请输入要替换的location名字")
flag.Parse()
//fileList := addFile(".")
//for _, filename := range fileList {
// checkFile(filename)
//}
checkFile("fe-application-admin_prod_values.yml")
}