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 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