/
module.go
140 lines (114 loc) · 3.71 KB
/
module.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
/*
* nagocheck - Reliable and lightweight Nagios plugins written in Go
* Copyright (C) 2018-2019 Pascal Mathis
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package nagocheck
import (
"fmt"
"github.com/snapserv/nagopher"
"gopkg.in/alecthomas/kingpin.v2"
)
// Module consists out of several plugins and offers methods for executing them
type Module interface {
Name() string
Description() string
Plugins() map[string]Plugin
DefineCommand() KingpinNode
DefineFlags(node KingpinNode)
RegisterPlugin(plugin Plugin)
ExecutePlugin(plugin Plugin) error
GetPluginByName(pluginName string) (Plugin, error)
}
// ModuleOpt is a type alias for functional options used by NewModule()
type ModuleOpt func(*baseModule)
type baseModule struct {
name string
description string
plugins map[string]Plugin
}
// RegisterModules returns a map of modules with their name as the respective key. Additionally, all plugins contained
// by these modules are being registered to their respective module using Plugin.setModule()
func RegisterModules(modules ...Module) map[string]Module {
result := make(map[string]Module)
for _, module := range modules {
result[module.Name()] = module
for _, plugin := range module.Plugins() {
plugin.setModule(module)
}
}
return result
}
// NewModule instantiates baseModule with the given functional options
func NewModule(name string, options ...ModuleOpt) Module {
module := &baseModule{
name: name,
description: name,
plugins: make(map[string]Plugin),
}
for _, option := range options {
option(module)
}
return module
}
// ModuleDescription is a functional option for NewModule(), which sets the module description
func ModuleDescription(description string) ModuleOpt {
return func(m *baseModule) {
m.description = description
}
}
// ModulePlugin is a functional option for NewModule(), which registers a plugin using Module.RegisterPlugin()
func ModulePlugin(plugin Plugin) ModuleOpt {
return func(m *baseModule) {
m.RegisterPlugin(plugin)
}
}
func (m *baseModule) RegisterPlugin(plugin Plugin) {
m.plugins[plugin.Name()] = plugin
}
func (m *baseModule) DefineCommand() KingpinNode {
moduleNode := kingpin.Command(m.name, m.description)
for _, plugin := range m.plugins {
pluginDescription := fmt.Sprintf("%s: %s", m.description, plugin.Description())
pluginNode := moduleNode.Command(plugin.Name(), pluginDescription)
plugin.defineDefaultFlags(pluginNode)
plugin.DefineFlags(pluginNode)
}
return moduleNode
}
func (m *baseModule) DefineFlags(node KingpinNode) {
}
func (m *baseModule) ExecutePlugin(plugin Plugin) error {
check := plugin.DefineCheck()
runtime := nagopher.NewRuntime(plugin.VerboseOutput())
runtime.ExecuteAndExit(check)
return nil
}
func (m *baseModule) GetPluginByName(pluginName string) (Plugin, error) {
plugin, ok := m.plugins[pluginName]
if !ok {
return nil, fmt.Errorf("plugin not found with name [%s]", pluginName)
}
return plugin, nil
}
func (m baseModule) Name() string {
return m.name
}
func (m baseModule) Description() string {
return m.description
}
func (m baseModule) Plugins() map[string]Plugin {
return m.plugins
}