nginx配置迁移到apisix方案—python3

网上尚未发现成熟方案,这是个人第一次尝试。
第一步,编辑解析模块 Parser.py

#!/usr/bin/env python
# encoding: utf-8
class Parser(object):
	def __init__(self, offset_char=' '):
		self._i = 0
		self._config = ''
		self._length = 0
		self._data = []
		self._off_char = offset_char

	def __call__(self):
		return self.gen_config()

	def load(self, config):
		self._config = config
		self._length = len(config) - 1
		self._i = 0
		return self.parse_block()

	def loadf(self, filename):
		conf = ''
		with open(filename, 'r') as f:
			cnt = f.readlines()
			temp=[i for i in cnt if not i.strip().startswith('#')]
			conf = "".join(temp)

		return self.load(conf)

	# 块解析器
	def parse_block(self):
		data = []
		param_name = None
		param_value = None
		buf = ''
		while self._i < self._length:
			# 换行符可能block换行或item之间的换行
			if '\n' == self._config[self._i]:
				if buf and param_name:
					if param_value is None:
							param_value = []
					param_value.append(buf.strip())
					buf = ''
			elif ' ' == self._config[self._i]:
				if not param_name and len(buf.strip()) > 0:
					param_name = buf.strip()
					buf = ''
				else:
					buf += self._config[self._i]
			elif ';' == self._config[self._i]:
				if isinstance(param_value, list):
					# tag value
					param_value.append(buf.strip())
				else:
					# tag value
					param_value = buf.strip()
				# tag
				data.append({'name': param_name, 'value': param_value.split(' '), 'type': 'item'})
				param_name = None
				param_value = None
				buf = ''
			elif '{' == self._config[self._i]:
				self._i += 1
				block = self.parse_block()
				data.append({'name': param_name, 'param': buf.strip(), 'value': block, 'type': 'block'})
				param_name = None
				param_value = None
				buf = ''
			elif '}' == self._config[self._i]:
				self._i += 1
				return data
			elif '#' == self._config[self._i]:  # skip comments
				# 遇到#时,忽略下一字符为空格的注释
				if ' ' == self._config[self._i + 1]:
					while self._i < self._length and '\n' != self._config[self._i]:
						self._i += 1
				else:
					buf += self._config[self._i]
			else:
				buf += self._config[self._i]
			self._i += 1
		return data

第二步,把nginx配置中的servers和upstream和upsync目录放在主目录下
第三步,执行nginx.py 开始解析

import requests
import json,os
from time import sleep
from parser import Parser
import random
#coding=utf-8

apisix_addr='http://127.0.0.1:80'
header={'X-API-KEY': 'xxxxxxxxxxxxxxxxxxxxxx'}

def getrand():
  str_list=[]
  for i in range(8):
    str_list.append(random.choice('abcdefghifklmnopqrstuvwxyz123456789'))
  return "".join(str_list)

#滚动发布的应用列表
upsync_list=['app1','app2','app3']
ups_map={}

def parsenginx(path):
  #解析配置文件
  try:
    data=Parser().loadf(path)
  except Exception as e:
    print(e)
    return False
  for line in data:
    if(line['name']=='upstream'):
      upstream={}
      name=line['param']   #upstream名称
      upstream['type']='roundrobin'
      upstream['scheme']='http'
      upstream['timeout']={"connect":30,"send":30,"read":30}
      upstream['name']=line['param']
      upstream['retries']=3
      content=line['value']
      if(content[0]['name']=='upsync'):  #发现配置滚动发布的应用 
        upsync_path=[i['value'] for i in content if i['name']=='upsync_dump_path'][0][0]
        upsync_path=os.path.join('upsync',os.path.basename(upsync_path))
        upsync_data=Parser().loadf(upsync_path)
        hosts=[i['value'][0] for i in upsync_data]
      else:
        hosts=[i['value'][0] for i in content if not i['name'].startswith('#')]  #后端列表
      upstream['nodes']={i:100 for i in hosts}
      for app in upsync_list:     #滚动发布的应用列表的应用 默认接入dapr
        if(app in name):
          upstream['nodes']={"127.0.0.1:3500":100}
      datapost=json.dumps(upstream)
      url=apisix_addr+"/apisix/admin/upstreams"
      res=requests.post(url,data=datapost,headers=header)
      if(res.status_code not in [200,201]):
        print(url,res.status_code)
        print(upstream,res.json())
        continue 
      else:
        ups_map[name]=upstream
  
    if(line['name']=='server'):
      content=line['value']
      portlist=[i['value'][0] for i in content if i['name']=='listen']
      hosts_info=[i['value'] for i in content if i['name']=='server_name']
      if not hosts_info:      #没有域名的忽略
        continue  
      hosts=[i['value'] for i in content if i['name']=='server_name'][0]
      location_list=[i for i in content if i['name']=='location']  #location项目
      for location_item in location_list:     #每个location都是独立的路由
        routes={}
        randstr=getrand()  #随机字符串
        routes['methods']=["GET","POST","PUT","DELETE","PATCH","HEAD","OPTIONS","CONNECT","TRACE"]
        routes['status']=1
        routes['hosts']=hosts
        routes['name']=routes['hosts'][0]+'-'+randstr   #路由名称用随机字符串
        loc_uri=location_item['param']
        routes['uri']=location_item['param']+"*"
        loc_cnt=location_item['value']
        proxyinfo=[i for i in loc_cnt if i['name']=='proxy_pass']
        if(not proxyinfo):  #没有proxy_pass
          continue
        proxy_pass=proxyinfo[0]['value'][0].replace('$scheme://','').replace('http://','').replace('/','')  #获取proxy_pass对象
        if('.' in proxy_pass):      #说明没有用到upstream后端
          routes['upstream']={"type": "roundrobin","nodes": {proxy_pass: 100}}
        else:
          ifupsync=False
          for app in upsync_list:   #滚动发布的应用 默认接入dapr
            if(app in proxy_pass):
              ifupsync=True
              routes["plugins"]={"proxy-rewrite":{"regex_uri":["(.*)","/v1.0/invoke/{}/method/$1".format(app)]}}
              routes['upstream']={"type": "roundrobin","nodes": {"127.0.0.1:3500": 100}}
          if not ifupsync:
            routes['upstream']=ups_map.get(proxy_pass)         #proxy_pass锁定upstream
        datapost=json.dumps(routes)
        url=apisix_addr+"/apisix/admin/routes"
        res=requests.post(url,data=datapost,headers=header)
        if(res.status_code not in [200,201]):
          print(url)
          print(routes,res.json())

#解析upstream
file_list=os.listdir('upstream')
conf_list=[i for i in file_list if i.endswith('.conf')]
for conf in conf_list:  #遍历每个配置文件
  path=os.path.join('upstream',conf)
  parsenginx(path)
#解析servers
file_list=os.listdir('servers')
conf_list=[i for i in file_list if i.endswith('.conf')]
for conf in conf_list:  #遍历每个配置文件
  path=os.path.join('servers',conf)
  parsenginx(path)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值