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 mongodb
21
22import (
23	"encoding/json"
24	"fmt"
25	"net"
26	"strings"
27	"time"
28
29	"zabbix.com/pkg/zbxerr"
30)
31
32type lldShEntity struct {
33	ID        string `json:"{#ID}"`
34	Hostname  string `json:"{#HOSTNAME}"`
35	MongodURI string `json:"{#MONGOD_URI}"`
36	State     string `json:"{#STATE}"`
37}
38
39type shEntry struct {
40	ID    string      `bson:"_id"`
41	Host  string      `bson:"host"`
42	State json.Number `bson:"state"`
43}
44
45// shardsDiscoveryHandler
46// https://docs.mongodb.com/manual/reference/method/sh.status/#sh.status
47func shardsDiscoveryHandler(s Session, _ map[string]string) (interface{}, error) {
48	var shards []shEntry
49
50	if err := s.DB("config").C("shards").Find(nil).Sort(sortAsc).
51		SetMaxTime(time.Duration(s.GetMaxTimeMS()) * time.Millisecond).
52		All(&shards); err != nil {
53		return nil, zbxerr.ErrorCannotFetchData.Wrap(err)
54	}
55
56	lld := make([]lldShEntity, 0)
57
58	for _, sh := range shards {
59		hosts := sh.Host
60
61		h := strings.SplitN(sh.Host, "/", 2)
62		if len(h) > 1 {
63			hosts = h[1]
64		}
65
66		for _, hostport := range strings.Split(hosts, ",") {
67			host, _, err := net.SplitHostPort(hostport)
68			if err != nil {
69				return nil, zbxerr.ErrorCannotParseResult.Wrap(err)
70			}
71
72			lld = append(lld, lldShEntity{
73				ID:        sh.ID,
74				Hostname:  host,
75				MongodURI: fmt.Sprintf("%s://%s", uriDefaults.Scheme, hostport),
76				State:     sh.State.String(),
77			})
78		}
79	}
80
81	jsonLLD, err := json.Marshal(lld)
82	if err != nil {
83		return nil, zbxerr.ErrorCannotMarshalJSON.Wrap(err)
84	}
85
86	return string(jsonLLD), nil
87}
88