pytbox 0.1.0__py3-none-any.whl → 0.1.2__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.

Potentially problematic release.


This version of pytbox might be problematic. Click here for more details.

pytbox/base.py CHANGED
@@ -8,7 +8,10 @@ from pytbox.feishu.client import Client as FeishuClient
8
8
  from pytbox.dida365 import Dida365
9
9
  from pytbox.alert.alert_handler import AlertHandler
10
10
  from pytbox.log.logger import AppLogger
11
-
11
+ from pytbox.win.ad import ADClient
12
+ from pytbox.network.meraki import Meraki
13
+ from pytbox.utils.env import get_env_by_os_environment
14
+ from pytbox.vmware import VMwareClient
12
15
 
13
16
  config = load_config_by_file(path='/workspaces/pytbox/tests/alert/config_dev.toml', oc_vault_id=os.environ.get('oc_vault_id'))
14
17
 
@@ -45,4 +48,29 @@ def get_logger(app):
45
48
  feishu=feishu,
46
49
  dida=dida,
47
50
  mongo=get_mongo('alert_program')
48
- )
51
+ )
52
+
53
+ # ad_dev = ADClient(
54
+ # server=config['ad']['dev']['AD_SERVER'],
55
+ # base_dn=config['ad']['dev']['BASE_DN'],
56
+ # username=config['ad']['dev']['AD_USERNAME'],
57
+ # password=config['ad']['dev']['AD_PASSWORD']
58
+ # )
59
+
60
+ # ad_prod = ADClient(
61
+ # server=config['ad']['prod']['AD_SERVER'],
62
+ # base_dn=config['ad']['prod']['BASE_DN'],
63
+ # username=config['ad']['prod']['AD_USERNAME'],
64
+ # password=config['ad']['prod']['AD_PASSWORD']
65
+ # )
66
+
67
+ env = get_env_by_os_environment(check_key='ENV')
68
+ meraki = Meraki(api_key=config['meraki']['api_key'], organization_id=config['meraki']['organization_id'])
69
+
70
+ vmware_test = VMwareClient(
71
+ host=config['vmware']['test']['host'],
72
+ username=config['vmware']['test']['username'],
73
+ password=config['vmware']['test']['password'],
74
+ version=config['vmware']['test']['version'],
75
+ proxies=config['vmware']['test']['proxies']
76
+ )
@@ -41,33 +41,36 @@ class BuildConfig:
41
41
  f.write(render_data)
42
42
 
43
43
  def ping(self):
44
- instances = self.instances['ping']['instance']
45
- render_data = ping_template.render(instances=instances)
46
- target_dir = Path(self.output_dir) / 'input.ping'
47
- if not target_dir.exists():
48
- target_dir.mkdir(parents=True, exist_ok=True)
49
-
50
- with open(Path(self.output_dir) / 'input.ping' / 'ping.toml', 'w', encoding='utf-8') as f:
51
- f.write(render_data)
44
+ if self.instances.get('ping'):
45
+ instances = self.instances['ping']['instance']
46
+ render_data = ping_template.render(instances=instances)
47
+ target_dir = Path(self.output_dir) / 'input.ping'
48
+ if not target_dir.exists():
49
+ target_dir.mkdir(parents=True, exist_ok=True)
50
+
51
+ with open(Path(self.output_dir) / 'input.ping' / 'ping.toml', 'w', encoding='utf-8') as f:
52
+ f.write(render_data)
52
53
 
53
54
  def prometheus(self):
54
- instances = self.instances['prometheus']['urls']
55
- render_data = prometheus_template.render(instances=instances)
56
- target_dir = Path(self.output_dir) / 'input.prometheus'
57
- if not target_dir.exists():
58
- target_dir.mkdir(parents=True, exist_ok=True)
59
- with open(Path(self.output_dir) / 'input.prometheus' / 'prometheus.toml', 'w', encoding='utf-8') as f:
60
- f.write(render_data)
55
+ if self.instances.get('prometheus'):
56
+ instances = self.instances['prometheus']['urls']
57
+ render_data = prometheus_template.render(instances=instances)
58
+ target_dir = Path(self.output_dir) / 'input.prometheus'
59
+ if not target_dir.exists():
60
+ target_dir.mkdir(parents=True, exist_ok=True)
61
+ with open(Path(self.output_dir) / 'input.prometheus' / 'prometheus.toml', 'w', encoding='utf-8') as f:
62
+ f.write(render_data)
61
63
 
62
64
  def vsphere(self):
63
- template = self._get_template('input.vsphere/vsphere.toml.j2')
64
- instances = self.instances['vsphere']['instance']
65
- render_data = template.render(instances=instances)
66
- target_dir = Path(self.output_dir) / 'input.vsphere'
67
- if not target_dir.exists():
68
- target_dir.mkdir(parents=True, exist_ok=True)
69
- with open(Path(self.output_dir) / 'input.vsphere' / 'vsphere.toml', 'w', encoding='utf-8') as f:
70
- f.write(render_data)
65
+ if self.instances.get('vsphere'):
66
+ template = self._get_template('input.vsphere/vsphere.toml.j2')
67
+ instances = self.instances['vsphere']['instance']
68
+ render_data = template.render(instances=instances)
69
+ target_dir = Path(self.output_dir) / 'input.vsphere'
70
+ if not target_dir.exists():
71
+ target_dir.mkdir(parents=True, exist_ok=True)
72
+ with open(Path(self.output_dir) / 'input.vsphere' / 'vsphere.toml', 'w', encoding='utf-8') as f:
73
+ f.write(render_data)
71
74
 
72
75
  def http_response(self):
73
76
  template = self._get_template('input.http_response/http_response.toml.j2')
@@ -111,16 +114,11 @@ class BuildConfig:
111
114
  device_templates = glob(str(jinja2_dir / f'{device_type}_*.toml.j2'))
112
115
  if not device_templates:
113
116
  continue
114
-
115
117
  for tmpl_path in device_templates:
116
118
  tmpl_name = os.path.basename(tmpl_path)
117
- # 例如 h3c_system.toml.j2 -> h3c_system
118
119
  base_name = tmpl_name.replace('.toml.j2', '')
119
-
120
120
  template = self._get_template(f'input.snmp/{tmpl_name}')
121
- # 修复数据结构:模板期望的是数组,每个元素是字典
122
- # instances 是 [{"udp://10.1.1.1:161": {...}, "udp://10.1.1.2:161": {...}}, ...]
123
- render_data = template.render(instances=instances)
121
+ render_data = template.render(instances=instances, config=self.instances['snmp']['config'])
124
122
 
125
123
  target_dir = Path(self.output_dir) / 'input.snmp'
126
124
  if not target_dir.exists():
@@ -5,7 +5,7 @@
5
5
 
6
6
  [prometheus]
7
7
  [[prometheus.urls]]
8
- "http://10.200.12.202:9100" = { name = "x", env = "prod" }
8
+ "http://10.1.1.1:9100" = { name = "x", env = "prod" }
9
9
 
10
10
  [vsphere]
11
11
  [[vsphere.instance]]
@@ -25,6 +25,10 @@
25
25
  "119.29.29.29_baidu.com" = { dns_server = "119.29.29.29", domains = "www.baidu.com", labels = { name = "x", env = "prod" } }
26
26
 
27
27
  [snmp]
28
+ [snmp.config]
29
+ timeout = '120s'
30
+ path = "/usr/share/snmp/mibs"
31
+ # 支持 h3c,huawei,cisco,ruijie
28
32
  [[snmp.instances.h3c]]
29
33
  "10.1.1.1:161" = { version = 2, community = "public" }
30
34
  "10.1.1.2:161" = { version = 2, community = "public" }
@@ -0,0 +1,96 @@
1
+ {% for instance in instances %}
2
+ {% for agent, detail in instance.items() %}
3
+ [[instances]]
4
+ agents = [
5
+ "udp://{{agent}}"
6
+ ]
7
+ {% if detail.version == 2 %}
8
+ version = {{detail.version}}
9
+ community = "{{detail.community}}"
10
+ {% endif %}
11
+ {% if detail.version == 3 %}
12
+ version = {{detail.version}}
13
+ sec_name = "{{detail.sec_name}}"
14
+ auth_protocol = "{{detail.auth_protocol}}"
15
+ auth_password = "{{detail.auth_password}}"
16
+ priv_protocol = "{{detail.priv_protocol}}"
17
+ priv_password = "{{detail.priv_password}}"
18
+ sec_level = "{{detail.sec_level}}"
19
+ {% endif %}
20
+ timeout = "{{config.timeout}}"
21
+ retries = 3
22
+ path = ["{{config.path}}"]
23
+ translator = "gosmi"
24
+ max_repetitions = 50
25
+
26
+ [[instances.field]]
27
+ name = "sysName"
28
+ oid = "1.3.6.1.2.1.1.5.0"
29
+ is_tag = true
30
+
31
+ [[instances.table]]
32
+ name = "interface"
33
+ inherit_tags = ["sysName"]
34
+ index_as_tag = true
35
+
36
+ [[instances.table.field]]
37
+ name = "ifIndex"
38
+ oid = "1.3.6.1.2.1.2.2.1.1"
39
+ is_tag = true
40
+
41
+ [[instances.table.field]]
42
+ name = "ifName"
43
+ oid = "1.3.6.1.2.1.31.1.1.1.1"
44
+ is_tag = true
45
+
46
+ [[instances.table.field]]
47
+ name = "ifDescr"
48
+ oid = "1.3.6.1.2.1.2.2.1.2"
49
+ is_tag = true
50
+
51
+ [[instances.table.field]]
52
+ name = "ifSpeed"
53
+ oid = "1.3.6.1.2.1.2.2.1.5"
54
+ # is_tag = true
55
+
56
+ [[instances.table.field]]
57
+ name = "ifAdminStatus"
58
+ oid = "1.3.6.1.2.1.2.2.1.7"
59
+ # is_tag = true
60
+
61
+ [[instances.table.field]]
62
+ name = "ifOperStatus"
63
+ oid = "1.3.6.1.2.1.2.2.1.8"
64
+ # is_tag = true
65
+
66
+ [[instances.table.field]]
67
+ name = "ifInDiscards"
68
+ oid = "1.3.6.1.2.1.2.2.1.13"
69
+
70
+ [[instances.table.field]]
71
+ name = "ifInErrors"
72
+ oid = "1.3.6.1.2.1.2.2.1.14"
73
+
74
+ [[instances.table.field]]
75
+ name = "ifOutDiscards"
76
+ oid = "1.3.6.1.2.1.2.2.1.19"
77
+
78
+ [[instances.table.field]]
79
+ name = "ifOutErrors"
80
+ oid = "1.3.6.1.2.1.2.2.1.20"
81
+
82
+ [[instances.table.field]]
83
+ name = "ifAlias"
84
+ oid = "1.3.6.1.2.1.31.1.1.1.18"
85
+ is_tag = true
86
+
87
+ [[instances.table.field]]
88
+ name = "ifHCInOctets"
89
+ oid = "1.3.6.1.2.1.31.1.1.1.6"
90
+
91
+ [[instances.table.field]]
92
+ name = "ifHCOutOctets"
93
+ oid = "1.3.6.1.2.1.31.1.1.1.10"
94
+
95
+ {% endfor %}
96
+ {% endfor %}
@@ -0,0 +1,41 @@
1
+ {% for instance in instances %}
2
+ {% for agent, detail in instance.items() %}
3
+ [[instances]]
4
+ agents = [
5
+ "udp://{{agent}}"
6
+ ]
7
+ {% if detail.version == 2 %}
8
+ version = {{detail.version}}
9
+ community = "{{detail.community}}"
10
+ {% endif %}
11
+ {% if detail.version == 3 %}
12
+ version = {{detail.version}}
13
+ sec_name = "{{detail.sec_name}}"
14
+ auth_protocol = "{{detail.auth_protocol}}"
15
+ auth_password = "{{detail.auth_password}}"
16
+ priv_protocol = "{{detail.priv_protocol}}"
17
+ priv_password = "{{detail.priv_password}}"
18
+ sec_level = "{{detail.sec_level}}"
19
+ {% endif %}
20
+ timeout = "{{config.timeout}}"
21
+ retries = 3
22
+ path = ["{{config.path}}"]
23
+ translator = "gosmi"
24
+ max_repetitions = 50
25
+
26
+ [[instances.field]]
27
+ name = "sysName"
28
+ oid = "1.3.6.1.2.1.1.5.0"
29
+ is_tag = true
30
+
31
+ [[instances.field]]
32
+ oid = "1.3.6.1.2.1.1.1.0"
33
+ name = "sysDescr"
34
+ is_tag = true
35
+
36
+ [[instances.field]]
37
+ oid = "1.3.6.1.2.1.1.3.0"
38
+ name = "sysUpTime"
39
+ conversion = "float(2)"
40
+ {% endfor %}
41
+ {% endfor %}
@@ -17,9 +17,9 @@ priv_protocol = "{{detail.priv_protocol}}"
17
17
  priv_password = "{{detail.priv_password}}"
18
18
  sec_level = "{{detail.sec_level}}"
19
19
  {% endif %}
20
- timeout = "5s"
20
+ timeout = "{{config.timeout}}"
21
21
  retries = 3
22
- path = ["/usr/share/snmp/mibs"]
22
+ path = ["{{config.path}}"]
23
23
  translator = "gosmi"
24
24
  max_repetitions = 50
25
25
 
@@ -17,9 +17,9 @@ priv_protocol = "{{detail.priv_protocol}}"
17
17
  priv_password = "{{detail.priv_password}}"
18
18
  sec_level = "{{detail.sec_level}}"
19
19
  {% endif %}
20
- timeout = "5s"
20
+ timeout = "{{config.timeout}}"
21
21
  retries = 3
22
- path = ["/usr/share/snmp/mibs"]
22
+ path = ["{{config.path}}"]
23
23
  translator = "gosmi"
24
24
  max_repetitions = 50
25
25
 
@@ -0,0 +1,96 @@
1
+ {% for instance in instances %}
2
+ {% for agent, detail in instance.items() %}
3
+ [[instances]]
4
+ agents = [
5
+ "udp://{{agent}}"
6
+ ]
7
+ {% if detail.version == 2 %}
8
+ version = {{detail.version}}
9
+ community = "{{detail.community}}"
10
+ {% endif %}
11
+ {% if detail.version == 3 %}
12
+ version = {{detail.version}}
13
+ sec_name = "{{detail.sec_name}}"
14
+ auth_protocol = "{{detail.auth_protocol}}"
15
+ auth_password = "{{detail.auth_password}}"
16
+ priv_protocol = "{{detail.priv_protocol}}"
17
+ priv_password = "{{detail.priv_password}}"
18
+ sec_level = "{{detail.sec_level}}"
19
+ {% endif %}
20
+ timeout = "{{config.timeout}}"
21
+ retries = 3
22
+ path = ["{{config.path}}"]
23
+ translator = "gosmi"
24
+ max_repetitions = 50
25
+
26
+ [[instances.field]]
27
+ name = "sysName"
28
+ oid = "1.3.6.1.2.1.1.5.0"
29
+ is_tag = true
30
+
31
+ [[instances.table]]
32
+ name = "interface"
33
+ inherit_tags = ["sysName"]
34
+ index_as_tag = true
35
+
36
+ [[instances.table.field]]
37
+ name = "ifIndex"
38
+ oid = "1.3.6.1.2.1.2.2.1.1"
39
+ is_tag = true
40
+
41
+ [[instances.table.field]]
42
+ name = "ifName"
43
+ oid = "1.3.6.1.2.1.31.1.1.1.1"
44
+ is_tag = true
45
+
46
+ [[instances.table.field]]
47
+ name = "ifDescr"
48
+ oid = "1.3.6.1.2.1.2.2.1.2"
49
+ is_tag = true
50
+
51
+ [[instances.table.field]]
52
+ name = "ifSpeed"
53
+ oid = "1.3.6.1.2.1.2.2.1.5"
54
+ # is_tag = true
55
+
56
+ [[instances.table.field]]
57
+ name = "ifAdminStatus"
58
+ oid = "1.3.6.1.2.1.2.2.1.7"
59
+ # is_tag = true
60
+
61
+ [[instances.table.field]]
62
+ name = "ifOperStatus"
63
+ oid = "1.3.6.1.2.1.2.2.1.8"
64
+ # is_tag = true
65
+
66
+ [[instances.table.field]]
67
+ name = "ifInDiscards"
68
+ oid = "1.3.6.1.2.1.2.2.1.13"
69
+
70
+ [[instances.table.field]]
71
+ name = "ifInErrors"
72
+ oid = "1.3.6.1.2.1.2.2.1.14"
73
+
74
+ [[instances.table.field]]
75
+ name = "ifOutDiscards"
76
+ oid = "1.3.6.1.2.1.2.2.1.19"
77
+
78
+ [[instances.table.field]]
79
+ name = "ifOutErrors"
80
+ oid = "1.3.6.1.2.1.2.2.1.20"
81
+
82
+ [[instances.table.field]]
83
+ name = "ifAlias"
84
+ oid = "1.3.6.1.2.1.31.1.1.1.18"
85
+ is_tag = true
86
+
87
+ [[instances.table.field]]
88
+ name = "ifHCInOctets"
89
+ oid = "1.3.6.1.2.1.31.1.1.1.6"
90
+
91
+ [[instances.table.field]]
92
+ name = "ifHCOutOctets"
93
+ oid = "1.3.6.1.2.1.31.1.1.1.10"
94
+
95
+ {% endfor %}
96
+ {% endfor %}
@@ -0,0 +1,41 @@
1
+ {% for instance in instances %}
2
+ {% for agent, detail in instance.items() %}
3
+ [[instances]]
4
+ agents = [
5
+ "udp://{{agent}}"
6
+ ]
7
+ {% if detail.version == 2 %}
8
+ version = {{detail.version}}
9
+ community = "{{detail.community}}"
10
+ {% endif %}
11
+ {% if detail.version == 3 %}
12
+ version = {{detail.version}}
13
+ sec_name = "{{detail.sec_name}}"
14
+ auth_protocol = "{{detail.auth_protocol}}"
15
+ auth_password = "{{detail.auth_password}}"
16
+ priv_protocol = "{{detail.priv_protocol}}"
17
+ priv_password = "{{detail.priv_password}}"
18
+ sec_level = "{{detail.sec_level}}"
19
+ {% endif %}
20
+ timeout = "{{config.timeout}}"
21
+ retries = 3
22
+ path = ["{{config.path}}"]
23
+ translator = "gosmi"
24
+ max_repetitions = 50
25
+
26
+ [[instances.field]]
27
+ name = "sysName"
28
+ oid = "1.3.6.1.2.1.1.5.0"
29
+ is_tag = true
30
+
31
+ [[instances.field]]
32
+ oid = "1.3.6.1.2.1.1.1.0"
33
+ name = "sysDescr"
34
+ is_tag = true
35
+
36
+ [[instances.field]]
37
+ oid = "1.3.6.1.2.1.1.3.0"
38
+ name = "sysUpTime"
39
+ conversion = "float(2)"
40
+ {% endfor %}
41
+ {% endfor %}
@@ -0,0 +1,96 @@
1
+ {% for instance in instances %}
2
+ {% for agent, detail in instance.items() %}
3
+ [[instances]]
4
+ agents = [
5
+ "udp://{{agent}}"
6
+ ]
7
+ {% if detail.version == 2 %}
8
+ version = {{detail.version}}
9
+ community = "{{detail.community}}"
10
+ {% endif %}
11
+ {% if detail.version == 3 %}
12
+ version = {{detail.version}}
13
+ sec_name = "{{detail.sec_name}}"
14
+ auth_protocol = "{{detail.auth_protocol}}"
15
+ auth_password = "{{detail.auth_password}}"
16
+ priv_protocol = "{{detail.priv_protocol}}"
17
+ priv_password = "{{detail.priv_password}}"
18
+ sec_level = "{{detail.sec_level}}"
19
+ {% endif %}
20
+ timeout = "{{config.timeout}}"
21
+ retries = 3
22
+ path = ["{{config.path}}"]
23
+ translator = "gosmi"
24
+ max_repetitions = 50
25
+
26
+ [[instances.field]]
27
+ name = "sysName"
28
+ oid = "1.3.6.1.2.1.1.5.0"
29
+ is_tag = true
30
+
31
+ [[instances.table]]
32
+ name = "interface"
33
+ inherit_tags = ["sysName"]
34
+ index_as_tag = true
35
+
36
+ [[instances.table.field]]
37
+ name = "ifIndex"
38
+ oid = "1.3.6.1.2.1.2.2.1.1"
39
+ is_tag = true
40
+
41
+ [[instances.table.field]]
42
+ name = "ifName"
43
+ oid = "1.3.6.1.2.1.31.1.1.1.1"
44
+ is_tag = true
45
+
46
+ [[instances.table.field]]
47
+ name = "ifDescr"
48
+ oid = "1.3.6.1.2.1.2.2.1.2"
49
+ is_tag = true
50
+
51
+ [[instances.table.field]]
52
+ name = "ifSpeed"
53
+ oid = "1.3.6.1.2.1.2.2.1.5"
54
+ # is_tag = true
55
+
56
+ [[instances.table.field]]
57
+ name = "ifAdminStatus"
58
+ oid = "1.3.6.1.2.1.2.2.1.7"
59
+ # is_tag = true
60
+
61
+ [[instances.table.field]]
62
+ name = "ifOperStatus"
63
+ oid = "1.3.6.1.2.1.2.2.1.8"
64
+ # is_tag = true
65
+
66
+ [[instances.table.field]]
67
+ name = "ifInDiscards"
68
+ oid = "1.3.6.1.2.1.2.2.1.13"
69
+
70
+ [[instances.table.field]]
71
+ name = "ifInErrors"
72
+ oid = "1.3.6.1.2.1.2.2.1.14"
73
+
74
+ [[instances.table.field]]
75
+ name = "ifOutDiscards"
76
+ oid = "1.3.6.1.2.1.2.2.1.19"
77
+
78
+ [[instances.table.field]]
79
+ name = "ifOutErrors"
80
+ oid = "1.3.6.1.2.1.2.2.1.20"
81
+
82
+ [[instances.table.field]]
83
+ name = "ifAlias"
84
+ oid = "1.3.6.1.2.1.31.1.1.1.18"
85
+ is_tag = true
86
+
87
+ [[instances.table.field]]
88
+ name = "ifHCInOctets"
89
+ oid = "1.3.6.1.2.1.31.1.1.1.6"
90
+
91
+ [[instances.table.field]]
92
+ name = "ifHCOutOctets"
93
+ oid = "1.3.6.1.2.1.31.1.1.1.10"
94
+
95
+ {% endfor %}
96
+ {% endfor %}
@@ -0,0 +1,41 @@
1
+ {% for instance in instances %}
2
+ {% for agent, detail in instance.items() %}
3
+ [[instances]]
4
+ agents = [
5
+ "udp://{{agent}}"
6
+ ]
7
+ {% if detail.version == 2 %}
8
+ version = {{detail.version}}
9
+ community = "{{detail.community}}"
10
+ {% endif %}
11
+ {% if detail.version == 3 %}
12
+ version = {{detail.version}}
13
+ sec_name = "{{detail.sec_name}}"
14
+ auth_protocol = "{{detail.auth_protocol}}"
15
+ auth_password = "{{detail.auth_password}}"
16
+ priv_protocol = "{{detail.priv_protocol}}"
17
+ priv_password = "{{detail.priv_password}}"
18
+ sec_level = "{{detail.sec_level}}"
19
+ {% endif %}
20
+ timeout = "{{config.timeout}}"
21
+ retries = 3
22
+ path = ["{{config.path}}"]
23
+ translator = "gosmi"
24
+ max_repetitions = 50
25
+
26
+ [[instances.field]]
27
+ name = "sysName"
28
+ oid = "1.3.6.1.2.1.1.5.0"
29
+ is_tag = true
30
+
31
+ [[instances.field]]
32
+ oid = "1.3.6.1.2.1.1.1.0"
33
+ name = "sysDescr"
34
+ is_tag = true
35
+
36
+ [[instances.field]]
37
+ oid = "1.3.6.1.2.1.1.3.0"
38
+ name = "sysUpTime"
39
+ conversion = "float(2)"
40
+ {% endfor %}
41
+ {% endfor %}
@@ -0,0 +1,22 @@
1
+ #!/usr/bin/env python3
2
+
3
+ import click
4
+ from pytbox.database.victoriametrics import VictoriaMetrics
5
+ from pytbox.utils.richutils import RichUtils
6
+
7
+ rich_utils = RichUtils()
8
+
9
+ @click.group()
10
+ def vm_group():
11
+ """VictoriaMetrics 查询工具"""
12
+ pass
13
+
14
+
15
+ @vm_group.command('query')
16
+ @click.option('--url', '-u', type=str, required=True)
17
+ @click.option('--query', '-q', type=str, required=True)
18
+ def query(url, query):
19
+ """查询 VM 数据"""
20
+ vm_client = VictoriaMetrics(url=url)
21
+ r = vm_client.query(query, output_format='json')
22
+ rich_utils.print(msg=r)
pytbox/cli/main.py CHANGED
@@ -5,6 +5,7 @@ Pytbox 主命令行入口
5
5
 
6
6
  import click
7
7
  from .categraf import categraf_group
8
+ from .commands.vm import vm_group
8
9
 
9
10
 
10
11
  @click.group()
@@ -16,6 +17,7 @@ def main():
16
17
 
17
18
  # 注册子命令组
18
19
  main.add_command(categraf_group, name='categraf')
20
+ main.add_command(vm_group, name='vm')
19
21
 
20
22
 
21
23
  if __name__ == "__main__":