Skip to content

Commit

Permalink
added nic configuration on intialization
Browse files Browse the repository at this point in the history
Setting the nic configuration on vm creation enables to
set the IP address of the VM statically.

Signed-off-by: Michael Engel <mengel@redhat.com>
  • Loading branch information
engelmi committed Aug 3, 2023
1 parent f2fe2ed commit 91e8911
Show file tree
Hide file tree
Showing 3 changed files with 157 additions and 14 deletions.
105 changes: 100 additions & 5 deletions vm.go
Original file line number Diff line number Diff line change
Expand Up @@ -373,28 +373,33 @@ func VMHugePagesValues() VMHugePagesList {
type Initialization interface {
CustomScript() string
HostName() string
NicConfiguration() NicConfiguration
}

// BuildableInitialization is a buildable version of Initialization.
type BuildableInitialization interface {
Initialization
WithCustomScript(customScript string) BuildableInitialization
WithHostname(hostname string) BuildableInitialization
WithNicConfiguration(nic NicConfiguration) BuildableInitialization
}

// initialization defines to the virtual machine’s initialization configuration.
// customScript - Cloud-init script which will be executed on Virtual Machine when deployed.
// hostname - Hostname to be set to Virtual Machine when deployed.
// nicConfiguration - Optional. The nic configuration used on boot time.
type initialization struct {
customScript string
hostname string
customScript string
hostname string
nicConfiguration NicConfiguration
}

// NewInitialization creates a new Initialization from the specified parameters.
func NewInitialization(customScript, hostname string) Initialization {
func NewInitialization(customScript, hostname string) BuildableInitialization {
return &initialization{
customScript: customScript,
hostname: hostname,
customScript: customScript,
hostname: hostname,
nicConfiguration: nil,
}
}

Expand All @@ -406,6 +411,10 @@ func (i *initialization) HostName() string {
return i.hostname
}

func (i *initialization) NicConfiguration() NicConfiguration {
return i.nicConfiguration
}

func (i *initialization) WithCustomScript(customScript string) BuildableInitialization {
i.customScript = customScript
return i
Expand All @@ -416,6 +425,78 @@ func (i *initialization) WithHostname(hostname string) BuildableInitialization {
return i
}

func (i *initialization) WithNicConfiguration(nic NicConfiguration) BuildableInitialization {
i.nicConfiguration = nic
return i
}

type IpVersion string

const (
IPVERSION_V4 IpVersion = "v4"
IPVERSION_V6 IpVersion = "v6"
)

// Ip Represents the IP configuration of a network interface.
type IP struct {
Address string
Gateway string
Netmask string
Version IpVersion
}

func (ip IP) IsIPv4() bool {
return ip.Version == IPVERSION_V4
}

func (ip IP) IsIPv6() bool {
return ip.Version == IPVERSION_V6
}

// NicConfiguration defines a virtual machine’s initialization nic configuration.
type NicConfiguration interface {
Name() string
IP() IP
}

// BuildableNicConfiguration is a buildable version of NicConfiguration.
type BuildableNicConfiguration interface {
NicConfiguration
WithName(name string) BuildableNicConfiguration
WithIP(ip IP) BuildableNicConfiguration
}

type nicConfiguration struct {
name string
ip IP
}

// NewNicConfiguration creates a new NicConfiguration from the specified parameters.
func NewNicConfiguration(name string, ip IP) NicConfiguration {
return &nicConfiguration{
name: name,
ip: ip,
}
}

func (i *nicConfiguration) Name() string {
return i.name
}

func (i *nicConfiguration) IP() IP {
return i.ip
}

func (i *nicConfiguration) WithName(name string) BuildableNicConfiguration {
i.name = name
return i
}

func (i *nicConfiguration) WithIP(ip IP) BuildableNicConfiguration {
i.ip = ip
return i
}

// convertSDKInitialization converts the initialization of a VM. We keep the error return in case we need it later
// as errors may happen as we extend this function and we don't want to touch other functions.
func convertSDKInitialization(sdkObject *ovirtsdk.Vm) (*initialization, error) { //nolint:unparam
Expand All @@ -434,9 +515,23 @@ func convertSDKInitialization(sdkObject *ovirtsdk.Vm) (*initialization, error) {
if ok {
init.hostname = hostname
}
nicConfigs, ok := initializationSDK.NicConfigurations()
if ok && len(nicConfigs.Slice()) >= 1 {
init.nicConfiguration = convertSDKNicConfiguration(nicConfigs.Slice()[0])
}
return &init, nil
}

func convertSDKNicConfiguration(sdkObject *ovirtsdk.NicConfiguration) NicConfiguration {
ip := sdkObject.MustIp()
return NewNicConfiguration(sdkObject.MustName(), IP{
Address: ip.MustAddress(),
Gateway: ip.MustGateway(),
Netmask: ip.MustNetmask(),
Version: IpVersion(ip.MustVersion()),
})
}

// VM is the implementation of the virtual machine in oVirt.
type VM interface {
VMData
Expand Down
36 changes: 28 additions & 8 deletions vm_create.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,17 +65,37 @@ func vmBuilderMemory(params OptionalVMParameters, builder *ovirtsdk.VmBuilder) {
}

func vmBuilderInitialization(params OptionalVMParameters, builder *ovirtsdk.VmBuilder) {
if init := params.Initialization(); init != nil {
initBuilder := ovirtsdk.NewInitializationBuilder()
if params.Initialization() == nil {
return
}

if init.CustomScript() != "" {
initBuilder.CustomScript(init.CustomScript())
}
if init.HostName() != "" {
initBuilder.HostName(init.HostName())
init := params.Initialization()
initBuilder := ovirtsdk.NewInitializationBuilder()

if init.CustomScript() != "" {
initBuilder.CustomScript(init.CustomScript())
}
if init.HostName() != "" {
initBuilder.HostName(init.HostName())
}
if nicConf := init.NicConfiguration(); nicConf != nil {
ipBuilder := ovirtsdk.NewIpBuilder().
Address(nicConf.IP().Address).
Gateway(nicConf.IP().Gateway).
Netmask(nicConf.IP().Netmask)
ipBuilder.Version(ovirtsdk.IPVERSION_V4)
if nicConf.IP().IsIPv6() {
ipBuilder.Version(ovirtsdk.IPVERSION_V4)
}
builder.InitializationBuilder(initBuilder)

nicBuilder := ovirtsdk.NewNicConfigurationBuilder()
nicBuilder.BootProtocol(ovirtsdk.BOOTPROTOCOL_STATIC)
nicBuilder.OnBoot(true)
nicBuilder.Ip(ipBuilder.MustBuild())

initBuilder.NicConfigurationsOfAny(nicBuilder.MustBuild())
}
builder.InitializationBuilder(initBuilder)
}

func vmPlacementPolicyParameterConverter(params OptionalVMParameters, builder *ovirtsdk.VmBuilder) {
Expand Down
30 changes: 29 additions & 1 deletion vm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -220,12 +220,22 @@ func TestVMCreationWithInit(t *testing.T) {
ovirtclient.CreateVMParams(),
)
tpl := assertCanCreateTemplate(t, helper, vm1)

init := ovirtclient.NewInitialization("script-test", "test-vm").WithNicConfiguration(
ovirtclient.NewNicConfiguration("custom-nic", ovirtclient.IP{
Version: ovirtclient.IPVERSION_V4,
Address: "192.168.178.15",
Gateway: "192.168.19.1",
Netmask: "255.255.255.0",
}),
)

vm2 := assertCanCreateVMFromTemplate(
t,
helper,
fmt.Sprintf("test-%s", helper.GenerateRandomID(5)),
tpl.ID(),
ovirtclient.CreateVMParams().MustWithInitializationParameters("script-test", "test-vm"),
ovirtclient.CreateVMParams().MustWithInitialization(init),
)

if vm2.Initialization().CustomScript() != "script-test" {
Expand All @@ -235,6 +245,24 @@ func TestVMCreationWithInit(t *testing.T) {
if vm2.Initialization().HostName() != "test-vm" {
t.Fatalf("got Unexpected output from the HostName (%s) init field ", vm2.Initialization().HostName())
}

if vm2.Initialization().NicConfiguration() == nil {
t.Fatalf("got Unexpected output from the NicConfiguration (%s) init field ", vm2.Initialization().NicConfiguration())
}

if vm2.Initialization().NicConfiguration().Name() != "custom-nic" {
t.Fatalf("got Unexpected output from the NicConfiguration.Name (%s) init field ", vm2.Initialization().NicConfiguration().Name())
}

if vm2.Initialization().NicConfiguration().IP().Address != "192.168.178.15" {
t.Fatalf("got Unexpected output from the NicConfiguration.IP.Address (%s) init field ", vm2.Initialization().NicConfiguration().IP().Address)
}
if vm2.Initialization().NicConfiguration().IP().Gateway != "192.168.19.1" {
t.Fatalf("got Unexpected output from the NicConfiguration.IP.Gateway (%s) init field ", vm2.Initialization().NicConfiguration().IP().Gateway)
}
if vm2.Initialization().NicConfiguration().IP().Netmask != "255.255.255.0" {
t.Fatalf("got Unexpected output from the NicConfiguration.IP.Netmask (%s) init field ", vm2.Initialization().NicConfiguration().IP().Netmask)
}
}

func TestVMCreationWithDescription(t *testing.T) {
Expand Down

0 comments on commit 91e8911

Please sign in to comment.