diff --git a/flask-consul/manager.py b/flask-consul/manager.py index 66da848..a0fcdec 100755 --- a/flask-consul/manager.py +++ b/flask-consul/manager.py @@ -6,7 +6,7 @@ skey_path = 'ConsulManager/assets/secret/skey' if consul_kv.get_kv_dict(skey_path) == {}: consul_kv.put_kv(skey_path,{'sk':''.join(str(uuid.uuid4()).split('-'))}) -from views import login, blackbox, consul, jobs, nodes, selfnode, avd +from views import login, blackbox, consul, jobs, nodes, selfnode, avd, exp from units.cloud import huaweicloud,alicloud,tencent_cloud from units.avd import avd_list app = Flask(__name__) @@ -17,12 +17,14 @@ app.register_blueprint(jobs.blueprint) app.register_blueprint(nodes.blueprint) app.register_blueprint(selfnode.blueprint) app.register_blueprint(avd.blueprint) +app.register_blueprint(exp.blueprint) class Config(object): JOBS = [] SCHEDULER_API_ENABLED = True -init_jobs = consul_kv.get_kv_dict('ConsulManager/jobs') +ecs_jobs = consul_kv.get_kv_dict('ConsulManager/jobs') avd_jobs = consul_kv.get_kv_dict('ConsulManager/avd/jobs') -init_jobs.update(avd_jobs) +exp_jobs = consul_kv.get_kv_dict('ConsulManager/exp/jobs') +init_jobs = { **ecs_jobs, **avd_jobs, **exp_jobs } if init_jobs is not None: for k,v in init_jobs.items(): diff --git a/flask-consul/requirements.txt b/flask-consul/requirements.txt index e1117f6..8674e67 100644 --- a/flask-consul/requirements.txt +++ b/flask-consul/requirements.txt @@ -13,8 +13,11 @@ beautifulsoup4==4.11.1 huaweicloudsdkcore==3.0.78 huaweicloudsdkecs==3.0.78 huaweicloudsdkeps==3.0.78 +huaweicloudsdkbss==3.0.95 alibabacloud_resourcemanager20200331==2.1.0 alibabacloud_ecs20140526==2.1.0 +alibabacloud_bssopenapi20171214==2.0.5 tencentcloud-sdk-python-common==3.0.607 tencentcloud-sdk-python-cvm==3.0.607 tencentcloud-sdk-python-dcdb==3.0.607 +tencentcloud-sdk-python-billing==3.0.607 diff --git a/flask-consul/units/avd/avd_list.py b/flask-consul/units/avd/avd_list.py index 63a27bc..7d3e8de 100644 --- a/flask-consul/units/avd/avd_list.py +++ b/flask-consul/units/avd/avd_list.py @@ -41,9 +41,9 @@ def get_avd(): f"- 状态:{avd_dict['avd_stat']}({avd_dict['avd_collect']})\n" if avd_dict['avd_id'] == last_avd.get('avd_id'): content = content + '(已披露漏洞,今日推送为状态或类型有更新。)\n' - if avd_switch['switch'] and avd_switch['wecom'] and wecomwh.startswith('https://qyapi.weixin.qq.com'): + if avd_switch['switch'] and avd_switch.get('wecom',False) and wecomwh.startswith('https://qyapi.weixin.qq.com'): wecom(wecomwh,content) - if avd_switch['switch'] and avd_switch['dingding'] and dingdingwh.startswith('https://oapi.dingtalk.com'): + if avd_switch['switch'] and avd_switch.get('dingding',False) and dingdingwh.startswith('https://oapi.dingtalk.com'): dingding(dingdingwh,content) if avd_switch['switch'] and avd_switch.get('feishu',False) and feishuwh.startswith('https://open.feishu.cn'): title = '漏洞告警:' + avd_dict['avd_name'] diff --git a/flask-consul/units/cloud/alicloud.py b/flask-consul/units/cloud/alicloud.py index 7edef3a..f7c3433 100644 --- a/flask-consul/units/cloud/alicloud.py +++ b/flask-consul/units/cloud/alicloud.py @@ -4,10 +4,77 @@ from alibabacloud_resourcemanager20200331 import models as resource_manager_2020 from alibabacloud_ecs20140526.client import Client as Ecs20140526Client from alibabacloud_ecs20140526 import models as ecs_20140526_models from Tea.exceptions import TeaException +from alibabacloud_bssopenapi20171214.client import Client as BssOpenApi20171214Client +from alibabacloud_bssopenapi20171214 import models as bss_open_api_20171214_models +from alibabacloud_tea_util import models as util_models +from alibabacloud_tea_util.client import Client as UtilClient import sys,datetime from units import consul_kv from units.cloud import sync_ecs +from units.cloud import notify + +def exp(account,collect_days,notify_days,notify_amount): + ak,sk = consul_kv.get_aksk('alicloud',account) + now = datetime.datetime.utcnow().strftime('%Y-%m-%dT16:00:00Z') + collect = (datetime.datetime.utcnow() + datetime.timedelta(days=collect_days+1)).strftime('%Y-%m-%dT16:00:00Z') + config = open_api_models.Config(access_key_id=ak,access_key_secret=sk) + config.endpoint = f'business.aliyuncs.com' + client = BssOpenApi20171214Client(config) + query_available_instances_request = bss_open_api_20171214_models.QueryAvailableInstancesRequest( + renew_status='ManualRenewal', + end_time_start=now, + end_time_end=collect) + runtime = util_models.RuntimeOptions() + amount_response = client.query_account_balance() + try: + exp = client.query_available_instances_with_options(query_available_instances_request, runtime) + exp_list = exp.body.to_map()['Data']['InstanceList'] + exp_dict = {} + notify_dict = {} + amount_dict = {} + for i in exp_list: + endtime = datetime.datetime.strptime(i['EndTime'],'%Y-%m-%dT%H:%M:%SZ') + datetime.timedelta(hours=8) + endtime_str = endtime.strftime('%Y-%m-%d') + exp_dict[i['InstanceID']] = {'Region':i['Region'],'Product':i['ProductCode'], + 'EndTime':endtime_str,'Ptype':i.get('ProductType',i['ProductCode'])} + if (endtime - datetime.datetime.now()).days < notify_days: + notify_dict[i['InstanceID']] = exp_dict[i['InstanceID']] + consul_kv.put_kv(f'ConsulManager/exp/lists/alicloud/{account}/exp', exp_dict) + amount = float(amount_response.body.data.available_amount.replace(',','')) + consul_kv.put_kv(f'ConsulManager/exp/lists/alicloud/{account}/amount',{'amount':amount}) + if amount < notify_amount: + amount_dict = {'amount':amount} + exp_config = consul_kv.get_value('ConsulManager/exp/config') + wecomwh = exp_config.get('wecomwh','') + dingdingwh = exp_config.get('dingdingwh','') + feishuwh = exp_config.get('feishuwh','') + if notify_dict != {}: + msg = [f'### 阿里云账号 {account}:\n### 以下资源到期日小于 {notify_days} 天:'] + for k,v in notify_dict.items(): + msg.append(f"- {v['Region']}:{v['Product']}:{k}:{v['EndTime']}") + content = '\n'.join(msg) + if exp_config['switch'] and exp_config.get('wecom',False): + notify.wecom(wecomwh,content) + if exp_config['switch'] and exp_config.get('dingding',False): + notify.dingding(dingdingwh,content) + if exp_config['switch'] and exp_config.get('feishu',False): + title = '阿里云资源到期通知' + md = content + notify.feishu(feishuwh,title,md) + if amount_dict != {}: + content = f'### 阿里云账号 {account}:\n### 可用余额:{amount} 元' + if exp_config['switch'] and exp_config.get('wecom',False): + notify.wecom(wecomwh,content) + if exp_config['switch'] and exp_config.get('dingding',False): + notify.dingding(dingdingwh,content) + if exp_config['switch'] and exp_config.get('feishu',False): + title = '阿里云余额不足通知' + md = content + notify.feishu(feishuwh,title,md) + + except Exception as error: + UtilClient.assert_as_string(error.message) def group(account): ak,sk = consul_kv.get_aksk('alicloud',account) diff --git a/flask-consul/units/cloud/get_tx_exp.py b/flask-consul/units/cloud/get_tx_exp.py new file mode 100755 index 0000000..17c880f --- /dev/null +++ b/flask-consul/units/cloud/get_tx_exp.py @@ -0,0 +1,27 @@ +#!/usr/bin/python3 +import json +from tencentcloud.common import credential +from tencentcloud.common.profile.client_profile import ClientProfile +from tencentcloud.common.profile.http_profile import HttpProfile +from tencentcloud.common.exception.tencent_cloud_sdk_exception import TencentCloudSDKException +from tencentcloud.billing.v20180709 import billing_client, models +try: + cred = credential.Credential("AKIDWqwnOjpgHchX7SYP1NUMyKQGrCI8j40g", "TgdLn0xe5HDtJUQ6WgMqCKEuNdfS1LRJ") + httpProfile = HttpProfile() + httpProfile.endpoint = "billing.tencentcloudapi.com" + + clientProfile = ClientProfile() + clientProfile.httpProfile = httpProfile + client = billing_client.BillingClient(cred, "", clientProfile) + + req = models.DescribeAccountBalanceRequest() + params = { + + } + req.from_json_string(json.dumps(params)) + + resp = client.DescribeAccountBalance(req).RealBalance + print(resp/100) + +except TencentCloudSDKException as err: + print(err) diff --git a/flask-consul/units/cloud/huaweicloud.py b/flask-consul/units/cloud/huaweicloud.py index 8f1da57..5746b0a 100644 --- a/flask-consul/units/cloud/huaweicloud.py +++ b/flask-consul/units/cloud/huaweicloud.py @@ -1,12 +1,90 @@ from huaweicloudsdkcore.auth.credentials import GlobalCredentials,BasicCredentials from huaweicloudsdkeps.v1.region.eps_region import EpsRegion from huaweicloudsdkcore.exceptions import exceptions +from huaweicloudsdkbss.v2.region.bss_region import BssRegion from huaweicloudsdkeps.v1 import * from huaweicloudsdkecs.v2.region.ecs_region import EcsRegion from huaweicloudsdkecs.v2 import * +from huaweicloudsdkbss.v2 import * import sys,datetime from units import consul_kv from units.cloud import sync_ecs +from units.cloud import notify + +def exp(account,collect_days,notify_days,notify_amount): + ak,sk = consul_kv.get_aksk('huaweicloud',account) + now = datetime.datetime.utcnow().strftime('%Y-%m-%dT16:00:00Z') + collect = (datetime.datetime.utcnow() + datetime.timedelta(days=collect_days+1)).strftime('%Y-%m-%dT16:00:00Z') + credentials = GlobalCredentials(ak, sk) + try: + client = BssClient.new_builder() \ + .with_credentials(credentials) \ + .with_region(BssRegion.value_of("cn-north-1")) \ + .build() + request = ListPayPerUseCustomerResourcesRequest() + listQueryResourcesReqStatusListbody = [2] + request.body = QueryResourcesReq( + expire_time_end=collect, + limit=500, + status_list=listQueryResourcesReqStatusListbody, + only_main_resource=1 + ) + exp_list = client.list_pay_per_use_customer_resources(request).to_dict()['data'] + exp_dict = {} + notify_dict = {} + amount_dict = {} + for i in exp_list: + endtime = datetime.datetime.strptime(i['expire_time'],'%Y-%m-%dT%H:%M:%SZ') + datetime.timedelta(hours=8.1) + endtime_str = endtime.strftime('%Y-%m-%d') + i['service_type_code'].replace('hws.service.type.','') + if i['expire_policy'] not in [1,3,4]: + exp_dict[i['resource_id']] = {'Region':i['region_code'],'Product':i['resource_spec_code'], + 'EndTime':endtime_str,'Name':i['resource_name'],'Ptype':i['resource_type_code']} + if (endtime - datetime.datetime.now()).days < notify_days: + notify_dict[i['resource_id']] = exp_dict[i['resource_id']] + + consul_kv.put_kv(f'ConsulManager/exp/lists/huaweicloud/{account}/exp', exp_dict) + + request = ShowCustomerAccountBalancesRequest() + response = client.show_customer_account_balances(request).to_dict()['account_balances'] + amount = [i['amount'] for i in response if i['account_type'] == 1][0] + consul_kv.put_kv(f'ConsulManager/exp/lists/huaweicloud/{account}/amount',{'amount':amount}) + if amount < notify_amount: + amount_dict = {'amount':amount} + exp_config = consul_kv.get_value('ConsulManager/exp/config') + wecomwh = exp_config.get('wecomwh','') + dingdingwh = exp_config.get('dingdingwh','') + feishuwh = exp_config.get('feishuwh','') + if notify_dict != {}: + msg = [f'### 华为云账号 {account}:\n### 以下资源到期日小于 {notify_days} 天:'] + for k,v in notify_dict.items(): + msg.append(f"- {v['Region']}:{v['Product']}:{v['Name']}:{v['EndTime']}") + content = '\n'.join(msg) + if exp_config['switch'] and exp_config.get('wecom',False): + notify.wecom(wecomwh,content) + if exp_config['switch'] and exp_config.get('dingding',False): + notify.dingding(dingdingwh,content) + if exp_config['switch'] and exp_config.get('feishu',False): + title = '华为云资源到期通知' + md = content + notify.feishu(feishuwh,title,md) + if amount_dict != {}: + content = f'### 华为云账号 {account}:\n### 可用余额:{amount} 元' + if exp_config['switch'] and exp_config.get('wecom',False): + notify.wecom(wecomwh,content) + if exp_config['switch'] and exp_config.get('dingding',False): + notify.dingding(dingdingwh,content) + if exp_config['switch'] and exp_config.get('feishu',False): + title = '华为云余额不足通知' + md = content + notify.feishu(feishuwh,title,md) + + except exceptions.ClientRequestException as e: + print(e.status_code) + print(e.request_id) + print(e.error_code) + print(e.error_msg) + def group(account): ak,sk = consul_kv.get_aksk('huaweicloud',account) now = datetime.datetime.now().strftime('%m%d/%H:%M') diff --git a/flask-consul/units/cloud/notify.py b/flask-consul/units/cloud/notify.py new file mode 100644 index 0000000..9da0ca5 --- /dev/null +++ b/flask-consul/units/cloud/notify.py @@ -0,0 +1,23 @@ +import requests,json +def wecom(webhook,content): + headers = {'Content-Type': 'application/json'} + params = {'msgtype': 'markdown', 'markdown': {'content' : content}} + data = bytes(json.dumps(params), 'utf-8') + response = requests.post(webhook, headers=headers, data=data) + print('【wecom】',response.json(),flush=True) + +def dingding(webhook,content): + headers = {'Content-Type': 'application/json'} + params = {"msgtype":"markdown","markdown":{"title":"资源告警","text":content},"at":{"isAtAll":True}} + data = bytes(json.dumps(params), 'utf-8') + response = requests.post(webhook, headers=headers, data=data) + print('【dingding】',response.json(),flush=True) + +def feishu(webhook,title,md): + headers = {'Content-Type': 'application/json'} + params = {"msg_type": "interactive", + "card": {"header": {"title": {"tag": "plain_text","content": title},"template": "red"}, + "elements": [{"tag": "markdown","content": f"{md}\n",}]}} + data = json.dumps(params) + response = requests.post(webhook, headers=headers, data=data) + print('【feishu】',response.json(),flush=True) diff --git a/flask-consul/units/cloud/tencent_cloud.py b/flask-consul/units/cloud/tencent_cloud.py index 3deca41..60ad43f 100644 --- a/flask-consul/units/cloud/tencent_cloud.py +++ b/flask-consul/units/cloud/tencent_cloud.py @@ -9,6 +9,70 @@ import sys,datetime #import consul_kv,sync_ecs from units import consul_kv from units.cloud import sync_ecs +from units.cloud import notify +def exp(account,collect_days,notify_days,notify_amount): + from tencentcloud.billing.v20180709 import billing_client, models + ak,sk = consul_kv.get_aksk('tencent_cloud',account) + exp_dict = {} + notify_dict = {} + amount_dict = {} + try: + ecs_list = consul_kv.get_services_meta(f'tencent_cloud_{account}_ecs').get('ecs_list',[]) + now = datetime.datetime.now() + for i in ecs_list: + exp_day = datetime.datetime.strptime(i['exp'], '%Y-%m-%d') + if (now - exp_day).days <= collect_days: + exp_dict[i['iid']] = {'Region':i['region'],'Product':i['os'],'Name':i['name'], + 'EndTime':i['exp'],'Ptype':i['cpu']+i['mem'],'Group':i['group']} + if (now - exp_day).days <= notify_days: + notify_dict[i['iid']] = exp_dict[i['iid']] + consul_kv.put_kv(f'ConsulManager/exp/lists/tencent_cloud/{account}/exp', exp_dict) + + cred = credential.Credential(ak, sk) + httpProfile = HttpProfile() + httpProfile.endpoint = "billing.tencentcloudapi.com" + + clientProfile = ClientProfile() + clientProfile.httpProfile = httpProfile + client = billing_client.BillingClient(cred, "", clientProfile) + + req = models.DescribeAccountBalanceRequest() + params = {} + req.from_json_string(json.dumps(params)) + + amount = client.DescribeAccountBalance(req).RealBalance/100 + consul_kv.put_kv(f'ConsulManager/exp/lists/tencent_cloud/{account}/amount',{'amount':amount}) + if amount < notify_amount: + amount_dict = {'amount':amount} + exp_config = consul_kv.get_value('ConsulManager/exp/config') + wecomwh = exp_config.get('wecomwh','') + dingdingwh = exp_config.get('dingdingwh','') + feishuwh = exp_config.get('feishuwh','') + if notify_dict != {}: + msg = [f'### 腾讯云账号 {account}:\n### 以下资源到期日小于 {notify_days} 天:'] + for k,v in notify_dict.items(): + msg.append(f"- {v['Region']}:{v['Product']}:{v['Group']}:{v['Name']}:{v['EndTime']}") + content = '\n'.join(msg) + if exp_config['switch'] and exp_config.get('wecom',False): + notify.wecom(wecomwh,content) + if exp_config['switch'] and exp_config.get('dingding',False): + notify.dingding(dingdingwh,content) + if exp_config['switch'] and exp_config.get('feishu',False): + title = '腾讯云资源到期通知' + md = content + notify.feishu(feishuwh,title,md) + if amount_dict != {}: + content = f'### 腾讯云账号 {account}:\n### 可用余额:{amount} 元' + if exp_config['switch'] and exp_config.get('wecom',False): + notify.wecom(wecomwh,content) + if exp_config['switch'] and exp_config.get('dingding',False): + notify.dingding(dingdingwh,content) + if exp_config['switch'] and exp_config.get('feishu',False): + title = '腾讯云余额不足通知' + md = content + notify.feishu(feishuwh,title,md) + except TencentCloudSDKException as err: + print(err) def group(account): from tencentcloud.dcdb.v20180411 import dcdb_client, models diff --git a/flask-consul/units/consul_kv.py b/flask-consul/units/consul_kv.py index 2ca0e84..7cebe00 100644 --- a/flask-consul/units/consul_kv.py +++ b/flask-consul/units/consul_kv.py @@ -69,7 +69,17 @@ def get_ecs_services(job_id): return {'code': 20000,'ecs_list': ecs_list} else: return {'code': 50000, 'data': f'{response.status_code}:{response.text}'} - + +def get_services_meta(services_name): + url = f'{consul_url}/agent/services?filter=Service == "{services_name}"' + response = requests.get(url, headers=headers) + if response.status_code == 200: + info = response.json() + ecs_list = [i['Meta'] for i in info.values()] + return {'code': 20000,'ecs_list': ecs_list} + else: + return {'code': 50000, 'data': f'{response.status_code}:{response.text}'} + def get_aksk(cloud,account): import myaes aksk_dict = get_value(f'ConsulManager/assets/{cloud}/aksk/{account}') diff --git a/flask-consul/views/exp.py b/flask-consul/views/exp.py new file mode 100644 index 0000000..02e1627 --- /dev/null +++ b/flask-consul/views/exp.py @@ -0,0 +1,61 @@ +from flask import Blueprint +from flask_restful import reqparse, Resource, Api +from flask_apscheduler import APScheduler +from units import token_auth,consul_kv +import json +from .jobs import deljob,addjob,runjob +blueprint = Blueprint('exp',__name__) +api = Api(blueprint) + +parser = reqparse.RequestParser() +parser.add_argument('exp_config_dict',type=dict) + +class Exp(Resource): + #decorators = [token_auth.auth.login_required] + def get(self,stype): + if stype == 'list': + exp_dict = consul_kv.get_kv_dict('ConsulManager/exp/list') + exp_list = list(exp_dict.values()) + return {'code': 20000, 'exp_list': exp_list} + if stype == 'config': + exp_config = consul_kv.get_value('ConsulManager/exp/switch') + return {'code': 20000, 'exp_config': exp_config} + def post(self,stype): + if stype == 'config': + args = parser.parse_args() + exp_config_dict = args['exp_config_dict'] + consul_kv.put_kv('ConsulManager/exp/config',exp_config_dict) + cloud_job_list = consul_kv.get_keys_list('ConsulManager/jobs') + cloud_list = [i for i in cloud_job_list if i.endswith('/group') and 'tencent_cloud' in i] + collect_days = exp_config_dict['collect_days'] + notify_days = exp_config_dict['notify_days'] + notify_amount = exp_config_dict['notify_amount'] + if exp_config_dict['switch']: + for i in cloud_list: + vendor,account = i.split('/')[2:4] + exp_job_id = f'{vendor}/{account}/exp' + exp_job_func = f'__main__:{vendor}.exp' + exp_job_args = [account,collect_days,notify_days,notify_amount] + exp_job_interval = 60 + addjob(exp_job_id,exp_job_func,exp_job_args,exp_job_interval) + exp_job_dict = {'id':exp_job_id,'func':exp_job_func,'args':exp_job_args,'minutes':exp_job_interval,'trigger': 'interval','replace_existing': True} + consul_kv.put_kv(f'ConsulManager/exp/jobs/{vendor}/{account}',exp_job_dict) + runjob(exp_job_id) + return {'code': 20000, 'data': '到期日与余额采集功能开启!'} + else: + for i in cloud_list: + vendor,account = i.split('/')[2:4] + exp_job_id = f'{vendor}/{account}/exp' + deljob(exp_job_id) + consul_kv.del_key_all('ConsulManager/exp/jobs/') + consul_kv.del_key_all('ConsulManager/exp/lists/') + return {'code': 20000, 'data': '到期日与余额采集功能关闭!'} + if stype == 'run': + exp_config_dict = consul_kv.get_value('ConsulManager/exp/switch') + if exp_config_dict['switch']: + consul_kv.del_key('ConsulManager/exp/list/0') + runjob('exp_list') + return {'code': 20000, 'data': '漏洞采集通知执行成功!'} + else: + return {'code': 50000, 'data': '漏洞采集功能未开启!'} +api.add_resource(Exp, '/api/exp/') diff --git a/vue-consul/Dockerfile b/vue-consul/Dockerfile index 59dad1b..26086ca 100644 --- a/vue-consul/Dockerfile +++ b/vue-consul/Dockerfile @@ -5,5 +5,5 @@ RUN npm install --registry=https://registry.npm.taobao.org && npm run build:prod FROM nginx:stable-alpine WORKDIR /www -COPY --from=builder /vue/http-ops.conf /etc/nginx/conf.d/ +COPY --from=builder /vue/http-ops.conf /etc/nginx/conf.d/default.conf COPY --from=builder /vue/dist dist/ diff --git a/vue-consul/Dockerfile.tensuns b/vue-consul/Dockerfile.tensuns index 8b0a7c3..bdaa066 100644 --- a/vue-consul/Dockerfile.tensuns +++ b/vue-consul/Dockerfile.tensuns @@ -7,5 +7,5 @@ RUN mv -f src/views/login/index.vue.tensuns src/views/login/index.vue && \ FROM nginx:stable-alpine WORKDIR /www -COPY --from=builder /vue/http-ops.conf /etc/nginx/conf.d/ +COPY --from=builder /vue/http-ops.conf /etc/nginx/conf.d/default.conf COPY --from=builder /vue/dist dist/ diff --git a/vue-consul/src/main.js b/vue-consul/src/main.js index ffc1880..599c3d0 100644 --- a/vue-consul/src/main.js +++ b/vue-consul/src/main.js @@ -46,6 +46,7 @@ Object.keys(filters).forEach(key => { }) Vue.config.productionTip = false +Vue.prototype.VER = 'v0.6.5' new Vue({ el: '#app', diff --git a/vue-consul/src/views/login/index.vue b/vue-consul/src/views/login/index.vue index 1ee8c6d..04c64ba 100644 --- a/vue-consul/src/views/login/index.vue +++ b/vue-consul/src/views/login/index.vue @@ -46,7 +46,7 @@
- v0.6.5 + {{ VER }}
diff --git a/vue-consul/src/views/login/index.vue.tensuns b/vue-consul/src/views/login/index.vue.tensuns index 1292b27..1eef321 100644 --- a/vue-consul/src/views/login/index.vue.tensuns +++ b/vue-consul/src/views/login/index.vue.tensuns @@ -43,7 +43,7 @@
- v0.6.5 + {{ VER }}
diff --git a/vue-consul/src/views/node-exporter/self.vue b/vue-consul/src/views/node-exporter/self.vue index b275838..edb403f 100644 --- a/vue-consul/src/views/node-exporter/self.vue +++ b/vue-consul/src/views/node-exporter/self.vue @@ -23,7 +23,7 @@ 导出 - + 导入 @@ -43,7 +43,7 @@ 批量删除 -
+