Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extend nic with mac #240

Merged
merged 11 commits into from
Nov 29, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 10 additions & 10 deletions disk_helper_imagetransfer.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,16 @@ func generateCorrelationID(prefix string) string {
// newImageTransfer creates a new image transfer for both uploads and downloads of images. It must be passed the
// following parameters:
//
// - cli is the oVirt SDK client.
// - logger is a logger from the go-ovirt-client-logger library
// - diskID is the ID of the disk that is being transferred to/from.
// - correlationID is an optional unique ID that can be used to check if the job completed. If no correlation ID is
// passed, this function generates a random one.
// - retries is a list of retry strategies to use for each API call.
// - direction is the direction of transfer. See ovirtsdk.ImageTransferDirection.
// - format is the disk format being uploaded, or the disk format requested. The oVirt Engine will automatically convert
// images to the requested format.
// - updateDisk is a function that will be called whenever the disk object is updated.
// - cli is the oVirt SDK client.
// - logger is a logger from the go-ovirt-client-logger library
// - diskID is the ID of the disk that is being transferred to/from.
// - correlationID is an optional unique ID that can be used to check if the job completed. If no correlation ID is
// passed, this function generates a random one.
// - retries is a list of retry strategies to use for each API call.
// - direction is the direction of transfer. See ovirtsdk.ImageTransferDirection.
// - format is the disk format being uploaded, or the disk format requested. The oVirt Engine will automatically convert
// images to the requested format.
// - updateDisk is a function that will be called whenever the disk object is updated.
func newImageTransfer(
cli *oVirtClient,
logger Logger,
Expand Down
50 changes: 25 additions & 25 deletions new.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,63 +77,63 @@ func (e *extraSettings) WithProxy(addr string) ExtraSettingsBuilder {

// New creates a new copy of the enhanced oVirt client. It accepts the following options:
//
// url
// url
//
// This is the oVirt engine URL. This must start with http:// or https:// and typically ends with /ovirt-engine/.
//
// username
// username
//
// This is the username for the oVirt engine. This must contain the profile separated with an @ sign. For example,
// admin@internal.
//
// password
// password
//
// This is the password for the oVirt engine. Other authentication mechanisms are not supported.
//
// tls
// tls
//
// This is a TLSProvider responsible for supplying TLS configuration to the client. See below for a simple example.
//
// logger
// logger
//
// This is an implementation of ovirtclientlog.Logger to provide logging.
//
// extraSettings
// extraSettings
//
// This is an implementation of the ExtraSettings interface, allowing for customization of headers and turning on
// compression.
//
// TLS
// # TLS
//
// This library tries to follow best practices when it comes to connection security. Therefore, you will need to pass
// a valid implementation of the TLSProvider interface in the tls parameter. The easiest way to do this is calling
// the ovirtclient.TLS() function and then configuring the resulting variable with the following functions:
//
// tls := ovirtclient.TLS()
// tls := ovirtclient.TLS()
//
// // Add certificates from an in-memory byte slice. Certificates must be in PEM format.
// tls.CACertsFromMemory(caCerts)
// // Add certificates from an in-memory byte slice. Certificates must be in PEM format.
// tls.CACertsFromMemory(caCerts)
//
// // Add certificates from a single file. Certificates must be in PEM format.
// tls.CACertsFromFile("/path/to/file.pem")
// // Add certificates from a single file. Certificates must be in PEM format.
// tls.CACertsFromFile("/path/to/file.pem")
//
// // Add certificates from a directory. Optionally, regular expressions can be passed that must match the file
// // names.
// tls.CACertsFromDir("/path/to/certs", regexp.MustCompile(`\.pem`))
// // Add certificates from a directory. Optionally, regular expressions can be passed that must match the file
// // names.
// tls.CACertsFromDir("/path/to/certs", regexp.MustCompile(`\.pem`))
//
// // Add system certificates
// tls.CACertsFromSystem()
// // Add system certificates
// tls.CACertsFromSystem()
//
// // Disable certificate verification. This is a bad idea.
// tls.Insecure()
// // Disable certificate verification. This is a bad idea.
// tls.Insecure()
//
// client, err := ovirtclient.New(
// url, username, password,
// tls,
// logger, extraSettings
// )
// client, err := ovirtclient.New(
// url, username, password,
// tls,
// logger, extraSettings
// )
//
// Extra settings
// # Extra settings
//
// This library also supports customizing the connection settings. In order to stay backwards compatible the
// extraSettings parameter must implement the ovirtclient.ExtraSettings interface. Future versions of this library will
Expand Down
1 change: 1 addition & 0 deletions newmock.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (

// NewMock creates a new in-memory mock client. This client can be used as a testing facility for
// higher level code.
//
//goland:noinspection GoUnusedExportedFunction
func NewMock() MockClient {
return NewMockWithLogger(&noopLogger{})
Expand Down
87 changes: 85 additions & 2 deletions nic.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,20 +33,48 @@ type NICClient interface {
}

// OptionalNICParameters is an interface that declares the source of optional parameters for NIC creation.
type OptionalNICParameters interface{}
type OptionalNICParameters interface {
// represent mac_address for NIC
Mac() string
}

// BuildableNICParameters is a modifiable version of OptionalNICParameters. You can use CreateNICParams() to create a
// new copy, or implement your own.
type BuildableNICParameters interface {
OptionalNICParameters

// WithMac sets macAddress for the NIC.
WithMac(mac string) (BuildableNICParameters, error)

// MustWithMac is the same as WithMac, but panics instead of returning an error.
MustWithMac(mac string) BuildableNICParameters
}

// CreateNICParams returns a buildable structure of OptionalNICParameters.
func CreateNICParams() BuildableNICParameters {
return &nicParams{}
}

type nicParams struct{}
type nicParams struct {
mac string
}

func (c *nicParams) Mac() string {
return c.mac
}

func (c *nicParams) WithMac(mac string) (BuildableNICParameters, error) {
c.mac = mac
return c, nil
}

func (c *nicParams) MustWithMac(mac string) BuildableNICParameters {
builder, err := c.WithMac(mac)
if err != nil {
panic(err)
}
return builder
}

// UpdateNICParameters is an interface that declares methods of changeable parameters for NIC's. Each
// method can return nil to leave an attribute unchanged, or a new value for the attribute.
Expand All @@ -56,6 +84,9 @@ type UpdateNICParameters interface {

// VNICProfileID potentially returns a change VNIC profile for a NIC.
VNICProfileID() *VNICProfileID

// Mac potentially returns a change MacAddress for a nic
Mac() *string
}

// BuildableUpdateNICParameters is a buildable version of UpdateNICParameters.
Expand All @@ -71,6 +102,11 @@ type BuildableUpdateNICParameters interface {
WithVNICProfileID(id VNICProfileID) (BuildableUpdateNICParameters, error)
// MustWithVNICProfileID is identical to WithVNICProfileID, but panics instead of returning an error.
MustWithVNICProfileID(id VNICProfileID) BuildableUpdateNICParameters

// WithMac sets MaAddress of a NIC for the UpdateNIC method.
WithMac(mac string) (BuildableUpdateNICParameters, error)
// MustWithMac is identical to WithMac, but panics instead of returning an error.
MustWithMac(mac string) BuildableUpdateNICParameters
}

// UpdateNICParams creates a buildable UpdateNICParameters.
Expand All @@ -81,6 +117,7 @@ func UpdateNICParams() BuildableUpdateNICParameters {
type updateNICParams struct {
name *string
vnicProfileID *VNICProfileID
mac *string
}

func (u *updateNICParams) Name() *string {
Expand All @@ -91,6 +128,10 @@ func (u *updateNICParams) VNICProfileID() *VNICProfileID {
return u.vnicProfileID
}

func (u *updateNICParams) Mac() *string {
return u.mac
}

func (u *updateNICParams) WithName(name string) (BuildableUpdateNICParameters, error) {
u.name = &name
return u, nil
Expand All @@ -117,6 +158,19 @@ func (u *updateNICParams) MustWithVNICProfileID(id VNICProfileID) BuildableUpdat
return b
}

func (u *updateNICParams) WithMac(mac string) (BuildableUpdateNICParameters, error) {
u.mac = &mac
return u, nil
}

func (u *updateNICParams) MustWithMac(mac string) BuildableUpdateNICParameters {
b, err := u.WithMac(mac)
if err != nil {
panic(err)
}
return b
}

// NICData is the core of NIC which only provides data-access functions.
type NICData interface {
// ID is the identifier for this network interface.
Expand All @@ -127,6 +181,8 @@ type NICData interface {
VMID() VMID
// VNICProfileID returns the ID of the VNIC profile in use by the NIC.
VNICProfileID() VNICProfileID
// Mac returns a MacAddress for a nic
Mac() string
}

// NIC represents a network interface.
Expand Down Expand Up @@ -170,12 +226,21 @@ func convertSDKNIC(sdkObject *ovirtsdk.Nic, cli Client) (NIC, error) {
if !ok {
return nil, newFieldNotFound("vNIC Profile on VM", "ID")
}
mac, ok := sdkObject.Mac()
if !ok {
return nil, newFieldNotFound("mac", "NIC")
}
macAddr, ok := mac.Address()
if !ok {
return nil, newFieldNotFound("address", "mac")
}
return &nic{
cli,
NICID(id),
name,
VMID(vmid),
VNICProfileID(vnicProfileID),
macAddr,
}, nil
}

Expand All @@ -186,6 +251,7 @@ type nic struct {
name string
vmid VMID
vnicProfileID VNICProfileID
mac string
}

func (n nic) Update(params UpdateNICParameters, retries ...RetryStrategy) (NIC, error) {
Expand Down Expand Up @@ -216,6 +282,10 @@ func (n nic) VMID() VMID {
return n.vmid
}

func (n nic) Mac() string {
return n.mac
}

func (n nic) Remove(retries ...RetryStrategy) error {
return n.client.RemoveNIC(n.vmid, n.id, retries...)
}
Expand All @@ -227,6 +297,7 @@ func (n nic) withName(name string) *nic {
name: name,
vmid: n.vmid,
vnicProfileID: n.vnicProfileID,
mac: n.mac,
}
}

Expand All @@ -237,5 +308,17 @@ func (n nic) withVNICProfileID(vnicProfileID VNICProfileID) *nic {
name: n.name,
vmid: n.vmid,
vnicProfileID: vnicProfileID,
mac: n.mac,
}
}

func (n nic) withMac(mac string) *nic {
return &nic{
client: n.client,
id: n.id,
name: n.name,
vmid: n.vmid,
vnicProfileID: n.vnicProfileID,
mac: mac,
}
}
35 changes: 33 additions & 2 deletions nic_create.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package ovirtclient

import (
"fmt"
"net"

"github.com/google/uuid"
ovirtsdk "github.com/ovirt/go-ovirt"
Expand All @@ -11,13 +12,21 @@ func (o *oVirtClient) CreateNIC(
vmid VMID,
vnicProfileID VNICProfileID,
name string,
_ OptionalNICParameters,
params OptionalNICParameters,
retries ...RetryStrategy,
) (result NIC, err error) {
if err := validateNICCreationParameters(vmid, name); err != nil {
return nil, err
}

var mac string
if params != nil {
if err := validateNICCreationOptionalParameters(params); err != nil {
return nil, err
}
mac = params.Mac()
}

retries = defaultRetries(retries, defaultReadTimeouts(o))
err = retry(
fmt.Sprintf("creating NIC for VM %s", vmid),
Expand All @@ -27,6 +36,11 @@ func (o *oVirtClient) CreateNIC(
nicBuilder := ovirtsdk.NewNicBuilder()
nicBuilder.Name(name)
nicBuilder.VnicProfile(ovirtsdk.NewVnicProfileBuilder().Id(string(vnicProfileID)).MustBuild())

if mac != "" {
nicBuilder.Mac(ovirtsdk.NewMacBuilder().Address(mac).MustBuild())
}

nic := nicBuilder.MustBuild()

response, err := o.conn.SystemService().VmsService().VmService(string(vmid)).NicsService().Add().Nic(nic).Send()
Expand Down Expand Up @@ -60,7 +74,7 @@ func (m *mockClient) CreateNIC(
vmid VMID,
vnicProfileID VNICProfileID,
name string,
_ OptionalNICParameters,
params OptionalNICParameters,
_ ...RetryStrategy,
) (NIC, error) {
m.lock.Lock()
Expand All @@ -87,6 +101,14 @@ func (m *mockClient) CreateNIC(
vmid: vmid,
vnicProfileID: vnicProfileID,
}

if params != nil {
if err := validateNICCreationOptionalParameters(params); err != nil {
return nil, err
}
nic.mac = params.Mac()
}

m.nics[id] = nic

return nic, nil
Expand All @@ -101,3 +123,12 @@ func validateNICCreationParameters(vmid VMID, name string) error {
}
return nil
}

func validateNICCreationOptionalParameters(params OptionalNICParameters) error {
if mac := params.Mac(); mac != "" {
if _, err := net.ParseMAC(mac); err != nil {
return newError(EUnidentified, "Failed to parse MacAddress: %s", mac)
}
}
return nil
}
Loading