Skip to content

Commit

Permalink
Merge 6ceb6e4 into c59a149
Browse files Browse the repository at this point in the history
  • Loading branch information
LeonMatthes committed Mar 13, 2019
2 parents c59a149 + 6ceb6e4 commit 42ac082
Show file tree
Hide file tree
Showing 7 changed files with 82 additions and 50 deletions.
4 changes: 4 additions & 0 deletions app/api/v_sphere/cluster.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ def ==(other)
equal? other
end

def networks
@cluster.network
end

private

def managed_folder_entry
Expand Down
8 changes: 5 additions & 3 deletions app/api/v_sphere/folder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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',
Expand Down Expand Up @@ -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'
)
Expand Down
32 changes: 19 additions & 13 deletions app/models/request.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion app/views/layouts/_flash_message.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<% flash.each do |key, value| %>
<div class="alert alert-<%= translate_flash_key(key) %>">
<a href="#" data-dismiss="alert" class="close">×</a>
<%= content_tag :div, value %>
<%= content_tag :div, simple_format(value) %>
</div>
<% end %>
</div>
2 changes: 1 addition & 1 deletion app/views/requests/show.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<table class="table table-fixed-columns table-flex-width">
<tbody>
<tr>
<th style="width: 300px">VM Name</td>
<td><strong>VM Name</strong></td>
<td><%= @request.name %></td>
</tr>

Expand Down
41 changes: 23 additions & 18 deletions spec/api/v_sphere_api_mocker.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand All @@ -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
Expand All @@ -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',
Expand All @@ -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,
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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)
Expand All @@ -212,4 +216,5 @@ def v_sphere_connection_mock(
double_connection
end

# rubocop:enable Metrics/AbcSize, Metrics/MethodLength
# rubocop:enable RSpec/MessageChain
43 changes: 29 additions & 14 deletions spec/controllers/requests_controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand All @@ -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: ['']
Expand All @@ -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

Expand Down

0 comments on commit 42ac082

Please sign in to comment.