Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
F
foreman_wds
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Iterations
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Locked files
Build
Pipelines
Jobs
Pipeline schedules
Test cases
Artifacts
Deploy
Releases
Package registry
Model registry
Operate
Terraform modules
Analyze
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
LiU IT - Infrastructure
foreman_wds
Commits
91805e1d
Verified
Commit
91805e1d
authored
1 year ago
by
Alexander Olofsson
Browse files
Options
Downloads
Patches
Plain Diff
Rework testing to properly stub WinRM
parent
08a4c372
No related branches found
Branches containing commit
No related tags found
No related merge requests found
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
app/models/wds_server.rb
+42
-41
42 additions, 41 deletions
app/models/wds_server.rb
test/models/foreman_wds/wds_facet_test.rb
+7
-1
7 additions, 1 deletion
test/models/foreman_wds/wds_facet_test.rb
test/test_plugin_helper.rb
+45
-0
45 additions, 0 deletions
test/test_plugin_helper.rb
with
94 additions
and
42 deletions
app/models/wds_server.rb
+
42
−
41
View file @
91805e1d
...
...
@@ -49,12 +49,9 @@ class WdsServer < ApplicationRecord
objects
=
run_wql
(
'SELECT * FROM MSFT_WdsClient'
,
on_error:
{})[
:msft_wdsclient
]
objects
=
nil
if
objects
&
.
empty?
objects
||=
begin
data
=
connection
.
shell
(
:powershell
)
do
|
s
|
s
.
run
(
'Get-WdsClient | ConvertTo-Json -Compress'
)
end
.
stdout
data
=
'[]'
if
data
.
empty?
underscore_result
([
JSON
.
parse
(
data
)].
flatten
)
clients
=
run_pwsh
(
'Get-WdsClient'
).
stdout
clients
=
'[]'
if
clients
.
empty?
underscore_result
([
JSON
.
parse
(
clients
)].
flatten
)
end
objects
...
...
@@ -82,18 +79,14 @@ class WdsServer < ApplicationRecord
raise
NotImplementedError
,
'Not finished yet'
ensure_unattend
(
host
)
connection
.
shell
(
:powershell
)
do
|
sh
|
sh
.
run
(
"New-WdsClient -DeviceID '
#{
host
.
mac
.
upcase
.
delete
':'
}
' -DeviceName '
#{
host
.
name
}
' -WdsClientUnattend '
#{
unattend_file
(
host
)
}
' -BootImagePath 'boot
\\
#{
wdsify_architecture
(
host
.
architecture
)
}
\\
images
\\
#{
(
host
.
wds_boot_image
||
boot_images
.
first
).
file_name
}
' -PxePromptPolicy 'NoPrompt'"
)
end
run_pwsh
(
"New-WdsClient -DeviceID '
#{
host
.
mac
.
upcase
.
delete
':'
}
' -DeviceName '
#{
host
.
name
}
' -WdsClientUnattend '
#{
unattend_file
(
host
)
}
' -BootImagePath 'boot
\\
#{
wdsify_architecture
(
host
.
architecture
)
}
\\
images
\\
#{
(
host
.
wds_boot_image
||
boot_images
.
first
).
file_name
}
' -PxePromptPolicy 'NoPrompt'"
)
end
def
delete_client
(
host
)
raise
NotImplementedError
,
'Not finished yet'
delete_unattend
(
host
)
connection
.
shell
(
:powershell
)
do
|
sh
|
sh
.
run
(
"Remove-WdsClient -DeviceID '
#{
host
.
mac
.
upcase
.
delete
':'
}
'"
)
end
run_pwsh
(
"Remove-WdsClient -DeviceID '
#{
host
.
mac
.
upcase
.
delete
':'
}
'"
,
json:
false
)
end
def
all_images
...
...
@@ -162,9 +155,10 @@ class WdsServer < ApplicationRecord
def
unattend_path
cache
.
cache
(
:unattend_path
)
do
JSON
.
parse
(
connection
.
shell
(
:powershell
)
do
|
sh
|
sh
.
run
(
'Get-ItemProperty -Path HKLM:\SYSTEM\CurrentControlSet\Services\WDSServer\Providers\WDSTFTP -Name RootFolder | select RootFolder | ConvertTo-Json -Compress'
)
end
,
symbolize_names:
true
)[
:RootFolder
]
JSON
.
parse
(
run_pwsh
(
'Get-ItemProperty -Path HKLM:\SYSTEM\CurrentControlSet\Services\WDSServer\Providers\WDSTFTP -Name RootFolder | select RootFolder'
),
symbolize_names:
true
)[
:RootFolder
]
end
end
...
...
@@ -187,6 +181,7 @@ class WdsServer < ApplicationRecord
raise
'No provisioning interface available'
unless
iface
raise
NotImplementedException
,
'TODO: Not implemented yet'
raise
NotImplementedException
,
'TODO: Not implemented yet'
if
SETTINGS
[
:wds_unattend_group
]
# TODO: render template, send as heredoc
template
=
host
.
operatingsystem
.
provisioning_templates
.
find
{
|
t
|
t
.
template_kind
.
name
==
'wds_unattend'
}
...
...
@@ -198,33 +193,33 @@ class WdsServer < ApplicationRecord
template_data
=
host
.
render_template
template:
template
connection
.
shell
(
:powershell
)
do
|
sh
|
file_path
=
unattend_file
(
host
)
sh
.
run
(
"$unattend_render = @'
\n
#{
template_data
}
\n
'@"
)
sh
.
run
(
"New-Item -Path '
#{
file_path
}
' -ItemType 'file' -Value $unattend_render"
)
source_image
=
host
.
wds_facet
.
install_image
target_image
=
target_image_for
(
host
)
if
SETTINGS
[
:wds_unattend_group
]
raise
NotImplementedException
,
'TODO: Not implemented yet'
# New-WdsInstallImageGroup -Name #{SETTINGS[:wds_unattend_group]}
# Export-WdsInstallImage -ImageGroup <Group> ...
# Import-WdsInstallImage -ImageGroup #{SETTINGS[:wds_unattend_group]} -UnattendFile '#{file_path}' -OverwriteUnattend ...
else
sh
.
run
(
"Copy-WdsInstallImage -ImageGroup '
#{
source_image
.
image_group
}
' -FileName '
#{
source_image
.
file_name
}
' -ImageName '
#{
source_image
.
image_name
}
' -NewFileName '
#{
target_image
.
file_name
}
' -NewImageName '
#{
target_image
.
image_name
}
'"
)
sh
.
run
(
"Set-WdsInstallImage -ImageGroup '
#{
target_image
.
image_group
}
' -FileName '
#{
target_image
.
file_name
}
' -ImageName '
#{
target_image
.
image_name
}
' -DisplayOrder 99999 -UnattendFile '
#{
file_path
}
' -OverwriteUnattend"
)
end
file_path
=
unattend_file
(
host
)
script
=
[]
script
<<
"$unattend_render = @'
\n
#{
template_data
}
\n
'@"
script
<<
"New-Item -Path '
#{
file_path
}
' -ItemType 'file' -Value $unattend_render"
source_image
=
host
.
wds_facet
.
install_image
target_image
=
target_image_for
(
host
)
if
SETTINGS
[
:wds_unattend_group
]
# New-WdsInstallImageGroup -Name #{SETTINGS[:wds_unattend_group]}
# Export-WdsInstallImage -ImageGroup <Group> ...
# Import-WdsInstallImage -ImageGroup #{SETTINGS[:wds_unattend_group]} -UnattendFile '#{file_path}' -OverwriteUnattend ...
else
script
<<
"Copy-WdsInstallImage -ImageGroup '
#{
source_image
.
image_group
}
' -FileName '
#{
source_image
.
file_name
}
' -ImageName '
#{
source_image
.
image_name
}
' -NewFileName '
#{
target_image
.
file_name
}
' -NewImageName '
#{
target_image
.
image_name
}
'"
script
<<
"Set-WdsInstallImage -ImageGroup '
#{
target_image
.
image_group
}
' -FileName '
#{
target_image
.
file_name
}
' -ImageName '
#{
target_image
.
image_name
}
' -DisplayOrder 99999 -UnattendFile '
#{
file_path
}
' -OverwriteUnattend"
end
run_pwsh
script
.
join
(
"
\n
"
),
json:
false
end
def
delete_unattend
(
host
)
image
=
target_image_for
(
host
)
co
nnection
.
shell
(
:powershell
)
do
|
sh
|
sh
.
run
(
"Remove-WdsInstallImage -ImageGroup '
#{
image
.
image_group
}
' -ImageName '
#{
image
.
image_name
}
' -FileName '
#{
image
.
file_name
}
'"
)
sh
.
run
(
"Remove-Item -Path '
#{
unattend_file
(
host
)
}
'"
)
end
.
errcode
.
zero?
co
mmand
=
[]
command
<<
"Remove-WdsInstallImage -ImageGroup '
#{
image
.
image_group
}
' -ImageName '
#{
image
.
image_name
}
' -FileName '
#{
image
.
file_name
}
'"
command
<<
"Remove-Item -Path '
#{
unattend_file
(
host
)
}
'"
run_pwsh
(
command
.
join
(
"
\n
"
),
json:
false
)
.
errcode
.
zero?
end
def
ensure_client
(
_host
)
...
...
@@ -242,14 +237,12 @@ class WdsServer < ApplicationRecord
objects
=
nil
if
objects
.
empty?
unless
objects
begin
result
=
connection
.
shell
(
:powershell
)
do
|
s
|
s
.
run
(
"Get-WDS
#{
type
.
to_s
.
capitalize
}
Image
#{
"-ImageName '
#{
name
.
sub
(
"'"
,
"`'"
)
}
'"
if
name
}
| ConvertTo-Json -Compress"
)
end
result
=
run_pwsh
"Get-WDS
#{
type
.
to_s
.
capitalize
}
Image
#{
" -ImageName '
#{
name
.
sub
(
"'"
,
"`'"
)
}
'"
if
name
}
"
begin
objects
=
underscore_result
([
JSON
.
parse
(
result
.
stdout
)].
flatten
)
rescue
JSON
::
ParserError
=>
e
::
Rails
.
logger
.
error
"
#{
e
.
class
}
:
#{
e
}
\n
#{
result
}
"
::
Rails
.
logger
.
error
"
Failed to parse images -
#{
e
.
class
}
:
#{
e
}
, the data was;
\n
#{
result
.
inspect
}
"
raise
e
end
end
...
...
@@ -270,6 +263,14 @@ class WdsServer < ApplicationRecord
end
end
def
run_pwsh
(
command
,
json:
true
)
cmd_arr
=
[
command
]
cmd_arr
<<
'| ConvertTo-Json -Compress'
if
json
connection
.
shell
(
:powershell
)
do
|
s
|
s
.
run
cmd_arr
.
join
(
' '
)
end
end
def
run_wql
(
wql
,
on_error: :raise
)
connection
.
run_wql
(
wql
)
rescue
StandardError
...
...
This diff is collapsed.
Click to expand it.
test/models/foreman_wds/wds_facet_test.rb
+
7
−
1
View file @
91805e1d
...
...
@@ -8,7 +8,7 @@ module ForemanWds
FactoryBot
.
build
(
:wds_server
)
end
let
(
:host
)
do
FactoryBot
.
build
(
:host
,
:managed
,
:with_wds_facet
)
do
FactoryBot
.
build
(
:host
,
:managed
,
:with_wds_facet
)
do
|
host
|
host
.
wds_facet
.
wds_server
=
wds_server
end
end
...
...
@@ -23,6 +23,12 @@ module ForemanWds
end
context
'with WDS server'
do
setup
do
wds_server
.
stubs
(
:run_wql
).
returns
({})
wds_server
.
stubs
(
:run_pwsh
).
with
(
'Get-WDSBootImage'
).
returns
(
OpenStruct
.
new
stdout:
'[]'
)
wds_server
.
stubs
(
:run_pwsh
).
with
(
"Get-WDSInstallImage -ImageName 'install.wim'"
).
returns
(
OpenStruct
.
new
stdout:
'[]'
)
end
it
'does not error'
do
assert_nil
host
.
wds_facet
.
boot_image
assert_nil
host
.
wds_facet
.
install_image
...
...
This diff is collapsed.
Click to expand it.
test/test_plugin_helper.rb
+
45
−
0
View file @
91805e1d
...
...
@@ -21,3 +21,48 @@ ActiveSupport::TestCase.file_fixture_path = File.join(__dir__, 'fixtures')
# Add plugin to FactoryBot's paths
FactoryBot
.
definition_file_paths
<<
File
.
join
(
__dir__
,
'factories'
)
FactoryBot
.
reload
class
ActiveSupport::TestCase
setup
:setup_winrm_stubs
def
stub_winrm_powershell
(
command
=
nil
,
&
block
)
ret
=
if
block_given?
@winrm_shell_mock
[
:powershell
].
stubs
(
:run
).
with
(
&
block
)
else
@winrm_shell_mock
[
:powershell
].
stubs
(
:run
).
with
(
command
)
end
class
<<
ret
def
returns_pwsh
(
value
,
**
params
)
returns
OpenStruct
.
new
(
stdout:
value
,
**
params
)
end
end
ret
end
def
stub_winrm_wql
(
query
=
nil
)
if
query
WinRM
::
Connection
.
any_instance
.
stubs
(
:run_wql
).
with
(
query
)
else
WinRM
::
Connection
.
any_instance
.
stubs
(
:run_wql
)
end
end
private
def
setup_winrm_stubs
return
if
@winrm_mock
@winrm_mock
=
true
require
'winrm'
transport_mock
=
mock
(
'winrm::http::transport'
)
WinRM
::
Connection
.
any_instance
.
stubs
(
:transport
).
returns
(
transport_mock
)
transport_mock
.
stubs
(
:send_request
).
raises
(
StandardError
,
'Real WinRM connections are not allowed'
)
@winrm_shell_mock
=
{
powershell:
mock
(
'winrm::shell::powershell'
)
}
WinRM
::
Connection
.
any_instance
.
stubs
(
:shell
).
with
(
:powershell
).
yields
@winrm_shell_mock
[
:powershell
]
end
end
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment