codosdk 1.0.0__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- codosdk-1.0.0.data/data/share/doc/codo_sdk/README.md +50 -0
- codosdk-1.0.0.dist-info/LICENSE +674 -0
- codosdk-1.0.0.dist-info/METADATA +35 -0
- codosdk-1.0.0.dist-info/RECORD +45 -0
- codosdk-1.0.0.dist-info/WHEEL +6 -0
- codosdk-1.0.0.dist-info/top_level.txt +2 -0
- opssdk/__init__.py +0 -0
- opssdk/utils/__init__.py +24 -0
- websdk2/__init__.py +0 -0
- websdk2/api_set.py +43 -0
- websdk2/apis/__init__.py +9 -0
- websdk2/apis/admin_apis.py +160 -0
- websdk2/apis/agent_apis.py +44 -0
- websdk2/apis/cmdb_apis.py +22 -0
- websdk2/apis/kerrigan_apis.py +21 -0
- websdk2/apis/mgv4_apis.py +95 -0
- websdk2/apis/task_apis.py +80 -0
- websdk2/application.py +77 -0
- websdk2/base_handler.py +275 -0
- websdk2/cache.py +128 -0
- websdk2/cache_context.py +38 -0
- websdk2/client.py +173 -0
- websdk2/cloud/__init__.py +0 -0
- websdk2/cloud/qcloud_api.py +57 -0
- websdk2/cloud/ucloud_api.py +73 -0
- websdk2/cloud_utils.py +26 -0
- websdk2/configs.py +97 -0
- websdk2/consts.py +212 -0
- websdk2/db_context.py +150 -0
- websdk2/error.py +50 -0
- websdk2/fetch_coroutine.py +12 -0
- websdk2/jwt_token.py +135 -0
- websdk2/ldap.py +117 -0
- websdk2/logger.py +42 -0
- websdk2/model_utils.py +156 -0
- websdk2/mqhelper.py +120 -0
- websdk2/program.py +20 -0
- websdk2/salt_api.py +107 -0
- websdk2/sqlalchemy_pagination.py +73 -0
- websdk2/tools.py +198 -0
- websdk2/utils/__init__.py +257 -0
- websdk2/utils/cc_crypto.py +85 -0
- websdk2/utils/date_format.py +35 -0
- websdk2/utils/pydantic_utils.py +55 -0
- websdk2/web_logs.py +127 -0
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
""""
|
|
4
|
+
Contact : 191715030@qq.com
|
|
5
|
+
Author : shenshuo
|
|
6
|
+
Date : 2019年2月5日13:37:54
|
|
7
|
+
Desc : 云厂商的一些方法
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
import hmac
|
|
11
|
+
import hashlib
|
|
12
|
+
import base64
|
|
13
|
+
from urllib import parse
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class QCloudApiOpt:
|
|
17
|
+
|
|
18
|
+
@staticmethod
|
|
19
|
+
def sort_dic(keydict):
|
|
20
|
+
return sorted(zip(keydict.keys(), keydict.values()))
|
|
21
|
+
|
|
22
|
+
@staticmethod
|
|
23
|
+
def get_str_sign(sortlist, api_url):
|
|
24
|
+
sign_str_init = ''
|
|
25
|
+
for value in sortlist:
|
|
26
|
+
sign_str_init += value[0] + '=' + value[1] + '&'
|
|
27
|
+
sign_str = 'GET' + api_url + sign_str_init[:-1]
|
|
28
|
+
return sign_str, sign_str_init
|
|
29
|
+
|
|
30
|
+
@staticmethod
|
|
31
|
+
def get_signature(sign_str, secret_key):
|
|
32
|
+
secretkey = secret_key
|
|
33
|
+
signature = bytes(sign_str, encoding='utf-8')
|
|
34
|
+
secretkey = bytes(secretkey, encoding='utf-8')
|
|
35
|
+
my_sign = hmac.new(secretkey, signature, hashlib.sha1).digest()
|
|
36
|
+
return base64.b64encode(my_sign)
|
|
37
|
+
|
|
38
|
+
@staticmethod
|
|
39
|
+
def encode_signature(my_sign):
|
|
40
|
+
return parse.quote(my_sign)
|
|
41
|
+
|
|
42
|
+
@staticmethod
|
|
43
|
+
def get_result_url(sign_str, result_sign, api_url):
|
|
44
|
+
return 'https://' + api_url + sign_str + 'Signature=' + result_sign
|
|
45
|
+
|
|
46
|
+
@staticmethod
|
|
47
|
+
def run(keydict, api_url, secret_key):
|
|
48
|
+
sortlist = QCloudApiOpt.sort_dic(keydict)
|
|
49
|
+
# 获取拼接后的sign字符串
|
|
50
|
+
sign_str, sign_str_int = QCloudApiOpt.get_str_sign(sortlist, api_url)
|
|
51
|
+
# 获取签名
|
|
52
|
+
my_sign = QCloudApiOpt.get_signature(sign_str, secret_key)
|
|
53
|
+
# 对签名串进行编码
|
|
54
|
+
result_sign = QCloudApiOpt.encode_signature(my_sign)
|
|
55
|
+
# 获取最终请求url
|
|
56
|
+
result_url = QCloudApiOpt.get_result_url(sign_str_int, result_sign, api_url)
|
|
57
|
+
return result_url
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
"""
|
|
4
|
+
Contact : 191715030@qq.com
|
|
5
|
+
Author : shenshuo
|
|
6
|
+
Date : 2019年2月5日13:37:54
|
|
7
|
+
Desc : 云厂商的一些方法
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
import requests
|
|
11
|
+
import hashlib
|
|
12
|
+
import logging
|
|
13
|
+
|
|
14
|
+
logging.basicConfig(level=logging.INFO, format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',
|
|
15
|
+
datefmt='%Y %H:%M:%S')
|
|
16
|
+
|
|
17
|
+
logger = logging.getLogger("ucloud")
|
|
18
|
+
logger.setLevel(logging.WARN)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class UCloudApi:
|
|
22
|
+
"""UCloud接口"""
|
|
23
|
+
|
|
24
|
+
def __init__(self, access_id, access_key, url='https://api.ucloud.cn/'):
|
|
25
|
+
self.url = url
|
|
26
|
+
self.access_id = access_id
|
|
27
|
+
self.access_key = access_key
|
|
28
|
+
|
|
29
|
+
def get_region_list(self):
|
|
30
|
+
params = {
|
|
31
|
+
'Action': 'GetRegion',
|
|
32
|
+
'PublicKey': self.access_id
|
|
33
|
+
}
|
|
34
|
+
params = self.add_signature(params)
|
|
35
|
+
req = requests.get(url=self.url, params=params)
|
|
36
|
+
regions = list(set([r['Region'] for r in req.json()['Regions']]))
|
|
37
|
+
return regions
|
|
38
|
+
|
|
39
|
+
def get_project_list(self):
|
|
40
|
+
params = {
|
|
41
|
+
'Action': 'GetProjectList',
|
|
42
|
+
'PublicKey': self.access_id
|
|
43
|
+
}
|
|
44
|
+
params = self.add_signature(params)
|
|
45
|
+
req = requests.get(url=self.url, params=params)
|
|
46
|
+
project = list(set([r['ProjectId'] for r in req.json()['ProjectSet']]))
|
|
47
|
+
return project
|
|
48
|
+
|
|
49
|
+
def get_project_info(self):
|
|
50
|
+
params = {
|
|
51
|
+
'Action': 'GetProjectList',
|
|
52
|
+
'PublicKey': self.access_id
|
|
53
|
+
}
|
|
54
|
+
params = self.add_signature(params)
|
|
55
|
+
req = requests.get(url=self.url, params=params)
|
|
56
|
+
project_list = []
|
|
57
|
+
for i in req.json()['ProjectSet']:
|
|
58
|
+
if isinstance(i, dict):
|
|
59
|
+
project_list.append(i)
|
|
60
|
+
return project_list
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def add_signature(self, params):
|
|
64
|
+
items = params.items()
|
|
65
|
+
params_data = ""
|
|
66
|
+
for key in sorted(items):
|
|
67
|
+
params_data = params_data + str(key[0]) + str(key[1])
|
|
68
|
+
params_data = params_data + self.access_key
|
|
69
|
+
sign = hashlib.sha1()
|
|
70
|
+
sign.update(params_data.encode('utf8'))
|
|
71
|
+
signature = sign.hexdigest()
|
|
72
|
+
params['Signature'] = signature
|
|
73
|
+
return params
|
websdk2/cloud_utils.py
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
""""
|
|
4
|
+
Contact : 191715030@qq.com
|
|
5
|
+
Author : shenshuo
|
|
6
|
+
Date : 2019年2月5日13:37:54
|
|
7
|
+
Desc : 云厂商的一些方法
|
|
8
|
+
"""
|
|
9
|
+
from .cloud.qcloud_api import QCloudApiOpt
|
|
10
|
+
from .cloud.ucloud_api import UCloudApi
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def cloud_factory(cloud):
|
|
14
|
+
if cloud == 'aliyun':
|
|
15
|
+
return None
|
|
16
|
+
|
|
17
|
+
elif cloud == 'qcloud':
|
|
18
|
+
return QCloudApiOpt()
|
|
19
|
+
|
|
20
|
+
elif cloud == 'ucloud':
|
|
21
|
+
return UCloudApi()
|
|
22
|
+
|
|
23
|
+
elif cloud == 'aws':
|
|
24
|
+
return None
|
|
25
|
+
else:
|
|
26
|
+
return None
|
websdk2/configs.py
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
"""
|
|
4
|
+
Contact : 191715030@qq.com
|
|
5
|
+
Author : shenshuo
|
|
6
|
+
Date : 2018/9/5
|
|
7
|
+
Desc : 配置文件
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from .consts import const
|
|
11
|
+
from .tools import singleton
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@singleton
|
|
15
|
+
class Config(dict):
|
|
16
|
+
def __init__(self):
|
|
17
|
+
self.__can_import = True
|
|
18
|
+
self.__init_default()
|
|
19
|
+
dict.__init__(self)
|
|
20
|
+
|
|
21
|
+
def __getattr__(self, item, default=""):
|
|
22
|
+
if item in self:
|
|
23
|
+
return self[item]
|
|
24
|
+
return ""
|
|
25
|
+
|
|
26
|
+
@property
|
|
27
|
+
def can_import(self):
|
|
28
|
+
return self.__can_import
|
|
29
|
+
|
|
30
|
+
def import_dict(self, **kwargs):
|
|
31
|
+
if self.__can_import:
|
|
32
|
+
for k, v in kwargs.items():
|
|
33
|
+
self[k] = v
|
|
34
|
+
self.__can_import = False
|
|
35
|
+
else:
|
|
36
|
+
raise Exception('ConfigImportError')
|
|
37
|
+
|
|
38
|
+
def __init_default(self):
|
|
39
|
+
self['debug'] = False
|
|
40
|
+
self['autoreload'] = True
|
|
41
|
+
self[const.DB_CONFIG_ITEM] = {
|
|
42
|
+
const.DEFAULT_DB_KEY: {
|
|
43
|
+
const.DBHOST_KEY: '',
|
|
44
|
+
const.DBPORT_KEY: 3306,
|
|
45
|
+
const.DBUSER_KEY: '',
|
|
46
|
+
const.DBPWD_KEY: '',
|
|
47
|
+
const.DBNAME_KEY: '',
|
|
48
|
+
},
|
|
49
|
+
const.READONLY_DB_KEY: {
|
|
50
|
+
const.DBHOST_KEY: '',
|
|
51
|
+
const.DBPORT_KEY: 3306,
|
|
52
|
+
const.DBUSER_KEY: '',
|
|
53
|
+
const.DBPWD_KEY: '',
|
|
54
|
+
const.DBNAME_KEY: '',
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
self[const.REDIS_CONFIG_ITEM] = {
|
|
58
|
+
const.DEFAULT_RD_KEY: {
|
|
59
|
+
const.RD_HOST_KEY: '',
|
|
60
|
+
const.RD_PORT_KEY: 6379,
|
|
61
|
+
const.RD_DB_KEY: -1,
|
|
62
|
+
const.RD_AUTH_KEY: True,
|
|
63
|
+
const.RD_CHARSET_KEY: 'utf-8',
|
|
64
|
+
const.RD_PASSWORD_KEY: ''
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
self[const.MQ_CONFIG_ITEM] = {
|
|
68
|
+
const.DEFAULT_MQ_KEY: {
|
|
69
|
+
const.MQ_ADDR: '',
|
|
70
|
+
const.MQ_PORT: 5672,
|
|
71
|
+
const.MQ_VHOST: '/',
|
|
72
|
+
const.MQ_USER: '',
|
|
73
|
+
const.MQ_PWD: '',
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
# self[const.APP_NAME] = ''
|
|
77
|
+
# self[const.LOG_TO_FILE] = False
|
|
78
|
+
|
|
79
|
+
def has_item(self, item):
|
|
80
|
+
return item in self
|
|
81
|
+
|
|
82
|
+
def clear(self):
|
|
83
|
+
self.__can_import = True
|
|
84
|
+
dict.clear(self)
|
|
85
|
+
self.__init_default()
|
|
86
|
+
|
|
87
|
+
@staticmethod
|
|
88
|
+
def __get_key_dict(sub_set, key):
|
|
89
|
+
if key in sub_set:
|
|
90
|
+
sk_dict = sub_set[key]
|
|
91
|
+
else:
|
|
92
|
+
sk_dict = {}
|
|
93
|
+
sub_set[key] = sk_dict
|
|
94
|
+
return sk_dict
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
configs = Config()
|
websdk2/consts.py
ADDED
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
# -*-coding:utf-8-*-
|
|
3
|
+
"""
|
|
4
|
+
Author : ming
|
|
5
|
+
date : 2017/4/11 下午1:54
|
|
6
|
+
role : 常量管理
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from enum import IntEnum as Enum
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class ConstError(TypeError):
|
|
13
|
+
pass
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class IntEnum(Enum):
|
|
17
|
+
@staticmethod
|
|
18
|
+
def find_enum(cls, value):
|
|
19
|
+
for k, v in cls._value2member_map_.items():
|
|
20
|
+
if k == value:
|
|
21
|
+
return v
|
|
22
|
+
return None
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class ErrorCode(IntEnum):
|
|
26
|
+
""" 错误码枚举 """
|
|
27
|
+
|
|
28
|
+
not_found = 404
|
|
29
|
+
bad_request = 400
|
|
30
|
+
unauthorized = 401
|
|
31
|
+
forbidden = 403
|
|
32
|
+
not_allowed = 405
|
|
33
|
+
not_acceptable = 406
|
|
34
|
+
conflict = 409
|
|
35
|
+
gone = 410
|
|
36
|
+
precondition_failed = 412
|
|
37
|
+
request_entity_too_large = 413
|
|
38
|
+
unsupport_media_type = 415
|
|
39
|
+
internal_server_error = 500
|
|
40
|
+
service_unavailable = 503
|
|
41
|
+
service_not_implemented = 501
|
|
42
|
+
handler_uncatched_exception = 504
|
|
43
|
+
config_import_error = 1001
|
|
44
|
+
config_item_notfound_error = 1002
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
class _const(object):
|
|
48
|
+
def __setattr__(self, name, value):
|
|
49
|
+
if name in self.__dict__:
|
|
50
|
+
raise ConstError("Can't rebind const (%s)" % name)
|
|
51
|
+
if not name.isupper():
|
|
52
|
+
raise ConstError("Const must be upper.")
|
|
53
|
+
self.__dict__[name] = value
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
const = _const()
|
|
57
|
+
|
|
58
|
+
const.DB_CONFIG_ITEM = 'databases'
|
|
59
|
+
const.DBHOST_KEY = 'host'
|
|
60
|
+
const.DBPWD_KEY = 'pwd'
|
|
61
|
+
const.DBUSER_KEY = 'user'
|
|
62
|
+
const.DBNAME_KEY = 'name'
|
|
63
|
+
const.DBPORT_KEY = 'port'
|
|
64
|
+
const.SF_DB_KEY = 'vmobel'
|
|
65
|
+
const.DEFAULT_DB_KEY = 'default'
|
|
66
|
+
const.READONLY_DB_KEY = 'readonly'
|
|
67
|
+
|
|
68
|
+
const.REDIS_CONFIG_ITEM = 'redises'
|
|
69
|
+
const.RD_HOST_KEY = 'host'
|
|
70
|
+
const.RD_PORT_KEY = 'port'
|
|
71
|
+
const.RD_DB_KEY = 'db'
|
|
72
|
+
const.RD_AUTH_KEY = 'auth'
|
|
73
|
+
const.RD_CHARSET_KEY = 'charset'
|
|
74
|
+
const.RD_DECODE_RESPONSES = 'decode_responses'
|
|
75
|
+
const.RD_PASSWORD_KEY = 'password'
|
|
76
|
+
const.DEFAULT_RD_KEY = 'default'
|
|
77
|
+
|
|
78
|
+
# ETCD
|
|
79
|
+
const.DEFAULT_ETCD_KEY = "default"
|
|
80
|
+
const.BACKUP_ETCD_KEY = "backup"
|
|
81
|
+
const.DEFAULT_ETCD_HOST = "host"
|
|
82
|
+
const.DEFAULT_ETCD_PORT = "port"
|
|
83
|
+
const.DEFAULT_ETCD_PROTOCOL = "protocol"
|
|
84
|
+
const.DEFAULT_ETCD_USER = "user"
|
|
85
|
+
const.DEFAULT_ETCD_PWD = "pwd"
|
|
86
|
+
|
|
87
|
+
# MQ
|
|
88
|
+
const.MQ_CONFIG_ITEM = 'mqs'
|
|
89
|
+
const.MQ_ADDR = 'MQ_ADDR'
|
|
90
|
+
const.MQ_PORT = 'MQ_PORT'
|
|
91
|
+
const.MQ_VHOST = 'MQ_VHOST'
|
|
92
|
+
const.MQ_USER = 'MQ_USER'
|
|
93
|
+
const.MQ_PWD = 'MQ_PWD'
|
|
94
|
+
const.DEFAULT_MQ_KEY = 'default'
|
|
95
|
+
const.AGENT_MQ_KEY = 'agent'
|
|
96
|
+
|
|
97
|
+
# JMS
|
|
98
|
+
const.JMS_CONFIG_ITEM = 'jmss'
|
|
99
|
+
const.DEFAULT_JMS_KEY = 'default'
|
|
100
|
+
const.JMS_API_BASE_URL = "jms_url"
|
|
101
|
+
const.JMS_API_KEY_ID = "jms_key_id"
|
|
102
|
+
const.JMS_API_KEY_SECRET = "jms_key_secret"
|
|
103
|
+
|
|
104
|
+
# consul
|
|
105
|
+
const.CONSUL_CONFIG_ITEM = 'consuls'
|
|
106
|
+
const.DEFAULT_CS_KEY = 'default'
|
|
107
|
+
const.CONSUL_HOST_KEY = 'cs_host'
|
|
108
|
+
const.CONSUL_PORT_KEY = 'cs_port'
|
|
109
|
+
const.CONSUL_TOKEN_KEY = 'cs_token'
|
|
110
|
+
const.CONSUL_SCHEME_KEY = 'cs_scheme'
|
|
111
|
+
|
|
112
|
+
const.APP_NAME = 'app_name'
|
|
113
|
+
const.LOG_PATH = 'log_path'
|
|
114
|
+
const.LOG_BACKUP_COUNT = 'log_backup_count'
|
|
115
|
+
const.LOG_MAX_FILE_SIZE = 'log_max_filesize'
|
|
116
|
+
|
|
117
|
+
const.REQUEST_START_SIGNAL = 'request_start'
|
|
118
|
+
const.REQUEST_FINISHED_SIGNAL = 'request_finished'
|
|
119
|
+
|
|
120
|
+
const.NW_SALT = 'nw'
|
|
121
|
+
const.ALY_SALT = 'aly'
|
|
122
|
+
const.TX_SALT = 'tx'
|
|
123
|
+
const.SG_SALT = 'sg'
|
|
124
|
+
const.DEFAULT_SALT = 'default'
|
|
125
|
+
const.SALT_API = 'salt_api'
|
|
126
|
+
const.SALT_USER = 'salt_username'
|
|
127
|
+
const.SALT_PW = 'salt_password'
|
|
128
|
+
const.SALT_OUT = 'salt_timeout'
|
|
129
|
+
|
|
130
|
+
const.NW_INCEPTION = 'nw'
|
|
131
|
+
const.ALY_INCEPTION = 'aly'
|
|
132
|
+
const.TX_INCEPTION = 'tx'
|
|
133
|
+
const.DEFAULT_INCEPTION = 'default'
|
|
134
|
+
|
|
135
|
+
const.REGION = "cn-hangzhou"
|
|
136
|
+
const.PRODUCT_NAME = "Dysmsapi"
|
|
137
|
+
const.DOMAIN = "dysmsapi.aliyuncs.com"
|
|
138
|
+
|
|
139
|
+
# crypto
|
|
140
|
+
const.AES_CRYPTO_KEY = 'aes_crypto_key'
|
|
141
|
+
### app settings
|
|
142
|
+
const.APP_SETTINGS = 'APP_SETTINGS'
|
|
143
|
+
### all user info
|
|
144
|
+
const.USERS_INFO = 'USERS_INFO'
|
|
145
|
+
|
|
146
|
+
# API GW
|
|
147
|
+
const.WEBSITE_API_GW_URL = 'api_gw'
|
|
148
|
+
const.API_AUTH_KEY = 'settings_auth_key'
|
|
149
|
+
const.EMAILLOGIN_DOMAIN = 'EMAILLOGIN_DOMAIN'
|
|
150
|
+
const.EMAILLOGIN_SERVER = 'EMAILLOGIN_SERVER'
|
|
151
|
+
|
|
152
|
+
# email
|
|
153
|
+
const.EMAIL_SUBJECT_PREFIX = "EMAIL_SUBJECT_PREFIX"
|
|
154
|
+
const.EMAIL_HOST = "EMAIL_HOST"
|
|
155
|
+
const.EMAIL_PORT = "EMAIL_PORT"
|
|
156
|
+
const.EMAIL_HOST_USER = "EMAIL_HOST_USER"
|
|
157
|
+
const.EMAIL_HOST_PASSWORD = "EMAIL_HOST_PASSWORD"
|
|
158
|
+
const.EMAIL_USE_SSL = "EMAIL_USE_SSL"
|
|
159
|
+
const.EMAIL_USE_TLS = "EMAIL_USE_TLS"
|
|
160
|
+
|
|
161
|
+
# 短信配置
|
|
162
|
+
const.SMS_REGION = "SMS_REGION"
|
|
163
|
+
const.SMS_PRODUCT_NAME = "SMS_PRODUCT_NAME"
|
|
164
|
+
const.SMS_DOMAIN = "SMS_DOMAIN"
|
|
165
|
+
|
|
166
|
+
const.SMS_ACCESS_KEY_ID = 'SMS_ACCESS_KEY_ID'
|
|
167
|
+
const.SMS_ACCESS_KEY_SECRET = 'SMS_ACCESS_KEY_SECRET'
|
|
168
|
+
# 钉钉
|
|
169
|
+
const.DING_TALK_WEBHOOK = "DING_TALK_WEBHOOK"
|
|
170
|
+
# 存储
|
|
171
|
+
const.STORAGE_REGION = "STORAGE_REGION"
|
|
172
|
+
const.STORAGE_NAME = "STORAGE_NAME"
|
|
173
|
+
const.STORAGE_PATH = "STORAGE_PATH"
|
|
174
|
+
const.STORAGE_KEY_ID = "STORAGE_KEY_ID"
|
|
175
|
+
const.STORAGE_KEY_SECRET = "STORAGE_KEY_SECRET"
|
|
176
|
+
|
|
177
|
+
### LDAP
|
|
178
|
+
const.LDAP_SERVER_HOST = "LDAP_SERVER_HOST"
|
|
179
|
+
const.LDAP_SERVER_PORT = "LDAP_SERVER_PORT"
|
|
180
|
+
const.LDAP_ADMIN_DN = "LDAP_ADMIN_DN"
|
|
181
|
+
const.LDAP_ADMIN_PASSWORD = "LDAP_ADMIN_PASSWORD"
|
|
182
|
+
const.LDAP_SEARCH_BASE = "LDAP_SEARCH_BASE"
|
|
183
|
+
const.LDAP_SEARCH_FILTER = "LDAP_SEARCH_FILTER"
|
|
184
|
+
const.LDAP_ATTRIBUTES = "LDAP_ATTRIBUTES"
|
|
185
|
+
const.LDAP_USE_SSL = "LDAP_USE_SSL"
|
|
186
|
+
const.LDAP_ENABLE = "LDAP_ENABLE"
|
|
187
|
+
|
|
188
|
+
### token 超时时间
|
|
189
|
+
const.TOKEN_EXP_TIME = "TOKEN_EXP_TIME"
|
|
190
|
+
|
|
191
|
+
### 全局 二次认证
|
|
192
|
+
const.MFA_GLOBAL = 'MFA_GLOBAL'
|
|
193
|
+
|
|
194
|
+
### 任务状态
|
|
195
|
+
const.STATE_NEW = '0'
|
|
196
|
+
const.STATE_WAIT = '1'
|
|
197
|
+
const.STATE_RUNNING = '2'
|
|
198
|
+
const.STATE_SUCCESS = '3'
|
|
199
|
+
const.STATE_ERROR = '4'
|
|
200
|
+
const.STATE_MANUAL = '5'
|
|
201
|
+
const.STATE_BREAK = '6'
|
|
202
|
+
const.STATE_TIMING = '7'
|
|
203
|
+
const.STATE_UNKNOWN = '8'
|
|
204
|
+
const.STATE_FAIL = '9'
|
|
205
|
+
const.STATE_IGNORE = '10' # 忽略
|
|
206
|
+
const.STATE_QUEUE = '11' # 排队中
|
|
207
|
+
const.EXEC_TIMEOUT = 1800
|
|
208
|
+
|
|
209
|
+
## 节点地址
|
|
210
|
+
const.NODE_ADDRESS = 'NODE_ADDRESS'
|
|
211
|
+
const.EXEC_NODE_MAP_KEY = 'EXEC_NODE_MAP_KEY'
|
|
212
|
+
const.AGENT_USED_KEY = "agent_is_used_map_mark_key"
|
websdk2/db_context.py
ADDED
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
# -*-coding:utf-8-*-
|
|
2
|
+
"""
|
|
3
|
+
Author : shenshuo
|
|
4
|
+
date : 2017年10月17日17:23:19
|
|
5
|
+
role : 数据库连接
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import pymysql
|
|
9
|
+
from urllib.parse import quote_plus
|
|
10
|
+
from sqlalchemy import create_engine
|
|
11
|
+
from sqlalchemy.pool import NullPool
|
|
12
|
+
from sqlalchemy.orm import sessionmaker
|
|
13
|
+
from .consts import const
|
|
14
|
+
from .configs import configs
|
|
15
|
+
|
|
16
|
+
engines = {}
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def init_engine(**settings):
|
|
20
|
+
if settings:
|
|
21
|
+
databases = settings[const.DB_CONFIG_ITEM]
|
|
22
|
+
else:
|
|
23
|
+
databases = configs[const.DB_CONFIG_ITEM]
|
|
24
|
+
for dbkey, db_conf in databases.items():
|
|
25
|
+
dbuser = db_conf[const.DBUSER_KEY]
|
|
26
|
+
dbpwd = db_conf[const.DBPWD_KEY]
|
|
27
|
+
dbhost = db_conf[const.DBHOST_KEY]
|
|
28
|
+
dbport = db_conf[const.DBPORT_KEY]
|
|
29
|
+
dbname = db_conf[const.DBNAME_KEY]
|
|
30
|
+
engine = create_engine('mysql+pymysql://{user}:{pwd}@{host}:{port}/{dbname}?charset=utf8mb4'
|
|
31
|
+
.format(user=dbuser, pwd=quote_plus(dbpwd), host=dbhost, port=dbport, dbname=dbname),
|
|
32
|
+
# logging_name=dbkey)
|
|
33
|
+
logging_name=dbkey, poolclass=NullPool)
|
|
34
|
+
engines[dbkey] = engine
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def get_db_url(dbkey):
|
|
38
|
+
databases = configs[const.DB_CONFIG_ITEM]
|
|
39
|
+
db_conf = databases[dbkey]
|
|
40
|
+
dbuser = db_conf['user']
|
|
41
|
+
dbpwd = db_conf['pwd']
|
|
42
|
+
dbhost = db_conf['host']
|
|
43
|
+
dbport = db_conf.get('port', 3306)
|
|
44
|
+
dbname = db_conf['name']
|
|
45
|
+
|
|
46
|
+
return 'mysql+pymysql://{user}:{pwd}@{host}:{port}/{dbname}?charset=utf8mb4'.format(user=dbuser, pwd=quote_plus(dbpwd),
|
|
47
|
+
host=dbhost, port=dbport,
|
|
48
|
+
dbname=dbname, poolclass=NullPool)
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
class DBContext(object):
|
|
52
|
+
def __init__(self, rw='r', db_key=None, need_commit=False, **settings):
|
|
53
|
+
self.__db_key = db_key
|
|
54
|
+
if not self.__db_key:
|
|
55
|
+
if rw == 'w':
|
|
56
|
+
self.__db_key = const.DEFAULT_DB_KEY
|
|
57
|
+
elif rw == 'r':
|
|
58
|
+
self.__db_key = const.READONLY_DB_KEY
|
|
59
|
+
engine = self.__get_db_engine(self.__db_key, **settings)
|
|
60
|
+
self.__engine = engine
|
|
61
|
+
self.need_commit = need_commit
|
|
62
|
+
|
|
63
|
+
# @property
|
|
64
|
+
# def db_key(self):
|
|
65
|
+
# return self.__db_key
|
|
66
|
+
|
|
67
|
+
@staticmethod
|
|
68
|
+
def __get_db_engine(db_key, **settings):
|
|
69
|
+
if len(engines) == 0:
|
|
70
|
+
init_engine(**settings)
|
|
71
|
+
return engines[db_key]
|
|
72
|
+
|
|
73
|
+
@property
|
|
74
|
+
def session(self):
|
|
75
|
+
return self.__session
|
|
76
|
+
|
|
77
|
+
def __enter__(self):
|
|
78
|
+
self.__session = sessionmaker(bind=self.__engine)()
|
|
79
|
+
return self.__session
|
|
80
|
+
|
|
81
|
+
def __exit__(self, exc_type, exc_val, exc_tb):
|
|
82
|
+
if self.need_commit:
|
|
83
|
+
if exc_type:
|
|
84
|
+
self.__session.rollback()
|
|
85
|
+
else:
|
|
86
|
+
self.__session.commit()
|
|
87
|
+
self.__session.close()
|
|
88
|
+
|
|
89
|
+
def get_session(self):
|
|
90
|
+
return self.__session
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def init_engine_v2(**settings):
|
|
94
|
+
if settings:
|
|
95
|
+
databases = settings[const.DB_CONFIG_ITEM]
|
|
96
|
+
else:
|
|
97
|
+
databases = configs[const.DB_CONFIG_ITEM]
|
|
98
|
+
for dbkey, db_conf in databases.items():
|
|
99
|
+
dbuser = db_conf[const.DBUSER_KEY]
|
|
100
|
+
dbpwd = db_conf[const.DBPWD_KEY]
|
|
101
|
+
dbhost = db_conf[const.DBHOST_KEY]
|
|
102
|
+
dbport = db_conf[const.DBPORT_KEY]
|
|
103
|
+
dbname = db_conf[const.DBNAME_KEY]
|
|
104
|
+
engine = create_engine('mysql+pymysql://{user}:{pwd}@{host}:{port}/{dbname}?charset=utf8mb4'
|
|
105
|
+
.format(user=dbuser, pwd=quote_plus(dbpwd), host=dbhost, port=dbport, dbname=dbname),
|
|
106
|
+
logging_name=dbkey, poolclass=None, pool_size=10, max_overflow=50, pool_recycle=3600,
|
|
107
|
+
pool_pre_ping=True, pool_timeout=60)
|
|
108
|
+
engines[dbkey] = engine
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
class DBContextV2(object):
|
|
112
|
+
def __init__(self, rw='r', db_key=None, need_commit=False, **settings):
|
|
113
|
+
self.__db_key = db_key
|
|
114
|
+
if not self.__db_key:
|
|
115
|
+
if rw == 'w':
|
|
116
|
+
self.__db_key = const.DEFAULT_DB_KEY
|
|
117
|
+
elif rw == 'r':
|
|
118
|
+
self.__db_key = const.READONLY_DB_KEY
|
|
119
|
+
engine = self.__get_db_engine(self.__db_key, **settings)
|
|
120
|
+
self.__engine = engine
|
|
121
|
+
self.need_commit = need_commit
|
|
122
|
+
|
|
123
|
+
# @property
|
|
124
|
+
# def db_key(self):
|
|
125
|
+
# return self.__db_key
|
|
126
|
+
|
|
127
|
+
@staticmethod
|
|
128
|
+
def __get_db_engine(db_key, **settings):
|
|
129
|
+
if len(engines) == 0:
|
|
130
|
+
init_engine_v2(**settings)
|
|
131
|
+
return engines[db_key]
|
|
132
|
+
|
|
133
|
+
@property
|
|
134
|
+
def session(self):
|
|
135
|
+
return self.__session
|
|
136
|
+
|
|
137
|
+
def __enter__(self):
|
|
138
|
+
self.__session = sessionmaker(bind=self.__engine)()
|
|
139
|
+
return self.__session
|
|
140
|
+
|
|
141
|
+
def __exit__(self, exc_type, exc_val, exc_tb):
|
|
142
|
+
if self.need_commit:
|
|
143
|
+
if exc_type:
|
|
144
|
+
self.__session.rollback()
|
|
145
|
+
else:
|
|
146
|
+
self.__session.commit()
|
|
147
|
+
self.__session.close()
|
|
148
|
+
|
|
149
|
+
def get_session(self):
|
|
150
|
+
return self.__session
|
websdk2/error.py
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
from enum import IntEnum
|
|
2
|
+
from .consts import ErrorCode
|
|
3
|
+
class BaseError(Exception):
|
|
4
|
+
""" 错误基类,所有错误必须从该类继承 """
|
|
5
|
+
|
|
6
|
+
def __init__(self, errorcode, *args, **kwargs):
|
|
7
|
+
"""
|
|
8
|
+
初始化错误基类
|
|
9
|
+
:param errorcode: 错误码
|
|
10
|
+
:param args:
|
|
11
|
+
:param kwargs:
|
|
12
|
+
"""
|
|
13
|
+
if isinstance(errorcode, IntEnum):
|
|
14
|
+
self._errorcode = errorcode
|
|
15
|
+
self.kwargs = kwargs
|
|
16
|
+
super(BaseError, self).__init__(*args)
|
|
17
|
+
else:
|
|
18
|
+
raise TypeError(
|
|
19
|
+
'Error code must be vmbsdk.constants.enums.ErrorCode type.')
|
|
20
|
+
|
|
21
|
+
@property
|
|
22
|
+
def errorcode(self):
|
|
23
|
+
return self._errorcode
|
|
24
|
+
class BizError(BaseError):
|
|
25
|
+
""" 业务错误 """
|
|
26
|
+
|
|
27
|
+
def __init__(self, errorcode, *args, **kwargs):
|
|
28
|
+
self.__subcode = int(args[1]) if len(args) > 1 else 0
|
|
29
|
+
super(BizError, self).__init__(errorcode, *args, **kwargs)
|
|
30
|
+
|
|
31
|
+
@property
|
|
32
|
+
def subcode(self):
|
|
33
|
+
"""
|
|
34
|
+
获取
|
|
35
|
+
:return:
|
|
36
|
+
"""
|
|
37
|
+
return self.__subcode
|
|
38
|
+
|
|
39
|
+
class BadRequestError(BizError):
|
|
40
|
+
""" 错误的请求 """
|
|
41
|
+
|
|
42
|
+
def __init__(self, *args, **kwargs):
|
|
43
|
+
super(BadRequestError, self).__init__(ErrorCode.bad_request,
|
|
44
|
+
*args, **kwargs)
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
class ConfigError(Exception):
|
|
48
|
+
def __init__(self, config_key, *args, **kwargs):
|
|
49
|
+
self.config_key = config_key
|
|
50
|
+
super(ConfigError, self).__init__(*args, **kwargs)
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import json
|
|
2
|
+
from tornado.httpclient import HTTPRequest, AsyncHTTPClient
|
|
3
|
+
from tornado.gen import coroutine
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
@coroutine
|
|
7
|
+
def fetch_coroutine(url, method='GET', body=None, **kwargs):
|
|
8
|
+
request = HTTPRequest(url, method=method, body=body, connect_timeout=5, request_timeout=10)
|
|
9
|
+
http_client = AsyncHTTPClient(**kwargs)
|
|
10
|
+
response = yield http_client.fetch(request)
|
|
11
|
+
body = json.loads(response.body)
|
|
12
|
+
return body
|