vcloud 0.0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. data/.gitignore +5 -0
  2. data/Gemfile +14 -0
  3. data/Gemfile.lock +39 -0
  4. data/LICENSE +7 -0
  5. data/README.md +53 -0
  6. data/Rakefile +8 -0
  7. data/examples/hello_vcloud.rb +183 -0
  8. data/lib/vcloud.rb +16 -0
  9. data/lib/vcloud/base_vcloud_entity.rb +59 -0
  10. data/lib/vcloud/client.rb +117 -0
  11. data/lib/vcloud/constants.rb +38 -0
  12. data/lib/vcloud/errors.rb +31 -0
  13. data/lib/vcloud/parses_xml.rb +33 -0
  14. data/lib/vcloud/rest_api.rb +91 -0
  15. data/lib/vcloud/user.rb +5 -0
  16. data/lib/vcloud/user/catalog.rb +32 -0
  17. data/lib/vcloud/user/catalog_item.rb +10 -0
  18. data/lib/vcloud/user/error.rb +12 -0
  19. data/lib/vcloud/user/instantiate_vapp_template_params.rb +36 -0
  20. data/lib/vcloud/user/link.rb +30 -0
  21. data/lib/vcloud/user/network_config.rb +20 -0
  22. data/lib/vcloud/user/network_config_section.rb +20 -0
  23. data/lib/vcloud/user/org.rb +69 -0
  24. data/lib/vcloud/user/org_list.rb +10 -0
  25. data/lib/vcloud/user/reference.rb +27 -0
  26. data/lib/vcloud/user/task.rb +54 -0
  27. data/lib/vcloud/user/vapp.rb +103 -0
  28. data/lib/vcloud/user/vdc.rb +32 -0
  29. data/lib/version.rb +3 -0
  30. data/spec/catalog_item_spec.rb +35 -0
  31. data/spec/catalog_spec.rb +62 -0
  32. data/spec/client_spec.rb +87 -0
  33. data/spec/fixtures/catalog.xml +8 -0
  34. data/spec/fixtures/catalog_item.xml +6 -0
  35. data/spec/fixtures/error_login_404.html +24 -0
  36. data/spec/fixtures/instantiate_vapp_template_params.xml +11 -0
  37. data/spec/fixtures/network_config.xml +6 -0
  38. data/spec/fixtures/network_config_section.xml +6 -0
  39. data/spec/fixtures/org.xml +11 -0
  40. data/spec/fixtures/org_list.xml +4 -0
  41. data/spec/fixtures/session.xml +7 -0
  42. data/spec/fixtures/task.xml +6 -0
  43. data/spec/fixtures/vapp.xml +31 -0
  44. data/spec/fixtures/vapp_template.xml +74 -0
  45. data/spec/fixtures/vdc.xml +55 -0
  46. data/spec/instantiate_vapp_template_params_spec.rb +60 -0
  47. data/spec/network_config_section_spec.rb +42 -0
  48. data/spec/network_config_spec.rb +31 -0
  49. data/spec/org_spec.rb +99 -0
  50. data/spec/rest_api_spec.rb +48 -0
  51. data/spec/spec_helper.rb +20 -0
  52. data/spec/task_spec.rb +74 -0
  53. data/spec/vapp_spec.rb +85 -0
  54. data/spec/vdc_spec.rb +83 -0
  55. data/vcloud.gemspec +19 -0
  56. metadata +173 -0
@@ -0,0 +1,5 @@
1
+ pkg
2
+ ignore_test
3
+ vendor
4
+ doc
5
+ .yardoc
data/Gemfile ADDED
@@ -0,0 +1,14 @@
1
+ source "http://rubygems.org"
2
+
3
+ gem 'rest-client', '1.6.7'
4
+ gem 'nokogiri-happymapper', '0.5.5'
5
+
6
+ gem 'rake', '0.9.2.2', :group => [:development, :test]
7
+
8
+ group :test do
9
+ gem 'rspec', '2.11.0'
10
+ gem 'rspec-mocks', '2.11.3'
11
+ gem 'webmock', '1.8.10'
12
+ gem 'yard', '0.8.2.1'
13
+ gem 'redcarpet', '2.1.1'
14
+ end
@@ -0,0 +1,39 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ addressable (2.3.2)
5
+ crack (0.3.1)
6
+ diff-lcs (1.1.3)
7
+ mime-types (1.19)
8
+ nokogiri (1.5.5)
9
+ nokogiri-happymapper (0.5.5)
10
+ nokogiri (~> 1.4)
11
+ rake (0.9.2.2)
12
+ redcarpet (2.1.1)
13
+ rest-client (1.6.7)
14
+ mime-types (>= 1.16)
15
+ rspec (2.11.0)
16
+ rspec-core (~> 2.11.0)
17
+ rspec-expectations (~> 2.11.0)
18
+ rspec-mocks (~> 2.11.0)
19
+ rspec-core (2.11.1)
20
+ rspec-expectations (2.11.3)
21
+ diff-lcs (~> 1.1.3)
22
+ rspec-mocks (2.11.3)
23
+ webmock (1.8.10)
24
+ addressable (>= 2.2.7)
25
+ crack (>= 0.1.7)
26
+ yard (0.8.2.1)
27
+
28
+ PLATFORMS
29
+ ruby
30
+
31
+ DEPENDENCIES
32
+ nokogiri-happymapper (= 0.5.5)
33
+ rake (= 0.9.2.2)
34
+ redcarpet (= 2.1.1)
35
+ rest-client (= 1.6.7)
36
+ rspec (= 2.11.0)
37
+ rspec-mocks (= 2.11.3)
38
+ webmock (= 1.8.10)
39
+ yard (= 0.8.2.1)
data/LICENSE ADDED
@@ -0,0 +1,7 @@
1
+ Copyright © 2012 Diebold, Inc. (http://www.diebold.com/)
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
+
5
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6
+
7
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,53 @@
1
+ vcloud-ruby
2
+ ===========
3
+
4
+ DESCRIPTION
5
+ -----------
6
+
7
+ Ruby bindings to the VMware vCloud Director REST API
8
+
9
+ This is a work in progress, but it currently supports enough functionality to perform the entire Hello vCloud example in the [vCloud API Guide](http://www.vmware.com/pdf/vcd_15_api_guide.pdf).
10
+
11
+
12
+ INSTALL
13
+ -------
14
+
15
+ <pre>gem install vcloud-ruby</pre>
16
+
17
+
18
+ USAGE
19
+ -----
20
+
21
+ The examples/hello_vcloud.rb file demonstrates basic usage of the gem, for example...
22
+
23
+ ```
24
+ require 'vcloud'
25
+ @session = VCloud::Client.new("https://my.vcloud.local/api/"), '1.5')
26
+ @session.login('someuser@someorg', 'secretp@ssw0rd)
27
+ @org = @session.get_org_from_name('myorg')
28
+ @catalog = @org.get_catalog_from_name('TestCatalog')
29
+ @vdc = @org.get_vdc_from_name('TestVDC')
30
+ @catalog_item = @catalog.get_catalog_item_from_name('TestLinuxTemplate')
31
+ ```
32
+
33
+ ...and so on
34
+
35
+ CONTRIBUTE
36
+ ----------
37
+ * Fork the project
38
+ * Make your feature addition or bug fix.
39
+ * Add tests
40
+ * Commit, do not modify with rakefile or version, we'll handle this
41
+ * Send a pull request
42
+
43
+ LICENSE
44
+ -------
45
+ (The MIT License)
46
+
47
+ Copyright © 2012 Diebold, Inc. [http://www.diebold.com](http://www.diebold.com)
48
+
49
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
50
+
51
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
52
+
53
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
3
+ require "rspec/core/rake_task"
4
+
5
+ RSpec::Core::RakeTask.new(:spec) do |spec|
6
+ spec.pattern = 'spec/*_spec.rb'
7
+ spec.rspec_opts = ['--backtrace', '--format documentation']
8
+ end
@@ -0,0 +1,183 @@
1
+ $:.unshift File.join( File.dirname( __FILE__ ), '..', 'lib')
2
+ require 'vcloud'
3
+
4
+ # Check for command line arguments
5
+ if ARGV.length != 7
6
+ puts "hello_vcloud.rb vCloudURL user@vcloud-organization password orgName vdcName ovfFileLocation catalogName"
7
+ exit
8
+ else
9
+ @url = ARGV[0]
10
+ @username = ARGV[1]
11
+ @password = ARGV[2]
12
+ @org_name = ARGV[3]
13
+ @vdc_name = ARGV[4]
14
+ @catalog_item_name = ARGV[5]
15
+ @catalog_name = ARGV[6]
16
+ end
17
+
18
+ begin
19
+ puts "###############################################"
20
+ puts "1. Log in and retrieve Org"
21
+ puts "###############################################"
22
+ puts
23
+
24
+ @session = VCloud::Client.new(@url, '1.5', :verify_ssl => false)
25
+ @session.login(@username, @password)
26
+
27
+ puts 'Available orgs'
28
+ puts '--------------'
29
+ @session.get_org_references.each do |org_ref|
30
+ puts org_ref.name
31
+ end
32
+
33
+ @org = @session.get_org_from_name(@org_name)
34
+ ## ---
35
+ ## or get the org from a reference
36
+ ## ---
37
+ # org_ref_hash = @session.get_org_references_by_name
38
+ # org_ref = org_ref_hash[@org_name]
39
+ # @org = VCloud::Org.from_reference(org_ref, @session)
40
+
41
+ puts
42
+ puts "Selected org: #{@org.name}"
43
+
44
+ puts
45
+ puts "###############################################"
46
+ puts "2. Find a Catalog and a vDC"
47
+ puts "###############################################"
48
+ puts
49
+
50
+ @catalog = @org.get_catalog_from_name(@catalog_name)
51
+ @vdc = @org.get_vdc_from_name(@vdc_name)
52
+ ## ---
53
+ ## or get the catalog and vdc from a link
54
+ ## ---
55
+ # catalog_link_hash = @org.get_catalog_links_by_name
56
+ # catalog_link = catalog_link_hash[@catalog_name]
57
+ # @catalog = VCloud::Catalog.from_reference(catalog_link, @session)
58
+ #
59
+ # vdc_link_hash = @org.get_vdc_links_by_name
60
+ # vdc_link = vdc_link_hash[@vdc_name]
61
+ # @vdc = VCloud::Vdc.from_reference(vdc_link, @session)
62
+
63
+ puts "Selected catalog: #{@catalog.name}"
64
+ puts "Selected vdc: #{@vdc.name}"
65
+
66
+ puts
67
+ puts "###############################################"
68
+ puts "4. Retrieve a Catalog Item"
69
+ puts "###############################################"
70
+ puts
71
+
72
+ @catalog_item = @catalog.get_catalog_item_from_name(@catalog_item_name)
73
+ ## ---
74
+ ## or get the catalog_item from a reference
75
+ ## ---
76
+ # catalog_item_ref_hash = @catalog.get_catalog_item_references_by_name
77
+ # catalog_item_ref = catalog_item_ref_hash[@catalog_item_name]
78
+ # @catalog_item = VCloud::CatalogItem.from_reference(catalog_item_ref, @session)
79
+
80
+ @vapp_ref = @catalog_item.entity_reference
81
+
82
+ puts "Selected catalog item: #{@catalog_item.name}"
83
+
84
+ puts
85
+ puts "###############################################"
86
+ puts "5. Retrieve Deployment Information From the vDC"
87
+ puts "###############################################"
88
+ puts
89
+
90
+ @network_ref = @vdc.network_references.first
91
+
92
+ puts "Selected network: #{@network_ref.name}"
93
+
94
+ puts
95
+ puts "###############################################"
96
+ puts "6. Deploy the vApp"
97
+ puts "###############################################"
98
+ puts
99
+
100
+ net_config = VCloud::NetworkConfig.new
101
+ net_config.network_name = @network_ref.name
102
+ net_config.parent_network_reference = @network_ref
103
+ net_config.fence_mode = VCloud::NetworkConfig::FenceMode::BRIDGED
104
+
105
+ @vapp_template = VCloud::InstantiateVAppTemplateParams.new
106
+ @vapp_template.name = "HelloVCloud-VappTemplate"
107
+ @vapp_template.description = "HelloVCloud-VappTemplate description"
108
+ @vapp_template.power_on = false
109
+ @vapp_template.deploy = false
110
+ @vapp_template.network_config_section = VCloud::NetworkConfigSection.new
111
+ @vapp_template.network_config_section.network_configs << net_config
112
+ @vapp_template.source_reference = @vapp_ref
113
+
114
+ @vapp = @vdc.instantiate_vapp_template(@vapp_template)
115
+
116
+ print "Deploying vapp #{@vapp.name}...."
117
+ if @vapp.tasks.count > 0
118
+ @vapp.tasks.first.wait_to_finish { @vapp.refresh }
119
+ end
120
+ puts "Deployed."
121
+
122
+ puts
123
+ puts "###############################################"
124
+ puts "7. Operate the vApp"
125
+ puts "###############################################"
126
+ puts
127
+
128
+ print "Powering on vapp #{@vapp.name}..."
129
+ @vapp.power_on.wait_to_finish { @vapp.refresh }
130
+ puts 'Powered on.'
131
+
132
+ print "Suspending vapp #{@vapp.name}..."
133
+ @vapp.undeploy(VCloud::VApp::UndeployPowerAction::SUSPEND).wait_to_finish { @vapp.refresh }
134
+ puts "Suspended."
135
+
136
+ print "Powering on vapp #{@vapp.name}..."
137
+ @vapp.power_on.wait_to_finish { @vapp.refresh }
138
+ puts 'Powered on.'
139
+
140
+ puts
141
+ puts "###############################################"
142
+ puts "8. Displaying the Virtual Machine Console"
143
+ puts "###############################################"
144
+ puts
145
+
146
+ puts
147
+ puts "###############################################"
148
+ puts "9. Delete the vApp"
149
+ puts "###############################################"
150
+ puts
151
+
152
+ print "Powering off vapp #{@vapp.name}..."
153
+ @vapp.undeploy(VCloud::VApp::UndeployPowerAction::POWER_OFF).wait_to_finish { @vapp.refresh }
154
+ puts 'Undeployed.'
155
+
156
+ print "Removing vapp #{@vapp.name}..."
157
+ @vapp.remove.wait_to_finish
158
+ puts 'Removed.'
159
+
160
+ puts
161
+ puts "###############################################"
162
+ puts "10. Log Out"
163
+ puts "###############################################"
164
+
165
+ @session.logout
166
+
167
+ rescue Timeout::Error => err
168
+ puts
169
+ puts "#{err.class} occurred."
170
+ puts err.message
171
+ rescue VCloud::VCloudError => err
172
+ puts
173
+ puts "#{err.class} occurred."
174
+ puts err.message
175
+ rescue SocketError => err
176
+ puts
177
+ puts "#{err.class} occurred."
178
+ puts err.message
179
+ rescue Exception => err
180
+ puts
181
+ puts "#{err.class} occurred."
182
+ puts err.message
183
+ end
@@ -0,0 +1,16 @@
1
+ # Require files in lib/vcloud
2
+
3
+ module VCloud
4
+ require 'restclient'
5
+ require 'happymapper'
6
+ require 'set'
7
+
8
+ require 'vcloud/errors'
9
+ require 'vcloud/constants'
10
+ require 'vcloud/parses_xml'
11
+ require 'vcloud/rest_api'
12
+ require 'vcloud/base_vcloud_entity'
13
+
14
+ require 'vcloud/user'
15
+ require 'vcloud/client'
16
+ end
@@ -0,0 +1,59 @@
1
+ module VCloud
2
+ # Base class for all vCloud entities (Org, CatalogItem, vApp, etc.)
3
+ class BaseVCloudEntity
4
+ include RestApi
5
+
6
+ def self.inherited(base)
7
+ base.class_variable_set(:@@initialize_args, Set.new)
8
+ base.send(:include, ParsesXml)
9
+ base.class_eval { attr_accessor :session }
10
+ end
11
+
12
+ def initialize(params = {})
13
+ initialize_args.each do |arg|
14
+ self.instance_variable_set("@#{arg}".to_sym, params[arg])
15
+ end
16
+ @type = self.type
17
+ end
18
+
19
+ def self.type
20
+ self.class_variable_get(:@@content_type)
21
+ end
22
+
23
+ # Retrieve an entity from a VCloud::Reference
24
+ #
25
+ # @param [VCloud::Reference] ref Reference to retrieve the entity with
26
+ # @param [VCloud::Client] session Session to authenticate with when retrieving the entity
27
+ # @param [VCloud::BaseVCloudEntity] Entity from vCloud Director
28
+ def self.from_reference(ref, session)
29
+ obj = new(:href => ref.href, :session => session)
30
+ obj.refresh
31
+ obj
32
+ end
33
+
34
+ def self.attr_reader *args
35
+ super *args
36
+ args.each { |arg| self.class_variable_get(:@@initialize_args) << arg }
37
+ end
38
+
39
+ def self.attr_writer *args
40
+ super *args
41
+ args.each { |arg| self.class_variable_get(:@@initialize_args) << arg }
42
+ end
43
+
44
+ def self.attr_accessor *args
45
+ super *args
46
+ args.each { |arg| self.class_variable_get(:@@initialize_args) << arg }
47
+ end
48
+
49
+ private
50
+
51
+ def self.has_type(type)
52
+ self.class_variable_set(:@@content_type, type)
53
+ end
54
+
55
+ def initialize_args
56
+ self.class.class_variable_get(:@@initialize_args)
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,117 @@
1
+ module VCloud
2
+
3
+ # Handles creating and managing a session in vCloud Director.
4
+ class Client < BaseVCloudEntity
5
+
6
+ tag 'Session'
7
+ has_links
8
+ attribute :type, String
9
+ attribute :href, String
10
+ attribute :user, String
11
+ attribute :org, String
12
+
13
+ LOGIN = 'login'
14
+ SESSION = 'sessions'
15
+ LOGOUT_SESSION = 'session'
16
+ LOGOUT_HTTP_RESPONSE = 204
17
+ TOKEN = 'x_vcloud_authorization'.to_sym
18
+
19
+ attr_reader :api_version, :url, :token
20
+ attr_accessor :verify_ssl
21
+
22
+ # Create a new client
23
+ #
24
+ # @param [String] url API endpoint URL
25
+ # @param [VCloud::Constants::Version] api_version API version
26
+ def initialize(url, api_version, opts={})
27
+ @links=[]
28
+ @url = url.strip
29
+ @api_version = api_version
30
+ @token = {}
31
+ @logged_in = false
32
+
33
+ @verify_ssl = opts[:verify_ssl].nil? ? true : opts[:verify_ssl]
34
+ end
35
+
36
+ # Create a new session and retrieves the session token
37
+ #
38
+ # @param [String] username Username to log in with
39
+ # @param [String] password Password to log in with
40
+ # @return [Boolean] True if a session token has been generated
41
+ def login(username, password)
42
+ return true if @logged_in
43
+
44
+ url = @api_version > VCloud::Constants::Version::V0_9 ? @url + SESSION : @url + LOGIN
45
+
46
+ response = post(url, nil, nil, self, :user => username, :password => password)
47
+ parse_xml(response)
48
+
49
+ @token = { TOKEN => response.headers[TOKEN] }
50
+ @logged_in = true
51
+
52
+ return true
53
+ end
54
+
55
+ # Returns a hash of of all Org refs keyed by the Org name
56
+ #
57
+ # @return [Hash{String => VCloud::Reference}] Reference to all Orgs the user has access to, keyed by Org name
58
+ def get_org_references_by_name()
59
+ Hash[get_org_references.collect{ |i| [i.name, i] }]
60
+ end
61
+
62
+ # Returns an OrgList that contains all of the Orgs the user has access to
63
+ #
64
+ # @return [VCloud::OrgList] OrgList that contains all of the Orgs the user has access to
65
+ def get_org_references()
66
+ OrgList.from_reference(get_orglist_link, self).org_references
67
+ end
68
+
69
+ # Retrieves an Org, assuming the user has access to it
70
+ #
71
+ # @param [String] name Org name
72
+ # @return [VCloud::Org] Org object
73
+ def get_org_from_name(name)
74
+ orgs = get_org_references_by_name
75
+ ref = orgs[name] or return nil
76
+ org = Org.from_reference(ref, self)
77
+ return org
78
+ end
79
+
80
+ # Returns the Link object to retrieve an OrgList
81
+ #
82
+ # @return [VCloud::Link] Link for the OrgList
83
+ def get_orglist_link
84
+ @orglist ||= @links.select {|l| l.type == VCloud::Constants::ContentType::ORG_LIST}.first
85
+ end
86
+
87
+ # Determins if the user is logged in
88
+ #
89
+ # @return [Boolean] True if the user is logged in, otherwise false
90
+ def logged_in?
91
+ @logged_in
92
+ end
93
+
94
+ # Destroy the current session
95
+ #
96
+ # @return [Boolean] True if the session was destroyed, false if it could not be destroyed or a session does not exist
97
+ def logout
98
+ return false if not logged_in?
99
+
100
+ url = @api_version > VCloud::Constants::Version::V0_9 ? @url + LOGOUT_SESSION : @url + LOGIN
101
+
102
+ begin
103
+ delete(url, nil, nil, self)
104
+ rescue => error
105
+ if error.instance_of? VCloud::VCloudError
106
+ raise error
107
+ else
108
+ return false
109
+ end
110
+ end
111
+
112
+ @token = nil
113
+ @logged_in = false
114
+ return true
115
+ end
116
+ end
117
+ end