1/*
2** Zabbix
3** Copyright (C) 2001-2021 Zabbix SIA
4**
5** This program is free software; you can redistribute it and/or modify
6** it under the terms of the GNU General Public License as published by
7** the Free Software Foundation; either version 2 of the License, or
8** (at your option) any later version.
9**
10** This program is distributed in the hope that it will be useful,
11** but WITHOUT ANY WARRANTY; without even the implied warranty of
12** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13** GNU General Public License for more details.
14**
15** You should have received a copy of the GNU General Public License
16** along with this program; if not, write to the Free Software
17** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
18**/
19
20package ceph
21
22import (
23	"zabbix.com/pkg/metric"
24	"zabbix.com/pkg/plugin"
25	"zabbix.com/pkg/uri"
26)
27
28type command string
29
30// handlerFunc defines an interface must be implemented by handlers.
31type handlerFunc func(data map[command][]byte) (res interface{}, err error)
32
33type metricMeta struct {
34	commands []command
35	args     map[string]string
36	handler  handlerFunc
37}
38
39// handle runs metric's handler.
40func (m *metricMeta) handle(data map[command][]byte) (res interface{}, err error) {
41	return m.handler(data)
42}
43
44const (
45	keyDf            = "ceph.df.details"
46	keyOSD           = "ceph.osd.stats"
47	keyOSDDiscovery  = "ceph.osd.discovery"
48	keyOSDDump       = "ceph.osd.dump"
49	keyPing          = "ceph.ping"
50	keyPoolDiscovery = "ceph.pool.discovery"
51	keyStatus        = "ceph.status"
52)
53
54const (
55	cmdDf               = "df"
56	cmdPgDump           = "pg dump"
57	cmdOSDCrushRuleDump = "osd crush rule dump"
58	cmdOSDCrushTree     = "osd crush tree"
59	cmdOSDDump          = "osd dump"
60	cmdHealth           = "health"
61	cmdStatus           = "status"
62)
63
64var metricsMeta = map[string]metricMeta{
65	keyDf: {
66		commands: []command{cmdDf},
67		args:     map[string]string{"detail": "detail"},
68		handler:  dfHandler,
69	},
70	keyOSD: {
71		commands: []command{cmdPgDump},
72		args:     nil,
73		handler:  osdHandler,
74	},
75	keyOSDDiscovery: {
76		commands: []command{cmdOSDCrushTree},
77		args:     nil,
78		handler:  osdDiscoveryHandler,
79	},
80	keyOSDDump: {
81		commands: []command{cmdOSDDump},
82		args:     nil,
83		handler:  osdDumpHandler,
84	},
85	keyPing: {
86		commands: []command{cmdHealth},
87		args:     nil,
88		handler:  pingHandler,
89	},
90	keyPoolDiscovery: {
91		commands: []command{cmdOSDDump, cmdOSDCrushRuleDump},
92		args:     nil,
93		handler:  poolDiscoveryHandler,
94	},
95	keyStatus: {
96		commands: []command{cmdStatus},
97		args:     nil,
98		handler:  statusHandler,
99	},
100}
101
102var (
103	uriDefaults = &uri.Defaults{Scheme: "https", Port: "8003"}
104)
105
106// Common params: [URI|Session][,User][,ApiKey]
107var (
108	paramURI = metric.NewConnParam("URI", "URI to connect or session name.").
109			WithDefault(uriDefaults.Scheme + "://localhost:" + uriDefaults.Port).WithSession().
110			WithValidator(uri.URIValidator{Defaults: uriDefaults, AllowedSchemes: []string{"https"}})
111	paramUsername = metric.NewConnParam("User", "Ceph API user.").SetRequired()
112	paramAPIKey   = metric.NewConnParam("APIKey", "Ceph API key.").SetRequired()
113)
114
115var metrics = metric.MetricSet{
116	keyDf: metric.New("Returns information about cluster’s data usage and distribution among pools.",
117		[]*metric.Param{paramURI, paramUsername, paramAPIKey}, false),
118
119	keyOSD: metric.New("Returns aggregated and per OSD statistics.",
120		[]*metric.Param{paramURI, paramUsername, paramAPIKey}, false),
121
122	keyOSDDiscovery: metric.New("Returns a list of discovered OSDs.",
123		[]*metric.Param{paramURI, paramUsername, paramAPIKey}, false),
124
125	keyOSDDump: metric.New("Returns usage thresholds and statuses of OSDs.",
126		[]*metric.Param{paramURI, paramUsername, paramAPIKey}, false),
127
128	keyPing: metric.New("Tests if a connection is alive or not.",
129		[]*metric.Param{paramURI, paramUsername, paramAPIKey}, false),
130
131	keyPoolDiscovery: metric.New("Returns a list of discovered pools.",
132		[]*metric.Param{paramURI, paramUsername, paramAPIKey}, false),
133
134	keyStatus: metric.New("Returns an overall cluster's status.",
135		[]*metric.Param{paramURI, paramUsername, paramAPIKey}, false),
136}
137
138func init() {
139	plugin.RegisterMetrics(&impl, pluginName, metrics.List()...)
140}
141