Monthly Archives: February 2013

Modifying partial network configuration

The setup networks API expects the target configuration the administrator wishes to apply to the host. Therefore sometimes we wish to perform only minor change that shouldn’t affect existing settings. For that we need to resend as part of the parameters the unmodified network interfaces together with the modified one.

Any interface that will not be send to the engine will be considered as not-configured and any existing configuration will be removed.

The next program will show how to modify few interfaces and maintain the management network intact:

from ovirtsdk.api import API
from ovirtsdk.xml import params

URL = 'http://localhost:8700/api'
USERNAME = 'admin@internal'
PASSWORD = 'letmein!'

'''
Host venus-vdsb has 3 interfaces: eth0, eth4 and eth5
eth0 - is the management network interface  
'''
api = API(url=URL, username=USERNAME, password=PASSWORD)

MY_HOST_NAME = 'venus-vdsb'

def nullifyNic(hostNIC):
    ''' resets nic configuration to enable its reuse
    '''
    hostNIC.network =  params.Network()
    hostNIC.boot_protocol = 'none'
    hostNIC.ip = params.IP(address='', netmask='', gateway='')
    return hostNIC

hostNics = api.hosts.get(MY_HOST_NAME).nics

# We send eth0 as already defined on the engine
nic0 = hostNics.get(name = 'eth0')

# We configure eth2 and eth3 for their target configuration - as bond
nic2 = nullifyNic(params.HostNIC(name = 'eth4'))
nic3 = nullifyNic(params.HostNIC(name = 'eth5'))

bond = params.Bonding(
      slaves = params.Slaves(host_nic = [ nic2, nic3 ]),
               options = params.Options(
                           option = [
                             params.Option(name = 'miimon', value = '100'),
                             params.Option(name = 'mode', value = '1'),
                             params.Option(name = 'primary', value = 'eth4')]
                           )
                         )

bondnic = params.HostNIC(network = params.Network(name = 'bridge11'),
                         name = 'bond0',
                         boot_protocol = 'none',
                         override_configuration = 1,
                         bonding = bond)

hostNics.setupnetworks(params.Action(force = 0,
                                     check_connectivity = 1,
                                     host_nics = params.HostNics(host_nic = [ bondnic, nic0 ])))

In the example above nic0 represents interface “eth0”, the physical interface the management network is assigned to.
nic0 is loaded from the host’s network interfaces list and send as is to the engine

nic1 and nic2 represent eth4 and eth5 respectively which are intended to get bonded. First the nics should be nullify so previous configuration is deleted. It prevents cases in which a nic assigned with network is being used to assign by another network.

Next, the new configuration for nic1 and nic2 is set, and together the new bond0 definition and the nic0 interfaces are being passed as the setup network parameters.

The result as appear on the ‘setup dialog’ after the execution is completed:

SetupNetworkAfterBondCreation

Creating networks on top of a bond

The program creates a network configuration using the python sdk.
The target configuration requires preconfigured definition on the ovirt-engine system:
1. ovirtmgmt – the management network is defined as non-vm network.
2. nettest – a cluster assinged with the required networks.


from ovirtsdk.api import API
from ovirtsdk.xml import params

URL = 'http://localhost:8700/api'
USERNAME = 'admin@internal'
PASSWORD = 'letmein!'

'''
The target configuration of the following program is:

eth0 ---|
        |          |------ ovirtmgmt
        |--- bond0 |------ bond0.100 ----- NON_VM_VLAN_100
        |          |------ bond0.200 ----- VM_VLAN_200
eth4 ---|
'''
api = API(url = URL, username = USERNAME, password = PASSWORD)

# the eth0 configuration which used for the managment network should be nullify in order to allow reusing eth0 as a slave
nic0 = params.HostNIC(name = 'eth0', network =  params.Network(), boot_protocol='none', ip=params.IP(address='', netmask='', gateway=''))
nic1 = params.HostNIC(name = 'eth4', network =  params.Network(), boot_protocol='none', ip=params.IP(address='', netmask='', gateway=''))

# bond0 definition on top of eth0 and eth4
bond = params.Bonding(
   slaves = params.Slaves(host_nic = [ nic0, nic1 ]),
            options = params.Options(
                        option = [
                          params.Option(name = 'miimon', value = '100'),
                          params.Option(name = 'mode', value = '1'),
                          params.Option(name = 'primary', value = 'eth0')]
                        )
                      )

# Configure the management network on top of the bond
managementNetwork = params.HostNIC(network = params.Network(name = 'ovirtmgmt'),
                      name = 'bond0',
                      boot_protocol = 'static',
                          ip = params.IP(
                          address = '10.1.1.1',
                          netmask = '255.255.254.0',
                          gateway = '10.1.1.254'),
                      override_configuration = 1,
                      bonding = bond)

# create vlan device for network with vlan tag 100
networkName = 'NON_VM_VLAN_100'
clusterNetwork = api.clusters.get('nettest').networks.get(name = networkName)
vlanNetwork = params.HostNIC(network = params.Network(name = networkName), name = "bond0.%s" % clusterNetwork.vlan.id)

# create vlan device for network with vlan tag 200
networkName = 'VM_VLAN_200'
clusterNetwork = api.clusters.get('nettest').networks.get(name = networkName)
vlanNetwork2 = params.HostNIC(network = params.Network(name = networkName), name = "bond0.%s" % clusterNetwork.vlan.id)

# Now apply the configuration
host = api.hosts.get('my-host-name')
host.nics.setupnetworks(params.Action(force = 0,
                                      check_connectivity = 1,
                                      host_nics = params.HostNics(host_nic = [ managementNetwork,
                                                                               vlanNetwork,
                                                                               vlanNetwork2 ])))

Reset network configuration

Once a solid network configuration is known, you can always revert to it.
In my case I’m using the following program to initialize my host’s network configuration to the minimal required by ovirt-engine:

from ovirtsdk.api import API
from ovirtsdk.xml import params

URL = 'http://localhost:8700/api'
USERNAME = 'admin@internal'
PASSWORD = 'letmein!'

'''
The target configuration of the following program is:

eth0 --------- ovirtmgmt (dhcp)

'''
api = API(url = URL, username = USERNAME, password = PASSWORD)

# define the management network
managementNetwork = params.HostNIC(network = params.Network(name = 'ovirtmgmt'),
                      name = 'eth0',
                      boot_protocol = 'dhcp')


nics = api.hosts.get(name = 'my-host-name').nics

# Now apply the configuration
nics.setupnetworks(params.Action(force = 0,
                                 check_connectivity = 1,
                                 host_nics = params.HostNics(host_nic = [ managementNetwork ])))

Alternately, the ground-base configuration can rely on static IP address:

from ovirtsdk.api import API
from ovirtsdk.xml import params

URL = 'http://localhost:8700/api'
USERNAME = 'admin@internal'
PASSWORD = 'letmein!'

'''
The target configuration of the following program is:

eth0 --------- ovirtmgmt (static-ip)    

'''
api = API(url = URL, username = USERNAME, password = PASSWORD)

# define the management network
managementNetwork = params.HostNIC(network = params.Network(name = 'ovirtmgmt'),
                      name = 'eth0',
                      boot_protocol = 'static',
                          ip = params.IP(
                          address = '10.1.1.1',
                          netmask = '255.255.254.0',
                          gateway = '10.1.1.254'))

# Now apply the configuration
host = api.hosts.get('my-host-name')
host.nics.setupnetworks(params.Action(force = 0,
                                      check_connectivity = 1,
                                      host_nics = params.HostNics(host_nic = [ managementNetwork ])))

Add new networks

The next program creates a vm network with vlan-id and attaches it to a cluster:

from ovirtsdk.api import API
from ovirtsdk.xml import params

URL = 'http://localhost:8700/api'
USERNAME = 'admin@internal'
PASSWORD = 'letmein!'

api = API(url = URL, username = USERNAME, password = PASSWORD, debug=True)

vmVlan400 = params.Network(name = 'VM_VLAN_400',
                       data_center = api.datacenters.get(name = 'nettest'), 
                       description = 'a tagged vm network',
                       vlan = params.VLAN(id = '400'))


vmVlan400 = api.networks.add(vmVlan400)

# Attach network to cluster
api.clusters.get('nettest').networks.add(vmVlan400)

The next program creates a non-vm network with vlan-id and attaches it to a cluster:


from ovirtsdk.api import API
from ovirtsdk.xml import params

URL = 'http://localhost:8700/api'
USERNAME = 'admin@internal'
PASSWORD = 'letmein!'

api = API(url = URL, username = USERNAME, password = PASSWORD)

nonVmVlan500 = params.Network(name = 'NON_VM_VLAN_500',
                       data_center = api.datacenters.get(name = 'nettest'), 
                       description = 'a tagged non-vm network',
                       vlan = params.VLAN(id = '500'),
                       usages = params.Usages())

nonVmVlan500 = api.networks.add(nonVmVlan500)

# Attach network to cluster
api.clusters.get('nettest').networks.add(nonVmVlan500)

Setup Networks

In ovirt-engine the Setup Networks feature enables easy management of the host’s network configuration, either by using the cool drag & drop dialogue from the web administrator portal  (see image below) or via the rest-api (by rest client or by using the SDK).

The image shows the ‘setup networks’ dialogue, followed by a quick legend: Selection_040

      1. Interfaces – the physical interfaces as reported by the host from the latest host configuration sampling. Currently refreshing the network configuration is done either by activating the host (when host is on ‘maintenance’ or on ‘non operational’ state) or by executing ‘setup networks’ action. The interfaces might represent a plan interface or a bond. For bond there is an option to set the bonding options (by clicking the pencil icon next to the bond name).
      2. Assigned Logical Networks – The logical networks which are assigned to the interfaces. There are several types of assigned networks which will be reviewed in a latter posts: managed (synced or not-synced) and unmanaged. The definition of the network for managed networks is taken from the Logical Network on data-center level. Network’s boot protocol can be edited by clicking the pencil icon next to the network name. For the management network the option to provide the default gateway is enabled.
      3. Unassigned Logical Networks – A list of the available networks which aren’t assigned to any interface:
        1. Required – The networks that required to exist on the host so it can be claimed as operational.
        2. Non Required – The networks that could be defined on the host, but their absence will not affect the host’s status.
      4. Connectivity Check – performs connectivity check between the engine to the host during to the setup network execution. This indicates the VDSM agent on the host whether to revert the host’s network configuration to the last stable in case of communication failure from the engine.
      5. Save Network Configuration – stores the network configuration that was applied on the host, so upon VDSM service restart or upon reboot, the network configuration is persisted. Also in case of failed setup network command, VDSM will revert to this (latest saved) configuration.

In a future posts I’ll describe the ‘sync network’ feature which is an enhancement to the setup network.

oVirt engine

The oVirt project is an open source virtualization solution. It allows to create virtual machines and manage them. In addition, it provides the ability to configure the hosts that run the virtual machines.

The oVirt-engine, which is the management system, has two major interfaces to use it: a web-interface UI or a rest-api.

On top of the rest-api, few SDKs were developed: a python SDK and a java SDK.

In the next posts series I intend to show examples related to network configuration using the ovirt-engine python SDK.