mirror of
https://github.com/veops/cmdb.git
synced 2025-08-07 00:21:07 +08:00
Modify code organization
This commit is contained in:
29
cmdb-api/api/views/__init__.py
Normal file
29
cmdb-api/api/views/__init__.py
Normal file
@@ -0,0 +1,29 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
|
||||
import os
|
||||
|
||||
from flask import Blueprint
|
||||
from flask_restful import Api
|
||||
|
||||
from api.resource import register_resources
|
||||
from api.views.account import LoginView, LogoutView
|
||||
|
||||
HERE = os.path.abspath(os.path.dirname(__file__))
|
||||
|
||||
# account
|
||||
blueprint_account = Blueprint('account_api', __name__, url_prefix='/api')
|
||||
account_rest = Api(blueprint_account)
|
||||
account_rest.add_resource(LoginView, LoginView.url_prefix)
|
||||
account_rest.add_resource(LogoutView, LogoutView.url_prefix)
|
||||
|
||||
|
||||
# cmdb
|
||||
blueprint_cmdb_v01 = Blueprint('cmdb_api_v01', __name__, url_prefix='/api/v0.1')
|
||||
rest = Api(blueprint_cmdb_v01)
|
||||
register_resources(os.path.join(HERE, "cmdb"), rest)
|
||||
|
||||
|
||||
# acl
|
||||
blueprint_acl_v1 = Blueprint('acl_api_v1', __name__, url_prefix='/api/v1/acl')
|
||||
rest = Api(blueprint_acl_v1)
|
||||
register_resources(os.path.join(HERE, "acl"), rest)
|
64
cmdb-api/api/views/account.py
Normal file
64
cmdb-api/api/views/account.py
Normal file
@@ -0,0 +1,64 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
|
||||
import datetime
|
||||
|
||||
import jwt
|
||||
from flask import abort
|
||||
from flask import current_app
|
||||
from flask import request
|
||||
from flask import session
|
||||
from flask_login import login_user, logout_user
|
||||
|
||||
from api.lib.decorator import args_required
|
||||
from api.lib.perm.auth import auth_abandoned
|
||||
from api.models.acl import User, Role
|
||||
from api.resource import APIView
|
||||
from api.lib.perm.acl.role import RoleRelationCRUD
|
||||
from api.lib.perm.acl.cache import RoleCache
|
||||
|
||||
|
||||
class LoginView(APIView):
|
||||
url_prefix = "/login"
|
||||
|
||||
@args_required("username")
|
||||
@args_required("password")
|
||||
@auth_abandoned
|
||||
def post(self):
|
||||
username = request.values.get("username") or request.values.get("email")
|
||||
password = request.values.get("password")
|
||||
user, authenticated = User.query.authenticate(username, password)
|
||||
if not user:
|
||||
return abort(403, "User <{0}> does not exist".format(username))
|
||||
if not authenticated:
|
||||
return abort(403, "invalid username or password")
|
||||
|
||||
login_user(user)
|
||||
|
||||
token = jwt.encode({
|
||||
'sub': user.email,
|
||||
'iat': datetime.datetime.now(),
|
||||
'exp': datetime.datetime.now() + datetime.timedelta(minutes=24 * 60 * 7)},
|
||||
current_app.config['SECRET_KEY'])
|
||||
|
||||
role = Role.get_by(uid=user.uid, first=True, to_dict=False)
|
||||
if role:
|
||||
parent_ids = RoleRelationCRUD.recursive_parent_ids(role.id)
|
||||
parent_roles = [RoleCache.get(i).name for i in parent_ids]
|
||||
else:
|
||||
parent_roles = []
|
||||
session["acl"] = dict(uid=user.uid,
|
||||
avatar=user.avatar,
|
||||
userName=user.username,
|
||||
nickName=user.nickname,
|
||||
parentRoles=parent_roles)
|
||||
|
||||
return self.jsonify(token=token.decode())
|
||||
|
||||
|
||||
class LogoutView(APIView):
|
||||
url_prefix = "/logout"
|
||||
|
||||
@auth_abandoned
|
||||
def post(self):
|
||||
logout_user()
|
||||
self.jsonify(code=200)
|
1
cmdb-api/api/views/acl/__init__.py
Normal file
1
cmdb-api/api/views/acl/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
# -*- coding:utf-8 -*-
|
40
cmdb-api/api/views/acl/permission.py
Normal file
40
cmdb-api/api/views/acl/permission.py
Normal file
@@ -0,0 +1,40 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
|
||||
|
||||
from flask import request
|
||||
|
||||
from api.lib.decorator import args_required
|
||||
from api.lib.perm.acl.permission import PermissionCRUD
|
||||
from api.lib.utils import handle_arg_list
|
||||
from api.resource import APIView
|
||||
|
||||
|
||||
class ResourcePermissionView(APIView):
|
||||
url_prefix = ("/resources/<int:resource_id>/permissions", "/resource_groups/<int:group_id>/permissions")
|
||||
|
||||
def get(self, resource_id=None, group_id=None):
|
||||
return self.jsonify(PermissionCRUD.get_all(resource_id, group_id))
|
||||
|
||||
|
||||
class RolePermissionGrantView(APIView):
|
||||
url_prefix = ('/roles/<int:rid>/resources/<int:resource_id>/grant',
|
||||
'/roles/<int:rid>/resource_groups/<int:group_id>/grant')
|
||||
|
||||
@args_required('perms')
|
||||
def post(self, rid, resource_id=None, group_id=None):
|
||||
perms = handle_arg_list(request.values.get("perms"))
|
||||
PermissionCRUD.grant(rid, perms, resource_id=resource_id, group_id=group_id)
|
||||
|
||||
return self.jsonify(rid=rid, resource_id=resource_id, group_id=group_id, perms=perms)
|
||||
|
||||
|
||||
class RolePermissionRevokeView(APIView):
|
||||
url_prefix = ('/roles/<int:rid>/resources/<int:resource_id>/revoke',
|
||||
'/roles/<int:rid>/resource_groups/<int:group_id>/revoke')
|
||||
|
||||
@args_required('perms')
|
||||
def post(self, rid, resource_id=None, group_id=None):
|
||||
perms = handle_arg_list(request.values.get("perms"))
|
||||
PermissionCRUD.revoke(rid, perms, resource_id=resource_id, group_id=group_id)
|
||||
|
||||
return self.jsonify(rid=rid, resource_id=resource_id, group_id=group_id, perms=perms)
|
166
cmdb-api/api/views/acl/resources.py
Normal file
166
cmdb-api/api/views/acl/resources.py
Normal file
@@ -0,0 +1,166 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
|
||||
from flask import request
|
||||
|
||||
from api.lib.decorator import args_required
|
||||
from api.lib.perm.acl import validate_app
|
||||
from api.lib.perm.acl.resource import ResourceCRUD
|
||||
from api.lib.perm.acl.resource import ResourceGroupCRUD
|
||||
from api.lib.perm.acl.resource import ResourceTypeCRUD
|
||||
from api.lib.utils import get_page
|
||||
from api.lib.utils import get_page_size
|
||||
from api.lib.utils import handle_arg_list
|
||||
from api.resource import APIView
|
||||
|
||||
|
||||
class ResourceTypeView(APIView):
|
||||
url_prefix = ("/resource_types", "/resource_types/<int:type_id>")
|
||||
|
||||
@args_required('app_id')
|
||||
@validate_app
|
||||
def get(self):
|
||||
page = get_page(request.values.get("page", 1))
|
||||
page_size = get_page_size(request.values.get("page_size"))
|
||||
q = request.values.get('q')
|
||||
app_id = request.values.get('app_id')
|
||||
|
||||
numfound, res, id2perms = ResourceTypeCRUD.search(q, app_id, page, page_size)
|
||||
|
||||
return self.jsonify(numfound=numfound,
|
||||
page=page,
|
||||
page_size=page_size,
|
||||
groups=[i.to_dict() for i in res],
|
||||
id2perms=id2perms)
|
||||
|
||||
@args_required('name')
|
||||
@args_required('app_id')
|
||||
@args_required('perms')
|
||||
@validate_app
|
||||
def post(self):
|
||||
name = request.values.get('name')
|
||||
app_id = request.values.get('app_id')
|
||||
description = request.values.get('description', '')
|
||||
perms = request.values.get('perms')
|
||||
|
||||
rt = ResourceTypeCRUD.add(app_id, name, description, perms)
|
||||
|
||||
return self.jsonify(rt.to_dict())
|
||||
|
||||
def put(self, type_id):
|
||||
rt = ResourceTypeCRUD.update(type_id, **request.values)
|
||||
|
||||
return self.jsonify(rt.to_dict())
|
||||
|
||||
def delete(self, type_id):
|
||||
ResourceTypeCRUD.delete(type_id)
|
||||
|
||||
return self.jsonify(type_id=type_id)
|
||||
|
||||
|
||||
class ResourceTypePermsView(APIView):
|
||||
url_prefix = "/resource_types/<int:type_id>/perms"
|
||||
|
||||
def get(self, type_id):
|
||||
return self.jsonify(ResourceTypeCRUD.get_perms(type_id))
|
||||
|
||||
|
||||
class ResourceView(APIView):
|
||||
url_prefix = ("/resources", "/resources/<int:resource_id>")
|
||||
|
||||
@args_required('app_id')
|
||||
@validate_app
|
||||
def get(self):
|
||||
page = get_page(request.values.get("page", 1))
|
||||
page_size = get_page_size(request.values.get("page_size"))
|
||||
q = request.values.get('q')
|
||||
resource_type_id = request.values.get('resource_type_id')
|
||||
app_id = request.values.get('app_id')
|
||||
|
||||
numfound, res = ResourceCRUD.search(q, app_id, resource_type_id, page, page_size)
|
||||
|
||||
return self.jsonify(numfound=numfound,
|
||||
page=page,
|
||||
page_size=page_size,
|
||||
resources=[i.to_dict() for i in res])
|
||||
|
||||
@args_required('name')
|
||||
@args_required('type_id')
|
||||
@args_required('app_id')
|
||||
@validate_app
|
||||
def post(self):
|
||||
name = request.values.get('name')
|
||||
type_id = request.values.get('type_id')
|
||||
app_id = request.values.get('app_id')
|
||||
|
||||
resource = ResourceCRUD.add(name, type_id, app_id)
|
||||
|
||||
return self.jsonify(resource.to_dict())
|
||||
|
||||
@args_required('name')
|
||||
def put(self, resource_id):
|
||||
name = request.values.get('name')
|
||||
|
||||
resource = ResourceCRUD.update(resource_id, name)
|
||||
|
||||
return self.jsonify(resource.to_dict())
|
||||
|
||||
def delete(self, resource_id):
|
||||
ResourceCRUD.delete(resource_id)
|
||||
|
||||
return self.jsonify(resource_id=resource_id)
|
||||
|
||||
|
||||
class ResourceGroupView(APIView):
|
||||
url_prefix = ("/resource_groups", "/resource_groups/<int:group_id>")
|
||||
|
||||
@args_required('app_id')
|
||||
@validate_app
|
||||
def get(self):
|
||||
page = get_page(request.values.get("page", 1))
|
||||
page_size = get_page_size(request.values.get("page_size"))
|
||||
q = request.values.get('q')
|
||||
app_id = request.values.get('app_id')
|
||||
|
||||
numfound, res = ResourceGroupCRUD.search(q, app_id, page, page_size)
|
||||
|
||||
return self.jsonify(numfound=numfound,
|
||||
page=page,
|
||||
page_size=page_size,
|
||||
groups=[i.to_dict() for i in res])
|
||||
|
||||
@args_required('name')
|
||||
@args_required('type_id')
|
||||
@args_required('app_id')
|
||||
@validate_app
|
||||
def post(self):
|
||||
name = request.values.get('name')
|
||||
type_id = request.values.get('type_id')
|
||||
app_id = request.values.get('app_id')
|
||||
|
||||
group = ResourceGroupCRUD.add(name, type_id, app_id)
|
||||
|
||||
return self.jsonify(group.to_dict())
|
||||
|
||||
@args_required('items')
|
||||
def put(self, group_id):
|
||||
items = handle_arg_list(request.values.get("items"))
|
||||
|
||||
ResourceGroupCRUD.update(group_id, items)
|
||||
|
||||
items = ResourceGroupCRUD.get_items(group_id)
|
||||
|
||||
return self.jsonify(items)
|
||||
|
||||
def delete(self, group_id):
|
||||
ResourceGroupCRUD.delete(group_id)
|
||||
|
||||
return self.jsonify(group_id=group_id)
|
||||
|
||||
|
||||
class ResourceGroupItemsView(APIView):
|
||||
url_prefix = "/resource_groups/<int:group_id>/items"
|
||||
|
||||
def get(self, group_id):
|
||||
items = ResourceGroupCRUD.get_items(group_id)
|
||||
|
||||
return self.jsonify(items)
|
77
cmdb-api/api/views/acl/role.py
Normal file
77
cmdb-api/api/views/acl/role.py
Normal file
@@ -0,0 +1,77 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
|
||||
from flask import current_app
|
||||
from flask import request
|
||||
|
||||
from api.lib.decorator import args_required
|
||||
from api.lib.perm.acl import validate_app
|
||||
from api.lib.perm.acl.role import RoleCRUD
|
||||
from api.lib.perm.acl.role import RoleRelationCRUD
|
||||
from api.lib.utils import get_page
|
||||
from api.lib.utils import get_page_size
|
||||
from api.resource import APIView
|
||||
|
||||
|
||||
class RoleView(APIView):
|
||||
url_prefix = ("/roles", "/roles/<int:rid>")
|
||||
|
||||
@args_required('app_id')
|
||||
@validate_app
|
||||
def get(self):
|
||||
page = get_page(request.values.get("page", 1))
|
||||
page_size = get_page_size(request.values.get("page_size"))
|
||||
q = request.values.get('q')
|
||||
app_id = request.values.get('app_id')
|
||||
user_role = request.values.get('user_role', True)
|
||||
user_role = True if user_role in current_app.config.get("BOOL_TRUE") else False
|
||||
|
||||
numfound, roles = RoleCRUD.search(q, app_id, page, page_size, user_role)
|
||||
|
||||
id2parents = RoleRelationCRUD.get_parents([i.id for i in roles])
|
||||
|
||||
return self.jsonify(numfound=numfound,
|
||||
page=page,
|
||||
page_size=page_size,
|
||||
id2parents=id2parents,
|
||||
roles=[i.to_dict() for i in roles])
|
||||
|
||||
@args_required('name')
|
||||
@args_required('app_id')
|
||||
@validate_app
|
||||
def post(self):
|
||||
name = request.values.get('name')
|
||||
app_id = request.values.get('app_id')
|
||||
is_app_admin = request.values.get('is_app_admin', False)
|
||||
|
||||
role = RoleCRUD.add_role(name, app_id, is_app_admin=is_app_admin)
|
||||
|
||||
return self.jsonify(role.to_dict())
|
||||
|
||||
def put(self, rid):
|
||||
role = RoleCRUD.update_role(rid, **request.values)
|
||||
|
||||
return self.jsonify(role.to_dict())
|
||||
|
||||
def delete(self, rid):
|
||||
RoleCRUD.delete_role(rid)
|
||||
|
||||
return self.jsonify(rid=rid)
|
||||
|
||||
|
||||
class RoleRelationView(APIView):
|
||||
url_prefix = "/roles/<int:child_id>/parents"
|
||||
|
||||
@args_required('parent_id')
|
||||
def post(self, child_id):
|
||||
parent_id = request.values.get('parent_id')
|
||||
res = RoleRelationCRUD.add(parent_id, child_id)
|
||||
|
||||
return self.jsonify(res.to_dict())
|
||||
|
||||
@args_required('parent_id')
|
||||
def delete(self, child_id):
|
||||
parent_id = request.values.get('parent_id')
|
||||
|
||||
RoleRelationCRUD.delete2(parent_id, child_id)
|
||||
|
||||
return self.jsonify(parent_id=parent_id, child_id=child_id)
|
78
cmdb-api/api/views/acl/user.py
Normal file
78
cmdb-api/api/views/acl/user.py
Normal file
@@ -0,0 +1,78 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
|
||||
|
||||
from flask import request
|
||||
from flask import session
|
||||
from flask_login import current_user
|
||||
|
||||
from api.lib.decorator import args_required
|
||||
from api.lib.perm.acl.role import RoleRelationCRUD
|
||||
from api.lib.perm.acl.user import UserCRUD
|
||||
from api.lib.utils import get_page
|
||||
from api.lib.utils import get_page_size
|
||||
from api.resource import APIView
|
||||
|
||||
|
||||
class GetUserInfoView(APIView):
|
||||
url_prefix = "/users/info"
|
||||
|
||||
def get(self):
|
||||
name = session.get("CAS_USERNAME") or current_user.nickname
|
||||
role = dict(permissions=session.get("acl", {}).get("parentRoles", []))
|
||||
avatar = current_user.avatar
|
||||
|
||||
return self.jsonify(result=dict(name=name,
|
||||
role=role,
|
||||
avatar=avatar))
|
||||
|
||||
|
||||
class UserView(APIView):
|
||||
url_prefix = ("/users", "/users/<int:uid>")
|
||||
|
||||
def get(self):
|
||||
page = get_page(request.values.get('page', 1))
|
||||
page_size = get_page_size(request.values.get('page_size'))
|
||||
q = request.values.get("q")
|
||||
numfound, users = UserCRUD.search(q, page, page_size)
|
||||
id2parents = RoleRelationCRUD.get_parents(uids=[i.uid for i in users])
|
||||
|
||||
users = [i.to_dict() for i in users]
|
||||
for u in users:
|
||||
u.pop('password', None)
|
||||
u.pop('key', None)
|
||||
u.pop('secret', None)
|
||||
|
||||
return self.jsonify(numfound=numfound,
|
||||
page=page,
|
||||
page_size=page_size,
|
||||
id2parents=id2parents,
|
||||
users=users)
|
||||
|
||||
@args_required('username')
|
||||
@args_required('email')
|
||||
def post(self):
|
||||
user = UserCRUD.add(**request.values)
|
||||
|
||||
return self.jsonify(user.to_dict())
|
||||
|
||||
def put(self, uid):
|
||||
user = UserCRUD.update(uid, **request.values)
|
||||
|
||||
return self.jsonify(user.to_dict())
|
||||
|
||||
def delete(self, uid):
|
||||
UserCRUD.delete(uid)
|
||||
|
||||
return self.jsonify(uid=uid)
|
||||
|
||||
|
||||
class UserResetKeySecretView(APIView):
|
||||
url_prefix = "/users/reset_key_secret"
|
||||
|
||||
def post(self):
|
||||
key, secret = UserCRUD.reset_key_secret()
|
||||
|
||||
return self.jsonify(key=key, secret=secret)
|
||||
|
||||
def put(self):
|
||||
return self.post()
|
1
cmdb-api/api/views/cmdb/__init__.py
Normal file
1
cmdb-api/api/views/cmdb/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
# -*- coding:utf-8 -*-
|
74
cmdb-api/api/views/cmdb/attribute.py
Normal file
74
cmdb-api/api/views/cmdb/attribute.py
Normal file
@@ -0,0 +1,74 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
|
||||
|
||||
from flask import abort
|
||||
from flask import current_app
|
||||
from flask import request
|
||||
|
||||
from api.lib.cmdb.attribute import AttributeManager
|
||||
from api.lib.cmdb.const import RoleEnum
|
||||
from api.lib.decorator import args_required
|
||||
from api.lib.perm.acl.acl import role_required
|
||||
from api.lib.utils import get_page
|
||||
from api.lib.utils import get_page_size
|
||||
from api.lib.utils import handle_arg_list
|
||||
from api.resource import APIView
|
||||
|
||||
|
||||
class AttributeSearchView(APIView):
|
||||
url_prefix = ("/attributes/s", "/attributes/search")
|
||||
|
||||
def get(self):
|
||||
name = request.values.get("name")
|
||||
alias = request.values.get("alias")
|
||||
page = get_page(request.values.get("page", 1))
|
||||
page_size = get_page_size(request.values.get("page_size"))
|
||||
numfound, res = AttributeManager.search_attributes(name=name, alias=alias, page=page, page_size=page_size)
|
||||
|
||||
return self.jsonify(page=page,
|
||||
page_size=page_size,
|
||||
numfound=numfound,
|
||||
total=len(res),
|
||||
attributes=res)
|
||||
|
||||
|
||||
class AttributeView(APIView):
|
||||
url_prefix = ("/attributes", "/attributes/<string:attr_name>", "/attributes/<int:attr_id>")
|
||||
|
||||
def get(self, attr_name=None, attr_id=None):
|
||||
attr_manager = AttributeManager()
|
||||
attr_dict = None
|
||||
if attr_name is not None:
|
||||
attr_dict = attr_manager.get_attribute_by_name(attr_name)
|
||||
if attr_dict is None:
|
||||
attr_dict = attr_manager.get_attribute_by_alias(attr_name)
|
||||
elif attr_id is not None:
|
||||
attr_dict = attr_manager.get_attribute_by_id(attr_id)
|
||||
if attr_dict is not None:
|
||||
return self.jsonify(attribute=attr_dict)
|
||||
abort(404, "Attribute is not found")
|
||||
|
||||
@role_required(RoleEnum.CONFIG)
|
||||
@args_required("name")
|
||||
def post(self):
|
||||
choice_value = handle_arg_list(request.values.get("choice_value"))
|
||||
params = request.values
|
||||
params["choice_value"] = choice_value
|
||||
current_app.logger.debug(params)
|
||||
|
||||
attr_id = AttributeManager.add(**params)
|
||||
return self.jsonify(attr_id=attr_id)
|
||||
|
||||
@role_required(RoleEnum.CONFIG)
|
||||
def put(self, attr_id):
|
||||
choice_value = handle_arg_list(request.values.get("choice_value"))
|
||||
params = request.values
|
||||
params["choice_value"] = choice_value
|
||||
current_app.logger.debug(params)
|
||||
AttributeManager().update(attr_id, **params)
|
||||
return self.jsonify(attr_id=attr_id)
|
||||
|
||||
@role_required(RoleEnum.CONFIG)
|
||||
def delete(self, attr_id):
|
||||
attr_name = AttributeManager.delete(attr_id)
|
||||
return self.jsonify(message="attribute {0} deleted".format(attr_name))
|
217
cmdb-api/api/views/cmdb/ci.py
Normal file
217
cmdb-api/api/views/cmdb/ci.py
Normal file
@@ -0,0 +1,217 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
|
||||
import time
|
||||
|
||||
import six
|
||||
from flask import abort
|
||||
from flask import current_app
|
||||
from flask import request
|
||||
|
||||
from api.lib.cmdb.cache import CITypeCache
|
||||
from api.lib.cmdb.ci import CIManager
|
||||
from api.lib.cmdb.const import ExistPolicy
|
||||
from api.lib.cmdb.const import ResourceTypeEnum, PermEnum
|
||||
from api.lib.cmdb.const import RetKey
|
||||
from api.lib.cmdb.search import SearchError
|
||||
from api.lib.cmdb.search.ci.db.search import Search as SearchFromDB
|
||||
from api.lib.cmdb.search.ci.es.search import Search as SearchFromES
|
||||
from api.lib.perm.acl.acl import has_perm_from_args
|
||||
from api.lib.perm.auth import auth_abandoned
|
||||
from api.lib.utils import get_page
|
||||
from api.lib.utils import get_page_size
|
||||
from api.lib.utils import handle_arg_list
|
||||
from api.models.cmdb import CI
|
||||
from api.resource import APIView
|
||||
|
||||
|
||||
class CIsByTypeView(APIView):
|
||||
url_prefix = "/ci/type/<int:type_id>"
|
||||
|
||||
def get(self, type_id):
|
||||
fields = handle_arg_list(request.values.get("fields", ""))
|
||||
|
||||
ret_key = request.values.get("ret_key", RetKey.NAME)
|
||||
if ret_key not in (RetKey.NAME, RetKey.ALIAS, RetKey.ID):
|
||||
ret_key = RetKey.NAME
|
||||
|
||||
page = get_page(request.values.get("page", 1))
|
||||
count = get_page_size(request.values.get("count"))
|
||||
|
||||
manager = CIManager()
|
||||
res = manager.get_cis_by_type(type_id,
|
||||
ret_key=ret_key,
|
||||
fields=fields,
|
||||
page=page,
|
||||
per_page=count)
|
||||
|
||||
return self.jsonify(type_id=type_id,
|
||||
numfound=res[0],
|
||||
total=len(res[2]),
|
||||
page=res[1],
|
||||
cis=res[2])
|
||||
|
||||
|
||||
class CIView(APIView):
|
||||
url_prefix = ("/ci/<int:ci_id>", "/ci")
|
||||
|
||||
def get(self, ci_id):
|
||||
fields = handle_arg_list(request.values.get("fields", ""))
|
||||
|
||||
ret_key = request.values.get("ret_key", RetKey.NAME)
|
||||
if ret_key not in (RetKey.NAME, RetKey.ALIAS, RetKey.ID):
|
||||
ret_key = RetKey.NAME
|
||||
|
||||
manager = CIManager()
|
||||
ci = manager.get_ci_by_id_from_db(ci_id, ret_key=ret_key, fields=fields)
|
||||
return self.jsonify(ci_id=ci_id, ci=ci)
|
||||
|
||||
@staticmethod
|
||||
def _wrap_ci_dict():
|
||||
ci_dict = dict()
|
||||
for k, v in request.values.items():
|
||||
if k != "ci_type" and not k.startswith("_"):
|
||||
ci_dict[k] = v.strip() if isinstance(v, six.string_types) else v
|
||||
return ci_dict
|
||||
|
||||
@has_perm_from_args("ci_type", ResourceTypeEnum.CI, PermEnum.ADD)
|
||||
def post(self):
|
||||
ci_type = request.values.get("ci_type")
|
||||
_no_attribute_policy = request.values.get("_no_attribute_policy", ExistPolicy.IGNORE)
|
||||
|
||||
ci_dict = self._wrap_ci_dict()
|
||||
|
||||
manager = CIManager()
|
||||
current_app.logger.debug(ci_dict)
|
||||
ci_id = manager.add(ci_type,
|
||||
exist_policy=ExistPolicy.REJECT,
|
||||
_no_attribute_policy=_no_attribute_policy, **ci_dict)
|
||||
return self.jsonify(ci_id=ci_id)
|
||||
|
||||
@has_perm_from_args("ci_id", ResourceTypeEnum.CI, PermEnum.UPDATE, CIManager.get_type_name)
|
||||
def put(self, ci_id=None):
|
||||
args = request.values
|
||||
ci_type = args.get("ci_type")
|
||||
_no_attribute_policy = args.get("_no_attribute_policy", ExistPolicy.IGNORE)
|
||||
|
||||
ci_dict = self._wrap_ci_dict()
|
||||
manager = CIManager()
|
||||
if ci_id is not None:
|
||||
manager.update(ci_id, **ci_dict)
|
||||
else:
|
||||
ci_id = manager.add(ci_type,
|
||||
exist_policy=ExistPolicy.REPLACE,
|
||||
_no_attribute_policy=_no_attribute_policy,
|
||||
**ci_dict)
|
||||
return self.jsonify(ci_id=ci_id)
|
||||
|
||||
@has_perm_from_args("ci_id", ResourceTypeEnum.CI, PermEnum.DELETE, CIManager.get_type_name)
|
||||
def delete(self, ci_id):
|
||||
manager = CIManager()
|
||||
manager.delete(ci_id)
|
||||
return self.jsonify(message="ok")
|
||||
|
||||
|
||||
class CIDetailView(APIView):
|
||||
url_prefix = "/ci/<int:ci_id>/detail"
|
||||
|
||||
def get(self, ci_id):
|
||||
_ci = CI.get_by_id(ci_id).to_dict()
|
||||
return self.jsonify(**_ci)
|
||||
|
||||
|
||||
class CISearchView(APIView):
|
||||
url_prefix = ("/ci/s", "/ci/search")
|
||||
|
||||
@auth_abandoned
|
||||
def get(self):
|
||||
"""@params: q: query statement
|
||||
fl: filter by column
|
||||
count/page_size: the number of ci
|
||||
ret_key: id, name, alias
|
||||
facet: statistic
|
||||
"""
|
||||
|
||||
page = get_page(request.values.get("page", 1))
|
||||
count = get_page_size(request.values.get("count") or request.values.get("page_size"))
|
||||
|
||||
query = request.values.get('q', "")
|
||||
fl = handle_arg_list(request.values.get('fl', ""))
|
||||
ret_key = request.values.get('ret_key', RetKey.NAME)
|
||||
if ret_key not in (RetKey.NAME, RetKey.ALIAS, RetKey.ID):
|
||||
ret_key = RetKey.NAME
|
||||
facet = handle_arg_list(request.values.get("facet", ""))
|
||||
sort = request.values.get("sort")
|
||||
|
||||
start = time.time()
|
||||
if current_app.config.get("USE_ES"):
|
||||
s = SearchFromES(query, fl, facet, page, ret_key, count, sort)
|
||||
else:
|
||||
s = SearchFromDB(query, fl, facet, page, ret_key, count, sort)
|
||||
try:
|
||||
response, counter, total, page, numfound, facet = s.search()
|
||||
except SearchError as e:
|
||||
return abort(400, str(e))
|
||||
current_app.logger.debug("search time is :{0}".format(time.time() - start))
|
||||
return self.jsonify(numfound=numfound,
|
||||
total=total,
|
||||
page=page,
|
||||
facet=facet,
|
||||
counter=counter,
|
||||
result=response)
|
||||
|
||||
|
||||
class CIUnique(APIView):
|
||||
url_prefix = "/ci/<int:ci_id>/unique"
|
||||
|
||||
@has_perm_from_args("ci_id", ResourceTypeEnum.CI, PermEnum.UPDATE, CIManager.get_type_name)
|
||||
def put(self, ci_id):
|
||||
params = request.values
|
||||
unique_name = params.keys()[0]
|
||||
unique_value = params.values()[0]
|
||||
|
||||
CIManager.update_unique_value(ci_id, unique_name, unique_value)
|
||||
|
||||
return self.jsonify(ci_id=ci_id)
|
||||
|
||||
|
||||
class CIHeartbeatView(APIView):
|
||||
url_prefix = ("/ci/heartbeat", "/ci/heartbeat/<string:ci_type>/<string:unique>")
|
||||
|
||||
def get(self):
|
||||
page = get_page(request.values.get("page", 1))
|
||||
ci_type = request.values.get("ci_type", "").strip()
|
||||
try:
|
||||
type_id = CITypeCache.get(ci_type).type_id
|
||||
except AttributeError:
|
||||
return self.jsonify(numfound=0, result=[])
|
||||
agent_status = request.values.get("agent_status")
|
||||
if agent_status:
|
||||
agent_status = int(agent_status)
|
||||
|
||||
numfound, result = CIManager.get_heartbeat(page, type_id, agent_status=agent_status)
|
||||
|
||||
return self.jsonify(numfound=numfound, result=result)
|
||||
|
||||
def post(self, ci_type, unique):
|
||||
if not unique or not ci_type:
|
||||
return self.jsonify(message="error")
|
||||
|
||||
msg, cmd = CIManager().add_heartbeat(ci_type, unique)
|
||||
|
||||
return self.jsonify(message=msg, cmd=cmd)
|
||||
|
||||
|
||||
class CIFlushView(APIView):
|
||||
url_prefix = ("/ci/flush", "/ci/<int:ci_id>/flush")
|
||||
|
||||
@auth_abandoned
|
||||
def get(self, ci_id=None):
|
||||
from api.tasks.cmdb import ci_cache
|
||||
from api.lib.cmdb.const import CMDB_QUEUE
|
||||
if ci_id is not None:
|
||||
ci_cache.apply_async([ci_id], queue=CMDB_QUEUE)
|
||||
else:
|
||||
cis = CI.get_by(to_dict=False)
|
||||
for ci in cis:
|
||||
ci_cache.apply_async([ci.id], queue=CMDB_QUEUE)
|
||||
return self.jsonify(code=200)
|
139
cmdb-api/api/views/cmdb/ci_relation.py
Normal file
139
cmdb-api/api/views/cmdb/ci_relation.py
Normal file
@@ -0,0 +1,139 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
|
||||
|
||||
import time
|
||||
|
||||
from flask import abort
|
||||
from flask import current_app
|
||||
from flask import request
|
||||
|
||||
from api.lib.cmdb.cache import RelationTypeCache
|
||||
from api.lib.cmdb.ci import CIRelationManager
|
||||
from api.lib.cmdb.search import SearchError
|
||||
from api.lib.cmdb.search.ci_relation.search import Search
|
||||
from api.lib.perm.auth import auth_abandoned
|
||||
from api.lib.utils import get_page
|
||||
from api.lib.utils import get_page_size
|
||||
from api.lib.utils import handle_arg_list
|
||||
from api.resource import APIView
|
||||
|
||||
|
||||
class CIRelationSearchView(APIView):
|
||||
url_prefix = ("/ci_relations/s", "/ci_relations/search")
|
||||
|
||||
@auth_abandoned
|
||||
def get(self):
|
||||
"""@params: q: query statement
|
||||
fl: filter by column
|
||||
count: the number of ci
|
||||
root_id: ci id
|
||||
level: default is 1
|
||||
facet: statistic
|
||||
"""
|
||||
|
||||
page = get_page(request.values.get("page", 1))
|
||||
count = get_page_size(request.values.get("count") or request.values.get("page_size"))
|
||||
|
||||
root_id = request.values.get('root_id')
|
||||
level = list(map(int, handle_arg_list(request.values.get('level', '1'))))
|
||||
|
||||
query = request.values.get('q', "")
|
||||
fl = handle_arg_list(request.values.get('fl', ""))
|
||||
facet = handle_arg_list(request.values.get("facet", ""))
|
||||
sort = request.values.get("sort")
|
||||
|
||||
start = time.time()
|
||||
s = Search(root_id, level, query, fl, facet, page, count, sort)
|
||||
try:
|
||||
response, counter, total, page, numfound, facet = s.search()
|
||||
except SearchError as e:
|
||||
return abort(400, str(e))
|
||||
current_app.logger.debug("search time is :{0}".format(time.time() - start))
|
||||
|
||||
return self.jsonify(numfound=numfound,
|
||||
total=total,
|
||||
page=page,
|
||||
facet=facet,
|
||||
counter=counter,
|
||||
result=response)
|
||||
|
||||
|
||||
class CIRelationStatisticsView(APIView):
|
||||
url_prefix = "/ci_relations/statistics"
|
||||
|
||||
@auth_abandoned
|
||||
def get(self):
|
||||
root_ids = list(map(int, handle_arg_list(request.values.get('root_ids'))))
|
||||
level = request.values.get('level', 1)
|
||||
type_ids = set(map(int, handle_arg_list(request.values.get('type_ids', []))))
|
||||
|
||||
start = time.time()
|
||||
s = Search(root_ids, level)
|
||||
try:
|
||||
result = s.statistics(type_ids)
|
||||
except SearchError as e:
|
||||
return abort(400, str(e))
|
||||
current_app.logger.debug("search time is :{0}".format(time.time() - start))
|
||||
|
||||
return self.jsonify(result)
|
||||
|
||||
|
||||
class GetSecondCIsView(APIView):
|
||||
url_prefix = "/ci_relations/<int:first_ci_id>/second_cis"
|
||||
|
||||
def get(self, first_ci_id):
|
||||
page = get_page(request.values.get("page", 1))
|
||||
count = get_page_size(request.values.get("count"))
|
||||
relation_type = request.values.get("relation_type")
|
||||
try:
|
||||
relation_type_id = RelationTypeCache.get(relation_type).id if relation_type else None
|
||||
except AttributeError:
|
||||
return abort(400, "invalid relation type <{0}>".format(relation_type))
|
||||
|
||||
manager = CIRelationManager()
|
||||
numfound, total, second_cis = manager.get_second_cis(
|
||||
first_ci_id, page=page, per_page=count, relation_type_id=relation_type_id)
|
||||
|
||||
return self.jsonify(numfound=numfound,
|
||||
total=total,
|
||||
page=page,
|
||||
second_cis=second_cis)
|
||||
|
||||
|
||||
class GetFirstCIsView(APIView):
|
||||
url_prefix = "/ci_relations/<int:second_ci_id>/first_cis"
|
||||
|
||||
def get(self, second_ci_id):
|
||||
page = get_page(request.values.get("page", 1))
|
||||
count = get_page_size(request.values.get("count"))
|
||||
|
||||
manager = CIRelationManager()
|
||||
numfound, total, first_cis = manager.get_first_cis(second_ci_id, per_page=count, page=page)
|
||||
|
||||
return self.jsonify(numfound=numfound,
|
||||
total=total,
|
||||
page=page,
|
||||
first_cis=first_cis)
|
||||
|
||||
|
||||
class CIRelationView(APIView):
|
||||
url_prefix = "/ci_relations/<int:first_ci_id>/<int:second_ci_id>"
|
||||
|
||||
def post(self, first_ci_id, second_ci_id):
|
||||
manager = CIRelationManager()
|
||||
res = manager.add(first_ci_id, second_ci_id)
|
||||
return self.jsonify(cr_id=res)
|
||||
|
||||
def delete(self, first_ci_id, second_ci_id):
|
||||
manager = CIRelationManager()
|
||||
manager.delete_2(first_ci_id, second_ci_id)
|
||||
return self.jsonify(message="CIType Relation is deleted")
|
||||
|
||||
|
||||
class DeleteCIRelationView(APIView):
|
||||
url_prefix = "/ci_relations/<int:cr_id>"
|
||||
|
||||
def delete(self, cr_id):
|
||||
manager = CIRelationManager()
|
||||
manager.delete(cr_id)
|
||||
return self.jsonify(message="CIType Relation is deleted")
|
202
cmdb-api/api/views/cmdb/ci_type.py
Normal file
202
cmdb-api/api/views/cmdb/ci_type.py
Normal file
@@ -0,0 +1,202 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
|
||||
|
||||
from flask import abort
|
||||
from flask import current_app
|
||||
from flask import request
|
||||
|
||||
from api.lib.cmdb.cache import AttributeCache
|
||||
from api.lib.cmdb.cache import CITypeCache
|
||||
from api.lib.cmdb.ci_type import CITypeAttributeGroupManager
|
||||
from api.lib.cmdb.ci_type import CITypeAttributeManager
|
||||
from api.lib.cmdb.ci_type import CITypeGroupManager
|
||||
from api.lib.cmdb.ci_type import CITypeManager
|
||||
from api.lib.cmdb.const import RoleEnum
|
||||
from api.lib.decorator import args_required
|
||||
from api.lib.perm.acl.acl import role_required
|
||||
from api.lib.utils import handle_arg_list
|
||||
from api.resource import APIView
|
||||
|
||||
|
||||
class CITypeView(APIView):
|
||||
url_prefix = ("/ci_types", "/ci_types/<int:type_id>", "/ci_types/<string:type_name>")
|
||||
|
||||
def get(self, type_id=None, type_name=None):
|
||||
q = request.args.get("type_name")
|
||||
|
||||
if type_id is not None:
|
||||
ci_types = [CITypeCache.get(type_id).to_dict()]
|
||||
elif type_name is not None:
|
||||
ci_types = [CITypeCache.get(type_name).to_dict()]
|
||||
else:
|
||||
ci_types = CITypeManager().get_ci_types(q)
|
||||
count = len(ci_types)
|
||||
|
||||
return self.jsonify(numfound=count, ci_types=ci_types)
|
||||
|
||||
@role_required(RoleEnum.CONFIG)
|
||||
@args_required("name")
|
||||
def post(self):
|
||||
params = request.values
|
||||
|
||||
type_name = params.get("name")
|
||||
type_alias = params.get("alias")
|
||||
type_alias = type_name if not type_alias else type_alias
|
||||
params['alias'] = type_alias
|
||||
|
||||
manager = CITypeManager()
|
||||
type_id = manager.add(**params)
|
||||
|
||||
return self.jsonify(type_id=type_id)
|
||||
|
||||
@role_required(RoleEnum.CONFIG)
|
||||
def put(self, type_id):
|
||||
params = request.values
|
||||
|
||||
manager = CITypeManager()
|
||||
manager.update(type_id, **params)
|
||||
return self.jsonify(type_id=type_id)
|
||||
|
||||
@role_required(RoleEnum.CONFIG)
|
||||
def delete(self, type_id):
|
||||
CITypeManager.delete(type_id)
|
||||
return self.jsonify(type_id=type_id)
|
||||
|
||||
|
||||
class CITypeGroupView(APIView):
|
||||
url_prefix = ("/ci_types/groups", "/ci_types/groups/<int:gid>")
|
||||
|
||||
def get(self):
|
||||
need_other = request.values.get("need_other")
|
||||
return self.jsonify(CITypeGroupManager.get(need_other))
|
||||
|
||||
@role_required(RoleEnum.CONFIG)
|
||||
@args_required("name")
|
||||
def post(self):
|
||||
name = request.values.get("name")
|
||||
group = CITypeGroupManager.add(name)
|
||||
return self.jsonify(group.to_dict())
|
||||
|
||||
@role_required(RoleEnum.CONFIG)
|
||||
def put(self, gid):
|
||||
name = request.values.get('name')
|
||||
type_ids = request.values.get('type_ids')
|
||||
CITypeGroupManager.update(gid, name, type_ids)
|
||||
return self.jsonify(gid=gid)
|
||||
|
||||
@role_required(RoleEnum.CONFIG)
|
||||
def delete(self, gid):
|
||||
CITypeGroupManager.delete(gid)
|
||||
return self.jsonify(gid=gid)
|
||||
|
||||
|
||||
class CITypeQueryView(APIView):
|
||||
url_prefix = "/ci_types/query"
|
||||
|
||||
@args_required("q")
|
||||
def get(self):
|
||||
q = request.args.get("q")
|
||||
res = CITypeManager.query(q)
|
||||
return self.jsonify(ci_type=res)
|
||||
|
||||
|
||||
class EnableCITypeView(APIView):
|
||||
url_prefix = "/ci_types/<int:type_id>/enable"
|
||||
|
||||
@role_required(RoleEnum.CONFIG)
|
||||
def post(self, type_id):
|
||||
enable = request.values.get("enable", True)
|
||||
CITypeManager.set_enabled(type_id, enabled=enable)
|
||||
return self.jsonify(type_id=type_id, enable=enable)
|
||||
|
||||
|
||||
class CITypeAttributeView(APIView):
|
||||
url_prefix = ("/ci_types/<int:type_id>/attributes", "/ci_types/<string:type_name>/attributes")
|
||||
|
||||
def get(self, type_id=None, type_name=None):
|
||||
t = CITypeCache.get(type_id) or CITypeCache.get(type_name) or abort(404, "CIType does not exist")
|
||||
type_id = t.id
|
||||
unique_id = t.unique_id
|
||||
unique = AttributeCache.get(unique_id).name
|
||||
return self.jsonify(attributes=CITypeAttributeManager.get_attributes_by_type_id(type_id),
|
||||
type_id=type_id,
|
||||
unique_id=unique_id,
|
||||
unique=unique)
|
||||
|
||||
@role_required(RoleEnum.CONFIG)
|
||||
@args_required("attr_id")
|
||||
def post(self, type_id=None):
|
||||
attr_id_list = handle_arg_list(request.values.get("attr_id"))
|
||||
params = request.values
|
||||
params.pop("attr_id", "")
|
||||
|
||||
CITypeAttributeManager.add(type_id, attr_id_list, **params)
|
||||
return self.jsonify(attributes=attr_id_list)
|
||||
|
||||
@role_required(RoleEnum.CONFIG)
|
||||
@args_required("attributes")
|
||||
def put(self, type_id=None):
|
||||
"""
|
||||
attributes is list, only support raw data request
|
||||
:param type_id:
|
||||
:return:
|
||||
"""
|
||||
attributes = request.values.get("attributes")
|
||||
current_app.logger.debug(attributes)
|
||||
if not isinstance(attributes, list):
|
||||
return abort(400, "attributes must be list")
|
||||
CITypeAttributeManager.update(type_id, attributes)
|
||||
return self.jsonify(attributes=attributes)
|
||||
|
||||
@role_required(RoleEnum.CONFIG)
|
||||
@args_required("attr_id")
|
||||
def delete(self, type_id=None):
|
||||
"""
|
||||
Form request: attr_id is a string, separated by commas
|
||||
Raw data request: attr_id is a list
|
||||
:param type_id:
|
||||
:return:
|
||||
"""
|
||||
attr_id_list = handle_arg_list(request.values.get("attr_id", ""))
|
||||
|
||||
CITypeAttributeManager.delete(type_id, attr_id_list)
|
||||
|
||||
return self.jsonify(attributes=attr_id_list)
|
||||
|
||||
|
||||
class CITypeAttributeGroupView(APIView):
|
||||
url_prefix = ("/ci_types/<int:type_id>/attribute_groups",
|
||||
"/ci_types/attribute_groups/<int:group_id>")
|
||||
|
||||
def get(self, type_id):
|
||||
need_other = request.values.get("need_other")
|
||||
return self.jsonify(CITypeAttributeGroupManager.get_by_type_id(type_id, need_other))
|
||||
|
||||
@role_required(RoleEnum.CONFIG)
|
||||
@args_required("name")
|
||||
def post(self, type_id):
|
||||
name = request.values.get("name").strip()
|
||||
order = request.values.get("order") or 0
|
||||
attrs = handle_arg_list(request.values.get("attributes", ""))
|
||||
orders = list(range(len(attrs)))
|
||||
|
||||
attr_order = list(zip(attrs, orders))
|
||||
group = CITypeAttributeGroupManager.create_or_update(type_id, name, attr_order, order)
|
||||
current_app.logger.warning(group.id)
|
||||
return self.jsonify(group_id=group.id)
|
||||
|
||||
@role_required(RoleEnum.CONFIG)
|
||||
def put(self, group_id):
|
||||
name = request.values.get("name")
|
||||
order = request.values.get("order") or 0
|
||||
attrs = handle_arg_list(request.values.get("attributes", ""))
|
||||
orders = list(range(len(attrs)))
|
||||
|
||||
attr_order = list(zip(attrs, orders))
|
||||
CITypeAttributeGroupManager.update(group_id, name, attr_order, order)
|
||||
return self.jsonify(group_id=group_id)
|
||||
|
||||
@role_required(RoleEnum.CONFIG)
|
||||
def delete(self, group_id):
|
||||
CITypeAttributeGroupManager.delete(group_id)
|
||||
return self.jsonify(group_id=group_id)
|
58
cmdb-api/api/views/cmdb/ci_type_relation.py
Normal file
58
cmdb-api/api/views/cmdb/ci_type_relation.py
Normal file
@@ -0,0 +1,58 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
|
||||
|
||||
from flask import request
|
||||
|
||||
from api.lib.cmdb.ci_type import CITypeRelationManager
|
||||
from api.lib.cmdb.const import RoleEnum
|
||||
from api.lib.decorator import args_required
|
||||
from api.lib.perm.acl.acl import role_required
|
||||
from api.resource import APIView
|
||||
|
||||
|
||||
class GetChildrenView(APIView):
|
||||
url_prefix = "/ci_type_relations/<int:parent_id>/children"
|
||||
|
||||
def get(self, parent_id):
|
||||
return self.jsonify(children=CITypeRelationManager.get_children(parent_id))
|
||||
|
||||
|
||||
class GetParentsView(APIView):
|
||||
url_prefix = "/ci_type_relations/<int:child_id>/parents"
|
||||
|
||||
def get(self, child_id):
|
||||
return self.jsonify(parents=CITypeRelationManager.get_parents(child_id))
|
||||
|
||||
|
||||
class CITypeRelationView(APIView):
|
||||
url_prefix = ("/ci_type_relations", "/ci_type_relations/<int:parent_id>/<int:child_id>")
|
||||
|
||||
@role_required(RoleEnum.CONFIG)
|
||||
def get(self):
|
||||
res = CITypeRelationManager.get()
|
||||
|
||||
return self.jsonify(res)
|
||||
|
||||
@role_required(RoleEnum.CONFIG)
|
||||
@args_required("relation_type_id")
|
||||
def post(self, parent_id, child_id):
|
||||
relation_type_id = request.values.get("relation_type_id")
|
||||
ctr_id = CITypeRelationManager.add(parent_id, child_id, relation_type_id)
|
||||
|
||||
return self.jsonify(ctr_id=ctr_id)
|
||||
|
||||
@role_required(RoleEnum.CONFIG)
|
||||
def delete(self, parent_id, child_id):
|
||||
CITypeRelationManager.delete_2(parent_id, child_id)
|
||||
|
||||
return self.jsonify(code=200, parent_id=parent_id, child_id=child_id)
|
||||
|
||||
|
||||
class CITypeRelationDelete2View(APIView):
|
||||
url_prefix = "/ci_type_relations/<int:ctr_id>"
|
||||
|
||||
@role_required(RoleEnum.CONFIG)
|
||||
def delete(self, ctr_id):
|
||||
CITypeRelationManager.delete(ctr_id)
|
||||
|
||||
return self.jsonify(code=200, ctr_id=ctr_id)
|
63
cmdb-api/api/views/cmdb/history.py
Normal file
63
cmdb-api/api/views/cmdb/history.py
Normal file
@@ -0,0 +1,63 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
|
||||
|
||||
import datetime
|
||||
|
||||
from flask import abort
|
||||
from flask import request
|
||||
|
||||
from api.lib.cmdb.history import AttributeHistoryManger
|
||||
from api.lib.utils import get_page
|
||||
from api.lib.utils import get_page_size
|
||||
from api.resource import APIView
|
||||
|
||||
|
||||
class RecordView(APIView):
|
||||
url_prefix = "/history/records"
|
||||
|
||||
def get(self):
|
||||
page = get_page(request.values.get("page", 1))
|
||||
page_size = get_page_size(request.values.get("page_size"))
|
||||
_start = request.values.get("start")
|
||||
_end = request.values.get("end")
|
||||
username = request.values.get("username", "")
|
||||
start, end = None, None
|
||||
if _start:
|
||||
try:
|
||||
start = datetime.datetime.strptime(_start, '%Y-%m-%d %H:%M:%S')
|
||||
except ValueError:
|
||||
abort(400, 'incorrect start date time')
|
||||
if _end:
|
||||
try:
|
||||
end = datetime.datetime.strptime(_end, '%Y-%m-%d %H:%M:%S')
|
||||
except ValueError:
|
||||
abort(400, 'incorrect end date time')
|
||||
|
||||
numfound, total, res = AttributeHistoryManger.get_records(start, end, username, page, page_size)
|
||||
|
||||
return self.jsonify(numfound=numfound,
|
||||
records=res,
|
||||
page=page,
|
||||
total=total,
|
||||
start=_start,
|
||||
end=_end,
|
||||
username=username)
|
||||
|
||||
|
||||
class CIHistoryView(APIView):
|
||||
url_prefix = "/history/ci/<int:ci_id>"
|
||||
|
||||
def get(self, ci_id):
|
||||
result = AttributeHistoryManger.get_by_ci_id(ci_id)
|
||||
return self.jsonify(result)
|
||||
|
||||
|
||||
class RecordDetailView(APIView):
|
||||
url_prefix = "/history/records/<int:record_id>"
|
||||
|
||||
def get(self, record_id):
|
||||
username, timestamp, attr_dict, rel_dict = AttributeHistoryManger.get_record_detail(record_id)
|
||||
return self.jsonify(username=username,
|
||||
timestamp=timestamp,
|
||||
attr_history=attr_dict,
|
||||
rel_history=rel_dict)
|
98
cmdb-api/api/views/cmdb/preference.py
Normal file
98
cmdb-api/api/views/cmdb/preference.py
Normal file
@@ -0,0 +1,98 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
|
||||
|
||||
from flask import request
|
||||
|
||||
from api.lib.cmdb.ci_type import CITypeManager
|
||||
from api.lib.cmdb.const import ResourceTypeEnum, PermEnum, RoleEnum
|
||||
from api.lib.cmdb.preference import PreferenceManager
|
||||
from api.lib.decorator import args_required
|
||||
from api.lib.perm.acl.acl import has_perm_from_args
|
||||
from api.lib.perm.acl.acl import role_required
|
||||
from api.lib.utils import handle_arg_list
|
||||
from api.resource import APIView
|
||||
|
||||
|
||||
class PreferenceShowCITypesView(APIView):
|
||||
url_prefix = "/preference/ci_types"
|
||||
|
||||
def get(self):
|
||||
instance = request.values.get("instance")
|
||||
tree = request.values.get("tree")
|
||||
|
||||
return self.jsonify(PreferenceManager.get_types(instance, tree))
|
||||
|
||||
|
||||
class PreferenceShowAttributesView(APIView):
|
||||
url_prefix = "/preference/ci_types/<id_or_name>/attributes"
|
||||
|
||||
def get(self, id_or_name):
|
||||
is_subscribed, attributes = PreferenceManager.get_show_attributes(id_or_name)
|
||||
|
||||
return self.jsonify(attributes=attributes, is_subscribed=is_subscribed)
|
||||
|
||||
@has_perm_from_args("id_or_name", ResourceTypeEnum.CI, PermEnum.READ, CITypeManager.get_name_by_id)
|
||||
@args_required("attr")
|
||||
def post(self, id_or_name):
|
||||
id_or_name = int(id_or_name)
|
||||
attr_list = handle_arg_list(request.values.get("attr", ""))
|
||||
orders = list(range(len(attr_list)))
|
||||
PreferenceManager.create_or_update_show_attributes(id_or_name, list(zip(attr_list, orders)))
|
||||
|
||||
return self.jsonify(type_id=id_or_name,
|
||||
attr_order=list(zip(attr_list, orders)))
|
||||
|
||||
@has_perm_from_args("id_or_name", ResourceTypeEnum.CI, PermEnum.READ, CITypeManager.get_name_by_id)
|
||||
def put(self, id_or_name):
|
||||
return self.post(id_or_name)
|
||||
|
||||
|
||||
class PreferenceTreeApiView(APIView):
|
||||
url_prefix = "/preference/tree/view"
|
||||
|
||||
def get(self):
|
||||
return self.jsonify(PreferenceManager.get_tree_view())
|
||||
|
||||
@has_perm_from_args("type_id", ResourceTypeEnum.CI, PermEnum.READ, CITypeManager.get_name_by_id)
|
||||
@args_required("type_id")
|
||||
@args_required("levels")
|
||||
def post(self):
|
||||
type_id = request.values.get("type_id")
|
||||
levels = handle_arg_list(request.values.get("levels"))
|
||||
res = PreferenceManager.create_or_update_tree_view(type_id, levels)
|
||||
|
||||
return self.jsonify(res and res.to_dict() or {})
|
||||
|
||||
def put(self):
|
||||
return self.post()
|
||||
|
||||
|
||||
class PreferenceRelationApiView(APIView):
|
||||
url_prefix = "/preference/relation/view"
|
||||
|
||||
def get(self):
|
||||
views, id2type, name2id = PreferenceManager.get_relation_view()
|
||||
|
||||
return self.jsonify(views=views, id2type=id2type, name2id=name2id)
|
||||
|
||||
@role_required(RoleEnum.CONFIG)
|
||||
@args_required("name")
|
||||
@args_required("cr_ids")
|
||||
def post(self):
|
||||
name = request.values.get("name")
|
||||
cr_ids = request.values.get("cr_ids")
|
||||
views, id2type, name2id = PreferenceManager.create_or_update_relation_view(name, cr_ids)
|
||||
|
||||
return self.jsonify(views=views, id2type=id2type, name2id=name2id)
|
||||
|
||||
@role_required(RoleEnum.CONFIG)
|
||||
def put(self):
|
||||
return self.post()
|
||||
|
||||
@role_required(RoleEnum.CONFIG)
|
||||
@args_required("name")
|
||||
def delete(self):
|
||||
name = request.values.get("name")
|
||||
PreferenceManager.delete_relation_view(name)
|
||||
|
||||
return self.jsonify(name=name)
|
37
cmdb-api/api/views/cmdb/relation_type.py
Normal file
37
cmdb-api/api/views/cmdb/relation_type.py
Normal file
@@ -0,0 +1,37 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
|
||||
|
||||
from flask import abort
|
||||
from flask import request
|
||||
|
||||
from api.lib.cmdb.const import RoleEnum
|
||||
from api.lib.cmdb.relation_type import RelationTypeManager
|
||||
from api.lib.decorator import args_required
|
||||
from api.lib.perm.acl.acl import role_required
|
||||
from api.resource import APIView
|
||||
|
||||
|
||||
class RelationTypeView(APIView):
|
||||
url_prefix = ("/relation_types", "/relation_types/<int:rel_id>")
|
||||
|
||||
def get(self):
|
||||
return self.jsonify([i.to_dict() for i in RelationTypeManager.get_all()])
|
||||
|
||||
@role_required(RoleEnum.CONFIG)
|
||||
@args_required("name")
|
||||
def post(self):
|
||||
name = request.values.get("name") or abort(400, "Name cannot be empty")
|
||||
rel = RelationTypeManager.add(name)
|
||||
return self.jsonify(rel.to_dict())
|
||||
|
||||
@role_required(RoleEnum.CONFIG)
|
||||
@args_required("name")
|
||||
def put(self, rel_id):
|
||||
name = request.values.get("name") or abort(400, "Name cannot be empty")
|
||||
rel = RelationTypeManager.update(rel_id, name)
|
||||
return self.jsonify(rel.to_dict())
|
||||
|
||||
@role_required(RoleEnum.CONFIG)
|
||||
def delete(self, rel_id):
|
||||
RelationTypeManager.delete(rel_id)
|
||||
return self.jsonify(rel_id=rel_id)
|
Reference in New Issue
Block a user