op5util 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -0,0 +1,7 @@
1
+ pkg/*/
2
+ !pkg/*pkg
3
+ *~
4
+ .bundle/
5
+ vendor/
6
+ pkg/op5util-0.0.*.gem
7
+ .DS_Store
data/Gemfile ADDED
@@ -0,0 +1,12 @@
1
+ source 'https://rubygems.org'
2
+ gemspec
3
+ gem 'colorize'
4
+ gem 'httparty'
5
+ gem 'terminal-table'
6
+
7
+ group :development do
8
+ gem 'awesome_print'
9
+ gem 'rake'
10
+ gem 'rdoc'
11
+ gem 'test-unit'
12
+ end
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
@@ -0,0 +1,6 @@
1
+ = op5util
2
+
3
+ Describe your project here
4
+
5
+ :include:op5util.rdoc
6
+
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
+ ![Usage example](https://raw.githubusercontent.com/np422/Op5util/master/screenshots/usecase2.png)
50
+
51
+ The newly added host in normal web-gui.
52
+
53
+ ![web-gui](https://raw.githubusercontent.com/np422/Op5util/master/screenshots/host_op5.png)
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
+ ![web-gui](https://raw.githubusercontent.com/np422/Op5util/master/screenshots/host_op5_listview.png)
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
+ ![screenshot](https://raw.githubusercontent.com/np422/Op5util/master/screenshots/usecase1.png)
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