vcloud-core 0.5.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (35) hide show
  1. data/.travis.yml +2 -0
  2. data/CHANGELOG.md +10 -1
  3. data/CONTRIBUTING.md +66 -0
  4. data/README.md +5 -5
  5. data/Rakefile +1 -1
  6. data/lib/vcloud/core/config_validator.rb +20 -20
  7. data/lib/vcloud/core/query_cli.rb +1 -1
  8. data/lib/vcloud/core/version.rb +1 -1
  9. data/lib/vcloud/core/vm.rb +2 -39
  10. data/lib/vcloud/fog/service_interface.rb +10 -5
  11. data/spec/integration/README.md +1 -1
  12. data/spec/integration/core/edge_gateway_spec.rb +133 -0
  13. data/spec/integration/core/query_runner_spec.rb +10 -4
  14. data/spec/integration/core/vapp_spec.rb +249 -0
  15. data/spec/integration/core/vdc_spec.rb +6 -4
  16. data/spec/integration/core/vm_spec.rb +24 -12
  17. data/spec/spec_helper.rb +21 -10
  18. data/spec/support/integration_helper.rb +27 -0
  19. data/spec/vcloud/core/config_loader_spec.rb +10 -10
  20. data/spec/vcloud/core/config_validator_spec.rb +7 -0
  21. data/spec/vcloud/core/edge_gateway_spec.rb +10 -10
  22. data/spec/vcloud/core/metadata_helper_spec.rb +2 -2
  23. data/spec/vcloud/core/org_vdc_network_spec.rb +15 -15
  24. data/spec/vcloud/core/query_runner_spec.rb +13 -13
  25. data/spec/vcloud/core/query_spec.rb +9 -9
  26. data/spec/vcloud/core/vapp_spec.rb +19 -19
  27. data/spec/vcloud/core/vapp_template_spec.rb +9 -9
  28. data/spec/vcloud/core/vdc_spec.rb +6 -6
  29. data/spec/vcloud/core/vm_spec.rb +50 -118
  30. data/spec/vcloud/fog/fog_model_interface_spec.rb +3 -3
  31. data/spec/vcloud/fog/service_interface_spec.rb +9 -9
  32. data/vcloud-core.gemspec +6 -6
  33. metadata +36 -35
  34. data/spec/integration/edge_gateway/configure_edge_gateway_services_spec.rb +0 -55
  35. data/spec/integration/edge_gateway/edge_gateway_spec.rb +0 -45
data/.travis.yml CHANGED
@@ -2,5 +2,7 @@
2
2
  language: ruby
3
3
  rvm:
4
4
  - 1.9.3
5
+ - 2.0.0
6
+ - 2.1.2
5
7
  notifications:
6
8
  email: false
data/CHANGELOG.md CHANGED
@@ -1,10 +1,19 @@
1
+ ## 0.6.0 (2014-07-14)
2
+
3
+ API changes:
4
+
5
+ - The minimum required Ruby version is now 1.9.3.
6
+ - The interface to `Vcloud::Core::Vm#configure_guest_customization_section`
7
+ has changed and much of its logic has moved to the vCloud Launcher gem.
8
+ Thanks to @bazbremner for this contribution.
9
+
1
10
  ## 0.5.0 (2014-05-30)
2
11
 
3
12
  Features:
4
13
 
5
14
  - `vcloud-query --version` now only returns the version string and no
6
15
  usage information.
7
- - Support 'pool' mode for VM IP address allocation.
16
+ - Support 'pool' mode for VM IP address allocation. Thanks @geriBatai.
8
17
 
9
18
  ## 0.4.0 (2014-05-23)
10
19
 
data/CONTRIBUTING.md ADDED
@@ -0,0 +1,66 @@
1
+ # Contributing to vCloud Core
2
+
3
+ We really welcome contributions.
4
+
5
+ ## A quick guide on how to contribute
6
+
7
+ 1. Clone the repo:
8
+
9
+ git clone git@github.com:gds-operations/vcloud-core.git
10
+
11
+ 2. Run `bundle` to get the required dependecies
12
+
13
+ 3. Run the tests. Pull requests that add features must include unit tests,
14
+ so it is good to ensure you've got them passing to begin with.
15
+
16
+ bundle exec rake
17
+
18
+ If you have access to a live environment for testing, it would be great
19
+ if you could run the integration tests too - for more details on the
20
+ set-up for that, please see the [integration tests README]
21
+ (https://github.com/gds-operations/vcloud-core/blob/master/spec/integration/README.md)
22
+
23
+ 4. Add your functionality or bug fix and a test for your change. Only refactoring and
24
+ documentation changes do not require tests. If the functionality is at all complicated
25
+ then it is likely that more than one test will be required. If you would like help
26
+ with writing tests please do ask us.
27
+
28
+ 5. Make sure all the tests pass, including the integration tests if possible.
29
+
30
+ 6. Update the [CHANGELOG](https://github.com/gds-operations/vcloud-core/blob/master/CHANGELOG.md)
31
+ with a short description of what the change is. This may be a feature, a bugfix, or an
32
+ API change. If your change is documenation or refactoring, you do not need to add a line
33
+ to the CHANGELOG.
34
+
35
+ 7. Fork the repo, push to your fork, and submit a pull request.
36
+
37
+ ## How soon will we respond?
38
+
39
+ We will comment on your pull request within two working days. However, we might not be able to review it immediately.
40
+
41
+ We may come back to you with comments and suggestions, and if we would like you to make changes, we will close the pull request as well as adding details of the changes we'd like you to make.
42
+
43
+ If you feel your pull request has been outstanding too long, please feel free to bump it by making a comment on it.
44
+
45
+ ## Guidelines for making a pull request
46
+
47
+ The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD",
48
+ "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be
49
+ interpreted as described in RFC 2119.
50
+
51
+ ## In order for a pull request to be accepted, it MUST
52
+
53
+ - Include at least one test (unless it is documentation or refactoring). If you have any questions about how to write tests, please ask us, we will be happy to help
54
+ - Follow our [Git style guide](https://github.com/alphagov/styleguides/blob/master/git.md)
55
+ - Include a clear summary in the pull request comments as to what the change is and why
56
+ you are making it
57
+ - Be readable - we might ask you to change unclear variable names or obscure syntactic sugar
58
+ - Have [good commit messages](http://robots.thoughtbot.com/5-useful-tips-for-a-better-commit-message)
59
+ that explain the change being made in that commit. Don't be afraid to write a lot in the
60
+ detail.
61
+
62
+ ## In order for a pull request to be accepted, it SHOULD
63
+
64
+ - Include a line in the CHANGELOG unless it is a refactoring or documentation change
65
+ - If it is code, follow our [Ruby style guide](https://github.com/alphagov/styleguides/blob/master/ruby.md)
66
+ - If it is documentation, follow the [GDS content style guide](https://www.gov.uk/design-principles/style-guide/style-points)
data/README.md CHANGED
@@ -1,8 +1,8 @@
1
- # VCloud Core
1
+ # vCloud Core
2
2
 
3
- VCloud Core is a gem that supports automatated provisioning of VMWare vCloud Director. It uses Fog under the hood. Primarily developed to support [VCloud Walker](https://github.com/alphagov/vcloud-walker) and [VCloud Tools](https://github.com/alphagov/vcloud-tools).
3
+ vCloud Core is a gem that supports automatated provisioning of VMWare vCloud Director. It uses Fog under the hood. Primarily developed to support [vCloud Walker](https://github.com/gds-operations/vcloud-walker) and [vCloud Tools](https://github.com/gds-operations/vcloud-tools).
4
4
 
5
- VCloud Core includes VCloud Query and a command-line wrapper for VCloud Query.
5
+ vCloud Core includes vCloud Query and a command-line wrapper for vCloud Query.
6
6
 
7
7
  ## Installation
8
8
 
@@ -56,11 +56,11 @@ credentials that allow it to talk to a vCloud Director environment.
56
56
  password in the fog file. This is **not recommended**.
57
57
 
58
58
 
59
- ## VCloud Query
59
+ ## vCloud Query
60
60
 
61
61
  ### Get results from the vCloud Query API
62
62
 
63
- VCloud Query is a light wrapper around the vCloud Query API.
63
+ vCloud Query is a light wrapper around the vCloud Query API.
64
64
 
65
65
  Any, or all, records of a particular 'type' can be returned. These types map to
66
66
  entities in the vCloud system itself, eg: 'vm', 'vApp', 'orgVdc', 'edgeGateway'.
data/Rakefile CHANGED
@@ -22,6 +22,6 @@ task :publish_gem do
22
22
  end
23
23
 
24
24
  require 'rubocop/rake_task'
25
- Rubocop::RakeTask.new(:rubocop) do |task|
25
+ RuboCop::RakeTask.new(:rubocop) do |task|
26
26
  task.options = ['--lint']
27
27
  end
@@ -1,26 +1,26 @@
1
1
  require 'ipaddr'
2
2
 
3
- ##
4
- # self::validate is entry point; this class method is called to
5
- # instantiate ConfigValidator. For example:
6
- #
7
- # Core::ConfigValidator.validate(key, data, schema)
8
- #
9
- # = Recursion in this class
10
- #
11
- # Note that this class will recursively call itself in order to validate deep
12
- # hash and array structures.
13
- #
14
- # The +data+ variable is usually either an array or hash and so will pass
15
- # through the ConfigValidator#validate_array and
16
- # ConfigValidator#validate_hash methods respectively.
17
- #
18
- # These methods then recursively instantiate this class by calling
19
- # ConfigValidator::validate again (ConfigValidator#validate_hash calls this
20
- # indirectly via the ConfigValidator#check_hash_parameter method).
21
-
22
3
  module Vcloud
23
4
  module Core
5
+ ##
6
+ # self::validate is entry point; this class method is called to
7
+ # instantiate ConfigValidator. For example:
8
+ #
9
+ # Core::ConfigValidator.validate(key, data, schema)
10
+ #
11
+ # = Recursion in this class
12
+ #
13
+ # Note that this class will recursively call itself in order to validate deep
14
+ # hash and array structures.
15
+ #
16
+ # The +data+ variable is usually either an array or hash and so will pass
17
+ # through the ConfigValidator#validate_array and
18
+ # ConfigValidator#validate_hash methods respectively.
19
+ #
20
+ # These methods then recursively instantiate this class by calling
21
+ # ConfigValidator::validate again (ConfigValidator#validate_hash calls this
22
+ # indirectly via the ConfigValidator#check_hash_parameter method).
23
+ #
24
24
  class ConfigValidator
25
25
 
26
26
  attr_reader :key, :data, :schema, :type, :errors, :warnings
@@ -252,7 +252,7 @@ module Vcloud
252
252
 
253
253
  def validate_string
254
254
  unless @data.is_a? String
255
- errors << "#{key}: #{@data} is not a string"
255
+ @errors << "#{key}: #{@data} is not a string"
256
256
  return
257
257
  end
258
258
  return unless check_emptyness_ok
@@ -34,7 +34,7 @@ Query types map to vCloud entities, for example: vApp, vm, orgVdc, orgVdcNetwork
34
34
 
35
35
  Without a type argument, returns a list of available Entity Types to query.
36
36
 
37
- See https://github.com/alphagov/vcloud-tools/blob/master/README.md for more info.
37
+ See https://github.com/gds-operations/vcloud-tools/blob/master/README.md for more info.
38
38
 
39
39
  Example use:
40
40
 
@@ -1,5 +1,5 @@
1
1
  module Vcloud
2
2
  module Core
3
- VERSION = '0.5.0'
3
+ VERSION = '0.6.0'
4
4
  end
5
5
  end
@@ -102,36 +102,10 @@ module Vcloud
102
102
  Vcloud::Fog::ServiceInterface.new.put_network_connection_system_section_vapp(id, section)
103
103
  end
104
104
 
105
- def configure_guest_customization_section(name, bootstrap_config, extra_disks)
106
- if bootstrap_config.nil? or bootstrap_config[:script_path].nil?
107
- interpolated_preamble = ''
108
- else
109
- preamble_vars = bootstrap_config[:vars] || {}
110
- preamble_vars.merge!(:extra_disks => extra_disks)
111
- interpolated_preamble = generate_preamble(
112
- bootstrap_config[:script_path],
113
- bootstrap_config[:script_post_processor],
114
- preamble_vars,
115
- )
116
- end
117
- Vcloud::Fog::ServiceInterface.new.put_guest_customization_section(id, name, interpolated_preamble)
118
- end
119
-
120
- def generate_preamble(script_path, script_post_processor, preamble_vars)
121
- erb_vars = OpenStruct.new({
122
- vapp_name: vapp_name,
123
- vars: preamble_vars
124
- })
125
- erb_vars_binding_object = erb_vars.instance_eval { binding }
126
- erb_output = interpolate_erb_file(script_path, erb_vars_binding_object)
127
- if script_post_processor
128
- post_process_erb_output(erb_output, script_post_processor) if script_post_processor
129
- else
130
- erb_output
131
- end
105
+ def configure_guest_customization_section(preamble)
106
+ Vcloud::Fog::ServiceInterface.new.put_guest_customization_section(id, vapp_name, preamble)
132
107
  end
133
108
 
134
-
135
109
  def update_storage_profile storage_profile
136
110
  storage_profile_href = get_storage_profile_href_by_name(storage_profile, @vapp.name)
137
111
  Vcloud::Fog::ServiceInterface.new.put_vm(id, name, {
@@ -144,17 +118,6 @@ module Vcloud
144
118
 
145
119
  private
146
120
 
147
- def interpolate_erb_file(erb_file, binding_object)
148
- ERB.new(File.read(File.expand_path(erb_file)), nil, '>-').result(binding_object)
149
- end
150
-
151
- def post_process_erb_output(data_to_process, post_processor_script)
152
- # Open3.capture2, as we just need to return STDOUT of the post_processor_script
153
- Open3.capture2(
154
- File.expand_path(post_processor_script),
155
- stdin_data: data_to_process).first
156
- end
157
-
158
121
  def virtual_hardware_section
159
122
  vcloud_attributes[:'ovf:VirtualHardwareSection'][:'ovf:Item']
160
123
  end
@@ -9,7 +9,7 @@ module Vcloud
9
9
  :get_execute_query, :get_vapp_metadata, :power_off_vapp, :shutdown_vapp, :session,
10
10
  :post_instantiate_vapp_template, :put_memory, :put_cpu, :power_on_vapp, :put_vapp_metadata_value,
11
11
  :put_vm, :get_edge_gateway, :get_network_complete, :delete_network, :post_create_org_vdc_network,
12
- :post_configure_edge_gateway_services, :get_vdc
12
+ :post_configure_edge_gateway_services, :get_vdc, :post_undeploy_vapp
13
13
 
14
14
  #########################
15
15
  # FogFacade Inner class to represent a logic free facade over our interactions with Fog
@@ -19,12 +19,12 @@ module Vcloud
19
19
  @vcloud = ::Fog::Compute::VcloudDirector.new
20
20
  end
21
21
 
22
- def get_vdc(name)
23
- @vcloud.get_vdc(name).body
22
+ def get_vdc(id)
23
+ @vcloud.get_vdc(id).body
24
24
  end
25
25
 
26
- def get_organization (name)
27
- @vcloud.get_organization(name).body
26
+ def get_organization (id)
27
+ @vcloud.get_organization(id).body
28
28
  end
29
29
 
30
30
  def session
@@ -99,6 +99,11 @@ module Vcloud
99
99
  @vcloud.org_name
100
100
  end
101
101
 
102
+ def post_undeploy_vapp(vapp_id)
103
+ task = @vcloud.post_undeploy_vapp(vapp_id).body
104
+ @vcloud.process_task(task)
105
+ end
106
+
102
107
  def delete_vapp(vapp_id)
103
108
  task = @vcloud.delete_vapp(vapp_id).body
104
109
  @vcloud.process_task(task)
@@ -15,7 +15,7 @@
15
15
  and update with parameters suitable for your environment.
16
16
 
17
17
  - You need to include the set-up for your testing environment in your
18
- [fog file](https://github.com/alphagov/vcloud-core#credentials).
18
+ [fog file](https://github.com/gds-operations/vcloud-core#credentials).
19
19
 
20
20
  - The tests use the [vCloud Tools Tester](http://rubygems.org/gems/vcloud-tools-tester) gem.
21
21
  You do not need to install this, `bundler` will do this for you.
@@ -0,0 +1,133 @@
1
+ require 'spec_helper'
2
+
3
+ module Vcloud
4
+ module Core
5
+ describe EdgeGateway do
6
+
7
+ before(:all) do
8
+ config_file = File.join(File.dirname(__FILE__), "../vcloud_tools_testing_config.yaml")
9
+ required_user_params = [
10
+ "edge_gateway",
11
+ "edge_gateway_id",
12
+ "network_1",
13
+ "network_1_id",
14
+ "provider_network_id",
15
+ ]
16
+
17
+ @test_params = Vcloud::Tools::Tester::TestSetup.new(config_file, required_user_params).test_params
18
+ end
19
+
20
+ let(:edge_gateway) { EdgeGateway.get_by_name(@test_params.edge_gateway) }
21
+ let(:spurious_id) { "12345678-1234-1234-1234-123456789012" }
22
+
23
+ context "when updating the edge gateway" do
24
+ before(:each) do
25
+ IntegrationHelper.reset_edge_gateway(edge_gateway)
26
+ end
27
+
28
+ it "updates as expected" do
29
+ configuration = {
30
+ :FirewallService =>
31
+ {
32
+ :IsEnabled => "true",
33
+ :FirewallRule => [],
34
+ :DefaultAction => "drop",
35
+ :LogDefaultAction => "false",
36
+ },
37
+ :LoadBalancerService =>
38
+ {
39
+ :IsEnabled => "true",
40
+ :Pool => [],
41
+ :VirtualServer => [],
42
+ },
43
+ :NatService =>
44
+ {
45
+ :IsEnabled => "true",
46
+ :NatRule => [],
47
+ },
48
+ }
49
+
50
+ edge_gateway.update_configuration(configuration)
51
+
52
+ actual_config = edge_gateway.vcloud_attributes[:Configuration][:EdgeGatewayServiceConfiguration]
53
+
54
+ expect(actual_config[:FirewallService]).to eq(configuration[:FirewallService])
55
+ expect(actual_config[:LoadBalancerService]).to eq(configuration[:LoadBalancerService])
56
+ expect(actual_config[:NatService]).to eq(configuration[:NatService])
57
+ end
58
+ end
59
+
60
+ context "get vCloud attributes for given gateway interface ID" do
61
+ it "returns a provider network" do
62
+ network_interface = edge_gateway.vcloud_gateway_interface_by_id(@test_params.provider_network_id)
63
+ expect(network_interface[:Network]).not_to be_nil
64
+ expect(network_interface[:Network][:href]).to include(@test_params.provider_network_id)
65
+ end
66
+
67
+ it "returns an orgVdcNetwork" do
68
+ network_interface = edge_gateway.vcloud_gateway_interface_by_id(@test_params.network_1_id)
69
+ expect(network_interface[:Network]).not_to be_nil
70
+ expect(network_interface[:Network][:href]).to include(@test_params.network_1_id)
71
+ end
72
+
73
+ it "returns nil if network with given ID is not found" do
74
+ network_interface = edge_gateway.vcloud_gateway_interface_by_id(spurious_id)
75
+ expect(network_interface).to be_nil
76
+ end
77
+ end
78
+
79
+ context "when retrieving an edge gateway ID (singular) by name" do
80
+ it "returns the an edge gateway object for that name" do
81
+ # See `let` statement above which calls EdgeGateway::get_by_name
82
+ expect(edge_gateway).to be_a(Vcloud::Core::EdgeGateway)
83
+ expect(edge_gateway.id).to eq(@test_params.edge_gateway_id)
84
+ end
85
+
86
+ it "raise an exception if edge gateway with given ID is not found" do
87
+ name = "this-would-never-exist"
88
+ expect { Vcloud::Core::EdgeGateway.get_by_name(name) }.to raise_error("edgeGateway #{name} not found")
89
+ end
90
+ end
91
+
92
+ context "when retrieving edge gateway IDs (plural) by name" do
93
+ it "returns the correct ID for that name" do
94
+ ids = Vcloud::Core::EdgeGateway.get_ids_by_name(@test_params.edge_gateway)
95
+ expect(ids.first).to eq(@test_params.edge_gateway_id)
96
+ end
97
+
98
+ it "returns an empty array if edge gateway with given ID is not found" do
99
+ name = "this-would-never-exist"
100
+ ids = Vcloud::Core::EdgeGateway.get_ids_by_name(name)
101
+ expect(ids).to eq([])
102
+ end
103
+ end
104
+
105
+ context "when retrieving vCloud attributes" do
106
+ it "returns the correct edge gateway for a given ID" do
107
+ vcloud_attributes = edge_gateway.vcloud_attributes
108
+ expect(vcloud_attributes[:href]).to include(@test_params.edge_gateway_id)
109
+ end
110
+
111
+ it "returns the correct href for a given edge gateway" do
112
+ href = edge_gateway.href
113
+ expect(href).to include(@test_params.edge_gateway_id)
114
+ end
115
+
116
+ it "returns the correct name for a given edge gateway" do
117
+ name = edge_gateway.name
118
+ expect(name).to eq(@test_params.edge_gateway)
119
+ end
120
+ end
121
+
122
+ context "when retrieving a gateway's interfaces" do
123
+ it "returns an array of interface objects" do
124
+ interfaces = edge_gateway.interfaces
125
+ network_1_interface = interfaces.detect { |i| i.name == @test_params.network_1 }
126
+
127
+ expect(interfaces.first).to be_a(Vcloud::Core::EdgeGatewayInterface)
128
+ expect(network_1_interface.name).to eq(@test_params.network_1)
129
+ end
130
+ end
131
+ end
132
+ end
133
+ end
@@ -6,10 +6,16 @@ module Vcloud
6
6
 
7
7
  before(:all) do
8
8
  config_file = File.join(File.dirname(__FILE__), "../vcloud_tools_testing_config.yaml")
9
- test_data = Vcloud::Tools::Tester::TestParameters.new(config_file)
10
- @vapp_template_name = test_data.vapp_template
11
- @vapp_template_catalog_name = test_data.catalog
12
- @vdc_name = test_data.vdc_1_name
9
+ required_user_params = [
10
+ "catalog",
11
+ "vapp_template",
12
+ "vdc_1_name",
13
+ ]
14
+
15
+ test_params = Vcloud::Tools::Tester::TestSetup.new(config_file, required_user_params).test_params
16
+ @vapp_template_name = test_params.vapp_template
17
+ @vapp_template_catalog_name = test_params.catalog
18
+ @vdc_name = test_params.vdc_1_name
13
19
  end
14
20
 
15
21
  context "#available_query_types" do