diff --git a/app/api/v_sphere/cluster.rb b/app/api/v_sphere/cluster.rb
index 094a74ab..e8f5d650 100644
--- a/app/api/v_sphere/cluster.rb
+++ b/app/api/v_sphere/cluster.rb
@@ -35,6 +35,10 @@ def ==(other)
equal? other
end
+ def networks
+ @cluster.network
+ end
+
private
def managed_folder_entry
diff --git a/app/api/v_sphere/folder.rb b/app/api/v_sphere/folder.rb
index 8fe623e7..7fcd7e66 100644
--- a/app/api/v_sphere/folder.rb
+++ b/app/api/v_sphere/folder.rb
@@ -70,7 +70,9 @@ def move_here(folder_entry)
end
def create_vm(cpu, ram, capacity, name, cluster)
- vm_config = creation_config(cpu, ram, capacity, name)
+ return nil if cluster.networks.empty?
+
+ vm_config = creation_config(cpu, ram, capacity, name, cluster.networks.first)
vm = @folder.CreateVM_Task(config: vm_config, pool: cluster.resource_pool).wait_for_completion
VSphere::VirtualMachine.new vm
end
@@ -81,7 +83,7 @@ def managed_folder_entry
@folder
end
- def creation_config(cpu, ram, capacity, name) # rubocop:disable Metrics/MethodLength
+ def creation_config(cpu, ram, capacity, name, network) # rubocop:disable Metrics/MethodLength
{
name: name,
guestId: 'otherGuest',
@@ -119,7 +121,7 @@ def creation_config(cpu, ram, capacity, name) # rubocop:disable Metrics/MethodLe
summary: 'VM Network'
},
backing: RbVmomi::VIM.VirtualEthernetCardNetworkBackingInfo(
- deviceName: 'VM Network'
+ deviceName: network.name
),
addressType: 'generated'
)
diff --git a/app/models/request.rb b/app/models/request.rb
index e9a7552a..71f4df19 100644
--- a/app/models/request.rb
+++ b/app/models/request.rb
@@ -84,27 +84,33 @@ def create_vm
clusters = VSphere::Cluster.all
return nil, 'VM could not be created, as there are no clusters available in vSphere!' if clusters.empty?
- warning = nil
- begin
- push_to_git
- rescue Git::GitExecuteError => e
- logger.error(e)
- warning = "Your VM was created, but users could not be associated with the VM! Push to git failed, error: \"#{e.message}\""
- end
- [create_vm_in_cluster(clusters.sample), warning]
+ cluster = clusters.sample
+ return nil, 'VM could not be created, there is no network available in the cluster' if cluster.networks.empty?
+
+ warning = push_to_git_with_warnings
+ [create_vm_in_cluster(cluster), warning]
end
def create_vm_in_cluster(cluster)
vm = VSphere::Connection.instance.root_folder.create_vm(cpu_cores, gibi_to_mibi(ram_gb), gibi_to_kibi(storage_gb), name, cluster)
- vm.ensure_config.responsible_users = responsible_users
- vm.config.project = project
- vm.config.description = description
- vm.config.save
+ vm.ensure_config.update(
+ responsible_users: responsible_users,
+ project: project,
+ description: description
+ )
vm.move_into_correct_subfolder
vm
end
- # Error handling has been moved into create_vm to provide easier feedback for the user
+ def push_to_git_with_warnings
+ push_to_git
+ nil
+ rescue Git::GitExecuteError => error
+ logger.error error
+ "Your VM was created, but users could not be associated with the VM! Push to git failed, error:\n\"#{error.message}\""
+ end
+
+ # Error handling has been moved into push_to_git_with_warnings to provide easier feedback for the user
def push_to_git
GitHelper.open_repository(Puppetscript.puppet_script_path, for_write: true) do |git_writer|
git_writer.write_file(Puppetscript.node_file_name(name), generate_puppet_node_script)
diff --git a/app/views/layouts/_flash_message.html.erb b/app/views/layouts/_flash_message.html.erb
index 9a031055..c658070b 100644
--- a/app/views/layouts/_flash_message.html.erb
+++ b/app/views/layouts/_flash_message.html.erb
@@ -2,7 +2,7 @@
<% flash.each do |key, value| %>
×
- <%= content_tag :div, value %>
+ <%= content_tag :div, simple_format(value) %>
<% end %>
diff --git a/app/views/requests/show.html.erb b/app/views/requests/show.html.erb
index d9c75233..8d4a057b 100644
--- a/app/views/requests/show.html.erb
+++ b/app/views/requests/show.html.erb
@@ -3,7 +3,7 @@
- VM Name
+ | VM Name |
<%= @request.name %> |
diff --git a/spec/api/v_sphere_api_mocker.rb b/spec/api/v_sphere_api_mocker.rb
index e202c9d7..21878cc4 100644
--- a/spec/api/v_sphere_api_mocker.rb
+++ b/spec/api/v_sphere_api_mocker.rb
@@ -25,6 +25,9 @@
# has many messages that have to be chained which we want to mock.
# rubocop:disable RSpec/MessageChain
+# Disable AbcSize and MethodLength as mocking is not really complex, but increases these 2 metrics very fast
+# rubocop:disable Metrics/AbcSize, Metrics/MethodLength
+
def extract_vim_objects(collection)
collection.map do |each|
if [VSphere::Cluster, VSphere::Folder, VSphere::VirtualMachine].include? each.class
@@ -66,7 +69,6 @@ def v_sphere_folder_mock(name, subfolders: [], vms: [], clusters: [])
VSphere::Folder.new vim_folder_mock(name, subfolders, vms, clusters)
end
-# rubocop:disable Metrics/AbcSize, Metrics/MethodLength
def vim_vm_summary_mock(power_state: 'poweredOn')
summary_double = double
allow(summary_double).to receive_message_chain(:storage, :committed).and_return(100)
@@ -83,7 +85,6 @@ def vim_vm_summary_mock(power_state: 'poweredOn')
allow(summary_double).to receive_message_chain(:runtime, :host, :name).and_return 'aHost'
summary_double
end
-# rubocop:enable Metrics/AbcSize, Metrics/MethodLength
def vim_disks_mock
disk = double
@@ -98,7 +99,6 @@ def vim_guest_mock(tools_status: 'toolsNotInstalled')
guest
end
-# rubocop:disable Metrics/AbcSize
def vim_vm_mock(
name,
power_state: 'poweredOn',
@@ -122,7 +122,6 @@ def vim_vm_mock(
vm
end
-# rubocop:enable Metrics/AbcSize
def v_sphere_vm_mock(name, power_state: 'poweredOn', vm_ware_tools: 'toolsNotInstalled', boot_time: Time.now - 60 * 60 * 24)
VSphere::VirtualMachine.new vim_vm_mock(name,
@@ -131,6 +130,21 @@ def v_sphere_vm_mock(name, power_state: 'poweredOn', vm_ware_tools: 'toolsNotIns
boot_time: boot_time)
end
+def vim_host_summary_mock
+ summary = double
+ allow(summary).to receive_message_chain(:runtime, :powerState)
+ allow(summary).to receive_message_chain(:config, :product, :osType).and_return('someOS')
+ allow(summary).to receive_message_chain(:config, :product, :fullName).and_return(['someProduct'])
+ allow(summary).to receive_message_chain(:hardware, :cpuModel).and_return('someModel')
+ allow(summary).to receive_message_chain(:hardware, :numCpuCores).and_return(4)
+ allow(summary).to receive_message_chain(:hardware, :numCpuThreads).and_return(4)
+ allow(summary).to receive_message_chain(:hardware, :cpuMhz).and_return(1000)
+ allow(summary).to receive_message_chain(:hardware, :memorySize).and_return(1000 * 1024**3) # in bytes
+ allow(summary).to receive_message_chain(:quickStats, :overallMemoryUsage).and_return(0)
+ allow(summary).to receive_message_chain(:quickStats, :overallCpuUsage).and_return(0)
+ summary
+end
+
def vim_host_mock(name)
host = double
allow(host).to receive(:name).and_return name
@@ -149,18 +163,7 @@ def vim_host_mock(name)
power_state: 'poweredOn',
vm_ware_tools: 'toolsInstalled')])
- summary = double
- allow(summary).to receive_message_chain(:runtime, :powerState)
- allow(summary).to receive_message_chain(:config, :product, :osType).and_return('someOS')
- allow(summary).to receive_message_chain(:config, :product, :fullName).and_return(['someProduct'])
- allow(summary).to receive_message_chain(:hardware, :cpuModel).and_return('someModel')
- allow(summary).to receive_message_chain(:hardware, :numCpuCores).and_return(4)
- allow(summary).to receive_message_chain(:hardware, :numCpuThreads).and_return(4)
- allow(summary).to receive_message_chain(:hardware, :cpuMhz).and_return(1000)
- allow(summary).to receive_message_chain(:hardware, :memorySize).and_return(1000 * 1024**3) # in bytes
- allow(summary).to receive_message_chain(:quickStats, :overallMemoryUsage).and_return(0)
- allow(summary).to receive_message_chain(:quickStats, :overallCpuUsage).and_return(0)
- allow(host).to receive(:summary).and_return summary
+ allow(host).to receive(:summary).and_return vim_host_summary_mock
datastore = double
allow(datastore).to receive_message_chain(:summary, :capacity).and_return(1000 * 1024**3) # in bytes
@@ -174,7 +177,6 @@ def v_sphere_host_mock(name)
VSphere::Host.new vim_host_mock(name)
end
-# rubocop:disable Metrics/AbcSize
def vim_cluster_mock(name, hosts)
hosts = extract_vim_objects hosts
cluster = double
@@ -183,9 +185,11 @@ def vim_cluster_mock(name, hosts)
allow(cluster).to receive(:host).and_return hosts
allow(cluster).to receive(:name).and_return name
allow(cluster).to receive(:resourcePool).and_return nil
+ network = double
+ allow(network).to receive(:name).and_return 'MyNetwork'
+ allow(cluster).to receive(:network).and_return [network]
cluster
end
-# rubocop:enable Metrics/AbcSize
def v_sphere_cluster_mock(name, hosts)
VSphere::Cluster.new vim_cluster_mock(name, hosts)
@@ -212,4 +216,5 @@ def v_sphere_connection_mock(
double_connection
end
+# rubocop:enable Metrics/AbcSize, Metrics/MethodLength
# rubocop:enable RSpec/MessageChain
diff --git a/spec/controllers/requests_controller_spec.rb b/spec/controllers/requests_controller_spec.rb
index f58ea32b..280b9812 100644
--- a/spec/controllers/requests_controller_spec.rb
+++ b/spec/controllers/requests_controller_spec.rb
@@ -221,7 +221,7 @@
end
describe 'PATCH #update' do
- context 'with valid params' do
+ context 'accepts the request' do
let(:new_attributes) do
{
name: 'mynewvm',
@@ -230,7 +230,6 @@
storage_gb: 3,
operating_system: 'MyNewOS',
comment: 'newComment',
- status: 'pending',
user: user,
sudo_user_ids: ['', sudo_user.id.to_s, user.id.to_s],
user_ids: ['']
@@ -245,25 +244,41 @@
request
end
- before do
+ it 'redirects to the index page if no cluster is available' do
+ allow(VSphere::Cluster).to receive(:all).and_return []
patch :update, params: { id: the_request.to_param, request: new_attributes }
- the_request.reload
+ expect(response).to redirect_to(requests_path)
end
- it 'updates the request' do
- expect(the_request.name).to eq('mynewvm')
+ it 'redirects to the index page if the cluster does not have a network' do
+ cluster = double
+ allow(cluster).to receive(:networks).and_return []
+ allow(VSphere::Cluster).to receive(:all).and_return [cluster]
+ patch :update, params: { id: the_request.to_param, request: new_attributes }
+ expect(response).to redirect_to(requests_path)
end
- it 'redirects to the new VMS config' do
- expect(response).to redirect_to(edit_config_path(the_request.name))
- end
+ context 'update already performed' do
+ before do
+ patch :update, params: { id: the_request.to_param, request: new_attributes }
+ the_request.reload
+ end
- it 'accepts the request' do
- expect(the_request).to be_accepted
- end
+ it 'updates the request' do
+ expect(the_request.name).to eq('mynewvm')
+ end
+
+ it 'redirects to the new VMS config' do
+ expect(response).to redirect_to(edit_config_path(the_request.name))
+ end
+
+ it 'accepts the request' do
+ expect(the_request).to be_accepted
+ end
- it 'correctly updates the sudo users' do
- expect(the_request.sudo_users).to match_array([sudo_user, user])
+ it 'correctly updates the sudo users' do
+ expect(the_request.sudo_users).to match_array([sudo_user, user])
+ end
end
end