opsview_rest 0.0.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.
data/Gemfile ADDED
@@ -0,0 +1,15 @@
1
+ source 'http://rubygems.org'
2
+
3
+ gem 'rest-client', :require=>"rest_client"
4
+ gem 'json'
5
+
6
+
7
+ group :development do
8
+ gem 'rake'
9
+ gem "rspec", "~> 2.0.0"
10
+ gem "yard"
11
+ gem 'jeweler'
12
+ end
13
+
14
+
15
+
data/README.rdoc ADDED
@@ -0,0 +1,41 @@
1
+ = WARNING! ACHTUNG!
2
+
3
+ Don't use yet! This gem is still in development, and I heavily recommend
4
+ against *anyone* using this gem.
5
+
6
+ Also, descriptions on how the gem works in this README is bound to change
7
+ at any time.
8
+
9
+ = opsview_rest
10
+
11
+ A Ruby Gem that allows you to interact with an Opsview server.
12
+
13
+ == Resources
14
+
15
+ First iteration will focus on creating/updating/deleting resources on an
16
+ Opsview server. The following resources are currently supported:
17
+
18
+ - Hosts
19
+ - Contacts
20
+ - Hostgroups
21
+ - Host Templates
22
+ - Notification Methods
23
+ - Roles
24
+ - Service Checks
25
+ - Service Groups
26
+
27
+ This gem is heavily based off of Adam Jacob's "dynect_rest" gem.
28
+
29
+ This is how you would use the gem to create a resource:
30
+
31
+ require 'opsview_rest'
32
+ connection = OpsviewRest.new(:url => "https://example.com/rest", :username => "hi", :password => "hello")
33
+ host = connection.create(:name => "foobar",
34
+ :ip => "192.168.1.1",
35
+ :type => :host,
36
+ :replace => false)
37
+
38
+ # Let's say we want to peer into what we have so far for hosts:
39
+
40
+ connection = Opsview.new(...)
41
+ hosts = connection.host.list
data/Rakefile ADDED
@@ -0,0 +1,36 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "opsview_rest"
8
+ gem.summary = %Q{Opsview REST API library}
9
+ gem.description = %Q{Update configuration on Opsview server via REST API}
10
+ gem.email = "christian.paredes@seattlebiomed.org"
11
+ gem.homepage = "http://github.com/cparedes/opsview_rest"
12
+ gem.authors = ["Christian Paredes"]
13
+ gem.add_development_dependency "rspec", ">= 2.0"
14
+ gem.add_development_dependency "yard", ">= 0"
15
+ gem.add_dependency('json')
16
+ gem.add_dependency('rest-client')
17
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
18
+ end
19
+ Jeweler::GemcutterTasks.new
20
+ rescue LoadError
21
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
22
+ end
23
+
24
+ require 'rspec/core/rake_task'
25
+ RSpec::Core::RakeTask.new(:spec)
26
+
27
+ task :default => :spec
28
+
29
+ begin
30
+ require 'yard'
31
+ YARD::Rake::YardocTask.new
32
+ rescue LoadError
33
+ task :yardoc do
34
+ abort "YARD is not available. In order to run yardoc, you must: sudo gem install yard"
35
+ end
36
+ end
data/TODO.md ADDED
@@ -0,0 +1,20 @@
1
+ TODO List
2
+ =========
3
+
4
+ 1. Figure out a way to instantiate a ton of methods for all of the different
5
+ resource types. There isn't a nice way to deal with, say, hosts, and
6
+ hostgroups at the moment (since they all have different parameters.)
7
+ The only things that are common between the different resource types
8
+ are "name" and "id".
9
+ 1a. If not this, then there should be a better way to deal with the plethora
10
+ of fields that we could possibly update in Opsview for each resource type.
11
+ I've mostly based the code off of Adam Jacob's dynect_rest gem, which
12
+ has a much simpler API and a predictable set of parameters - thus, it
13
+ makes sense to dynamically create a ton of methods and allow stuff like
14
+ "dynect.record.ip.foobar" as an accessor.
15
+
16
+ One thought is to simply choose a functional subset of the parameters we
17
+ could pass into each type of resource, and add more as the need arises.
18
+ Another thought is to simply pass in a hash with a bunch of data in it,
19
+ but I'd rather not do this, as it'd make the user guess how best to format
20
+ the data.
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.1
@@ -0,0 +1,31 @@
1
+ require 'opsview_rest/mixin'
2
+
3
+ class OpsviewRest
4
+ class Attribute
5
+
6
+ include OpsviewRest::Mixin
7
+
8
+ attr_accessor :options, :opsview
9
+
10
+ def initialize(opsview, options = {})
11
+ @options = {
12
+ :name => "PROCESSES",
13
+ :arg1 => "",
14
+ :arg2 => "",
15
+ :arg3 => "",
16
+ :arg4 => "",
17
+ :value => "",
18
+ :servicechecks => [],
19
+ :save => true,
20
+ :replace => false
21
+ }.update options
22
+
23
+ @opsview = opsview
24
+
25
+ @options[:servicechecks] = @options[:servicechecks].map { |x| { "name" => x } }
26
+
27
+ save(@options[:replace]) if @options[:save]
28
+ end
29
+
30
+ end
31
+ end
@@ -0,0 +1,68 @@
1
+ require 'opsview_rest/mixin'
2
+
3
+ class OpsviewRest
4
+ class Attribute
5
+
6
+ include OpsviewRest::Mixin
7
+
8
+ def initialize(opsview, options = {})
9
+ @options = {
10
+ :name => "foobar",
11
+ :fullname => "",
12
+ :description => "",
13
+ :encrypted_password => "$apr1$HTQogYE7$09TNcZWa/WzoBXdUF6Iyr1",
14
+ :realm => "local",
15
+ :language => "",
16
+ :role => "View all, change none",
17
+ :variables => [
18
+ { :value => "", :name => "EMAIL" },
19
+ { :value => 1, :name => "RSS_COLLAPSED" },
20
+ { :value => 1440, :name => "RSS_MAXIMUM_AGE" },
21
+ { :value => 30, :name => "RSS_MAXIMUM_ITEMS" }
22
+ ],
23
+ :notificationprofiles => [
24
+ { :name => "24x7",
25
+ :host_notification_options => "u,d,r,f",
26
+ :notificationmethods => [
27
+ { :name => "Email" }
28
+ ],
29
+ :servicegroups => [],
30
+ :all_servicegroups => 1,
31
+ :all_hostgroups => 0,
32
+ :keywords => [],
33
+ :service_notification_options => "w,c,r,u,f",
34
+ :hostgroups => [],
35
+ :notification_level => 1,
36
+ :notification_period => { :name => "24x7" } },
37
+ { :name => "8x5",
38
+ :host_notification_options => "u,d,r,f",
39
+ :notificationmethods => [
40
+ { :name => "Email" }
41
+ ],
42
+ :servicegroups => [],
43
+ :all_servicegroups => 1,
44
+ :all_hostgroups => 0,
45
+ :keywords => [],
46
+ :service_notification_options => "w,c,r,u,f",
47
+ :hostgroups => [],
48
+ :notification_level => 1,
49
+ :notification_period => { :name => "workhours" } }
50
+ ],
51
+ :save => true,
52
+ :replace => false
53
+ }.update options
54
+
55
+ @opsview = opsview
56
+
57
+ @options[:all_servicegroups] = if @options[:all_servicegroups] then 1 else 0 end
58
+ @options[:all_hostgroups] = if @options[:all_hostgroups] then 1 else 0 end
59
+ @options[:servicegroups] = @options[:servicegroups].map { |x| { "name" => x } }
60
+ @options[:keywords] = @options[:keywords].map { |x| { "name" => x } }
61
+ @options[:hostgroups] = @options[:hostgroups].map { |x| { "name" => x } }
62
+ @options[:role] = { "name" => @options[:role] }
63
+
64
+ save(@options[:replace]) if @options[:save]
65
+ end
66
+
67
+ end
68
+ end
@@ -0,0 +1,76 @@
1
+ require 'opsview_rest/mixin'
2
+
3
+ class OpsviewRest
4
+ class Host
5
+
6
+ include OpsviewRest::Mixin
7
+
8
+ attr_accessor :options, :opsview
9
+
10
+ def initialize(opsview, options = {})
11
+ # Default set of attributes to send to Opsview:
12
+ @options = {
13
+ :flap_detection_enabled => false,
14
+ :snmpv3_privprotocol => nil,
15
+ :hosttemplates => [],
16
+ :keywords => [],
17
+ :check_period => "24x7",
18
+ :hostattributes => [],
19
+ :notification_period => "24x7",
20
+ :name => "unknown",
21
+ :rancid_vendor => nil,
22
+ :snmp_community => "public",
23
+ :hostgroup => "Unknown",
24
+ :enable_snmp => false,
25
+ :monitored_by => "Master Monitoring Server",
26
+ :alias => "Managed Host",
27
+ :uncommitted => false,
28
+ :parents => [],
29
+ :icon => { "name" => "LOGO - Opsview" },
30
+ :retry_check_interval => 1,
31
+ :ip => "localhost",
32
+ :use_mrtg => false,
33
+ :servicechecks => [],
34
+ :use_rancid => false,
35
+ :nmis_node_type => "router",
36
+ :snmp_version => "2c",
37
+ :snmp_authpassword => "",
38
+ :use_nmis => false,
39
+ :rancid_connection_type => "ssh",
40
+ :snmpv3_authprotocol => nil,
41
+ :rancid_username => nil,
42
+ :rancid_password => nil,
43
+ :check_command => "ping",
44
+ :check_attempts => 2,
45
+ :check_interval => 0,
46
+ :notification_interval => 60,
47
+ :snmp_port => 161,
48
+ :snmpv3_username => "",
49
+ :snmpv3_privpassword => "",
50
+ :other_addresses => "",
51
+ :save => true,
52
+ :replace => false
53
+ }.update options
54
+
55
+ @opsview = opsview
56
+
57
+ # Add any weird exceptions here (like hostgroups having to be mapped
58
+ # to "name" => hostgroup, etc.):
59
+ @options[:flap_detection_enabled] = if @options[:flap_detection_enabled] then 1 else 0 end
60
+ @options[:enable_snmp] = if @options[:enable_snmp] then 1 else 0 end
61
+ @options[:use_mrtg] = if @options[:use_mrtg] then 1 else 0 end
62
+ @options[:use_rancid] = if @options[:use_rancid] then 1 else 0 end
63
+ @options[:use_nmis] = if @options[:use_nmis] then 1 else 0 end
64
+ @options[:uncommitted] = if @options[:uncommitted] then 1 else 0 end
65
+ @options[:check_period] = { "name" => @options[:check_period] }
66
+ @options[:hostgroup] = { "name" => @options[:hostgroup] }
67
+ @options[:notification_period] = { "name" => @options[:notification_period] }
68
+ @options[:monitored_by] = { "name" => @options[:monitored_by] }
69
+ @options[:servicechecks] = @options[:servicechecks].map { |x| { "name" => x } }
70
+ @options[:check_command] = { "name" => @options[:check_command] }
71
+
72
+ save(@options[:replace]) if @options[:save]
73
+ end
74
+
75
+ end
76
+ end
@@ -0,0 +1,31 @@
1
+ require 'opsview_rest/mixin'
2
+
3
+ class OpsviewRest
4
+ class Hostcheckcommand
5
+
6
+ include OpsviewRest::Mixin
7
+
8
+ attr_accessor :opsview, :options
9
+
10
+ def initialize(opsview, options = {})
11
+ @options = {
12
+ :name => "ping",
13
+ :args => "-H $HOSTADDRESS$ -t 3 -w 500.0,80% -c 1000.0,100%",
14
+ :priority => 1,
15
+ :plugin => "check_icmp",
16
+ :uncommitted => false,
17
+ :save => true,
18
+ :replace => false
19
+ }.update options
20
+
21
+ @opsview = opsview
22
+
23
+ @options[:plugin] = { "name" => @options[:plugin] }
24
+ @options[:hosts] = @options[:hosts].map { |x| { "name" => x } }
25
+ @options[:uncommitted] = if @options[:uncommitted] then 1 else 0 end
26
+
27
+ save(@options[:replace]) if @options[:save]
28
+ end
29
+
30
+ end
31
+ end
@@ -0,0 +1,28 @@
1
+ require 'opsview_rest/mixin'
2
+
3
+ class OpsviewRest
4
+ class Hostgroup
5
+
6
+ include OpsviewRest::Mixin
7
+
8
+ attr_accessor :opsview, :options
9
+
10
+ def initialize(opsview, options = {})
11
+ @options = {
12
+ :parent => "Opsview",
13
+ :name => "unknown",
14
+ :save => true,
15
+ :replace => false
16
+ }.update options
17
+
18
+ @opsview = opsview
19
+
20
+ @options[:parent] = { "name" => @options[:parent] }
21
+ @options[:hosts] = @options[:hosts].map { |x| { "name" => x } }
22
+ @options[:children] = @options[:children].map { |x| { "name" => x } }
23
+
24
+ save(@options[:replace]) if @options[:save]
25
+ end
26
+
27
+ end
28
+ end
@@ -0,0 +1,29 @@
1
+ class OpsviewRest
2
+ module Mixin
3
+
4
+ def resource_path(full=false)
5
+ if (full == true || full == :full)
6
+ "/rest/config/#{self.class.name.split('::').last.downcase}"
7
+ else
8
+ "config/#{self.class.name.split('::').last.downcase}"
9
+ end
10
+ end
11
+
12
+ def list
13
+ self.opsview.get(resource_path)
14
+ end
15
+
16
+ def save(replace=false)
17
+ if replace == true || replace == :replace
18
+ self.opsview.put(self.resource_path, self)
19
+ else
20
+ self.opsview.post(self.resource_path, self)
21
+ end
22
+ end
23
+
24
+ def to_json
25
+ self.options.to_json
26
+ end
27
+
28
+ end
29
+ end
@@ -0,0 +1,125 @@
1
+ require 'rest-client'
2
+ require 'json'
3
+
4
+ class OpsviewRest
5
+
6
+ attr_accessor :url, :username, :password, :rest
7
+
8
+ def initialize(url, options = {})
9
+ options = {
10
+ :username => "api",
11
+ :password => "changeme",
12
+ :connect => true
13
+ }.update options
14
+
15
+ @url = url
16
+ @username = options[:username]
17
+ @password = options[:password]
18
+ @rest = RestClient::Resource.new("#{@url}/rest/", :headers => { :content_type => 'application/json' })
19
+
20
+ login if options[:connect]
21
+ end
22
+
23
+ def login
24
+ response = post('login', { 'username' => @username, 'password' => @password })
25
+ @rest.headers[:x_opsview_token] = response['token']
26
+ @rest.headers[:x_opsview_username] = @username
27
+ response
28
+ end
29
+
30
+ def logout
31
+ delete('login')
32
+ end
33
+
34
+ def create(options = {})
35
+ case options[:type]
36
+ when :attribute
37
+ require 'opsview_rest/attribute'
38
+ OpsviewRest::Attribute.new(self, options)
39
+ when :contact
40
+ require 'opsview_rest/contact'
41
+ OpsviewRest::Contact.new(self, options)
42
+ when :host
43
+ require 'opsview_rest/host'
44
+ OpsviewRest::Host.new(self, options)
45
+ when :hostcheckcommand
46
+ require 'opsview_rest/hostcheckcommand'
47
+ OpsviewRest::Hostcheckcommand.new(self, options)
48
+ when :hostgroup
49
+ require 'opsview_rest/hostgroup'
50
+ OpsviewRest::Hostgroup.new(self, options)
51
+ when :hosttemplate
52
+ require 'opsview_rest/hosttemplate'
53
+ OpsviewRest::Hosttemplate.new(self, options)
54
+ when :keyword
55
+ require 'opsview_rest/keyword'
56
+ OpsviewRest::Keyword.new(self, options)
57
+ when :monitoring_server
58
+ require 'opsview_rest/monitoring_server'
59
+ OpsviewRest::MonitoringServer.new(self, options)
60
+ when :notification_method
61
+ require 'opsview_rest/notification_method'
62
+ OpsviewRest::NotificationMethod.new(self, options)
63
+ when :role
64
+ require 'opsview_rest/role'
65
+ OpsviewRest::Role.new(self, options)
66
+ when :servicecheck
67
+ require 'opsview_rest/servicecheck'
68
+ OpsviewRest::Servicecheck.new(self, options)
69
+ when :servicegroup
70
+ require 'opsview_rest/servicegroup'
71
+ OpsviewRest::Servicegroup.new(self, options)
72
+ when :timeperiod
73
+ require 'opsview_rest/timeperiod'
74
+ OpsviewRest::Timeperiod.new(self, options)
75
+ else
76
+ raise "Type not implemented yet."
77
+ end
78
+ end
79
+
80
+ def get(path_part, additional_headers = {}, &block)
81
+ api_request { @rest[path_part].get(additional_headers, &block) }
82
+ end
83
+
84
+ def delete(path_part, additional_headers = {}, &block)
85
+ api_request { @rest[path_part].delete(additional_headers, &block) }
86
+ end
87
+
88
+ def post(path_part, payload, additional_headers = {}, &block)
89
+ api_request { @rest[path_part].post(payload.to_json, additional_headers, &block) }
90
+ end
91
+
92
+ def put(path_part, payload, additional_headers = {}, &block)
93
+ api_request { @rest[path_part].put(payload.to_json, additional_headers, &block) }
94
+ end
95
+
96
+ def api_request(&block)
97
+ response_body = begin
98
+ response = block.call
99
+ response.body
100
+ rescue RestClient::Exception => e
101
+ puts "I have #{e.inspect} with #{e.http_code}"
102
+ if e.http_code == 307
103
+ get(e.response)
104
+ end
105
+ e.response
106
+ end
107
+ parse_response(JSON.parse(response_body))
108
+ end
109
+
110
+ def parse_response(response)
111
+ # We've got an error if there's "message" and "detail" fields
112
+ # in the response
113
+ if response["message"] and response["detail"]
114
+ raise Opsview::Exceptions::RequestFailed, "Request failed: #{response["message"]}, detail: #{response["detail"]}"
115
+ # If we have a token, return that:
116
+ elsif response["token"]
117
+ response
118
+ # If we have a list of objects, return the list:
119
+ elsif response["list"]
120
+ response["list"]
121
+ else
122
+ response["object"]
123
+ end
124
+ end
125
+ end
metadata ADDED
@@ -0,0 +1,218 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: opsview_rest
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Christian Paredes
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-09-15 00:00:00 Z
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ requirement: &id001 !ruby/object:Gem::Requirement
22
+ none: false
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ hash: 3
27
+ segments:
28
+ - 0
29
+ version: "0"
30
+ version_requirements: *id001
31
+ name: rest-client
32
+ prerelease: false
33
+ type: :runtime
34
+ - !ruby/object:Gem::Dependency
35
+ requirement: &id002 !ruby/object:Gem::Requirement
36
+ none: false
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ hash: 3
41
+ segments:
42
+ - 0
43
+ version: "0"
44
+ version_requirements: *id002
45
+ name: json
46
+ prerelease: false
47
+ type: :runtime
48
+ - !ruby/object:Gem::Dependency
49
+ requirement: &id003 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ hash: 3
55
+ segments:
56
+ - 0
57
+ version: "0"
58
+ version_requirements: *id003
59
+ name: rake
60
+ prerelease: false
61
+ type: :development
62
+ - !ruby/object:Gem::Dependency
63
+ requirement: &id004 !ruby/object:Gem::Requirement
64
+ none: false
65
+ requirements:
66
+ - - ~>
67
+ - !ruby/object:Gem::Version
68
+ hash: 15
69
+ segments:
70
+ - 2
71
+ - 0
72
+ - 0
73
+ version: 2.0.0
74
+ version_requirements: *id004
75
+ name: rspec
76
+ prerelease: false
77
+ type: :development
78
+ - !ruby/object:Gem::Dependency
79
+ requirement: &id005 !ruby/object:Gem::Requirement
80
+ none: false
81
+ requirements:
82
+ - - ">="
83
+ - !ruby/object:Gem::Version
84
+ hash: 3
85
+ segments:
86
+ - 0
87
+ version: "0"
88
+ version_requirements: *id005
89
+ name: yard
90
+ prerelease: false
91
+ type: :development
92
+ - !ruby/object:Gem::Dependency
93
+ requirement: &id006 !ruby/object:Gem::Requirement
94
+ none: false
95
+ requirements:
96
+ - - ">="
97
+ - !ruby/object:Gem::Version
98
+ hash: 3
99
+ segments:
100
+ - 0
101
+ version: "0"
102
+ version_requirements: *id006
103
+ name: jeweler
104
+ prerelease: false
105
+ type: :development
106
+ - !ruby/object:Gem::Dependency
107
+ requirement: &id007 !ruby/object:Gem::Requirement
108
+ none: false
109
+ requirements:
110
+ - - ">="
111
+ - !ruby/object:Gem::Version
112
+ hash: 3
113
+ segments:
114
+ - 2
115
+ - 0
116
+ version: "2.0"
117
+ version_requirements: *id007
118
+ name: rspec
119
+ prerelease: false
120
+ type: :development
121
+ - !ruby/object:Gem::Dependency
122
+ requirement: &id008 !ruby/object:Gem::Requirement
123
+ none: false
124
+ requirements:
125
+ - - ">="
126
+ - !ruby/object:Gem::Version
127
+ hash: 3
128
+ segments:
129
+ - 0
130
+ version: "0"
131
+ version_requirements: *id008
132
+ name: yard
133
+ prerelease: false
134
+ type: :development
135
+ - !ruby/object:Gem::Dependency
136
+ requirement: &id009 !ruby/object:Gem::Requirement
137
+ none: false
138
+ requirements:
139
+ - - ">="
140
+ - !ruby/object:Gem::Version
141
+ hash: 3
142
+ segments:
143
+ - 0
144
+ version: "0"
145
+ version_requirements: *id009
146
+ name: json
147
+ prerelease: false
148
+ type: :runtime
149
+ - !ruby/object:Gem::Dependency
150
+ requirement: &id010 !ruby/object:Gem::Requirement
151
+ none: false
152
+ requirements:
153
+ - - ">="
154
+ - !ruby/object:Gem::Version
155
+ hash: 3
156
+ segments:
157
+ - 0
158
+ version: "0"
159
+ version_requirements: *id010
160
+ name: rest-client
161
+ prerelease: false
162
+ type: :runtime
163
+ description: Update configuration on Opsview server via REST API
164
+ email: christian.paredes@seattlebiomed.org
165
+ executables: []
166
+
167
+ extensions: []
168
+
169
+ extra_rdoc_files:
170
+ - README.rdoc
171
+ files:
172
+ - Gemfile
173
+ - README.rdoc
174
+ - Rakefile
175
+ - TODO.md
176
+ - VERSION
177
+ - lib/opsview_rest.rb
178
+ - lib/opsview_rest/attribute.rb
179
+ - lib/opsview_rest/contact.rb
180
+ - lib/opsview_rest/host.rb
181
+ - lib/opsview_rest/hostcheckcommand.rb
182
+ - lib/opsview_rest/hostgroup.rb
183
+ - lib/opsview_rest/mixin.rb
184
+ homepage: http://github.com/cparedes/opsview_rest
185
+ licenses: []
186
+
187
+ post_install_message:
188
+ rdoc_options: []
189
+
190
+ require_paths:
191
+ - lib
192
+ required_ruby_version: !ruby/object:Gem::Requirement
193
+ none: false
194
+ requirements:
195
+ - - ">="
196
+ - !ruby/object:Gem::Version
197
+ hash: 3
198
+ segments:
199
+ - 0
200
+ version: "0"
201
+ required_rubygems_version: !ruby/object:Gem::Requirement
202
+ none: false
203
+ requirements:
204
+ - - ">="
205
+ - !ruby/object:Gem::Version
206
+ hash: 3
207
+ segments:
208
+ - 0
209
+ version: "0"
210
+ requirements: []
211
+
212
+ rubyforge_project:
213
+ rubygems_version: 1.8.6
214
+ signing_key:
215
+ specification_version: 3
216
+ summary: Opsview REST API library
217
+ test_files: []
218
+