egi-fedcloud-vmhound 0.0.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: a7d2500d9814285384362ec97be8452dc5d93d0e
4
+ data.tar.gz: 30e2f5b8618fdebff446a5b11c975d2c209e5c9a
5
+ SHA512:
6
+ metadata.gz: 3e04485f77b349d06f86276a2c3a7962608ca1b2a83843b570707c6bac429995d874ed8aaa47c7bf0cddbeb33ee2ee2892cddcd4fc5fe66c9afcbe81e1db6c73
7
+ data.tar.gz: f0f1cbf2155b63877890a640bff420ccb4a8ccf0e079341916b029827033f09719c8735b96479366690b20a24c4528eb9419ec02382618f2af937bc467ff1c91
data/.gitignore ADDED
@@ -0,0 +1,35 @@
1
+ *.gem
2
+ *.rbc
3
+ /.config
4
+ /coverage/
5
+ /InstalledFiles
6
+ /pkg/
7
+ /spec/reports/
8
+ /test/tmp/
9
+ /test/version_tmp/
10
+ /tmp/
11
+
12
+ ## Specific to RubyMotion:
13
+ .dat*
14
+ .repl_history
15
+ build/
16
+
17
+ ## Documentation cache and generated files:
18
+ /.yardoc/
19
+ /_yardoc/
20
+ /doc/
21
+ /rdoc/
22
+
23
+ ## Environment normalisation:
24
+ /.bundle/
25
+ /vendor/bundle
26
+ /lib/bundler/man/
27
+
28
+ # for a library or gem, you might want to ignore these files since the code is
29
+ # intended to run in multiple environments; otherwise, check them in:
30
+ Gemfile.lock
31
+ .ruby-version
32
+ .ruby-gemset
33
+
34
+ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
35
+ .rvmrc
data/.travis.yml ADDED
@@ -0,0 +1,17 @@
1
+ language: ruby
2
+
3
+ rvm:
4
+ - 1.9.3
5
+ - 2.0.0
6
+ - 2.1
7
+ - 2.2
8
+ - ruby-head
9
+
10
+ matrix:
11
+ allow_failures:
12
+ - rvm: ruby-head
13
+ fast_finish: true
14
+
15
+ branches:
16
+ only:
17
+ - master
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "https://rubygems.org/"
2
+
3
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,202 @@
1
+ Apache License
2
+ Version 2.0, January 2004
3
+ http://www.apache.org/licenses/
4
+
5
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6
+
7
+ 1. Definitions.
8
+
9
+ "License" shall mean the terms and conditions for use, reproduction,
10
+ and distribution as defined by Sections 1 through 9 of this document.
11
+
12
+ "Licensor" shall mean the copyright owner or entity authorized by
13
+ the copyright owner that is granting the License.
14
+
15
+ "Legal Entity" shall mean the union of the acting entity and all
16
+ other entities that control, are controlled by, or are under common
17
+ control with that entity. For the purposes of this definition,
18
+ "control" means (i) the power, direct or indirect, to cause the
19
+ direction or management of such entity, whether by contract or
20
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
21
+ outstanding shares, or (iii) beneficial ownership of such entity.
22
+
23
+ "You" (or "Your") shall mean an individual or Legal Entity
24
+ exercising permissions granted by this License.
25
+
26
+ "Source" form shall mean the preferred form for making modifications,
27
+ including but not limited to software source code, documentation
28
+ source, and configuration files.
29
+
30
+ "Object" form shall mean any form resulting from mechanical
31
+ transformation or translation of a Source form, including but
32
+ not limited to compiled object code, generated documentation,
33
+ and conversions to other media types.
34
+
35
+ "Work" shall mean the work of authorship, whether in Source or
36
+ Object form, made available under the License, as indicated by a
37
+ copyright notice that is included in or attached to the work
38
+ (an example is provided in the Appendix below).
39
+
40
+ "Derivative Works" shall mean any work, whether in Source or Object
41
+ form, that is based on (or derived from) the Work and for which the
42
+ editorial revisions, annotations, elaborations, or other modifications
43
+ represent, as a whole, an original work of authorship. For the purposes
44
+ of this License, Derivative Works shall not include works that remain
45
+ separable from, or merely link (or bind by name) to the interfaces of,
46
+ the Work and Derivative Works thereof.
47
+
48
+ "Contribution" shall mean any work of authorship, including
49
+ the original version of the Work and any modifications or additions
50
+ to that Work or Derivative Works thereof, that is intentionally
51
+ submitted to Licensor for inclusion in the Work by the copyright owner
52
+ or by an individual or Legal Entity authorized to submit on behalf of
53
+ the copyright owner. For the purposes of this definition, "submitted"
54
+ means any form of electronic, verbal, or written communication sent
55
+ to the Licensor or its representatives, including but not limited to
56
+ communication on electronic mailing lists, source code control systems,
57
+ and issue tracking systems that are managed by, or on behalf of, the
58
+ Licensor for the purpose of discussing and improving the Work, but
59
+ excluding communication that is conspicuously marked or otherwise
60
+ designated in writing by the copyright owner as "Not a Contribution."
61
+
62
+ "Contributor" shall mean Licensor and any individual or Legal Entity
63
+ on behalf of whom a Contribution has been received by Licensor and
64
+ subsequently incorporated within the Work.
65
+
66
+ 2. Grant of Copyright License. Subject to the terms and conditions of
67
+ this License, each Contributor hereby grants to You a perpetual,
68
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69
+ copyright license to reproduce, prepare Derivative Works of,
70
+ publicly display, publicly perform, sublicense, and distribute the
71
+ Work and such Derivative Works in Source or Object form.
72
+
73
+ 3. Grant of Patent License. Subject to the terms and conditions of
74
+ this License, each Contributor hereby grants to You a perpetual,
75
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76
+ (except as stated in this section) patent license to make, have made,
77
+ use, offer to sell, sell, import, and otherwise transfer the Work,
78
+ where such license applies only to those patent claims licensable
79
+ by such Contributor that are necessarily infringed by their
80
+ Contribution(s) alone or by combination of their Contribution(s)
81
+ with the Work to which such Contribution(s) was submitted. If You
82
+ institute patent litigation against any entity (including a
83
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
84
+ or a Contribution incorporated within the Work constitutes direct
85
+ or contributory patent infringement, then any patent licenses
86
+ granted to You under this License for that Work shall terminate
87
+ as of the date such litigation is filed.
88
+
89
+ 4. Redistribution. You may reproduce and distribute copies of the
90
+ Work or Derivative Works thereof in any medium, with or without
91
+ modifications, and in Source or Object form, provided that You
92
+ meet the following conditions:
93
+
94
+ (a) You must give any other recipients of the Work or
95
+ Derivative Works a copy of this License; and
96
+
97
+ (b) You must cause any modified files to carry prominent notices
98
+ stating that You changed the files; and
99
+
100
+ (c) You must retain, in the Source form of any Derivative Works
101
+ that You distribute, all copyright, patent, trademark, and
102
+ attribution notices from the Source form of the Work,
103
+ excluding those notices that do not pertain to any part of
104
+ the Derivative Works; and
105
+
106
+ (d) If the Work includes a "NOTICE" text file as part of its
107
+ distribution, then any Derivative Works that You distribute must
108
+ include a readable copy of the attribution notices contained
109
+ within such NOTICE file, excluding those notices that do not
110
+ pertain to any part of the Derivative Works, in at least one
111
+ of the following places: within a NOTICE text file distributed
112
+ as part of the Derivative Works; within the Source form or
113
+ documentation, if provided along with the Derivative Works; or,
114
+ within a display generated by the Derivative Works, if and
115
+ wherever such third-party notices normally appear. The contents
116
+ of the NOTICE file are for informational purposes only and
117
+ do not modify the License. You may add Your own attribution
118
+ notices within Derivative Works that You distribute, alongside
119
+ or as an addendum to the NOTICE text from the Work, provided
120
+ that such additional attribution notices cannot be construed
121
+ as modifying the License.
122
+
123
+ You may add Your own copyright statement to Your modifications and
124
+ may provide additional or different license terms and conditions
125
+ for use, reproduction, or distribution of Your modifications, or
126
+ for any such Derivative Works as a whole, provided Your use,
127
+ reproduction, and distribution of the Work otherwise complies with
128
+ the conditions stated in this License.
129
+
130
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
131
+ any Contribution intentionally submitted for inclusion in the Work
132
+ by You to the Licensor shall be under the terms and conditions of
133
+ this License, without any additional terms or conditions.
134
+ Notwithstanding the above, nothing herein shall supersede or modify
135
+ the terms of any separate license agreement you may have executed
136
+ with Licensor regarding such Contributions.
137
+
138
+ 6. Trademarks. This License does not grant permission to use the trade
139
+ names, trademarks, service marks, or product names of the Licensor,
140
+ except as required for reasonable and customary use in describing the
141
+ origin of the Work and reproducing the content of the NOTICE file.
142
+
143
+ 7. Disclaimer of Warranty. Unless required by applicable law or
144
+ agreed to in writing, Licensor provides the Work (and each
145
+ Contributor provides its Contributions) on an "AS IS" BASIS,
146
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147
+ implied, including, without limitation, any warranties or conditions
148
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149
+ PARTICULAR PURPOSE. You are solely responsible for determining the
150
+ appropriateness of using or redistributing the Work and assume any
151
+ risks associated with Your exercise of permissions under this License.
152
+
153
+ 8. Limitation of Liability. In no event and under no legal theory,
154
+ whether in tort (including negligence), contract, or otherwise,
155
+ unless required by applicable law (such as deliberate and grossly
156
+ negligent acts) or agreed to in writing, shall any Contributor be
157
+ liable to You for damages, including any direct, indirect, special,
158
+ incidental, or consequential damages of any character arising as a
159
+ result of this License or out of the use or inability to use the
160
+ Work (including but not limited to damages for loss of goodwill,
161
+ work stoppage, computer failure or malfunction, or any and all
162
+ other commercial damages or losses), even if such Contributor
163
+ has been advised of the possibility of such damages.
164
+
165
+ 9. Accepting Warranty or Additional Liability. While redistributing
166
+ the Work or Derivative Works thereof, You may choose to offer,
167
+ and charge a fee for, acceptance of support, warranty, indemnity,
168
+ or other liability obligations and/or rights consistent with this
169
+ License. However, in accepting such obligations, You may act only
170
+ on Your own behalf and on Your sole responsibility, not on behalf
171
+ of any other Contributor, and only if You agree to indemnify,
172
+ defend, and hold each Contributor harmless for any liability
173
+ incurred by, or claims asserted against, such Contributor by reason
174
+ of your accepting any such warranty or additional liability.
175
+
176
+ END OF TERMS AND CONDITIONS
177
+
178
+ APPENDIX: How to apply the Apache License to your work.
179
+
180
+ To apply the Apache License to your work, attach the following
181
+ boilerplate notice, with the fields enclosed by brackets "{}"
182
+ replaced with your own identifying information. (Don't include
183
+ the brackets!) The text should be enclosed in the appropriate
184
+ comment syntax for the file format. We also recommend that a
185
+ file or class name and description of purpose be included on the
186
+ same "printed page" as the copyright notice for easier
187
+ identification within third-party archives.
188
+
189
+ Copyright {yyyy} {name of copyright owner}
190
+
191
+ Licensed under the Apache License, Version 2.0 (the "License");
192
+ you may not use this file except in compliance with the License.
193
+ You may obtain a copy of the License at
194
+
195
+ http://www.apache.org/licenses/LICENSE-2.0
196
+
197
+ Unless required by applicable law or agreed to in writing, software
198
+ distributed under the License is distributed on an "AS IS" BASIS,
199
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200
+ See the License for the specific language governing permissions and
201
+ limitations under the License.
202
+
data/README.md ADDED
@@ -0,0 +1,16 @@
1
+ [![Build Status](https://secure.travis-ci.org/arax/egi-fedcloud-vmhound.png)](http://travis-ci.org/arax/egi-fedcloud-vmhound)
2
+ [![Dependency Status](https://gemnasium.com/arax/egi-fedcloud-vmhound.png)](https://gemnasium.com/arax/egi-fedcloud-vmhound)
3
+ [![Gem Version](https://fury-badge.herokuapp.com/rb/egi-fedcloud-vmhound.png)](https://badge.fury.io/rb/egi-fedcloud-vmhound)
4
+ [![Code Climate](https://codeclimate.com/github/arax/egi-fedcloud-vmhound.png)](https://codeclimate.com/github/arax/egi-fedcloud-vmhound)
5
+
6
+ # EGI FedCloud CloudHound
7
+
8
+ A proof-of-concept utility for locating VM instances in EGI Federated Cloud.
9
+
10
+ ## Contributing
11
+
12
+ 1. Fork it ( https://github.com/arax/egi-fedcloud-vmhound/fork )
13
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
14
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
15
+ 4. Push to the branch (`git push origin my-new-feature`)
16
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,27 @@
1
+ require 'rubygems/tasks'
2
+
3
+ task :default => 'test'
4
+
5
+ desc "Run all tests; includes rspec and coverage reports"
6
+ task :test => 'rcov:all'
7
+
8
+ desc "Run all tests; includes rspec and coverage reports"
9
+ task :spec => 'test'
10
+
11
+ Gem::Tasks.new(:build => {:tar => true, :zip => true}, :sign => {:checksum => true, :pgp => false})
12
+
13
+ namespace :rcov do
14
+
15
+ require 'rspec/core/rake_task'
16
+
17
+ RSpec::Core::RakeTask.new(:rspec) do |t|
18
+ ENV['COVERAGE'] = "true"
19
+ end
20
+
21
+ desc "Run rspec to generate aggregated coverage"
22
+ task :all do |t|
23
+ rm "coverage/coverage.data" if File.exist?("coverage/coverage.data")
24
+ Rake::Task['rcov:rspec'].invoke
25
+ end
26
+
27
+ end
@@ -0,0 +1,128 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # -------------------------------------------------------------------------- #
4
+ # Licensed under the Apache License, Version 2.0 (the "License"); you may #
5
+ # not use this file except in compliance with the License. You may obtain #
6
+ # a copy of the License at #
7
+ # #
8
+ # http://www.apache.org/licenses/LICENSE-2.0 #
9
+ # #
10
+ # Unless required by applicable law or agreed to in writing, software #
11
+ # distributed under the License is distributed on an "AS IS" BASIS, #
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
13
+ # See the License for the specific language governing permissions and #
14
+ # limitations under the License. #
15
+ #--------------------------------------------------------------------------- #
16
+
17
+ require 'rubygems'
18
+
19
+ require 'thor'
20
+ require 'egi-fedcloud-vmhound'
21
+
22
+ class EgiFedcloudVmhound < Thor
23
+ include Thor::Actions
24
+
25
+ desc "ip IP_ADDRESS", "Prints information based on the provided IP address or IP address range"
26
+ method_option :cmf, :type => :string, :default => Egi::Fedcloud::Vmhound::Settings.cmf,
27
+ :aliases => '-c', :desc => 'Type of the underlying CMF', :required => true
28
+ method_option :endpoint, :type => :string, :default => nil,
29
+ :aliases => '-e', :desc => 'Endpoint of the CMF'
30
+ method_option :username, :type => :string, :default => nil,
31
+ :aliases => '-u', :desc => 'Username for CMF access'
32
+ method_option :password, :type => :string, :default => nil,
33
+ :aliases => '-p', :desc => 'Password for CMF access'
34
+ method_option :auth_file, :type => :string, :default => nil,
35
+ :aliases => '-f', :desc => 'File with authentication information for CMF access'
36
+ method_option :ca_path, :type => :string, :default => Egi::Fedcloud::Vmhound::Settings.ca_path,
37
+ :aliases => '-x', :desc => 'Directory path to all trusted CA certificates'
38
+ method_option :insecure, :type => :boolean, :default => Egi::Fedcloud::Vmhound::Settings.insecure,
39
+ :aliases => '-k', :desc => 'Enable insecure mode for SSL (no peer validation)'
40
+ method_option :debug, :type => :boolean, :default => Egi::Fedcloud::Vmhound::Settings.debug,
41
+ :aliases => '-d', :desc => 'Enable debugging'
42
+ def ip(ip_address)
43
+ init_log options[:debug]
44
+
45
+ $stdout.puts Egi::Fedcloud::Vmhound::Formatter.as_table(
46
+ Egi::Fedcloud::Vmhound::Extractor.find_by_ip(
47
+ ip_address,
48
+ options
49
+ )
50
+ )
51
+ end
52
+
53
+ desc "appuri URI", "Prints information based on the provided Appliance MPURI"
54
+ method_option :cmf, :type => :string, :default => Egi::Fedcloud::Vmhound::Settings.cmf,
55
+ :aliases => '-c', :desc => 'Type of the underlying CMF', :required => true
56
+ method_option :endpoint, :type => :string, :default => nil,
57
+ :aliases => '-e', :desc => 'Endpoint of the CMF'
58
+ method_option :username, :type => :string, :default => nil,
59
+ :aliases => '-u', :desc => 'Username for CMF access'
60
+ method_option :password, :type => :string, :default => nil,
61
+ :aliases => '-p', :desc => 'Password for CMF access'
62
+ method_option :auth_file, :type => :string, :default => nil,
63
+ :aliases => '-f', :desc => 'File with authentication information for CMF access'
64
+ method_option :ca_path, :type => :string, :default => Egi::Fedcloud::Vmhound::Settings.ca_path,
65
+ :aliases => '-x', :desc => 'Directory path to all trusted CA certificates'
66
+ method_option :insecure, :type => :boolean, :default => Egi::Fedcloud::Vmhound::Settings.insecure,
67
+ :aliases => '-k', :desc => 'Enable insecure mode for SSL (no peer validation)'
68
+ method_option :debug, :type => :boolean, :default => Egi::Fedcloud::Vmhound::Settings.debug,
69
+ :aliases => '-d', :desc => 'Enable debugging'
70
+ def appuri(uri)
71
+ init_log options[:debug]
72
+
73
+ $stdout.puts Egi::Fedcloud::Vmhound::Formatter.as_table(
74
+ Egi::Fedcloud::Vmhound::Extractor.find_by_appuri(
75
+ uri,
76
+ options
77
+ )
78
+ )
79
+ end
80
+
81
+ desc "user ID", "Prints information based on the provided user identifier"
82
+ method_option :cmf, :type => :string, :default => Egi::Fedcloud::Vmhound::Settings.cmf,
83
+ :aliases => '-c', :desc => 'Type of the underlying CMF', :required => true
84
+ method_option :endpoint, :type => :string, :default => nil,
85
+ :aliases => '-e', :desc => 'Endpoint of the CMF'
86
+ method_option :username, :type => :string, :default => nil,
87
+ :aliases => '-u', :desc => 'Username for CMF access'
88
+ method_option :password, :type => :string, :default => nil,
89
+ :aliases => '-p', :desc => 'Password for CMF access'
90
+ method_option :auth_file, :type => :string, :default => nil,
91
+ :aliases => '-f', :desc => 'File with authentication information for CMF access'
92
+ method_option :ca_path, :type => :string, :default => Egi::Fedcloud::Vmhound::Settings.ca_path,
93
+ :aliases => '-x', :desc => 'Directory path to all trusted CA certificates'
94
+ method_option :insecure, :type => :boolean, :default => Egi::Fedcloud::Vmhound::Settings.insecure,
95
+ :aliases => '-k', :desc => 'Enable insecure mode for SSL (no peer validation)'
96
+ method_option :debug, :type => :boolean, :default => Egi::Fedcloud::Vmhound::Settings.debug,
97
+ :aliases => '-d', :desc => 'Enable debugging'
98
+ def user(id)
99
+ init_log options[:debug]
100
+
101
+ $stdout.puts Egi::Fedcloud::Vmhound::Formatter.as_table(
102
+ Egi::Fedcloud::Vmhound::Extractor.find_by_user(
103
+ id,
104
+ options
105
+ )
106
+ )
107
+ end
108
+
109
+ # Static method required by Thor to make certain
110
+ # actions work.
111
+ def self.source_root
112
+ File.expand_path(File.join('..', '..', 'config'), __FILE__)
113
+ end
114
+
115
+ private
116
+
117
+ # Initializes logging facilities.
118
+ #
119
+ # @param debug [Boolean] rudimentary logging level control
120
+ # @return [Egi::Fedcloud::Vmhound::Log] logger instance for additional configuration
121
+ def init_log(debug = false)
122
+ logger = Egi::Fedcloud::Vmhound::Log.new(STDERR)
123
+ logger.level = debug ? Egi::Fedcloud::Vmhound::Log::DEBUG : Egi::Fedcloud::Vmhound::Log::ERROR
124
+ logger
125
+ end
126
+ end
127
+
128
+ EgiFedcloudVmhound.start
@@ -0,0 +1,18 @@
1
+ ---
2
+ production:
3
+ cmf: opennebula
4
+ ca_path: '/etc/grid-security/certificates'
5
+ insecure: false
6
+ debug: false
7
+
8
+ development:
9
+ cmf: opennebula
10
+ ca_path: '/etc/grid-security/certificates'
11
+ insecure: true
12
+ debug: true
13
+
14
+ test:
15
+ cmf: dummy
16
+ ca_path: '/etc/grid-security/certificates'
17
+ insecure: true
18
+ debug: true
@@ -0,0 +1,36 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib/', __FILE__)
3
+ $:.unshift lib unless $:.include?(lib)
4
+
5
+ require 'egi/fedcloud/vmhound/version'
6
+
7
+ Gem::Specification.new do |gem|
8
+ gem.name = "egi-fedcloud-vmhound"
9
+ gem.version = Egi::Fedcloud::Vmhound::VERSION
10
+ gem.authors = ["Boris Parak"]
11
+ gem.email = ['parak@cesnet.cz']
12
+ gem.description = %q{A proof-of-concept utility for locating VM instances in EGI Federated Cloud}
13
+ gem.summary = %q{A proof-of-concept utility for locating VM instances in EGI Federated Cloud}
14
+ gem.homepage = 'https://github.com/arax/egi-fedcloud-vmhound'
15
+ gem.license = 'Apache License, Version 2.0'
16
+
17
+ gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
18
+ gem.files = `git ls-files`.split("\n")
19
+ gem.test_files = `git ls-files -- {test,spec}/*`.split("\n")
20
+ gem.require_paths = ['lib']
21
+
22
+ gem.add_dependency 'activesupport', '~> 4.0', '>= 4.0.0'
23
+ gem.add_dependency 'settingslogic', '~> 2.0', '>= 2.0.9'
24
+ gem.add_dependency 'thor', '~> 0.19', '>= 0.19.1'
25
+ gem.add_dependency 'opennebula', '~> 4.10', '>= 4.10.2'
26
+ gem.add_dependency 'terminal-table', '~> 1.4', '>= 1.4.5'
27
+ gem.add_dependency 'ox', '~> 2.2', '>= 2.2.0'
28
+
29
+ gem.add_development_dependency 'bundler', '~> 1.6'
30
+ gem.add_development_dependency 'rake', '~> 10.0'
31
+ gem.add_development_dependency 'rspec', '~> 3.0.0'
32
+ gem.add_development_dependency 'simplecov', '~> 0.9.0'
33
+ gem.add_development_dependency 'rubygems-tasks', '~> 0.2.4'
34
+
35
+ gem.required_ruby_version = ">= 1.9.3"
36
+ end
@@ -0,0 +1,18 @@
1
+ # Initialize modules, if necessary
2
+ module Egi; end
3
+ module Egi::Fedcloud; end
4
+ module Egi::Fedcloud::Vmhound; end
5
+ module Egi::Fedcloud::Vmhound::Connectors; end
6
+
7
+ require 'active_support'
8
+ require 'active_support/core_ext'
9
+ require 'active_support/json'
10
+ require 'active_support/inflector'
11
+ require 'active_support/notifications'
12
+
13
+ require 'egi/fedcloud/vmhound/version'
14
+ require 'egi/fedcloud/vmhound/settings'
15
+ require 'egi/fedcloud/vmhound/log'
16
+ require 'egi/fedcloud/vmhound/connectors'
17
+ require 'egi/fedcloud/vmhound/formatter'
18
+ require 'egi/fedcloud/vmhound/extractor'
@@ -0,0 +1,5 @@
1
+ # Load base connector first
2
+ require File.join(File.dirname(__FILE__), 'connectors', "base_connector")
3
+
4
+ # Load all available connectors
5
+ Dir.glob(File.join(File.dirname(__FILE__), 'connectors', "*.rb")) { |connector_file| require connector_file.chomp('.rb') }
@@ -0,0 +1,24 @@
1
+ #
2
+ class Egi::Fedcloud::Vmhound::Connectors::BaseConnector
3
+
4
+ # Initializes a connector instance.
5
+ #
6
+ # @param opts [Hash] options for the connector
7
+ def initialize(opts = {})
8
+ @options = opts.freeze
9
+ end
10
+
11
+ # Retrieves active instances from the underlying CMF. Including instances
12
+ # in transitional or suspended states. Terminated instances will not be
13
+ # included.
14
+ #
15
+ # @return [Array<Hash>] List of instances, each represented as a hash
16
+ def active_instances; end
17
+
18
+ # Retrieves running instances from the underlying CMF. Only currently
19
+ # running instances will be included.
20
+ #
21
+ # @return [Array<Hash>] List of instances, each represented as a hash
22
+ def running_instances; end
23
+
24
+ end
@@ -0,0 +1,21 @@
1
+ #
2
+ class Egi::Fedcloud::Vmhound::Connectors::DummyConnector < Egi::Fedcloud::Vmhound::Connectors::BaseConnector
3
+
4
+ # Retrieves active instances from the underlying Dummy. Including instances
5
+ # in transitional or suspended states. Terminated instances will not be
6
+ # included.
7
+ #
8
+ # @return [Array<Hash>] List of instances, each represented as a hash
9
+ def active_instances
10
+ []
11
+ end
12
+
13
+ # Retrieves running instances from the underlying Dummy. Only currently
14
+ # running instances will be included.
15
+ #
16
+ # @return [Array<Hash>] List of instances, each represented as a hash
17
+ def running_instances
18
+ []
19
+ end
20
+
21
+ end
@@ -0,0 +1,293 @@
1
+ require 'opennebula'
2
+
3
+ #
4
+ class Egi::Fedcloud::Vmhound::Connectors::OpennebulaConnector < Egi::Fedcloud::Vmhound::Connectors::BaseConnector
5
+
6
+ # Number of VMs to process in one iteration
7
+ VM_POOL_BATCH_SIZE = 10000
8
+
9
+ # Initializes a connector instance.
10
+ #
11
+ # @param opts [Hash] options for the connector
12
+ def initialize(opts = {})
13
+ super
14
+
15
+ secret = if opts[:username] && opts[:password]
16
+ "#{opts[:username]}:#{opts[:password]}"
17
+ else
18
+ opts[:auth_file] ? File.read(opts[:auth_file]) : nil
19
+ end
20
+ secret.strip! if secret
21
+
22
+ options = {}
23
+ options[:sync] = true
24
+ # TODO: fix https://github.com/OpenNebula/one/blob/ced1a29bfb3f3d1991ea88e658ea9462071fe4b8/src/oca/ruby/opennebula/client.rb#L166
25
+ #options[:cert_dir] = opts[:ca_path] unless opts[:ca_path].blank?
26
+ options[:disable_ssl_verify] = opts[:insecure]
27
+
28
+ client = OpenNebula::Client.new(secret, opts[:endpoint], options)
29
+
30
+ @vm_pool = OpenNebula::VirtualMachinePool.new(client)
31
+ @vm_pool_ary = nil
32
+
33
+ @image_pool = OpenNebula::ImagePool.new(client)
34
+ @canonical_image_pool = nil
35
+
36
+ @user_pool = OpenNebula::UserPool.new(client)
37
+ @canonical_user_pool = nil
38
+ end
39
+
40
+ # Retrieves active instances from the underlying OpenNebula. Including instances
41
+ # in transitional or suspended states. Terminated instances will not be
42
+ # included.
43
+ #
44
+ # @return [Array<Hash>] List of instances, each represented as a hash
45
+ def active_instances
46
+ instances
47
+ end
48
+
49
+ # Retrieves running instances from the underlying OpenNebula. Only currently
50
+ # running instances will be included.
51
+ #
52
+ # @return [Array<Hash>] List of instances, each represented as a hash
53
+ def running_instances
54
+ instances ['ACTIVE']
55
+ end
56
+
57
+ private
58
+
59
+ # Retrieves a list of instances matching given criteria.
60
+ #
61
+ # @param allow_states [Array<String>] a list of allowed states
62
+ # @param reject_states [Array<String>] a list of states to be rejected
63
+ # @return [Array<Hash>] a list of instances matching given criteria
64
+ def instances(allow_states = nil, reject_states = nil)
65
+ return if allow_states && allow_states.empty?
66
+ reject_states ||= []
67
+
68
+ @vm_pool_ary = instances_batch_pool(@vm_pool) unless @vm_pool_ary
69
+
70
+ vms = []
71
+ @vm_pool_ary.each do |vm|
72
+ next if reject_states.include? vm.state_str
73
+ vms << canonical_instance(vm) if (allow_states.nil? || (allow_states && allow_states.include?(vm.state_str)))
74
+ end
75
+
76
+ vms
77
+ end
78
+
79
+ # Hides batch processing from the rest of the application. Returns
80
+ # a complete list of VM instances regardless of the underlying
81
+ # batch size.
82
+ #
83
+ # @param vm_pool [OpenNebula::VirtualMachinePool] ONe pool instance
84
+ # @return [Array<OpenNebula::VirtualMachine>] a list of VM instances
85
+ def instances_batch_pool(vm_pool)
86
+ fail 'Pool object not provided!' unless vm_pool
87
+
88
+ batch_start = 0
89
+ batch_stop = VM_POOL_BATCH_SIZE - 1
90
+ vm_pool_ary = []
91
+
92
+ begin
93
+ check_retval vm_pool.info(
94
+ OpenNebula::VirtualMachinePool::INFO_ALL,
95
+ batch_start, batch_stop,
96
+ OpenNebula::VirtualMachinePool::INFO_NOT_DONE
97
+ )
98
+ vm_pool_ary.concat vm_pool.to_a unless vm_pool.count < 1
99
+
100
+ batch_start = batch_stop + 1
101
+ batch_stop += VM_POOL_BATCH_SIZE
102
+ end until vm_pool.count < 1
103
+
104
+ vm_pool_ary.compact!
105
+ vm_pool_ary
106
+ end
107
+
108
+ # Retrieves a list of images.
109
+ #
110
+ # @return [Array<Hash>] a list of images
111
+ def images
112
+ return @canonical_image_pool if @canonical_image_pool
113
+ check_retval @image_pool.info_all!
114
+
115
+ @canonical_image_pool = []
116
+ @image_pool.each { |image| @canonical_image_pool << canonical_image(image) }
117
+ @canonical_image_pool
118
+ end
119
+
120
+ # Retrieves images by ID.
121
+ #
122
+ # @param image_id [String,Integer] native image ID
123
+ # @return [Hash,NilClass] canonical image structure
124
+ def image_by_id(image_id)
125
+ images.select { |image| image[:id] == image_id.to_i }.first
126
+ end
127
+
128
+ # Retrieves a list of users.
129
+ #
130
+ # @return [Array<Hash>] a list of users
131
+ def users
132
+ return @canonical_user_pool if @canonical_user_pool
133
+ check_retval @user_pool.info!
134
+
135
+ @canonical_user_pool = []
136
+ @user_pool.each { |user| @canonical_user_pool << canonical_user(user) }
137
+ @canonical_user_pool
138
+ end
139
+
140
+ # Retrieves users by ID.
141
+ #
142
+ # @param user_id [String,Integer] native user ID
143
+ # @return [Hash,NilClass] canonical user structure
144
+ def user_by_id(user_id)
145
+ users.select { |user| user[:id] == user_id.to_i }.first
146
+ end
147
+
148
+ # Creates a canonical instance representation in hash form.
149
+ #
150
+ # @param opennebula_instance [OpenNebula::VirtualMachine] ONe VM instance
151
+ # @return [Hash] canonical VM representation in hash form
152
+ def canonical_instance(opennebula_instance)
153
+ fail 'Instance object not provided!' unless opennebula_instance
154
+ {
155
+ id: opennebula_instance['ID'].to_i,
156
+ name: opennebula_instance['NAME'],
157
+ group: opennebula_instance['GNAME'],
158
+ owner: user_by_id(opennebula_instance['UID']),
159
+ appliance: image_by_id(opennebula_instance['TEMPLATE/DISK[1]/IMAGE_ID']),
160
+ ips: canonical_instance_ips(opennebula_instance),
161
+ identifiers: canonical_instance_identifiers(opennebula_instance),
162
+ host: canonical_instance_host(opennebula_instance),
163
+ state: "#{opennebula_instance.state_str} - #{opennebula_instance.lcm_state_str}",
164
+ }
165
+ end
166
+
167
+ # Creates a canonical IP representation in array form.
168
+ #
169
+ # @param opennebula_instance [OpenNebula::VirtualMachine] ONe VM instance
170
+ # @return [Array<String>] canonical IP representation in array form
171
+ def canonical_instance_ips(opennebula_instance)
172
+ fail 'Instance object not provided!' unless opennebula_instance
173
+ ips = []
174
+
175
+ opennebula_instance.each('TEMPLATE/NIC') { |nic| ips << nic['IP'] }
176
+ ips.compact!
177
+
178
+ ips
179
+ end
180
+
181
+ # Creates a canonical representation of instance identifiers in array form.
182
+ #
183
+ # @param opennebula_instance [OpenNebula::VirtualMachine] ONe VM instance
184
+ # @return [Array<String>] canonical representation of instance identifiers in array form
185
+ def canonical_instance_identifiers(opennebula_instance)
186
+ fail 'Instance object not provided!' unless opennebula_instance
187
+ identifiers = []
188
+
189
+ identifiers << opennebula_instance['USER_TEMPLATE/OCCI_ID']
190
+ identifiers << opennebula_instance['NAME']
191
+ identifiers << opennebula_instance['ID'].to_s
192
+ identifiers.compact!
193
+
194
+ identifiers
195
+ end
196
+
197
+ # Creates a canonical representation of an instance host in string form.
198
+ #
199
+ # @param opennebula_instance [OpenNebula::VirtualMachine] ONe VM instance
200
+ # @return [String] canonical representation of an instance host in string form
201
+ def canonical_instance_host(opennebula_instance)
202
+ fail 'Instance object not provided!' unless opennebula_instance
203
+ hosts = []
204
+
205
+ opennebula_instance.each('HISTORY_RECORDS/HISTORY') { |history| hosts << history['HOSTNAME'] }
206
+ hosts.compact!
207
+
208
+ hosts.last
209
+ end
210
+
211
+ # Creates a canonical image representation in hash form.
212
+ #
213
+ # @param opennebula_image [OpenNebula::Image] ONe image
214
+ # @return [Hash] canonical image representation in hash form
215
+ def canonical_image(opennebula_image)
216
+ fail 'Image object not provided!' unless opennebula_image
217
+ {
218
+ id: opennebula_image['ID'].to_i,
219
+ name: opennebula_image['NAME'],
220
+ location: opennebula_image['SOURCE'],
221
+ state: opennebula_image.state_str,
222
+ datastore: opennebula_image['DATASTORE'],
223
+ owner: {
224
+ user: opennebula_image['UNAME'],
225
+ group: opennebula_image['GNAME'],
226
+ },
227
+ identifiers: canonical_image_identifiers(opennebula_image),
228
+ }
229
+ end
230
+
231
+ # Creates a canonical representation of image identifiers in array form.
232
+ #
233
+ # @param opennebula_image [OpenNebula::Image] ONe image
234
+ # @return [Array<String>] canonical representation of identifiers in array form
235
+ def canonical_image_identifiers(opennebula_image)
236
+ fail 'Image object not provided!' unless opennebula_image
237
+ identifiers = []
238
+
239
+ identifiers << opennebula_image['TEMPLATE/VMCATCHER_EVENT_AD_MPURI']
240
+ identifiers << opennebula_image['TEMPLATE/VMCATCHER_EVENT_DC_IDENTIFIER']
241
+ identifiers << opennebula_image['NAME']
242
+ identifiers << opennebula_image['ID'].to_s
243
+ identifiers.compact!
244
+
245
+ identifiers
246
+ end
247
+
248
+ # Creates a canonical user representation in hash form.
249
+ #
250
+ # @param opennebula_user [OpenNebula::User] ONe user
251
+ # @return [Hash] canonical user representation in hash form
252
+ def canonical_user(opennebula_user)
253
+ fail 'User object not provided!' unless opennebula_user
254
+ {
255
+ id: opennebula_user['ID'].to_i,
256
+ name: opennebula_user['TEMPLATE/NAME'],
257
+ identities: canonical_user_identities(opennebula_user),
258
+ email: opennebula_user['TEMPLATE/EMAIL'],
259
+ groups: [
260
+ opennebula_user['GNAME'], # TODO: more groups
261
+ ],
262
+ }
263
+ end
264
+
265
+ # Creates a canonical representation of user identities in array form.
266
+ #
267
+ # @param opennebula_user [OpenNebula::User] ONe user
268
+ # @return [Array<String>] canonical representation of identities in array form
269
+ def canonical_user_identities(opennebula_user)
270
+ fail 'User object not provided!' unless opennebula_user
271
+ identities = []
272
+
273
+ identities << opennebula_user['TEMPLATE/KRB_PRINCIPAL']
274
+ identities << opennebula_user['TEMPLATE/X509_DN'].split('|') if opennebula_user['TEMPLATE/X509_DN']
275
+ identities << opennebula_user['NAME']
276
+ identities << opennebula_user['ID'].to_s
277
+ identities.flatten!
278
+ identities.compact!
279
+
280
+ identities
281
+ end
282
+
283
+ # Checks OpenNebula return codes for errors. Raises an error of the
284
+ # provided type (class) if applicable.
285
+ #
286
+ # @param rc [Object] object to be checked
287
+ # @param e_klass [Object] error class
288
+ def check_retval(rc, e_klass = nil)
289
+ return true unless ::OpenNebula.is_error?(rc)
290
+ fail (e_klass ? e_klass : RuntimeError ), rc.message
291
+ end
292
+
293
+ end
@@ -0,0 +1,42 @@
1
+ require 'ipaddr'
2
+
3
+ #
4
+ class Egi::Fedcloud::Vmhound::Extractor
5
+
6
+ class << self
7
+
8
+ # @param options [Hash] hash with connector options
9
+ # @return [String] name of the initialized connector
10
+ def env_init(options = {})
11
+ fail 'Connector type not specified!' unless options[:cmf]
12
+ return if defined?(@@connector)
13
+
14
+ connector_name = "#{options[:cmf].camelize}Connector"
15
+ @@connector = Egi::Fedcloud::Vmhound::Connectors.const_get(connector_name).new(options)
16
+
17
+ connector_name
18
+ end
19
+
20
+ #
21
+ def find_by_ip(ip, options = {})
22
+ env_init options
23
+ Egi::Fedcloud::Vmhound::Log.debug "[#{self}] Searching for instances by IP: #{ip.inspect}"
24
+ @@connector.active_instances.select { |instance| instance[:ips] && instance[:ips].include?(ip) }
25
+ end
26
+
27
+ #
28
+ def find_by_appuri(uri, options = {})
29
+ env_init options
30
+ Egi::Fedcloud::Vmhound::Log.debug "[#{self}] Searching for instances by MPURI: #{uri.inspect}"
31
+ @@connector.active_instances.select { |instance| instance[:appliance] && instance[:appliance][:identifiers].include?(uri) }
32
+ end
33
+
34
+ #
35
+ def find_by_user(id, options = {})
36
+ env_init options
37
+ Egi::Fedcloud::Vmhound::Log.debug "[#{self}] Searching for instances by user ID: #{id.inspect}"
38
+ @@connector.active_instances.select { |instance| instance[:owner] && instance[:owner][:identities].include?(id) }
39
+ end
40
+ end
41
+
42
+ end
@@ -0,0 +1,37 @@
1
+ require 'terminal-table'
2
+
3
+ #
4
+ class Egi::Fedcloud::Vmhound::Formatter
5
+
6
+ class << self
7
+ #
8
+ def as_table(data)
9
+ data ||= []
10
+ Egi::Fedcloud::Vmhound::Log.debug "[#{self}] Transforming #{data.inspect} into a table"
11
+ table = Terminal::Table.new
12
+
13
+ table.add_row [
14
+ ' >>> VM ID <<< ', ' >>> Owner <<< ', ' >>> VO/Group <<< ',
15
+ ' >>> IPs <<< ', ' >>> Phys. location <<< ', ' >>> State <<< ',
16
+ ' >>> Contact <<< '
17
+ ]
18
+ table.add_separator
19
+ data.each do |vm|
20
+ table.add_separator
21
+ table.add_row [
22
+ vm[:id], vm[:owner][:identities].join("\n"), vm[:group],
23
+ vm[:ips].join("\n"), vm[:host], vm[:state], vm[:owner][:email]
24
+ ]
25
+ end
26
+
27
+ table
28
+ end
29
+
30
+ #
31
+ def as_json(data)
32
+ data ||= []
33
+ data ? JSON.generate(data) : '{}'
34
+ end
35
+ end
36
+
37
+ end
@@ -0,0 +1,69 @@
1
+ require 'logger'
2
+
3
+ class Egi::Fedcloud::Vmhound::Log
4
+ include ::Logger::Severity
5
+
6
+ attr_reader :logger, :log_prefix
7
+
8
+ SUBSCRIPTION_HANDLE = "egi-fedcloud-vmhound.log"
9
+
10
+ # Creates a new logger instance.
11
+ #
12
+ # @param log_dev [IO,String] The log device. This is a filename (String) or IO object (typically +STDOUT+)
13
+ # @param log_prefix [String] String placed in front of every logged message +STDERR+, or an open file).
14
+ def initialize(log_dev, log_prefix = '')
15
+ if log_dev.kind_of? ::Logger
16
+ @logger = log_dev
17
+ else
18
+ @logger = ::Logger.new(log_dev)
19
+ end
20
+
21
+ @log_prefix = log_prefix.blank? ? '' : log_prefix.strip
22
+ @log_prefix << ' ' unless @log_prefix.blank?
23
+
24
+ # subscribe to log messages and send to logger
25
+ @log_subscriber = ActiveSupport::Notifications.subscribe(self.class::SUBSCRIPTION_HANDLE) do |name, start, finish, id, payload|
26
+ @logger.log(payload[:level], "#{@log_prefix}#{payload[:message]}") if @logger
27
+ end
28
+ end
29
+
30
+ def close
31
+ ActiveSupport::Notifications.unsubscribe(@log_subscriber)
32
+ end
33
+
34
+ # @param severity [::Logger::Severity] severity
35
+ def level=(severity)
36
+ @logger.level = severity
37
+ end
38
+
39
+ # @return [::Logger::Severity]
40
+ def level
41
+ @logger.level
42
+ end
43
+
44
+ # @see info
45
+ def self.debug(message)
46
+ ActiveSupport::Notifications.instrument(self::SUBSCRIPTION_HANDLE, :level => ::Logger::DEBUG, :message => message)
47
+ end
48
+
49
+ # Log an +INFO+ message
50
+ # @param message [String] message the message to log; does not need to be a String
51
+ def self.info(message)
52
+ ActiveSupport::Notifications.instrument(self::SUBSCRIPTION_HANDLE, :level => ::Logger::INFO, :message => message)
53
+ end
54
+
55
+ # @see info
56
+ def self.warn(message)
57
+ ActiveSupport::Notifications.instrument(self::SUBSCRIPTION_HANDLE, :level => ::Logger::WARN, :message => message)
58
+ end
59
+
60
+ # @see info
61
+ def self.error(message)
62
+ ActiveSupport::Notifications.instrument(self::SUBSCRIPTION_HANDLE, :level => ::Logger::ERROR, :message => message)
63
+ end
64
+
65
+ # @see info
66
+ def self.fatal(message)
67
+ ActiveSupport::Notifications.instrument(self::SUBSCRIPTION_HANDLE, :level => ::Logger::FATAL, :message => message)
68
+ end
69
+ end
@@ -0,0 +1,11 @@
1
+ require 'settingslogic'
2
+
3
+ #
4
+ class Egi::Fedcloud::Vmhound::Settings < Settingslogic
5
+ GEM_ROOT = File.expand_path '../../../../..', __FILE__
6
+
7
+ source "#{ENV['HOME']}/.egi-fedcloud-vmhound" if File.readable?("#{ENV['HOME']}/.egi-fedcloud-vmhound")
8
+ source "#{GEM_ROOT}/config/settings.yml"
9
+
10
+ namespace ((ENV['DEBUG'] == '1') ? 'development' : 'production')
11
+ end
@@ -0,0 +1,8 @@
1
+ module Egi
2
+ module Fedcloud
3
+ module Vmhound
4
+ # Versioning constant
5
+ VERSION = "0.0.1" unless defined?(::Egi::Fedcloud::Vmhound::VERSION)
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,11 @@
1
+ require 'rubygems'
2
+
3
+ # enable coverage reports
4
+ if ENV['COVERAGE']
5
+ require 'simplecov'
6
+
7
+ SimpleCov.add_filter "/spec/"
8
+ SimpleCov.start
9
+ end
10
+
11
+ require 'egi-fedcloud-vmhound'
metadata ADDED
@@ -0,0 +1,256 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: egi-fedcloud-vmhound
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Boris Parak
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-06-09 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activesupport
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '4.0'
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 4.0.0
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: '4.0'
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 4.0.0
33
+ - !ruby/object:Gem::Dependency
34
+ name: settingslogic
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '2.0'
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ version: 2.0.9
43
+ type: :runtime
44
+ prerelease: false
45
+ version_requirements: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - "~>"
48
+ - !ruby/object:Gem::Version
49
+ version: '2.0'
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: 2.0.9
53
+ - !ruby/object:Gem::Dependency
54
+ name: thor
55
+ requirement: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - "~>"
58
+ - !ruby/object:Gem::Version
59
+ version: '0.19'
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: 0.19.1
63
+ type: :runtime
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - "~>"
68
+ - !ruby/object:Gem::Version
69
+ version: '0.19'
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ version: 0.19.1
73
+ - !ruby/object:Gem::Dependency
74
+ name: opennebula
75
+ requirement: !ruby/object:Gem::Requirement
76
+ requirements:
77
+ - - "~>"
78
+ - !ruby/object:Gem::Version
79
+ version: '4.10'
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: 4.10.2
83
+ type: :runtime
84
+ prerelease: false
85
+ version_requirements: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '4.10'
90
+ - - ">="
91
+ - !ruby/object:Gem::Version
92
+ version: 4.10.2
93
+ - !ruby/object:Gem::Dependency
94
+ name: terminal-table
95
+ requirement: !ruby/object:Gem::Requirement
96
+ requirements:
97
+ - - "~>"
98
+ - !ruby/object:Gem::Version
99
+ version: '1.4'
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ version: 1.4.5
103
+ type: :runtime
104
+ prerelease: false
105
+ version_requirements: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - "~>"
108
+ - !ruby/object:Gem::Version
109
+ version: '1.4'
110
+ - - ">="
111
+ - !ruby/object:Gem::Version
112
+ version: 1.4.5
113
+ - !ruby/object:Gem::Dependency
114
+ name: ox
115
+ requirement: !ruby/object:Gem::Requirement
116
+ requirements:
117
+ - - "~>"
118
+ - !ruby/object:Gem::Version
119
+ version: '2.2'
120
+ - - ">="
121
+ - !ruby/object:Gem::Version
122
+ version: 2.2.0
123
+ type: :runtime
124
+ prerelease: false
125
+ version_requirements: !ruby/object:Gem::Requirement
126
+ requirements:
127
+ - - "~>"
128
+ - !ruby/object:Gem::Version
129
+ version: '2.2'
130
+ - - ">="
131
+ - !ruby/object:Gem::Version
132
+ version: 2.2.0
133
+ - !ruby/object:Gem::Dependency
134
+ name: bundler
135
+ requirement: !ruby/object:Gem::Requirement
136
+ requirements:
137
+ - - "~>"
138
+ - !ruby/object:Gem::Version
139
+ version: '1.6'
140
+ type: :development
141
+ prerelease: false
142
+ version_requirements: !ruby/object:Gem::Requirement
143
+ requirements:
144
+ - - "~>"
145
+ - !ruby/object:Gem::Version
146
+ version: '1.6'
147
+ - !ruby/object:Gem::Dependency
148
+ name: rake
149
+ requirement: !ruby/object:Gem::Requirement
150
+ requirements:
151
+ - - "~>"
152
+ - !ruby/object:Gem::Version
153
+ version: '10.0'
154
+ type: :development
155
+ prerelease: false
156
+ version_requirements: !ruby/object:Gem::Requirement
157
+ requirements:
158
+ - - "~>"
159
+ - !ruby/object:Gem::Version
160
+ version: '10.0'
161
+ - !ruby/object:Gem::Dependency
162
+ name: rspec
163
+ requirement: !ruby/object:Gem::Requirement
164
+ requirements:
165
+ - - "~>"
166
+ - !ruby/object:Gem::Version
167
+ version: 3.0.0
168
+ type: :development
169
+ prerelease: false
170
+ version_requirements: !ruby/object:Gem::Requirement
171
+ requirements:
172
+ - - "~>"
173
+ - !ruby/object:Gem::Version
174
+ version: 3.0.0
175
+ - !ruby/object:Gem::Dependency
176
+ name: simplecov
177
+ requirement: !ruby/object:Gem::Requirement
178
+ requirements:
179
+ - - "~>"
180
+ - !ruby/object:Gem::Version
181
+ version: 0.9.0
182
+ type: :development
183
+ prerelease: false
184
+ version_requirements: !ruby/object:Gem::Requirement
185
+ requirements:
186
+ - - "~>"
187
+ - !ruby/object:Gem::Version
188
+ version: 0.9.0
189
+ - !ruby/object:Gem::Dependency
190
+ name: rubygems-tasks
191
+ requirement: !ruby/object:Gem::Requirement
192
+ requirements:
193
+ - - "~>"
194
+ - !ruby/object:Gem::Version
195
+ version: 0.2.4
196
+ type: :development
197
+ prerelease: false
198
+ version_requirements: !ruby/object:Gem::Requirement
199
+ requirements:
200
+ - - "~>"
201
+ - !ruby/object:Gem::Version
202
+ version: 0.2.4
203
+ description: A proof-of-concept utility for locating VM instances in EGI Federated
204
+ Cloud
205
+ email:
206
+ - parak@cesnet.cz
207
+ executables:
208
+ - egi-fedcloud-vmhound
209
+ extensions: []
210
+ extra_rdoc_files: []
211
+ files:
212
+ - ".gitignore"
213
+ - ".travis.yml"
214
+ - Gemfile
215
+ - LICENSE
216
+ - README.md
217
+ - Rakefile
218
+ - bin/egi-fedcloud-vmhound
219
+ - config/settings.yml
220
+ - egi-fedcloud-vmhound.gemspec
221
+ - lib/egi-fedcloud-vmhound.rb
222
+ - lib/egi/fedcloud/vmhound/connectors.rb
223
+ - lib/egi/fedcloud/vmhound/connectors/base_connector.rb
224
+ - lib/egi/fedcloud/vmhound/connectors/dummy_connector.rb
225
+ - lib/egi/fedcloud/vmhound/connectors/opennebula_connector.rb
226
+ - lib/egi/fedcloud/vmhound/extractor.rb
227
+ - lib/egi/fedcloud/vmhound/formatter.rb
228
+ - lib/egi/fedcloud/vmhound/log.rb
229
+ - lib/egi/fedcloud/vmhound/settings.rb
230
+ - lib/egi/fedcloud/vmhound/version.rb
231
+ - spec/spec_helper.rb
232
+ homepage: https://github.com/arax/egi-fedcloud-vmhound
233
+ licenses:
234
+ - Apache License, Version 2.0
235
+ metadata: {}
236
+ post_install_message:
237
+ rdoc_options: []
238
+ require_paths:
239
+ - lib
240
+ required_ruby_version: !ruby/object:Gem::Requirement
241
+ requirements:
242
+ - - ">="
243
+ - !ruby/object:Gem::Version
244
+ version: 1.9.3
245
+ required_rubygems_version: !ruby/object:Gem::Requirement
246
+ requirements:
247
+ - - ">="
248
+ - !ruby/object:Gem::Version
249
+ version: '0'
250
+ requirements: []
251
+ rubyforge_project:
252
+ rubygems_version: 2.2.2
253
+ signing_key:
254
+ specification_version: 4
255
+ summary: A proof-of-concept utility for locating VM instances in EGI Federated Cloud
256
+ test_files: []