opennebula 5.12.13 → 5.13.80.pre
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/lib/ActionManager.rb +1 -1
- data/lib/CommandManager.rb +1 -1
- data/lib/DriverExecHelper.rb +44 -28
- data/lib/OpenNebulaDriver.rb +8 -4
- data/lib/VirtualMachineDriver.rb +9 -2
- data/lib/cloud/CloudClient.rb +3 -3
- data/lib/datacenter.rb +1258 -0
- data/lib/datastore.rb +1025 -0
- data/lib/distributed_firewall.rb +280 -0
- data/lib/file_helper.rb +370 -0
- data/lib/host.rb +1517 -0
- data/lib/logical_port.rb +50 -0
- data/lib/logical_switch.rb +77 -0
- data/lib/memoize.rb +74 -0
- data/lib/models/role.rb +39 -8
- data/lib/models/service.rb +92 -31
- data/lib/models.rb +5 -5
- data/lib/network.rb +635 -0
- data/lib/nsx_client.rb +144 -0
- data/lib/nsx_component.rb +28 -0
- data/lib/nsx_constants.rb +149 -0
- data/lib/nsx_driver.rb +78 -0
- data/lib/nsx_error.rb +77 -0
- data/lib/nsx_rule.rb +193 -0
- data/lib/nsxt_client.rb +176 -0
- data/lib/nsxt_dfw.rb +196 -0
- data/lib/nsxt_logical_port.rb +94 -0
- data/lib/nsxt_rule.rb +188 -0
- data/lib/nsxt_tz.rb +38 -0
- data/lib/nsxv_client.rb +176 -0
- data/lib/nsxv_dfw.rb +202 -0
- data/lib/nsxv_logical_port.rb +107 -0
- data/lib/nsxv_rule.rb +172 -0
- data/lib/nsxv_tz.rb +41 -0
- data/lib/opaque_network.rb +134 -0
- data/lib/opennebula/acl.rb +1 -1
- data/lib/opennebula/acl_pool.rb +1 -1
- data/lib/opennebula/client.rb +1 -1
- data/lib/opennebula/cluster.rb +1 -1
- data/lib/opennebula/cluster_pool.rb +1 -1
- data/lib/opennebula/datastore.rb +1 -1
- data/lib/opennebula/datastore_pool.rb +1 -1
- data/lib/opennebula/document.rb +8 -29
- data/lib/opennebula/document_json.rb +42 -12
- data/lib/opennebula/document_pool.rb +1 -1
- data/lib/opennebula/document_pool_json.rb +1 -1
- data/lib/opennebula/error.rb +4 -1
- data/lib/opennebula/flow/grammar.rb +1195 -0
- data/lib/{models → opennebula/flow}/service_pool.rb +26 -2
- data/lib/{models → opennebula/flow}/service_template.rb +86 -17
- data/lib/opennebula/flow/service_template_ext.rb +84 -0
- data/lib/{models → opennebula/flow}/service_template_pool.rb +1 -1
- data/lib/opennebula/flow/validator.rb +499 -0
- data/lib/opennebula/flow.rb +23 -0
- data/lib/opennebula/group.rb +1 -1
- data/lib/opennebula/group_pool.rb +1 -1
- data/lib/opennebula/hook.rb +5 -12
- data/lib/opennebula/hook_log.rb +1 -1
- data/lib/opennebula/hook_pool.rb +1 -1
- data/lib/opennebula/host.rb +1 -1
- data/lib/opennebula/host_pool.rb +1 -1
- data/lib/opennebula/image.rb +17 -14
- data/lib/opennebula/image_pool.rb +1 -1
- data/lib/opennebula/ldap_auth.rb +1 -1
- data/lib/opennebula/ldap_auth_spec.rb +1 -1
- data/lib/opennebula/lockable_ext.rb +163 -0
- data/lib/opennebula/marketplace.rb +1 -1
- data/lib/opennebula/marketplace_pool.rb +1 -1
- data/lib/opennebula/marketplaceapp.rb +9 -119
- data/lib/opennebula/marketplaceapp_ext.rb +522 -0
- data/lib/opennebula/marketplaceapp_pool.rb +1 -1
- data/lib/opennebula/oneflow_client.rb +4 -3
- data/lib/opennebula/pool.rb +4 -3
- data/lib/opennebula/pool_element.rb +1 -1
- data/lib/opennebula/security_group.rb +1 -1
- data/lib/opennebula/security_group_pool.rb +1 -1
- data/lib/opennebula/server_cipher_auth.rb +1 -1
- data/lib/opennebula/server_x509_auth.rb +1 -1
- data/lib/opennebula/ssh_auth.rb +1 -1
- data/lib/opennebula/system.rb +1 -1
- data/lib/opennebula/template.rb +4 -13
- data/lib/opennebula/template_ext.rb +325 -0
- data/lib/opennebula/template_pool.rb +1 -1
- data/lib/opennebula/user.rb +26 -2
- data/lib/opennebula/user_pool.rb +1 -1
- data/lib/opennebula/utils.rb +1 -1
- data/lib/opennebula/vdc.rb +1 -1
- data/lib/opennebula/vdc_pool.rb +1 -1
- data/lib/opennebula/virtual_machine.rb +25 -207
- data/lib/opennebula/virtual_machine_ext.rb +469 -0
- data/lib/opennebula/virtual_machine_pool.rb +1 -5
- data/lib/opennebula/virtual_network.rb +4 -10
- data/lib/opennebula/virtual_network_pool.rb +1 -1
- data/lib/opennebula/virtual_router.rb +4 -12
- data/lib/opennebula/virtual_router_pool.rb +1 -1
- data/lib/opennebula/vm_group.rb +4 -11
- data/lib/opennebula/vm_group_pool.rb +1 -1
- data/lib/opennebula/vntemplate.rb +4 -13
- data/lib/opennebula/vntemplate_pool.rb +1 -1
- data/lib/opennebula/wait_ext.rb +222 -0
- data/lib/opennebula/x509_auth.rb +1 -1
- data/lib/opennebula/xml_element.rb +1 -1
- data/lib/opennebula/xml_pool.rb +1 -1
- data/lib/opennebula/xml_utils.rb +1 -1
- data/lib/opennebula/zone.rb +1 -1
- data/lib/opennebula/zone_pool.rb +1 -1
- data/lib/opennebula.rb +5 -2
- data/lib/rest_client.rb +201 -0
- data/lib/scripts_common.rb +180 -0
- data/lib/transport_zone.rb +43 -0
- data/lib/vcenter_driver.rb +9 -22
- data/lib/vcenter_importer.rb +616 -0
- data/lib/vi_client.rb +281 -0
- data/lib/vi_helper.rb +312 -0
- data/lib/virtual_machine.rb +3477 -0
- data/lib/virtual_wire.rb +158 -0
- data/lib/vm_device.rb +80 -0
- data/lib/vm_disk.rb +202 -0
- data/lib/vm_folder.rb +69 -0
- data/lib/vm_helper.rb +30 -0
- data/lib/vm_monitor.rb +303 -0
- data/lib/vm_nic.rb +70 -0
- data/lib/vm_template.rb +1961 -0
- data/lib/vmm_importer.rb +121 -0
- metadata +101 -35
data/lib/nsxv_client.rb
ADDED
@@ -0,0 +1,176 @@
|
|
1
|
+
# -------------------------------------------------------------------------- #
|
2
|
+
# Copyright 2002-2021, OpenNebula Project, OpenNebula Systems #
|
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
|
+
module NSXDriver
|
17
|
+
|
18
|
+
ONE_LOCATION = ENV['ONE_LOCATION'] unless defined?(ONE_LOCATION)
|
19
|
+
|
20
|
+
if !ONE_LOCATION
|
21
|
+
RUBY_LIB_LOCATION = '/usr/lib/one/ruby' \
|
22
|
+
unless defined?(RUBY_LIB_LOCATION)
|
23
|
+
GEMS_LOCATION = '/usr/share/one/gems' \
|
24
|
+
unless defined?(GEMS_LOCATION)
|
25
|
+
else
|
26
|
+
RUBY_LIB_LOCATION = ONE_LOCATION + '/lib/ruby' \
|
27
|
+
unless defined?(RUBY_LIB_LOCATION)
|
28
|
+
GEMS_LOCATION = ONE_LOCATION + '/share/gems' \
|
29
|
+
unless defined?(GEMS_LOCATION)
|
30
|
+
end
|
31
|
+
|
32
|
+
if File.directory?(GEMS_LOCATION)
|
33
|
+
real_gems_path = File.realpath(GEMS_LOCATION)
|
34
|
+
if !defined?(Gem) || Gem.path != [real_gems_path]
|
35
|
+
$LOAD_PATH.reject! {|l| l =~ /vendor_ruby/ }
|
36
|
+
require 'rubygems'
|
37
|
+
Gem.use_paths(real_gems_path)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
$LOAD_PATH << RUBY_LIB_LOCATION
|
42
|
+
|
43
|
+
# Class NSXVClient
|
44
|
+
class NSXVClient < NSXClient
|
45
|
+
|
46
|
+
# ATTIBUTES
|
47
|
+
attr_accessor :nsxmgr
|
48
|
+
attr_accessor :nsx_user
|
49
|
+
attr_accessor :nsx_password
|
50
|
+
attr_accessor :nsx_type
|
51
|
+
|
52
|
+
# CONSTRUCTORS
|
53
|
+
def initialize(nsxmgr, nsx_user, nsx_password)
|
54
|
+
super(nsxmgr, nsx_user, nsx_password)
|
55
|
+
@nsx_type = NSXConstants::NSXV
|
56
|
+
end
|
57
|
+
|
58
|
+
# Prepare headers
|
59
|
+
def add_headers(aditional_headers = [])
|
60
|
+
headers = NSXConstants::HEADER_XML.clone
|
61
|
+
unless aditional_headers.empty?
|
62
|
+
aditional_headers.each do |header|
|
63
|
+
headers[header.keys[0]] = header.values[0]
|
64
|
+
end
|
65
|
+
end
|
66
|
+
headers
|
67
|
+
end
|
68
|
+
|
69
|
+
# METHODS
|
70
|
+
def get(url, aditional_headers = [], valid_codes = [])
|
71
|
+
if valid_codes.empty?
|
72
|
+
valid_codes = [NSXConstants::CODE_OK,
|
73
|
+
NSXConstants::CODE_NO_CONTENT]
|
74
|
+
end
|
75
|
+
uri = URI.parse(@nsxmgr + url)
|
76
|
+
headers = add_headers(aditional_headers)
|
77
|
+
request = Net::HTTP::Get.new(uri.request_uri, headers)
|
78
|
+
request.basic_auth(@nsx_user, @nsx_password)
|
79
|
+
response = Net::HTTP.start(uri.host, uri.port, :use_ssl => true,
|
80
|
+
:verify_mode => OpenSSL::SSL::VERIFY_NONE) do |https|
|
81
|
+
https.request(request)
|
82
|
+
end
|
83
|
+
response = check_response(response, valid_codes)
|
84
|
+
Nokogiri::XML response.body
|
85
|
+
end
|
86
|
+
|
87
|
+
def get_full_response(url, aditional_headers = [], valid_codes = [])
|
88
|
+
if valid_codes.empty?
|
89
|
+
valid_codes = [NSXConstants::CODE_OK,
|
90
|
+
NSXConstants::CODE_NO_CONTENT]
|
91
|
+
end
|
92
|
+
uri = URI.parse(@nsxmgr + url)
|
93
|
+
headers = add_headers(aditional_headers)
|
94
|
+
request = Net::HTTP::Get.new(uri.request_uri, headers)
|
95
|
+
request.basic_auth(@nsx_user, @nsx_password)
|
96
|
+
response = Net::HTTP.start(uri.host, uri.port, :use_ssl => true,
|
97
|
+
:verify_mode => OpenSSL::SSL::VERIFY_NONE) do |https|
|
98
|
+
https.request(request)
|
99
|
+
end
|
100
|
+
check_response(response, valid_codes)
|
101
|
+
end
|
102
|
+
|
103
|
+
# Return: id of the created object
|
104
|
+
def post(url, data, aditional_headers = [], valid_codes = [])
|
105
|
+
if valid_codes.empty?
|
106
|
+
valid_codes = [NSXConstants::CODE_CREATED,
|
107
|
+
NSXConstants::CODE_OK]
|
108
|
+
end
|
109
|
+
uri = URI.parse(@nsxmgr + url)
|
110
|
+
headers = add_headers(aditional_headers)
|
111
|
+
request = Net::HTTP::Post.new(uri.request_uri, headers)
|
112
|
+
request.body = data
|
113
|
+
request.basic_auth(@nsx_user, @nsx_password)
|
114
|
+
response = Net::HTTP.start(uri.host, uri.port, :use_ssl => true,
|
115
|
+
:verify_mode => OpenSSL::SSL::VERIFY_NONE) do |https|
|
116
|
+
https.request(request)
|
117
|
+
end
|
118
|
+
response = check_response(response, valid_codes)
|
119
|
+
response.body
|
120
|
+
end
|
121
|
+
|
122
|
+
def put(url, data, aditional_headers = [], valid_codes = [])
|
123
|
+
if valid_codes.empty?
|
124
|
+
valid_codes = [NSXConstants::CODE_CREATED,
|
125
|
+
NSXConstants::CODE_OK]
|
126
|
+
end
|
127
|
+
uri = URI.parse(@nsxmgr + url)
|
128
|
+
headers = add_headers(aditional_headers)
|
129
|
+
request = Net::HTTP::Put.new(uri.request_uri, headers)
|
130
|
+
request.body = data
|
131
|
+
request.basic_auth(@nsx_user, @nsx_password)
|
132
|
+
response = Net::HTTP.start(uri.host, uri.port, :use_ssl => true,
|
133
|
+
:verify_mode => OpenSSL::SSL::VERIFY_NONE) do |https|
|
134
|
+
https.request(request)
|
135
|
+
end
|
136
|
+
response = check_response(response, valid_codes)
|
137
|
+
response.body
|
138
|
+
end
|
139
|
+
|
140
|
+
def delete(url, aditional_headers = [], valid_codes = [])
|
141
|
+
if valid_codes.empty?
|
142
|
+
valid_codes = [NSXConstants::CODE_OK,
|
143
|
+
NSXConstants::CODE_NO_CONTENT]
|
144
|
+
end
|
145
|
+
uri = URI.parse(@nsxmgr + url)
|
146
|
+
headers = add_headers(aditional_headers)
|
147
|
+
request = Net::HTTP::Delete.new(uri.request_uri, headers)
|
148
|
+
request.basic_auth(@nsx_user, @nsx_password)
|
149
|
+
response = Net::HTTP.start(uri.host, uri.port, :use_ssl => true,
|
150
|
+
:verify_mode => OpenSSL::SSL::VERIFY_NONE) do |https|
|
151
|
+
https.request(request)
|
152
|
+
end
|
153
|
+
check_response(response, valid_codes)
|
154
|
+
end
|
155
|
+
|
156
|
+
def get_token(url, aditional_headers = [], valid_codes = [])
|
157
|
+
if valid_codes.empty?
|
158
|
+
valid_codes = [NSXConstants::CODE_OK]
|
159
|
+
end
|
160
|
+
uri = URI.parse(@nsxmgr + url)
|
161
|
+
headers = add_headers(aditional_headers)
|
162
|
+
request = Net::HTTP::Post.new(uri.request_uri, headers)
|
163
|
+
request.basic_auth(@nsx_user, @nsx_password)
|
164
|
+
response = Net::HTTP.start(uri.host, uri.port, :use_ssl => true,
|
165
|
+
:verify_mode => OpenSSL::SSL::VERIFY_NONE) do |https|
|
166
|
+
https.request(request)
|
167
|
+
end
|
168
|
+
response = check_response(response, valid_codes)
|
169
|
+
response_xml = Nokogiri::XML response.body
|
170
|
+
token = response_xml.xpath('//authToken/value').text
|
171
|
+
{ 'token' => token }.to_json
|
172
|
+
end
|
173
|
+
|
174
|
+
end
|
175
|
+
|
176
|
+
end
|
data/lib/nsxv_dfw.rb
ADDED
@@ -0,0 +1,202 @@
|
|
1
|
+
# -------------------------------------------------------------------------- #
|
2
|
+
# Copyright 2002-2021, OpenNebula Project, OpenNebula Systems #
|
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
|
+
module NSXDriver
|
17
|
+
|
18
|
+
# Class Logical Switch
|
19
|
+
class NSXVdfw < DistributedFirewall
|
20
|
+
|
21
|
+
# ATTRIBUTES
|
22
|
+
attr_reader :one_section_id
|
23
|
+
|
24
|
+
# CONSTRUCTOR
|
25
|
+
# Creates OpenNebula section if not exists
|
26
|
+
def initialize(nsx_client)
|
27
|
+
super(nsx_client)
|
28
|
+
# Construct base URLs
|
29
|
+
@base_url = NSXConstants::NSXV_DFW_BASE
|
30
|
+
@url_sections = @base_url + \
|
31
|
+
NSXConstants::NSXV_DFW_SECTIONS
|
32
|
+
@one_section_id = init_section
|
33
|
+
end
|
34
|
+
|
35
|
+
# Sections
|
36
|
+
# Get all sections
|
37
|
+
# Creates OpenNebula section if not exists and returns
|
38
|
+
# its section_id. Returns its section_id if OpenNebula
|
39
|
+
# section already exists
|
40
|
+
def init_section
|
41
|
+
one_section = section_by_name(NSXConstants::ONE_SECTION_NAME)
|
42
|
+
one_section ||= create_section(NSXConstants::ONE_SECTION_NAME)
|
43
|
+
return one_section.xpath('@id').text if one_section
|
44
|
+
end
|
45
|
+
|
46
|
+
# Get all sections
|
47
|
+
# Params:
|
48
|
+
# - None
|
49
|
+
# Return:
|
50
|
+
# - nil | [Nokogiri::XML::NodeSet] sections
|
51
|
+
def sections
|
52
|
+
result = @nsx_client.get(@base_url)
|
53
|
+
xp = NSXConstants::NSXV_DFW_SECTION_XPATH
|
54
|
+
sections = result.xpath(xp)
|
55
|
+
return sections unless sections.empty?
|
56
|
+
end
|
57
|
+
|
58
|
+
# Get section by id
|
59
|
+
# Params:
|
60
|
+
# - section_id: [String] ID of the section or @one_section_id
|
61
|
+
# Return:
|
62
|
+
# - nil | [Nokogiri::XML::NodeSet] section
|
63
|
+
def section_by_id(section_id = @one_section_id)
|
64
|
+
url = @url_sections + '/' + section_id
|
65
|
+
result = @nsx_client.get(url)
|
66
|
+
xp = NSXConstants::NSXV_DFW_SECTION_XPATH
|
67
|
+
section = result.xpath(xp)
|
68
|
+
return section unless section.empty?
|
69
|
+
end
|
70
|
+
|
71
|
+
# Get section etag needed to manage FW rules
|
72
|
+
# Params:
|
73
|
+
# - section_id: [String] ID of the section or @one_section_id
|
74
|
+
# Return:
|
75
|
+
# - nil | etag [String] ID of the etag header
|
76
|
+
def section_etag(section_id = @one_section_id)
|
77
|
+
url = @url_sections + '/' + section_id
|
78
|
+
response = @nsx_client.get_full_response(url)
|
79
|
+
etag = response['etag']
|
80
|
+
return etag.delete('\"') if etag
|
81
|
+
end
|
82
|
+
|
83
|
+
# Get section by name
|
84
|
+
# Params:
|
85
|
+
# - section_name: [String] Name of the section
|
86
|
+
# Return:
|
87
|
+
# - nil | [Nokogiri::XML::NodeSet] section
|
88
|
+
def section_by_name(section_name)
|
89
|
+
url = @url_sections + '?name=' + section_name
|
90
|
+
result = @nsx_client.get(url) rescue nil
|
91
|
+
return if result.nil?
|
92
|
+
|
93
|
+
xp = NSXConstants::NSXV_DFW_SECTION_XPATH
|
94
|
+
result.xpath(xp)
|
95
|
+
end
|
96
|
+
|
97
|
+
# Create new section
|
98
|
+
# Params:
|
99
|
+
# - section_name [String] Name of the section
|
100
|
+
# Return:
|
101
|
+
# - [Nokogiri::XML::NodeSet]
|
102
|
+
def create_section(section_name)
|
103
|
+
section_spec =
|
104
|
+
"<section name=\"#{section_name}\"\
|
105
|
+
stateless=\"false\" tcpStrict=\"true\" useSid=\"false\">\
|
106
|
+
</section>"
|
107
|
+
|
108
|
+
section = Nokogiri::XML @nsx_client
|
109
|
+
.post(@url_sections, section_spec)
|
110
|
+
section_id = section.xpath('//section/@id').text
|
111
|
+
result = section_by_id(section_id)
|
112
|
+
raise 'Section was not created in DFW' unless result
|
113
|
+
|
114
|
+
result
|
115
|
+
end
|
116
|
+
|
117
|
+
# Delete section
|
118
|
+
# Params:
|
119
|
+
# - section_id: [String] ID of the section or @one_section_id
|
120
|
+
def delete_section(section_id = @one_section_id)
|
121
|
+
url = @url_sections + '/' + section_id
|
122
|
+
@nsx_client.delete(url)
|
123
|
+
end
|
124
|
+
|
125
|
+
# Rules
|
126
|
+
# Get all rules
|
127
|
+
# Params:
|
128
|
+
# - section_id: [String] ID of the section or @one_section_id
|
129
|
+
# Return:
|
130
|
+
# - [Nokogiri::XML::NodeSet]
|
131
|
+
def rules(section_id = @one_section_id)
|
132
|
+
url = @url_sections + '/' + section_id
|
133
|
+
rules = @nsx_client.get(url)
|
134
|
+
rules.xpath(NSXConstants::NSXV_DFW_RULE_XPATH)
|
135
|
+
end
|
136
|
+
|
137
|
+
# Get rule by id
|
138
|
+
# Return:
|
139
|
+
# - rule | nil
|
140
|
+
def rule_by_id(rule_id, section_id = @one_section_id)
|
141
|
+
url = @url_sections + '/' + section_id + '/rules/' + rule_id
|
142
|
+
valid_codes = [NSXConstants::CODE_CREATED,
|
143
|
+
NSXConstants::CODE_OK,
|
144
|
+
NSXConstants::CODE_BAD_REQUEST,
|
145
|
+
NSXConstants::CODE_NOT_FOUND]
|
146
|
+
additional_headers = []
|
147
|
+
result = @nsx_client.get(url, additional_headers, valid_codes)
|
148
|
+
result.xpath(NSXConstants::NSXV_DFW_RULE_XPATH)
|
149
|
+
end
|
150
|
+
|
151
|
+
# Get rules by name
|
152
|
+
# Return:
|
153
|
+
# - [Nokogiri::XML::NodeSet]
|
154
|
+
def rules_by_name(rule_name, section_id = @one_section_id)
|
155
|
+
rules = Nokogiri::XML::NodeSet.new(Nokogiri::XML::Document.new)
|
156
|
+
|
157
|
+
all_rules = rules(section_id)
|
158
|
+
return rules unless all_rules
|
159
|
+
|
160
|
+
all_rules.xpath("//rule[name=\"#{rule_name}\"]")
|
161
|
+
end
|
162
|
+
|
163
|
+
# Create new rule
|
164
|
+
def create_rule(rule_spec, section_id = @one_section_id)
|
165
|
+
# etag is needed to add a new header If-Match
|
166
|
+
etag = section_etag(section_id)
|
167
|
+
raise NSXError::ObjectNotFound('etag') \
|
168
|
+
unless etag
|
169
|
+
|
170
|
+
aditional_headers = [{ 'If-Match' => etag }]
|
171
|
+
url = @url_sections + '/' + section_id + '/rules'
|
172
|
+
@nsx_client.post(url, rule_spec, aditional_headers)
|
173
|
+
end
|
174
|
+
|
175
|
+
# Update rule
|
176
|
+
def update_rule(rule_id, rule_spec, section_id = @one_section_id)
|
177
|
+
url = @url_sections + '/' + section_id + '/rules/' + rule_id
|
178
|
+
rule = rule_by_id(rule_id)
|
179
|
+
raise "Rule id #{rule_id} not found" unless rule
|
180
|
+
|
181
|
+
# etag is needed to add a new header If-Match
|
182
|
+
etag = section_etag(section_id)
|
183
|
+
raise "Cannot get etag from section: #{section_id}" unless etag
|
184
|
+
|
185
|
+
aditional_headers = [{ 'If-Match' => etag }]
|
186
|
+
@nsx_client.put(url, rule_spec, aditional_headers)
|
187
|
+
end
|
188
|
+
|
189
|
+
# Delete rule
|
190
|
+
def delete_rule(rule_id, section_id = @one_section_id)
|
191
|
+
url = @url_sections + '/' + section_id + '/rules/' + rule_id
|
192
|
+
# etag is needed to add a new header If-Match
|
193
|
+
etag = section_etag(section_id)
|
194
|
+
raise "Cannot get etag from section: #{section_id}" unless etag
|
195
|
+
|
196
|
+
aditional_headers = [{ 'If-Match' => etag }]
|
197
|
+
@nsx_client.delete(url, aditional_headers)
|
198
|
+
end
|
199
|
+
|
200
|
+
end
|
201
|
+
|
202
|
+
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
# -------------------------------------------------------------------------- #
|
2
|
+
# Copyright 2002-2021, OpenNebula Project, OpenNebula Systems #
|
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
|
+
module NSXDriver
|
17
|
+
|
18
|
+
# The NSXVLogicalPort class represents a LogicalPort in NSXv
|
19
|
+
class NSXVLogicalPort < LogicalPort
|
20
|
+
|
21
|
+
# ATTRIBUTES
|
22
|
+
attr_reader :id, :name, :type, :url
|
23
|
+
|
24
|
+
# CONSTRUCTOR
|
25
|
+
# Logical port class variables:
|
26
|
+
# @lp_id
|
27
|
+
# @url_lp
|
28
|
+
# @lp_name
|
29
|
+
# @lp_type
|
30
|
+
def initialize(nsx_client, id = nil, data = nil)
|
31
|
+
super(nsx_client)
|
32
|
+
# lpid can be:
|
33
|
+
# - Logical port ID
|
34
|
+
# - Logical port attach ID
|
35
|
+
if id
|
36
|
+
initialize_with_id(id)
|
37
|
+
else
|
38
|
+
if data
|
39
|
+
begin
|
40
|
+
@id = new_logical_port(data)
|
41
|
+
rescue NSXError::IncorrectResponseCodeError => e
|
42
|
+
raise 'Logical Port not created in ' \
|
43
|
+
"NSX Manager: #{e.message}"
|
44
|
+
end
|
45
|
+
unless @id
|
46
|
+
raise 'Logical Port not created in NSX Manager: '\
|
47
|
+
'generic error'
|
48
|
+
end
|
49
|
+
# Construct logical port class variables
|
50
|
+
@url = NSXConstants::NSXT_LP_BASE + @id
|
51
|
+
@name = lp_name
|
52
|
+
@type = lp_type
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
# Creates a NSXTLogicalPort from its id
|
58
|
+
def initialize_with_id(id)
|
59
|
+
# First try lpid as logical port id
|
60
|
+
@id = id
|
61
|
+
# Construct URL of the created logical switch
|
62
|
+
@url = NSXConstants::NSXV_LP_BASE + @id
|
63
|
+
if lp?
|
64
|
+
@name = lp_name
|
65
|
+
@type = lp_type
|
66
|
+
else
|
67
|
+
# Second try with lpid as logical port attach id
|
68
|
+
@id = lp_with_attachid(id)
|
69
|
+
if @id.nil?
|
70
|
+
error_msg = "Logical port with id: #{id} not found"
|
71
|
+
error = NSXError::ObjectNotFound
|
72
|
+
.new(error_msg)
|
73
|
+
raise error
|
74
|
+
else
|
75
|
+
@url = NSXConstants::NSXT_LP_BASE + @id
|
76
|
+
@name = lp_name
|
77
|
+
@type = lp_type
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
# Check if logical port exists
|
83
|
+
def lp?
|
84
|
+
@nsx_client.get(@url) ? true : false
|
85
|
+
end
|
86
|
+
|
87
|
+
# Get logical port id from attach id
|
88
|
+
def lp_with_attachid(attach_id)
|
89
|
+
lps = @nsx_client.get(NSXConstants::NSXT_LP_BASE)
|
90
|
+
lps['results'].each do |lp|
|
91
|
+
return lp['id'] if lp['attachment']['id'] == attach_id
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
# Get logical port display name
|
96
|
+
def lp_name
|
97
|
+
@nsx_client.get(@url)['display_name']
|
98
|
+
end
|
99
|
+
|
100
|
+
# Get resource type
|
101
|
+
def lp_type
|
102
|
+
@nsx_client.get(@url)['resource_type']
|
103
|
+
end
|
104
|
+
|
105
|
+
end
|
106
|
+
|
107
|
+
end
|
data/lib/nsxv_rule.rb
ADDED
@@ -0,0 +1,172 @@
|
|
1
|
+
# -------------------------------------------------------------------------- #
|
2
|
+
# Copyright 2002-2021, OpenNebula Project, OpenNebula Systems #
|
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
|
+
module NSXDriver
|
17
|
+
|
18
|
+
module NSXRule
|
19
|
+
|
20
|
+
# Module NSXVRule
|
21
|
+
module NSXVRule
|
22
|
+
|
23
|
+
def nsxv_rule_spec(rule, vm_data, nic_data)
|
24
|
+
rule_name = "#{rule[:id]}-#{rule[:name]}-#{vm_data[:id]}"
|
25
|
+
rule_name << "-#{vm_data[:deploy_id]}-#{nic_data[:id]}"
|
26
|
+
|
27
|
+
# rubocop:disable Layout/LineLength
|
28
|
+
builder = Nokogiri::XML::Builder.new(:encoding => 'UTF-8') do |xml|
|
29
|
+
# rubocop:enable Layout/LineLength
|
30
|
+
xml.rule('disabled' => 'false', 'logged' => 'false') do
|
31
|
+
xml.name rule_name
|
32
|
+
xml.action 'allow'
|
33
|
+
xml.appliedToList do
|
34
|
+
xml.appliedTo do
|
35
|
+
xml.name nic_data[:name]
|
36
|
+
xml.value nic_data[:lp]
|
37
|
+
xml.type 'Vnic'
|
38
|
+
xml.isValid 'true'
|
39
|
+
end
|
40
|
+
end
|
41
|
+
xml.sectionId @one_section_id
|
42
|
+
|
43
|
+
# SOURCES / DESTINATIONS: Any | IP Address | Vnet
|
44
|
+
|
45
|
+
unless rule[:network_id].empty? && rule[:subnets].empty?
|
46
|
+
|
47
|
+
if rule[:direction] == 'IN'
|
48
|
+
xml.sources('excluded' => 'false') do
|
49
|
+
if !rule[:network_id].empty?
|
50
|
+
xml.source do
|
51
|
+
xml.name rule[:network_name]
|
52
|
+
xml.value rule[:network_nsxid]
|
53
|
+
xml.type 'VirtualWire'
|
54
|
+
xml.isValid 'true'
|
55
|
+
end
|
56
|
+
elsif !rule[:subnets].empty?
|
57
|
+
rule[:subnets].each do |subnet|
|
58
|
+
xml.source do
|
59
|
+
# rubocop:disable Layout/LineLength
|
60
|
+
ip_version = IPAddr.new(subnet).ipv4? ? 'Ipv4Address' : 'Ipv6Address'
|
61
|
+
# rubocop:enable Layout/LineLength
|
62
|
+
xml.value subnet
|
63
|
+
xml.type ip_version
|
64
|
+
xml.isValid 'true'
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
else
|
70
|
+
xml.destinations('excluded' => 'false') do
|
71
|
+
# Target network: Vnet
|
72
|
+
if !rule[:network_id].empty?
|
73
|
+
xml.destination do
|
74
|
+
xml.name nic_data[:network_name]
|
75
|
+
xml.value rule[:network_nsxid]
|
76
|
+
xml.type 'VirtualWire'
|
77
|
+
xml.isValid 'true'
|
78
|
+
end
|
79
|
+
# Target network: Manual network(IP Address)
|
80
|
+
elsif !rule[:subnets].empty?
|
81
|
+
rule[:subnets].each do |subnet|
|
82
|
+
xml.destination do
|
83
|
+
# rubocop:disable Layout/LineLength
|
84
|
+
ip_version = IPAddr.new(subnet).ipv4? ? 'Ipv4Address' : 'Ipv6Address'
|
85
|
+
# rubocop:enable Layout/LineLength
|
86
|
+
xml.value subnet
|
87
|
+
xml.type ip_version
|
88
|
+
xml.isValid 'true'
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
##### SERVICES #####
|
97
|
+
unless rule[:protocol].empty?
|
98
|
+
xml.services do
|
99
|
+
case rule[:protocol]
|
100
|
+
when 'TCP'
|
101
|
+
xml.service do
|
102
|
+
xml.isValid 'true'
|
103
|
+
xml.protocol '6'
|
104
|
+
xml.protocolName 'TCP'
|
105
|
+
# rubocop:disable Layout/LineLength
|
106
|
+
xml.sourcePort parse_ports(rule[:ports]) \
|
107
|
+
if rule[:direction] == 'IN'
|
108
|
+
xml.destinationPort parse_ports(rule[:ports]) \
|
109
|
+
if rule[:direction] == 'OUT'
|
110
|
+
# rubocop:enable Layout/LineLength
|
111
|
+
end
|
112
|
+
when 'UDP'
|
113
|
+
xml.service do
|
114
|
+
xml.isValid 'true'
|
115
|
+
xml.protocol '17'
|
116
|
+
xml.protocolName 'UDP'
|
117
|
+
# rubocop:disable Layout/LineLength
|
118
|
+
xml.sourcePort parse_ports(rule[:ports]) \
|
119
|
+
if rule[:direction] == 'IN'
|
120
|
+
xml.destinationPort parse_ports(rule[:ports]) \
|
121
|
+
if rule[:direction] == 'OUT'
|
122
|
+
# rubocop:enable Layout/LineLength
|
123
|
+
end
|
124
|
+
when 'ICMP'
|
125
|
+
xml.service do
|
126
|
+
xml.isValid 'true'
|
127
|
+
xml.protocol '1'
|
128
|
+
xml.protocolName 'ICMP'
|
129
|
+
end
|
130
|
+
when 'ICMPv6'
|
131
|
+
xml.service do
|
132
|
+
xml.isValid 'true'
|
133
|
+
xml.protocol '58'
|
134
|
+
xml.protocolName 'IPV6ICMP'
|
135
|
+
end
|
136
|
+
when 'IPSEC'
|
137
|
+
ports = NSXConstants::NSX_RULE_IPSEC_PORTS
|
138
|
+
xml.service do
|
139
|
+
xml.isValid 'true'
|
140
|
+
xml.protocol '50'
|
141
|
+
xml.protocolName 'ESP'
|
142
|
+
end
|
143
|
+
xml.service do
|
144
|
+
xml.isValid 'true'
|
145
|
+
xml.protocol '51'
|
146
|
+
xml.protocolName 'AH'
|
147
|
+
end
|
148
|
+
xml.service do
|
149
|
+
xml.isValid 'true'
|
150
|
+
xml.protocol '17'
|
151
|
+
xml.protocolName 'UDP'
|
152
|
+
xml.sourcePort parse_ports(ports) \
|
153
|
+
if rule[:direction] == 'IN'
|
154
|
+
xml.destinationPort parse_ports(ports) \
|
155
|
+
if rule[:direction] == 'OUT'
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
xml.direction rule[:direction].downcase
|
162
|
+
xml.packetType 'any'
|
163
|
+
end
|
164
|
+
end
|
165
|
+
builder.to_xml
|
166
|
+
end
|
167
|
+
|
168
|
+
end
|
169
|
+
|
170
|
+
end
|
171
|
+
|
172
|
+
end
|