forked from hashicorp/packer-plugin-vsphere
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'hashicorp:main' into main
- Loading branch information
Showing
18 changed files
with
536 additions
and
106 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
// Copyright (c) HashiCorp, Inc. | ||
// SPDX-License-Identifier: MPL-2.0 | ||
|
||
//go:generate packer-sdc struct-markdown | ||
//go:generate packer-sdc mapstructure-to-hcl2 -type FlagConfig | ||
|
||
package common | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
|
||
"github.com/hashicorp/packer-plugin-sdk/multistep" | ||
packersdk "github.com/hashicorp/packer-plugin-sdk/packer" | ||
"github.com/hashicorp/packer-plugin-vsphere/builder/vsphere/driver" | ||
"github.com/vmware/govmomi/vim25/types" | ||
) | ||
|
||
type FlagConfig struct { | ||
// Enable Virtualization Based Security option for virtual machine. Defaults to `false`. | ||
// Requires `vvtd_enabled` and `NestedHV` to be set to `true`. | ||
// Requires `vTPM` to be set to `true`. | ||
// Requires `firmware` to be set to `efi-secure`. | ||
VbsEnabled bool `mapstructure:"vbs_enabled"` | ||
// Enable IO/MMU option for virtual machine. Defaults to `false`. | ||
VvtdEnabled bool `mapstructure:"vvtd_enabled"` | ||
} | ||
|
||
func (c *FlagConfig) Prepare(h *HardwareConfig) []error { | ||
var errs []error | ||
|
||
if h == nil { | ||
return append(errs, fmt.Errorf("no hardware config provided")) | ||
} | ||
|
||
if c.VbsEnabled { | ||
if !c.VvtdEnabled { | ||
errs = append(errs, fmt.Errorf("`vvtd_enabled` must be set to `true` when `vbs_enabled` is set to `true`")) | ||
} | ||
|
||
if !h.NestedHV { | ||
errs = append(errs, fmt.Errorf("`nestedhv` must be set to `true` when `vbs_enabled` is set to `true`")) | ||
} | ||
|
||
if !h.VTPMEnabled { | ||
errs = append(errs, fmt.Errorf("`vtpm` must be set to `true` when `vbs_enabled` is set to `true`")) | ||
} | ||
|
||
if h.Firmware != "efi-secure" { | ||
errs = append(errs, fmt.Errorf("`firmware` must be set to `efi-secure` when `vbs_enabled` is set to `true`")) | ||
} | ||
} | ||
|
||
return errs | ||
} | ||
|
||
type StepAddFlag struct { | ||
FlagConfig FlagConfig | ||
} | ||
|
||
func (s *StepAddFlag) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction { | ||
ui := state.Get("ui").(packersdk.Ui) | ||
vm := state.Get("vm").(driver.VirtualMachine) | ||
|
||
var info *types.VirtualMachineFlagInfo | ||
|
||
if s.FlagConfig.VbsEnabled || s.FlagConfig.VvtdEnabled { | ||
info = &types.VirtualMachineFlagInfo{} | ||
|
||
if s.FlagConfig.VbsEnabled { | ||
info.VbsEnabled = &s.FlagConfig.VbsEnabled | ||
} | ||
|
||
if s.FlagConfig.VvtdEnabled { | ||
info.VvtdEnabled = &s.FlagConfig.VvtdEnabled | ||
} | ||
|
||
ui.Say("Adding virtual machine flags...") | ||
if err := vm.AddFlag(ctx, info); err != nil { | ||
state.Put("error", fmt.Errorf("error adding virtual machine flag: %v", err)) | ||
return multistep.ActionHalt | ||
} | ||
} | ||
|
||
return multistep.ActionContinue | ||
} | ||
|
||
func (s *StepAddFlag) Cleanup(state multistep.StateBag) { | ||
// Nothing to clean up. | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,196 @@ | ||
// Copyright (c) HashiCorp, Inc. | ||
// SPDX-License-Identifier: MPL-2.0 | ||
|
||
package common | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"testing" | ||
|
||
"github.com/google/go-cmp/cmp" | ||
"github.com/google/go-cmp/cmp/cmpopts" | ||
"github.com/hashicorp/packer-plugin-sdk/multistep" | ||
"github.com/hashicorp/packer-plugin-vsphere/builder/vsphere/driver" | ||
) | ||
|
||
func TestFlagConfig_Prepare(t *testing.T) { | ||
tc := []struct { | ||
name string | ||
config *FlagConfig | ||
hardwareConfig *HardwareConfig | ||
fail bool | ||
expectedErrMsg string | ||
}{ | ||
{ | ||
name: "Should not fail for empty config", | ||
config: new(FlagConfig), | ||
hardwareConfig: new(HardwareConfig), | ||
fail: false, | ||
expectedErrMsg: "", | ||
}, | ||
{ | ||
name: "VbsEnabled but VvtdEnabled not set", | ||
config: &FlagConfig{ | ||
VbsEnabled: true, | ||
}, | ||
hardwareConfig: &HardwareConfig{ | ||
Firmware: "efi-secure", | ||
NestedHV: true, | ||
VTPMEnabled: true, | ||
}, | ||
fail: true, | ||
expectedErrMsg: "`vvtd_enabled` must be set to `true` when `vbs_enabled` is set to `true`", | ||
}, | ||
{ | ||
name: "VbsEnabled but NestedHV not set", | ||
config: &FlagConfig{ | ||
VbsEnabled: true, | ||
VvtdEnabled: true, | ||
}, | ||
hardwareConfig: &HardwareConfig{ | ||
Firmware: "efi-secure", | ||
VTPMEnabled: true, | ||
}, | ||
fail: true, | ||
expectedErrMsg: "`nestedhv` must be set to `true` when `vbs_enabled` is set to `true`", | ||
}, | ||
{ | ||
name: "VbsEnabled but VTPMEnabled not set", | ||
config: &FlagConfig{ | ||
VbsEnabled: true, | ||
VvtdEnabled: true, | ||
}, | ||
hardwareConfig: &HardwareConfig{ | ||
NestedHV: true, | ||
Firmware: "efi-secure", | ||
}, | ||
fail: true, | ||
expectedErrMsg: "`vtpm` must be set to `true` when `vbs_enabled` is set to `true`", | ||
}, | ||
{ | ||
name: "VbsEnabled but Firmware not set to efi-secure", | ||
config: &FlagConfig{ | ||
VbsEnabled: true, | ||
VvtdEnabled: true, | ||
}, | ||
hardwareConfig: &HardwareConfig{ | ||
NestedHV: true, | ||
VTPMEnabled: true, | ||
Firmware: "efi", | ||
}, | ||
fail: true, | ||
expectedErrMsg: "`firmware` must be set to `efi-secure` when `vbs_enabled` is set to `true`", | ||
}, | ||
{ | ||
name: "VbsEnabled and all required fields set", | ||
config: &FlagConfig{ | ||
VbsEnabled: true, | ||
VvtdEnabled: true, | ||
}, | ||
hardwareConfig: &HardwareConfig{ | ||
NestedHV: true, | ||
VTPMEnabled: true, | ||
Firmware: "efi-secure", | ||
}, | ||
fail: false, | ||
expectedErrMsg: "", | ||
}, | ||
} | ||
|
||
for _, c := range tc { | ||
errs := c.config.Prepare(c.hardwareConfig) | ||
if c.fail { | ||
if len(errs) == 0 { | ||
t.Fatalf("Config prepare should fail") | ||
} | ||
if errs[0].Error() != c.expectedErrMsg { | ||
t.Fatalf("Expected error message: %s but was '%s'", c.expectedErrMsg, errs[0].Error()) | ||
} | ||
} else { | ||
if len(errs) != 0 { | ||
t.Fatalf("Config prepare should not fail") | ||
} | ||
} | ||
} | ||
} | ||
|
||
func TestStepAddFlag_Run(t *testing.T) { | ||
tc := []struct { | ||
name string | ||
state *multistep.BasicStateBag | ||
step *StepAddFlag | ||
vmMock *driver.VirtualMachineMock | ||
expectedAction multistep.StepAction | ||
expectedVmMock *driver.VirtualMachineMock | ||
fail bool | ||
errMessage string | ||
}{ | ||
{ | ||
name: "Add Flag", | ||
state: basicStateBag(nil), | ||
step: &StepAddFlag{ | ||
FlagConfig: FlagConfig{ | ||
VbsEnabled: true, | ||
VvtdEnabled: true, | ||
}, | ||
}, | ||
vmMock: new(driver.VirtualMachineMock), | ||
expectedAction: multistep.ActionContinue, | ||
expectedVmMock: &driver.VirtualMachineMock{ | ||
AddFlagCalled: true, | ||
AddFlagCalledTimes: 1, | ||
AddFlagVbsEnabledValues: true, | ||
AddFlagVvtdEnabledValues: true, | ||
}, | ||
fail: false, | ||
errMessage: "", | ||
}, | ||
{ | ||
name: "Fail to add flag", | ||
state: basicStateBag(nil), | ||
step: &StepAddFlag{ | ||
FlagConfig: FlagConfig{ | ||
VbsEnabled: true, | ||
VvtdEnabled: false, | ||
}, | ||
}, | ||
vmMock: &driver.VirtualMachineMock{ | ||
AddFlagErr: fmt.Errorf("AddFlag error"), | ||
}, | ||
expectedAction: multistep.ActionHalt, | ||
expectedVmMock: &driver.VirtualMachineMock{ | ||
AddFlagCalled: true, | ||
AddFlagCalledTimes: 1, | ||
AddFlagVbsEnabledValues: true, | ||
AddFlagVvtdEnabledValues: false, | ||
}, | ||
fail: true, | ||
errMessage: fmt.Sprintf("error adding virtual machine flag: %v", fmt.Errorf("AddFlag error")), | ||
}, | ||
} | ||
|
||
for _, c := range tc { | ||
t.Run(c.name, func(t *testing.T) { | ||
c.state.Put("vm", c.vmMock) | ||
if action := c.step.Run(context.TODO(), c.state); action != c.expectedAction { | ||
t.Fatalf("unexpected action %v", action) | ||
} | ||
err, ok := c.state.Get("error").(error) | ||
if ok { | ||
if err.Error() != c.errMessage { | ||
t.Fatalf("unexpected error %s", err.Error()) | ||
} | ||
} else { | ||
if c.fail { | ||
t.Fatalf("expected to fail but it didn't") | ||
} | ||
} | ||
|
||
if diff := cmp.Diff(c.vmMock, c.expectedVmMock, | ||
cmpopts.IgnoreInterfaces(struct{ error }{})); diff != "" { | ||
t.Fatalf("unexpected VirtualMachine calls: %s", diff) | ||
} | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.