op5util 0.1.1
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.
- checksums.yaml +7 -0
- data/.gitignore +7 -0
- data/Gemfile +12 -0
- data/Gemfile.lock +42 -0
- data/LICENSE +21 -0
- data/README.rdoc +6 -0
- data/Rakefile +16 -0
- data/Readme.md +180 -0
- data/bin/op5util +180 -0
- data/lib/op5util/acknowledge_alarm.rb +86 -0
- data/lib/op5util/add_host.rb +61 -0
- data/lib/op5util/add_hostgroups.rb +48 -0
- data/lib/op5util/check_auth.rb +36 -0
- data/lib/op5util/list_hostgroups.rb +63 -0
- data/lib/op5util/method_template.rb +13 -0
- data/lib/op5util/monitor.rb +29 -0
- data/lib/op5util/schedule_checks.rb +72 -0
- data/lib/op5util/schedule_downtime.rb +31 -0
- data/lib/op5util/status_host.rb +152 -0
- data/lib/op5util/status_summary.rb +88 -0
- data/lib/op5util/version.rb +3 -0
- data/lib/op5util.rb +11 -0
- data/op5util.gemspec +27 -0
- data/op5util.rdoc +5 -0
- data/pkg/op5util-0.0.1.gem +0 -0
- data/pkg/op5util-0.0.2.gem +0 -0
- data/pkg/op5util-0.0.3.gem +0 -0
- data/pkg/op5util-0.0.9.gem +0 -0
- data/pkg/op5util-0.1.0.gem +0 -0
- data/screenshots/host_op5.png +0 -0
- data/screenshots/host_op5_listview.png +0 -0
- data/screenshots/usecase1.png +0 -0
- data/screenshots/usecase2.png +0 -0
- data/test/default_test.rb +14 -0
- data/test/test_helper.rb +9 -0
- metadata +183 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 107908b5501c4f587f9d1d1ff3f2f90eb5396519
|
4
|
+
data.tar.gz: 2f6e63fea64bc6ed7c29cae3f44b9488d34f0223
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 4870871536c87d7127b45b956baadfa7e9e31c0f65dd789f2cbd5b2d000abc3186861fc80ad6dd9d8f316fb8a81c4b72862c093dc62d1312b5d38e4501ace6dd
|
7
|
+
data.tar.gz: 62cb31a8c2a0a975f2a328902b9234d903b24c1fcb2405aa83e360e92b98809da230b59e23236c6ff10de2bf903b56f5ba8b18ad591f0435b2f33d9090418f43
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
op5util (0.1.1)
|
5
|
+
colorize (= 0.8.1)
|
6
|
+
gli (= 2.16.1)
|
7
|
+
httparty (= 0.15.5)
|
8
|
+
terminal-table (= 1.8.0)
|
9
|
+
|
10
|
+
GEM
|
11
|
+
remote: https://rubygems.org/
|
12
|
+
specs:
|
13
|
+
awesome_print (1.7.0)
|
14
|
+
colorize (0.8.1)
|
15
|
+
gli (2.16.1)
|
16
|
+
httparty (0.15.5)
|
17
|
+
multi_xml (>= 0.5.2)
|
18
|
+
multi_xml (0.6.0)
|
19
|
+
power_assert (0.2.6)
|
20
|
+
rake (12.0.0)
|
21
|
+
rdoc (5.1.0)
|
22
|
+
terminal-table (1.8.0)
|
23
|
+
unicode-display_width (~> 1.1, >= 1.1.1)
|
24
|
+
test-unit (3.2.5)
|
25
|
+
power_assert
|
26
|
+
unicode-display_width (1.2.1)
|
27
|
+
|
28
|
+
PLATFORMS
|
29
|
+
ruby
|
30
|
+
|
31
|
+
DEPENDENCIES
|
32
|
+
awesome_print
|
33
|
+
colorize
|
34
|
+
httparty
|
35
|
+
op5util!
|
36
|
+
rake
|
37
|
+
rdoc
|
38
|
+
terminal-table
|
39
|
+
test-unit
|
40
|
+
|
41
|
+
BUNDLED WITH
|
42
|
+
1.15.1
|
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2017 Niklas Paulsson
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/README.rdoc
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'rake/clean'
|
2
|
+
require 'rubygems'
|
3
|
+
require 'rubygems/package_task'
|
4
|
+
require 'rdoc/task'
|
5
|
+
Rake::RDocTask.new do |rd|
|
6
|
+
rd.main = "README.rdoc"
|
7
|
+
rd.rdoc_files.include("README.rdoc","lib/**/*.rb","bin/**/*")
|
8
|
+
rd.title = 'Your application title'
|
9
|
+
end
|
10
|
+
|
11
|
+
spec = eval(File.read('op5util.gemspec'))
|
12
|
+
|
13
|
+
Gem::PackageTask.new(spec) do |pkg|
|
14
|
+
end
|
15
|
+
|
16
|
+
task :default => [:test]
|
data/Readme.md
ADDED
@@ -0,0 +1,180 @@
|
|
1
|
+
## Op5util
|
2
|
+
|
3
|
+
Are you using Op5? Perhaps you do most of your work from the command-line
|
4
|
+
and want to be able to do the most common Op5 tasks without logging in
|
5
|
+
to a web-gui?
|
6
|
+
|
7
|
+
Or you want to start monitoring the newly installed hosts with Op5
|
8
|
+
using your config management tool?
|
9
|
+
|
10
|
+
Those two use-cases were my biggest itches when I first started to use
|
11
|
+
saved curl commands to interact with the REST-api and soon op5util.rb
|
12
|
+
was born.
|
13
|
+
|
14
|
+
The design nowdays is reasonable modular so new functions can be easily
|
15
|
+
added if they are needed, pull requests are happily accepted.
|
16
|
+
|
17
|
+
I use op5util daily in a production environment, but it comes with no
|
18
|
+
warranties.
|
19
|
+
|
20
|
+
## Capabilities
|
21
|
+
|
22
|
+
Currently op5util have implemented these functions:
|
23
|
+
|
24
|
+
* Add a new host to be monitored by Op5
|
25
|
+
* Add a existing host to more hostgroups
|
26
|
+
* Schedule downtime for a host
|
27
|
+
* Show status summary of all services/host and summary of service per host
|
28
|
+
* Show status summary of services for a host and list all services w. status for a host
|
29
|
+
* Schedule forced checks of a host and the hosts services to be done now
|
30
|
+
* List all hostgroups available, including members and service checks
|
31
|
+
|
32
|
+
These are the most common vanilla administrative tasks I perform to keep
|
33
|
+
the networked monitored.
|
34
|
+
|
35
|
+
## Screenshots, example usage
|
36
|
+
|
37
|
+
A few usage example and the output from op5util.
|
38
|
+
|
39
|
+
### Add a host to op5, check host status
|
40
|
+
|
41
|
+
Adding a host using ```op5util add -g linux_hosts wiki``` and at the same time assigning
|
42
|
+
membership in the linux_hosts hostgroup for the host, so some standard service checks are
|
43
|
+
defined.
|
44
|
+
|
45
|
+
To avoid waiting for checks to be performed on the new host, we tell Op5 to check them
|
46
|
+
now with the command ```op5util schedule wiki```, and after only a short wait we can
|
47
|
+
take a look at the detailed host status with ```op5util status -l wiki```.
|
48
|
+
|
49
|
+

|
50
|
+
|
51
|
+
The newly added host in normal web-gui.
|
52
|
+
|
53
|
+

|
54
|
+
|
55
|
+
And the same host in a Op5 listview with service state after services was checked, as comparison
|
56
|
+
with the terminal output by op5util.
|
57
|
+
|
58
|
+

|
59
|
+
|
60
|
+
|
61
|
+
### Another use case
|
62
|
+
|
63
|
+
Op5util is installed using ```gem install pkg/0.1.0.pkg```
|
64
|
+
|
65
|
+
The export of the environment variable MONITOR is to avoid using the command-line
|
66
|
+
flag ```-m monitor.ipa.hemma``` on every command, and by saving credentials in the in the .op5pass
|
67
|
+
file you don't need type the -u/-p thereafter.
|
68
|
+
|
69
|
+
Check the overall status with the command ```op5util status```, as one host is down we request more
|
70
|
+
info to be displayed with ```op5util status -l```, and we see that the host gitlab01 is down, to
|
71
|
+
acknowledge the alarms, ```op5util acknowledge gitlab01```.
|
72
|
+
|
73
|
+
Once the problem is resolved and the host is up, ```op5util schedule gitlab01, because impatience,
|
74
|
+
a final check with ```op5util status gitlab01```.
|
75
|
+
|
76
|
+

|
77
|
+
|
78
|
+
## Installation
|
79
|
+
|
80
|
+
Download the latest pkg/op5util-0.X.Y.gem from this repo and install using
|
81
|
+
```shell
|
82
|
+
gem install op5util-0.1.0.gem
|
83
|
+
```
|
84
|
+
|
85
|
+
## Usage
|
86
|
+
|
87
|
+
There is no man-page, but the built in help text should do the job.
|
88
|
+
|
89
|
+
If you enter the command ```op5util help``` the top-level documentation is displayed.
|
90
|
+
|
91
|
+
IMHO git has very good command line interface and I've tried to make op5util to do user
|
92
|
+
interaction in the same spirit as git.
|
93
|
+
|
94
|
+
|
95
|
+
``` text
|
96
|
+
NAME
|
97
|
+
op5util - A small utility to perform common Op5 administration tasks from the command line
|
98
|
+
|
99
|
+
About authentication, if you supply username/password as command-line flags they will be
|
100
|
+
used first. If username/password options isn't supplied on the command-line, the environment
|
101
|
+
variables OP5USER and OP5PASS will be used. If there are no environment variables present,
|
102
|
+
the file ~/.op5pass (or --authfile=) will be read. The file format is a single line with
|
103
|
+
username and password separated by a : (colon). The supplied credentials shoud be an
|
104
|
+
account with administrative privileges.
|
105
|
+
|
106
|
+
This application uses the REST-api described at https://your.op5.sever/api/help. Although
|
107
|
+
TLS/SSL is used, no verification of the certificate is done as most Op5-servers have a
|
108
|
+
self-signed certificate.
|
109
|
+
|
110
|
+
SYNOPSIS
|
111
|
+
op5util [global options] command [command options] [arguments...]
|
112
|
+
|
113
|
+
VERSION
|
114
|
+
0.0.9
|
115
|
+
|
116
|
+
GLOBAL OPTIONS
|
117
|
+
-f, --authfile=authfile - Authfile containing "username:password" used to authenticate
|
118
|
+
with Op5 server (default: ~/.op5pass)
|
119
|
+
--help - Show this message
|
120
|
+
-m, --monitor=monitor - Hostname or IP-address of the Op5 monitor server, if not supplied
|
121
|
+
the environment variable MONITOR will be used (default: none)
|
122
|
+
-p, --password=password - Password used to authenticate with the Op5 server, if not supplied
|
123
|
+
the environment variable OP5PASS will be used (default: none)
|
124
|
+
-u, --username=username - Username used to authenticate with the Op5 server, if not supplied
|
125
|
+
the environment variable OP5USER will be used (default: none)
|
126
|
+
--version - Display the program version
|
127
|
+
|
128
|
+
COMMANDS
|
129
|
+
acknowledge - Acknowledge outstanding host and service alarms.
|
130
|
+
add - Add a new host to be monitored by the Op5 server
|
131
|
+
add_hostgroups - Add host to a new hostgroup(s)
|
132
|
+
downtime - Schedule fixed downtime for a host
|
133
|
+
help - Shows a list of commands or help for one command
|
134
|
+
hostgroups - List hostgroups, optionally with member and service info
|
135
|
+
to list members and services for the linux_hosts hostgroup
|
136
|
+
schedule - Schedule host and all host services checks to be performed swiftly for the given host
|
137
|
+
status - Show monitoring status, if no host is given all hosts/services are included
|
138
|
+
|
139
|
+
```
|
140
|
+
|
141
|
+
### Command usage
|
142
|
+
|
143
|
+
To get information about a specific command, use ```op5util help add``` , example below.
|
144
|
+
|
145
|
+
``` textNAME
|
146
|
+
add - Add a new host to be monitored by the Op5 server
|
147
|
+
|
148
|
+
SYNOPSIS
|
149
|
+
op5util [global options] add [command options] hostname
|
150
|
+
|
151
|
+
DESCRIPTION
|
152
|
+
The host is added using mostly default values for max_check_attempts (3),
|
153
|
+
notification_interval (0, aka notify once), notification_period (24x7), etc
|
154
|
+
using the default-host-template. For most off-the-shelf newly installed
|
155
|
+
servers these values usually are sufficient and can be fine-tuned using
|
156
|
+
the web-gui if so should be needed.
|
157
|
+
|
158
|
+
COMMAND OPTIONS
|
159
|
+
-a, --alias=arg - Alias for host, defaults to hostname with the domain name
|
160
|
+
removed (default: none)
|
161
|
+
-c, --contactgroups=arg - Contact groups for host, defaults to "support_group" (may
|
162
|
+
be used more than once, default: ["support-group"])
|
163
|
+
-g, --hostgroups=arg - Hostgroup(s) to which the new host will be added (may be
|
164
|
+
used more than once, default: none)
|
165
|
+
-i, --ipaddr=arg - IP-address of host, resolved with DNS from hostname if
|
166
|
+
not supplied (default: none)
|
167
|
+
```
|
168
|
+
|
169
|
+
|
170
|
+
## Roadmap, TODO
|
171
|
+
|
172
|
+
A lot remains, the code really should be DRY'ied up, more automated pre-release tests, more
|
173
|
+
documentation and perhaps even adding some more functions, but the current version of op5util
|
174
|
+
is already useful to me in my day-time job, perhaps it also could be useful to other Op5
|
175
|
+
administrators?
|
176
|
+
|
177
|
+
Please, give my repo a github star or drop me line if you find this utility useful. Feel
|
178
|
+
free to leave a bug-reports or feature requests as an issue in this repo.
|
179
|
+
|
180
|
+
/Niklas
|
data/bin/op5util
ADDED
@@ -0,0 +1,180 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# rubocop:disable Lint/UnneededDisable, LineLength, AbcSize, SymbolArray, MethodLength, HashSyntax
|
4
|
+
|
5
|
+
require 'gli'
|
6
|
+
require 'op5util'
|
7
|
+
|
8
|
+
include GLI::App
|
9
|
+
|
10
|
+
program_desc 'A small utility to perform common Op5 administration tasks from the command line'
|
11
|
+
program_long_desc '
|
12
|
+
About authentication, if you supply username/password as command-line flags they will be used first. If username/password options isn\'t supplied on the command-line, the environment variables OP5USER and OP5PASS will be used. If there are no environment variables present, the file ~/.op5pass (or --authfile=) will be read. The file format is a single line with username and password separated by a : (colon). The supplied credentials shoud be an account with administrative privileges.
|
13
|
+
|
14
|
+
This application uses the REST-api described at https://your.op5.sever/api/help. Although TLS/SSL is used, no verification of the certificate is done as most Op5-servers have a self-signed certificate.'
|
15
|
+
|
16
|
+
version Op5util::VERSION
|
17
|
+
|
18
|
+
subcommand_option_handling :normal
|
19
|
+
arguments :strict
|
20
|
+
|
21
|
+
monitor = nil
|
22
|
+
|
23
|
+
desc 'Username used to authenticate with the Op5 server, if not supplied the environment variable OP5USER will be used'
|
24
|
+
arg_name 'username'
|
25
|
+
flag [:u, :username]
|
26
|
+
|
27
|
+
desc 'Password used to authenticate with the Op5 server, if not supplied the environment variable OP5PASS will be used'
|
28
|
+
arg_name 'password'
|
29
|
+
flag [:p, :password]
|
30
|
+
|
31
|
+
desc 'Hostname or IP-address of the Op5 monitor server, if not supplied the environment variable MONITOR will be used'
|
32
|
+
arg_name 'monitor'
|
33
|
+
flag [:m, :monitor]
|
34
|
+
|
35
|
+
desc 'Authfile containing "username:password" used to authenticate with Op5 server'
|
36
|
+
default_value '~/.op5pass'
|
37
|
+
arg_name 'authfile'
|
38
|
+
flag [:f, :authfile]
|
39
|
+
|
40
|
+
desc 'Add a new host to be monitored by the Op5 server'
|
41
|
+
long_desc 'The host is added using mostly default values for max_check_attempts (3), notification_interval (0, aka notify once), notification_period (24x7), etc using the default-host-template. For most off-the-shelf newly installed servers these values usually are sufficient and can be fine-tuned using the web-gui if so should be needed.'
|
42
|
+
arg_name 'hostname'
|
43
|
+
command :add do |c|
|
44
|
+
c.desc 'Alias for host, defaults to hostname with the domain name removed'
|
45
|
+
c.flag [:a, :alias]
|
46
|
+
|
47
|
+
c.desc 'Hostgroup(s) to which the new host will be added'
|
48
|
+
c.flag [:g, :hostgroups], :multiple => true
|
49
|
+
|
50
|
+
c.desc 'Contact groups for host, defaults to "support_group"'
|
51
|
+
c.default_value ['support-group']
|
52
|
+
c.flag [:c, :contactgroups], :multiple => true
|
53
|
+
|
54
|
+
c.desc 'IP-address of host, resolved with DNS from hostname if not supplied'
|
55
|
+
c.flag [:i, :ipaddr]
|
56
|
+
|
57
|
+
c.action do |_global_options, options, args|
|
58
|
+
# Your command logic here
|
59
|
+
# If you have any errors, just raise them
|
60
|
+
# raise "that command made no sense"
|
61
|
+
monitor.add_host(args[0], options)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
desc 'Add host to a new hostgroup(s)'
|
66
|
+
long_desc 'Example: "op5util add_hostgroups -g linux_hosts -g webservers web-vl131-zrh" will add the host web-vl131-zrh to the hostgroups linux_hosts and webservers'
|
67
|
+
arg_name 'host'
|
68
|
+
command :add_hostgroups do |c|
|
69
|
+
c.desc 'Hostgroup(s) that host should be a member of'
|
70
|
+
c.flag [:g, :hostgroups], :multiple => true
|
71
|
+
|
72
|
+
c.action do |_global_options, options, args|
|
73
|
+
monitor.add_hostgroups(args[0], options[:hostgroups])
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
desc 'Schedule fixed downtime for a host'
|
78
|
+
arg_name 'host'
|
79
|
+
command :downtime do |c|
|
80
|
+
c.desc 'Duration of downtime, in number of hours'
|
81
|
+
c.default_value '2'
|
82
|
+
c.flag [:t, :time]
|
83
|
+
|
84
|
+
c.desc 'Start downtime in X hours. If not given, downtime starts now'
|
85
|
+
c.default_value 0
|
86
|
+
c.flag [:w, :wait]
|
87
|
+
|
88
|
+
c.desc 'Comment on reason for downtime downtime'
|
89
|
+
c.default_value 'Temporary downtime due to system administration'
|
90
|
+
c.flag [:c, :comment]
|
91
|
+
|
92
|
+
c.action do |_global_options, options, args|
|
93
|
+
monitor.schedule_downtime(args[0], options)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
desc 'Show monitoring status, if no host is given all hosts/services are included'
|
98
|
+
arg_name 'host'
|
99
|
+
command :status do |c|
|
100
|
+
c.desc 'Print only a brief status information with stats summarized'
|
101
|
+
c.switch [:s, :short]
|
102
|
+
|
103
|
+
c.desc 'Print a summary with hosts listed and service information per hsot'
|
104
|
+
c.switch [:l, :long]
|
105
|
+
|
106
|
+
c.action do |_global_options, options, args|
|
107
|
+
if args.count.zero?
|
108
|
+
monitor.status_summary(options)
|
109
|
+
else
|
110
|
+
monitor.status_host(args[0], options)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
desc 'Acknowledge outstanding host and service alarms, without host - *ALL* outstanding alarms and services are acknowledged, ackn is "sticky" - it lasts until host/service recovery.'
|
116
|
+
arg_name 'host'
|
117
|
+
command :acknowledge do |c|
|
118
|
+
c.desc 'comment on acknowledgement'
|
119
|
+
c.default_value 'Work in progress to resolve problem'
|
120
|
+
c.flag [:c, :comment]
|
121
|
+
|
122
|
+
c.desc 'Make comment persistent after problems are resolved'
|
123
|
+
c.switch [:p, :persistent]
|
124
|
+
|
125
|
+
c.desc 'Print more verbose output'
|
126
|
+
c.switch [:v, :verbose]
|
127
|
+
|
128
|
+
c.action do |_global_options, options, args|
|
129
|
+
if args[0].nil?
|
130
|
+
monitor.acknowledge_all_alarms(options)
|
131
|
+
else
|
132
|
+
monitor.acknowledge_host_alarms(args[0], options)
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
desc 'Schedule host and all host services checks to be performed swiftly for the given host'
|
138
|
+
arg_name 'host'
|
139
|
+
command :schedule do |c|
|
140
|
+
c.desc 'Print more information about progress'
|
141
|
+
c.switch [:v, :verbose]
|
142
|
+
|
143
|
+
c.action do |_global_options, options, args|
|
144
|
+
monitor.schedule_checks(args[0], options)
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
desc 'List hostgroups, optionally with member and service info, Usage examples: \'op5util hostgroups\' to list all hostgroups, \'op5util hostgroups -l linux_hosts\' to list members and services for the linux_hosts hostgroup'
|
149
|
+
arg_name 'hostgroup'
|
150
|
+
command :hostgroups do |c|
|
151
|
+
c.desc 'Include servicechecks and hosts for hostgroup in output, warning - this may take time if done for all hostgroups'
|
152
|
+
c.switch [:l, :long]
|
153
|
+
|
154
|
+
c.action do |_global_options, options, args|
|
155
|
+
monitor.list_hostgroups(args[0], options)
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
pre do |global, _command, _options, _args|
|
160
|
+
Op5util.check_auth(global) ? true : false
|
161
|
+
if global[:monitor].nil? && ENV['MONITOR'].nil?
|
162
|
+
false
|
163
|
+
else
|
164
|
+
global[:monitor] = ENV['MONITOR'] if global['monitor'].nil?
|
165
|
+
monitor = Op5util::Monitor.new(global[:monitor],
|
166
|
+
global[:username],
|
167
|
+
global[:password])
|
168
|
+
true
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
on_error do |exception|
|
173
|
+
# Error logic here
|
174
|
+
# return false to skip default error handling
|
175
|
+
# TODO: Catch error and print an apropriate message
|
176
|
+
puts "Error, #{exception}"
|
177
|
+
false
|
178
|
+
end
|
179
|
+
|
180
|
+
exit run(ARGV)
|
@@ -0,0 +1,86 @@
|
|
1
|
+
# rubocop:disable LineLength, AbcSize
|
2
|
+
# Foo
|
3
|
+
module Op5util
|
4
|
+
# Foo
|
5
|
+
class Monitor
|
6
|
+
def acknowledge_host_alarms(host, options)
|
7
|
+
host_states = host_status(host)
|
8
|
+
if host_states[:host] > 0
|
9
|
+
puts 'Acknowledge host alarm for host ' + host
|
10
|
+
ack_host_alarm(host, options)
|
11
|
+
else
|
12
|
+
puts 'No alarm for host ' + host + ', not acking host'
|
13
|
+
end
|
14
|
+
if host_states[:services].count > 0
|
15
|
+
host_states[:services].each do |s|
|
16
|
+
ack_host_service(host, s, options)
|
17
|
+
puts "Service \"#{s}\" acknowledged" if options[:verbose]
|
18
|
+
end
|
19
|
+
puts 'All service alarms for host ' + host + ' acknowledged'
|
20
|
+
else
|
21
|
+
puts "No service alarms to acknowledge for host #{host}"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def acknowledge_all_alarms(options)
|
26
|
+
response = self.class.get(@base_uri + 'config/host?format=json',
|
27
|
+
basic_auth: @auth, verify: false)
|
28
|
+
raise ApiError unless response.code == 200
|
29
|
+
JSON.parse!(response.body).map { |h| h['name'] }.each do |host|
|
30
|
+
acknowledge_host_alarms(host, options)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def ack_host_alarm_body(host, options)
|
37
|
+
{
|
38
|
+
host_name: host,
|
39
|
+
sticky: true,
|
40
|
+
notify: true,
|
41
|
+
persistent: options[:persistent],
|
42
|
+
comment: options[:comment]
|
43
|
+
}.to_json
|
44
|
+
end
|
45
|
+
|
46
|
+
def ack_host_alarm(host, options)
|
47
|
+
body = ack_host_alarm_body(host, options)
|
48
|
+
response = self.class.post(@base_uri + 'command/ACKNOWLEDGE_HOST_PROBLEM?format=json',
|
49
|
+
headers: { 'Content-Type' => 'application/json' },
|
50
|
+
body: body, basic_auth: @auth, verify: false)
|
51
|
+
raise ApiError unless response.code == 200
|
52
|
+
puts 'Host alarm acknowledged'
|
53
|
+
end
|
54
|
+
|
55
|
+
def ack_host_service_alarm_body(host, service, options)
|
56
|
+
{
|
57
|
+
host_name: host,
|
58
|
+
service_description: service,
|
59
|
+
sticky: true,
|
60
|
+
notify: true,
|
61
|
+
persistent: options[:persistent],
|
62
|
+
comment: options[:comment]
|
63
|
+
}.to_json
|
64
|
+
end
|
65
|
+
|
66
|
+
def ack_host_service(host, service, options)
|
67
|
+
body = ack_host_service_alarm_body(host, service, options)
|
68
|
+
response = self.class.post(@base_uri + 'command/ACKNOWLEDGE_SVC_PROBLEM?format=json',
|
69
|
+
headers: { 'Content-Type' => 'application/json' },
|
70
|
+
body: body, basic_auth: @auth, verify: false)
|
71
|
+
raise ApiError unless response.code == 200
|
72
|
+
puts "Alarm for service \"#{service}\" acknowledged" if options[:verbose]
|
73
|
+
end
|
74
|
+
|
75
|
+
def host_status(host)
|
76
|
+
response = self.class.get(@base_uri + "status/host/#{host}?format=json",
|
77
|
+
basic_auth: @auth, verify: false)
|
78
|
+
raise ApiError unless response.code == 200
|
79
|
+
state = JSON.parse!(response.body)
|
80
|
+
{
|
81
|
+
host: state['hard_state'],
|
82
|
+
services: state['services_with_state'].select { |s| s[1] > 0 }.map { |s| s[0] }
|
83
|
+
}
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
# rubocop:disable Lint/UnneededDisable
|
2
|
+
# rubocop:disable LineLength
|
3
|
+
# rubocop:disable AbcSize
|
4
|
+
# rubocop:disable SymbolArray
|
5
|
+
# rubocop:disable Metrics/MethodLength
|
6
|
+
# rubocop:disable HashSyntax
|
7
|
+
# Foo
|
8
|
+
module Op5util
|
9
|
+
require 'resolv'
|
10
|
+
class ApiError < StandardError; end
|
11
|
+
# Foo
|
12
|
+
class Monitor
|
13
|
+
def add_host(host, options)
|
14
|
+
body = build_add_host_request_body(host, options)
|
15
|
+
response = self.class.post(@base_uri + 'config/host',
|
16
|
+
headers: { 'Content-Type' => 'application/json' },
|
17
|
+
body: body, basic_auth: @auth, verify: false)
|
18
|
+
raise ApiError, "Response code: #{response.code}, Message: #{response.body}" if response.code != 201
|
19
|
+
puts 'New host created'
|
20
|
+
|
21
|
+
url = @base_uri + 'config/change'
|
22
|
+
response = self.class.post(url, body: {}, basic_auth: @auth, verify: false)
|
23
|
+
raise ApiError, "Response code: #{response.code}, Message: #{response.body}" if response.code != 200
|
24
|
+
puts 'New op5-config saved'
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def build_add_host_request_body(host, options)
|
30
|
+
host_ipaddr = options[:ipaddr].nil? ? Resolv.getaddress(host) : options[:ipaddr]
|
31
|
+
host_alias = options[:alias].nil? ? short_name(host) : options[:alias]
|
32
|
+
contactgroups = options[:contactgroups].nil? ? ['support-group'] : options[:contactgroups]
|
33
|
+
hostgroups = options[:hostgroups].nil? ? [] : options[:hostgroups]
|
34
|
+
add_host_request_body_as_json(host, host_ipaddr, host_alias, contactgroups, hostgroups)
|
35
|
+
end
|
36
|
+
|
37
|
+
def add_host_request_body_as_json(host, host_ipaddr, host_alias, contactgroups, hostgroups)
|
38
|
+
{ file_id: 'etc/hosts.cfg',
|
39
|
+
host_name: host.to_s,
|
40
|
+
address: host_ipaddr.to_s,
|
41
|
+
alias: host_alias.to_s,
|
42
|
+
max_check_attempts: 3,
|
43
|
+
notification_interval: 0,
|
44
|
+
notification_options: %w[d u r],
|
45
|
+
notification_period: '24x7',
|
46
|
+
notifications_enabled: true,
|
47
|
+
template: 'default-host-template',
|
48
|
+
contact_groups: contactgroups,
|
49
|
+
hostgroups: hostgroups }.to_json
|
50
|
+
end
|
51
|
+
|
52
|
+
def short_name(h)
|
53
|
+
split_host = h.split('.')
|
54
|
+
if split_host.count > 1
|
55
|
+
split_host[0]
|
56
|
+
else
|
57
|
+
''
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# rubocop:disable Lint/UnneededDisable, LineLength, AbcSize, SymbolArray, MethodLength, HashSyntax
|
2
|
+
# Foo
|
3
|
+
module Op5util
|
4
|
+
class NoSuchHostgroupError < StandardError; end
|
5
|
+
class NoSuchHostError < StandardError; end
|
6
|
+
# Foo
|
7
|
+
class Monitor
|
8
|
+
def add_hostgroups(host, hostgroups)
|
9
|
+
hostgroups.each do |group|
|
10
|
+
members = get_hostgroup_members(group)
|
11
|
+
if !members.grep(host).empty?
|
12
|
+
puts "Host #{host} is already a member of hostgroup #{group}"
|
13
|
+
else
|
14
|
+
raise NoSuchHostError, host unless host_exist?(host)
|
15
|
+
members << host
|
16
|
+
update_hostgroup(group, members)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def get_hostgroup_members(group)
|
24
|
+
response = self.class.get(@base_uri + "config/hostgroup/#{group}?format=json",
|
25
|
+
basic_auth: @auth, verify: false)
|
26
|
+
raise NoSuchHostgroupError if response.code == 404
|
27
|
+
JSON.parse!(response.body)['members']
|
28
|
+
end
|
29
|
+
|
30
|
+
def host_exist?(host)
|
31
|
+
response = self.class.get(@base_uri + "config/host/#{host}?format=json",
|
32
|
+
basic_auth: @auth, verify: false)
|
33
|
+
raise NoSuchHostError if response.code == 404
|
34
|
+
raise ApiError if response.code != 200
|
35
|
+
true
|
36
|
+
end
|
37
|
+
|
38
|
+
def update_hostgroup(hostgroup, members)
|
39
|
+
body = { file_id: 'etc/hostgroups.cfg',
|
40
|
+
hostgroup_name: hostgroup.to_s,
|
41
|
+
members: members }.to_json
|
42
|
+
response = self.class.patch(@base_uri + "config/hostgroup/#{hostgroup}",
|
43
|
+
headers: { 'Content-Type' => 'application/json' },
|
44
|
+
body: body, basic_auth: @auth, verify: false)
|
45
|
+
raise ApiError unless response.code == 200
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|