Skip to content

Commit d04372a

Browse files
authored
Merge pull request #49 from fadetop/0.8
Add v0.8
2 parents d2a7000 + d9787fc commit d04372a

17 files changed

Lines changed: 427 additions & 143 deletions

File tree

README.md

Lines changed: 0 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -205,91 +205,6 @@ bash omp grafana [status|start|stop|restart]
205205
bash omp loki [status|start|stop|restart]
206206
```
207207

208-
更新日志
209-
V0.1.0 (2021.11.30)
210-
新增功能:
211-
- 【仪表盘】
212-
- 全局状态概览
213-
- 当前异常信息展示
214-
- 各模块状态展示
215-
- 【主机管理】
216-
- 主机纳管(添加、导入、编辑、维护、删除)
217-
- 主机自动监控、告警
218-
- 【应用商店】
219-
- 组件、应用WEB发布、服务端自动发现
220-
- 组件、应用部署,自动编排解决依赖
221-
- 【服务管理】
222-
- 服务管理(启动、停止、重启、删除)
223-
- 服务监控(监控、日志、告警、自愈)
224-
- 【应用监控】
225-
- 实时展示处于异常的主机、服务信息,呼应仪表盘的异常清单
226-
- 告警历史记录查看,未读提醒,按添加检索
227-
- 支持监控组件地址自定义,便于对接现有监控平台
228-
- 【状态巡检】
229-
- 支持主机巡检、组件巡检、深度分析,且支持导出
230-
- 支持定时自动执行巡检任务
231-
- 【系统管理】
232-
- 用户账户管理
233-
- 支持全局维护模式,避免人为操作时误报
234-
235-
236-
更新日志
237-
V0.5.0 (2022.4.11)
238-
新增功能:
239-
- 【应用商店】
240-
- 组件、应用服务的升级及回滚
241-
- 应用服务的增量安装
242-
- 【部署模板】
243-
- 支持通过部署模版实现批量部署
244-
- 【应用监控】
245-
- 支持告警邮件配置,将告警信息发送至指定邮箱
246-
- 【故障自愈】
247-
- 展示故障自愈记录
248-
- 支持监控到服务状态异常后自动进行重启
249-
- 支持设置服务自愈尝试次数
250-
- 【指标中心】
251-
- 支持添加自定义告警指标规则
252-
- 添加自定义扩展采集指标
253-
- 【数据备份】
254-
- 支持mysql、arangodb、postgreSql数据备份
255-
- 备份记录展示、下载、删除
256-
- 支持自定义保存路径、定时备份策略及邮件推送备份内容
257-
- 【实用工具】
258-
- 内置部分运维实用小工具
259-
- 展示小工具执行过程、输出展示及生成文件下载
260-
- 【系统管理】
261-
- 增加邮件管理,支持设置smtp邮件服务器作为全局邮件发件箱
262-
263-
功能优化:
264-
- 【平台优化】
265-
- 优化主机纳管逻辑,增加纳管成功率,支持删除主机
266-
- 优化应用安装服务逻辑代码
267-
- 优化巡检逻辑
268-
- 优化部分前端页面显示及交互效果
269-
- 【其他】
270-
- 修复已知bug
271-
272-
V0.6.0 (2022.11.29)
273-
新增功能:
274-
- 升级内置基础组件和环境
275-
- alertmanager 升级至 v0.24.0
276-
- tengine 升级至 v1.22.0
277-
- 扩充内置环境中部分第三方库
278-
- 升级主机 Agent & 监控 Agent
279-
- 优化小工具异步任务执行逻辑
280-
- 更新 prometheus 和 loki 的配置
281-
- 修复 grafana 面板中 mysql 显示异常问题
282-
- 补充应用商店基础组件包:mysq、elasticsearch
283-
- 组件包从代码库抽离,减少源码 & 包体量
284-
285-
V0.7.0 (2022.12.30)
286-
- 完善 OMP 管理脚本功能
287-
- 支持升级、回滚,支持断点重试
288-
- 支持命令行卸载应用商店已发布服务
289-
- 内置 Redis 5.0.37 升级至 6.2.7
290-
- 验证码登陆
291-
- 修改密码长度异常问题
292-
293208
欢迎加入
294209
获取更多关于OMP的技术资料,或加入OMP开发者交流群,可扫描下方二维码咨询
295210

UpdateLog.md

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,23 +7,23 @@
77

88

99
## v0.1.0 (2021.11.30)
10-
- 【仪表盘】
10+
- 【仪表盘】
1111
- 全局状态概览
1212
- 当前异常信息展示
13-
- 各模块状态展示
13+
- 各模块状态展示
1414
- 【主机管理】
1515
- 主机纳管(添加、导入、编辑、维护、删除)
16-
- 主机自动监控、告警
16+
- 主机自动监控、告警
1717
- 【应用商店】
1818
- 组件、应用WEB发布、服务端自动发现
19-
- 组件、应用部署,自动编排解决依赖
19+
- 组件、应用部署,自动编排解决依赖
2020
- 【服务管理】
2121
- 服务管理(启动、停止、重启、删除)
2222
- 服务监控(监控、日志、告警、自愈)
2323
- 【应用监控】
2424
- 实时展示处于异常的主机、服务信息,呼应仪表盘的异常清单
2525
- 告警历史记录查看,未读提醒,按添加检索
26-
- 支持监控组件地址自定义,便于对接现有监控平台
26+
- 支持监控组件地址自定义,便于对接现有监控平台
2727
- 【状态巡检】
2828
- 支持主机巡检、组件巡检、深度分析,且支持导出
2929
- 支持定时自动执行巡检任务
@@ -35,7 +35,7 @@
3535

3636
## v0.5.0 (2022.04.11)
3737

38-
- 【应用商店】
38+
- 【应用商店】
3939
- 组件、应用服务的升级及回滚
4040
- 应用服务的增量安装
4141
- 【部署模板】
@@ -63,7 +63,7 @@
6363
- 优化主机纳管逻辑,增加纳管成功率,支持删除主机
6464
- 优化应用安装服务逻辑代码
6565
- 优化巡检逻辑
66-
- 优化部分前端页面显示及交互效果
66+
- 优化部分前端页面显示及交互效果
6767
- 【其他】
6868
- 修复已知bug
6969

@@ -92,4 +92,10 @@
9292
- 修改密码长度异常问题
9393

9494

95-
95+
## v0.8.0 (2023.01.30)
96+
- 新增监控功能
97+
- 产品http请求 5XX 错误
98+
- jvm 文件句柄使用率过高
99+
- 修复部分服务无法获取 cpu、内存问题
100+
- 增加只读用户功能
101+
- 修复添加主机提示已经存在问题
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Generated by Django 3.1.4 on 2023-01-10 17:39
2+
3+
from django.db import migrations, models
4+
5+
6+
class Migration(migrations.Migration):
7+
dependencies = [
8+
('db_models', '0028_auto_20220304_2001'),
9+
]
10+
11+
operations = [
12+
migrations.AddField(
13+
model_name='userprofile',
14+
name='role',
15+
field=models.CharField(blank=True, help_text='用户角色', max_length=128, null=True, verbose_name='用户角色'),
16+
),
17+
migrations.AlterField(
18+
model_name='alertrule',
19+
name='hash_data',
20+
field=models.CharField(blank=True, max_length=255, null=True, verbose_name='唯一hash值'),
21+
),
22+
]

omp_server/db_models/models/user.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
class UserProfile(AbstractUser):
66
""" 自定义用户表 """
7+
role = models.CharField("用户角色", max_length=128, null=True, blank=True, help_text="用户角色")
78

89
class Meta:
910
""" 元数据 """

omp_server/hosts/hosts_serializers.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -384,7 +384,7 @@ class HostFieldCheckSerializer(ModelSerializer):
384384
validators=[
385385
NoEmojiValidator(),
386386
NoChineseValidator(),
387-
ReValidator(regex=r"^[-a-z0-9].*$"),
387+
ReValidator(regex=r"^[-a-zA-Z0-9].*$"),
388388
])
389389

390390
ip = serializers.IPAddressField(

omp_server/omp_server/settings.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@
6363
'django.contrib.auth.middleware.AuthenticationMiddleware',
6464
'django.contrib.messages.middleware.MessageMiddleware',
6565
'django.middleware.clickjacking.XFrameOptionsMiddleware',
66+
'utils.middleware_handler.RoleAuthenticationMiddleware',
6667
'utils.middleware_handler.OperationLogMiddleware'
6768
]
6869

omp_server/promemonitor/grafana_url.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,9 +79,11 @@ def explain_prometheus(params):
7979
compare_list.append(tmp_list)
8080
tmp_dict['type'] = "host" if label.get(
8181
'job') == 'nodeExporter' else "service"
82-
tmp_dict['ip'] = label.get('instance').split(":")[0]
82+
tmp_dict['ip'] = label.get('instance').split(":")[0] if label.get('instance') else ''
8383
tmp_dict['instance_name'] = label.get('app') if label.get(
8484
'app') else host_list.get(tmp_dict.get('ip'))
85+
if not tmp_dict['instance_name']:
86+
tmp_dict['instance_name'] = label.get("job", "").split("Exporter")[0]
8587
tmp_dict['severity'] = label.get('severity')
8688
annotation = lab.get('annotations')
8789
tmp_dict['description'] = annotation.get('description')

omp_server/promemonitor/views.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -946,10 +946,15 @@ def create(self, request, *args, **kwargs):
946946
else:
947947
return Response(
948948
data={"code": 1, "message": f"创建指标规则过程中出错: 未识别的规则类型"})
949-
request.data["labels"] = {
950-
"job": '{}Exporter'.format(request.data["service"]),
951-
"severity": severity
952-
}
949+
if request.data["service"] != "service":
950+
request.data["labels"] = {
951+
"job": '{}Exporter'.format(request.data["service"]),
952+
"severity": severity
953+
}
954+
else:
955+
request.data["labels"] = {
956+
"severity": severity
957+
}
953958
if id != 0:
954959
if AlertRule.objects.filter(expr=request.data["expr"],
955960
severity=severity).exclude(id=id).exists():

omp_server/users/users_serializers.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ class Meta:
5252
""" 元数据 """
5353
model = UserProfile
5454
fields = ("id", "username", "password", "email", "re_password",
55-
"date_joined", "is_active", "is_superuser")
55+
"date_joined", "is_active", "is_superuser", "role")
5656
read_only_fields = ("date_joined", "is_active", "is_superuser")
5757

5858
def validate_username(self, username):

omp_server/utils/middleware_handler.py

Lines changed: 53 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,23 +15,36 @@
1515
import logging
1616

1717
from django.urls import resolve
18-
# from django.http import HttpRequest
1918
from django.utils.deprecation import MiddlewareMixin
19+
from django.http import JsonResponse
2020

2121
from rest_framework.reverse import reverse
2222
from rest_framework_jwt.utils import jwt_decode_handler
2323

2424
from jwt import DecodeError
2525

2626
from db_models.models import (
27-
OperateLog, UserLoginLog
27+
OperateLog, UserLoginLog, UserProfile
2828
)
2929
from django.utils import timezone
3030
from omp_server.settings import INTERFACE_KINDS
3131

3232
logger = logging.getLogger("server")
3333

3434

35+
def get_username_of_token(token):
36+
"""通过jwt token 解析username"""
37+
_token_user = jwt_decode_handler(token)
38+
_username = _token_user.get("username")
39+
return _username
40+
41+
42+
USER_TO_ROLE_EN_DICT = {
43+
"superuser": "普通管理员",
44+
"readonlyuser": "只读用户"
45+
}
46+
47+
3548
class OperationLogMiddleware(MiddlewareMixin):
3649
"""用于处理操作日志的中间件"""
3750

@@ -57,34 +70,34 @@ def process_response(self, request, response):
5770
_ip, _ = ipware.get_client_ip(request)
5871
try:
5972
token = request.COOKIES.get("jwtToken", "toke")
60-
_token_user = jwt_decode_handler(token)
61-
_username = _token_user.get("username")
73+
_username = get_username_of_token(token)
6274
except DecodeError:
6375
_username = "匿名用户"
6476
if _url == reverse("login"):
6577
_desc = "用户登录"
78+
request_result = ""
79+
_token = None
6680
if "token" in response.data:
6781
request_result = "登录成功"
82+
_token = response.data.get("token", "")
83+
_username = get_username_of_token(_token)
6884
else:
69-
request_result = "登录失败"
70-
# TODO 角色管理
71-
_username = "admin" if _username == "匿名用户" else _username
85+
return response
86+
_token_user = UserProfile.objects.filter(username=_username).first()
7287
data = {
7388
'username': _username,
7489
'login_time': timezone.now(),
75-
'role': "超级管理员用户",
90+
'role': USER_TO_ROLE_EN_DICT.get(_token_user.role.lower(), ""),
7691
'ip': _ip,
7792
'request_result': request_result
7893
}
7994
UserLoginLog.objects.create(**data)
80-
# OperateLog(
81-
# username=_username, request_ip=_ip, request_method=_method,
82-
# request_url=_url, description=_desc,
83-
# response_code=response_code, request_result=request_result
84-
# ).save()
8595
else:
8696
# 读取已封装响应数据
87-
res_data = json.loads(response.rendered_content)
97+
try:
98+
res_data = json.loads(response.rendered_content)
99+
except Exception as e:
100+
return response
88101
method_dc = {
89102
'put': '修改',
90103
'get': '查看',
@@ -103,3 +116,29 @@ def process_response(self, request, response):
103116
request_result=res_data.get("message", "")
104117
).save()
105118
return response
119+
120+
121+
class RoleAuthenticationMiddleware(MiddlewareMixin):
122+
"""用户角色访问限制"""
123+
124+
def process_view(self, request, func, *args, **kwargs):
125+
_method = request.method.lower()
126+
if _method == "get":
127+
return None
128+
_url = request.path
129+
if _url.startswith("/proxy/v1/grafana") or _url.startswith("/api/login/"):
130+
return None
131+
try:
132+
token = request.COOKIES.get("jwtToken", "toke")
133+
_token_user = jwt_decode_handler(token)
134+
_username = _token_user.get("username")
135+
except DecodeError:
136+
_username = "匿名用户"
137+
_token_user = UserProfile.objects.filter(username=_username).first()
138+
if not _token_user:
139+
# 非页面访问omp接口,放行
140+
return None
141+
if _token_user.role.lower() == "superuser":
142+
return None
143+
logger.error(f"{_token_user} prohibited this action")
144+
return JsonResponse({"code": 1, "data": None, "message": f"该{_token_user.username}用户无权限"})

0 commit comments

Comments
 (0)