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
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
...
@@ -49,12 +49,9 @@ class WdsServer < ApplicationRecord
objects
=
run_wql
(
'SELECT * FROM MSFT_WdsClient'
,
on_error:
{})[
:msft_wdsclient
]
objects
=
run_wql
(
'SELECT * FROM MSFT_WdsClient'
,
on_error:
{})[
:msft_wdsclient
]
objects
=
nil
if
objects
&
.
empty?
objects
=
nil
if
objects
&
.
empty?
objects
||=
begin
objects
||=
begin
data
=
connection
.
shell
(
:powershell
)
do
|
s
|
clients
=
run_pwsh
(
'Get-WdsClient'
).
stdout
s
.
run
(
'Get-WdsClient | ConvertTo-Json -Compress'
)
clients
=
'[]'
if
clients
.
empty?
end
.
stdout
underscore_result
([
JSON
.
parse
(
clients
)].
flatten
)
data
=
'[]'
if
data
.
empty?
underscore_result
([
JSON
.
parse
(
data
)].
flatten
)
end
end
objects
objects
...
@@ -82,18 +79,14 @@ class WdsServer < ApplicationRecord
...
@@ -82,18 +79,14 @@ class WdsServer < ApplicationRecord
raise
NotImplementedError
,
'Not finished yet'
raise
NotImplementedError
,
'Not finished yet'
ensure_unattend
(
host
)
ensure_unattend
(
host
)
connection
.
shell
(
:powershell
)
do
|
sh
|
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'"
)
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
end
end
def
delete_client
(
host
)
def
delete_client
(
host
)
raise
NotImplementedError
,
'Not finished yet'
raise
NotImplementedError
,
'Not finished yet'
delete_unattend
(
host
)
delete_unattend
(
host
)
connection
.
shell
(
:powershell
)
do
|
sh
|
run_pwsh
(
"Remove-WdsClient -DeviceID '
#{
host
.
mac
.
upcase
.
delete
':'
}
'"
,
json:
false
)
sh
.
run
(
"Remove-WdsClient -DeviceID '
#{
host
.
mac
.
upcase
.
delete
':'
}
'"
)
end
end
end
def
all_images
def
all_images
...
@@ -162,9 +155,10 @@ class WdsServer < ApplicationRecord
...
@@ -162,9 +155,10 @@ class WdsServer < ApplicationRecord
def
unattend_path
def
unattend_path
cache
.
cache
(
:unattend_path
)
do
cache
.
cache
(
:unattend_path
)
do
JSON
.
parse
(
connection
.
shell
(
:powershell
)
do
|
sh
|
JSON
.
parse
(
sh
.
run
(
'Get-ItemProperty -Path HKLM:\SYSTEM\CurrentControlSet\Services\WDSServer\Providers\WDSTFTP -Name RootFolder | select RootFolder | ConvertTo-Json -Compress'
)
run_pwsh
(
'Get-ItemProperty -Path HKLM:\SYSTEM\CurrentControlSet\Services\WDSServer\Providers\WDSTFTP -Name RootFolder | select RootFolder'
),
end
,
symbolize_names:
true
)[
:RootFolder
]
symbolize_names:
true
)[
:RootFolder
]
end
end
end
end
...
@@ -187,6 +181,7 @@ class WdsServer < ApplicationRecord
...
@@ -187,6 +181,7 @@ class WdsServer < ApplicationRecord
raise
'No provisioning interface available'
unless
iface
raise
'No provisioning interface available'
unless
iface
raise
NotImplementedException
,
'TODO: Not implemented yet'
raise
NotImplementedException
,
'TODO: Not implemented yet'
raise
NotImplementedException
,
'TODO: Not implemented yet'
if
SETTINGS
[
:wds_unattend_group
]
# TODO: render template, send as heredoc
# TODO: render template, send as heredoc
template
=
host
.
operatingsystem
.
provisioning_templates
.
find
{
|
t
|
t
.
template_kind
.
name
==
'wds_unattend'
}
template
=
host
.
operatingsystem
.
provisioning_templates
.
find
{
|
t
|
t
.
template_kind
.
name
==
'wds_unattend'
}
...
@@ -198,33 +193,33 @@ class WdsServer < ApplicationRecord
...
@@ -198,33 +193,33 @@ class WdsServer < ApplicationRecord
template_data
=
host
.
render_template
template:
template
template_data
=
host
.
render_template
template:
template
connection
.
shell
(
:powershell
)
do
|
sh
|
file_path
=
unattend_file
(
host
)
file_path
=
unattend_file
(
host
)
script
=
[]
script
<<
"$unattend_render = @'
\n
#{
template_data
}
\n
'@"
sh
.
run
(
"$unattend_render = @'
\n
#{
template_data
}
\n
'@"
)
script
<<
"New-Item -Path '
#{
file_path
}
' -ItemType 'file' -Value $unattend_render"
sh
.
run
(
"New-Item -Path '
#{
file_path
}
' -ItemType 'file' -Value $unattend_render"
)
source_image
=
host
.
wds_facet
.
install_image
source_image
=
host
.
wds_facet
.
install_image
target_image
=
target_image_for
(
host
)
target_image
=
target_image_for
(
host
)
if
SETTINGS
[
:wds_unattend_group
]
if
SETTINGS
[
:wds_unattend_group
]
raise
NotImplementedException
,
'TODO: Not implemented yet'
# New-WdsInstallImageGroup -Name #{SETTINGS[:wds_unattend_group]}
# New-WdsInstallImageGroup -Name #{SETTINGS[:wds_unattend_group]}
# Export-WdsInstallImage -ImageGroup <Group> ...
# Export-WdsInstallImage -ImageGroup <Group> ...
# Import-WdsInstallImage -ImageGroup #{SETTINGS[:wds_unattend_group]} -UnattendFile '#{file_path}' -OverwriteUnattend ...
# Import-WdsInstallImage -ImageGroup #{SETTINGS[:wds_unattend_group]} -UnattendFile '#{file_path}' -OverwriteUnattend ...
else
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
}
'"
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
}
'"
)
script
<<
"Set-WdsInstallImage -ImageGroup '
#{
target_image
.
image_group
}
' -FileName '
#{
target_image
.
file_name
}
' -ImageName '
#{
target_image
.
image_name
}
' -DisplayOrder 99999 -UnattendFile '
#{
file_path
}
' -OverwriteUnattend"
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
end
end
run_pwsh
script
.
join
(
"
\n
"
),
json:
false
end
end
def
delete_unattend
(
host
)
def
delete_unattend
(
host
)
image
=
target_image_for
(
host
)
image
=
target_image_for
(
host
)
co
nnection
.
shell
(
:powershell
)
do
|
sh
|
co
mmand
=
[]
sh
.
run
(
"Remove-WdsInstallImage -ImageGroup '
#{
image
.
image_group
}
' -ImageName '
#{
image
.
image_name
}
' -FileName '
#{
image
.
file_name
}
'"
)
command
<<
"Remove-WdsInstallImage -ImageGroup '
#{
image
.
image_group
}
' -ImageName '
#{
image
.
image_name
}
' -FileName '
#{
image
.
file_name
}
'"
sh
.
run
(
"Remove-Item -Path '
#{
unattend_file
(
host
)
}
'"
)
command
<<
"Remove-Item -Path '
#{
unattend_file
(
host
)
}
'"
end
.
errcode
.
zero?
run_pwsh
(
command
.
join
(
"
\n
"
),
json:
false
)
.
errcode
.
zero?
end
end
def
ensure_client
(
_host
)
def
ensure_client
(
_host
)
...
@@ -242,14 +237,12 @@ class WdsServer < ApplicationRecord
...
@@ -242,14 +237,12 @@ class WdsServer < ApplicationRecord
objects
=
nil
if
objects
.
empty?
objects
=
nil
if
objects
.
empty?
unless
objects
unless
objects
begin
result
=
run_pwsh
"Get-WDS
#{
type
.
to_s
.
capitalize
}
Image
#{
" -ImageName '
#{
name
.
sub
(
"'"
,
"`'"
)
}
'"
if
name
}
"
result
=
connection
.
shell
(
:powershell
)
do
|
s
|
s
.
run
(
"Get-WDS
#{
type
.
to_s
.
capitalize
}
Image
#{
"-ImageName '
#{
name
.
sub
(
"'"
,
"`'"
)
}
'"
if
name
}
| ConvertTo-Json -Compress"
)
end
begin
objects
=
underscore_result
([
JSON
.
parse
(
result
.
stdout
)].
flatten
)
objects
=
underscore_result
([
JSON
.
parse
(
result
.
stdout
)].
flatten
)
rescue
JSON
::
ParserError
=>
e
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
raise
e
end
end
end
end
...
@@ -270,6 +263,14 @@ class WdsServer < ApplicationRecord
...
@@ -270,6 +263,14 @@ class WdsServer < ApplicationRecord
end
end
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
)
def
run_wql
(
wql
,
on_error: :raise
)
connection
.
run_wql
(
wql
)
connection
.
run_wql
(
wql
)
rescue
StandardError
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
...
@@ -8,7 +8,7 @@ module ForemanWds
FactoryBot
.
build
(
:wds_server
)
FactoryBot
.
build
(
:wds_server
)
end
end
let
(
:host
)
do
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
host
.
wds_facet
.
wds_server
=
wds_server
end
end
end
end
...
@@ -23,6 +23,12 @@ module ForemanWds
...
@@ -23,6 +23,12 @@ module ForemanWds
end
end
context
'with WDS server'
do
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
it
'does not error'
do
assert_nil
host
.
wds_facet
.
boot_image
assert_nil
host
.
wds_facet
.
boot_image
assert_nil
host
.
wds_facet
.
install_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')
...
@@ -21,3 +21,48 @@ ActiveSupport::TestCase.file_fixture_path = File.join(__dir__, 'fixtures')
# Add plugin to FactoryBot's paths
# Add plugin to FactoryBot's paths
FactoryBot
.
definition_file_paths
<<
File
.
join
(
__dir__
,
'factories'
)
FactoryBot
.
definition_file_paths
<<
File
.
join
(
__dir__
,
'factories'
)
FactoryBot
.
reload
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