Usage

All example scripts are written using LMIShell.

We also assume that lmishell is connected to the CIMOM and the connection is stored in connection variable and variable ns points to cimv2 namespace:

connection = connect("server", "username", "password")
ns = connection.root.cimv2

Enumeration of network devices

Obtaining a list of network devices can be done by executing following commands in lmishell:

for device in ns.LMI_IPNetworkConnection.instances():
    print device.ElementName

Get parameters of network devices

Obtaining parameters of network device might be a little bit tricky. DMTF standards split network device to three classes and one might need to traverse between them through associations, see Networking API concepts.

Following example prints name, its status, MAC address, link technology and maximal speed for each device.

MAC address is not in the LMI_IPNetworkConnection class and must be accessed through LMI_EndpointForIPNetworkConnection association to LMI_LANEndpoint class, same for MaxSpeed and LinkTechnology, those are in CIM_NetworkPort subclasses, associated through LMI_NetworkDeviceSAPImplementation class:

for device in ns.LMI_IPNetworkConnection.instances():
    # print device name
    print device.ElementName,
    # print operating status
    print ns.LMI_IPNetworkConnection.OperatingStatusValues.value_name(device.OperatingStatus),

    # MAC address in not part of LMI_IPNetworkConnection but LMI_LANEndpoint class,
    # which is associated through LMI_EndpointForIPNetworkConnection
    lanendpoint = device.first_associator(AssocClass="LMI_EndpointForIPNetworkConnection")

    # print MAC address
    print lanendpoint.MACAddress,

    # LinkTechnology is part of CIM_NetworkPort subclasses, we need to traverse
    # through LMI_NetworkDeviceSAPImplementation association
    networkport = lanendpoint.first_associator(AssocClass="LMI_NetworkDeviceSAPImplementation")

    # print link technology
    print ns.CIM_NetworkPort.LinkTechnologyValues.value_name(networkport.LinkTechnology),

    # network speed might not be defined
    if networkport.MaxSpeed:
        # Convert bps to Mbps
        print "%dMbps" % (networkport.MaxSpeed // (1024*1024)),
    else:
        print "unknown",
    print

Get current IP configuration

Current IP addresses are in the LMI_IPProtocolEndpoint class associated to given LMI_IPNetworkConnection:

device = ns.LMI_IPNetworkConnection.first_instance({'ElementName': 'eth0'})
for endpoint in device.associators(AssocClass="LMI_NetworkSAPSAPDependency", ResultClass="LMI_IPProtocolEndpoint"):
    if endpoint.ProtocolIFType == ns.LMI_IPProtocolEndpoint.ProtocolIFTypeValues.IPv4:
        print "IPv4: %s/%s" % (endpoint.IPv4Address, endpoint.SubnetMask)
    elif endpoint.ProtocolIFType == ns.LMI_IPProtocolEndpoint.ProtocolIFTypeValues.IPv6:
        print "IPv6: %s/%d" % (endpoint.IPv6Address, endpoint.IPv6SubnetPrefixLength)

Default gateway is represented by instance of LMI_NetworkRemoteServiceAccessPoint with AccessContext equal to DefaultGateway:

for rsap in device.associators(AssocClass="LMI_NetworkRemoteAccessAvailableToElement", ResultClass="LMI_NetworkRemoteServiceAccessPoint"):
    if rsap.AccessContext == ns.LMI_NetworkRemoteServiceAccessPoint.AccessContextValues.DefaultGateway:
        print "Default Gateway: %s" % rsap.AccessInfo

For the list of DNS servers we need to traverse the object model a little bit. First get LMI_IPProtocolEndpoint instances associated with given LMI_IPNetworkConnection via LMI_NetworkSAPSAPDependency. Then use the same association to get instances of LMI_DNSProtocolEndpoint. Finally instances of LMI_NetworkRemoteServiceAccessPoint with AccessContext equal to DNS Server associated through LMI_NetworkRemoteAccessAvailableToElement have the DNS server address in the AccessInfo property.

Note that there might be more possible path to get to the RemoteServiceAccessPath and you might get duplicated entries. The set is used here to deduplicate the list of DNS servers:

dnsservers = set()
for ipendpoint in device.associators(AssocClass="LMI_NetworkSAPSAPDependency", ResultClass="LMI_IPProtocolEndpoint"):
    for dnsedpoint in ipendpoint.associators(AssocClass="LMI_NetworkSAPSAPDependency", ResultClass="LMI_DNSProtocolEndpoint"):
        for rsap in dnsedpoint.associators(AssocClass="LMI_NetworkRemoteAccessAvailableToElement", ResultClass="LMI_NetworkRemoteServiceAccessPoint"):
            if rsap.AccessContext == ns.LMI_NetworkRemoteServiceAccessPoint.AccessContextValues.DNSServer:
                dnsservers.add(rsap.AccessInfo)
print "DNS:", ", ".join(dnsservers)

Bring up / take down a network device

Note

Changing the state of a network device is not recommended! Just disconnect the active setting.

Use method RequestStateChange of the LMI_LANEndpoint object. RequestedState parameter can be either Enabled or Disabled:

lanendpoint = ns.LMI_LANEndpoint.first_instance({ "ElementName": "eth0" })
lanendpoint.RequestStateChange(RequestedState=ns.LMI_LANEndpoint.RequestedStateValues.Enabled)

Enumerate available settings

One setting is a set of configuration options that are applicable to a network interface. This setting is represented by a LMI_IPAssignmentSettingData instances that have AddressOrigin equal to Cumulative Configuration:

for settingdata in ns.LMI_IPAssignmentSettingData.instances():
    if settingdata.AddressOrigin == ns.LMI_IPAssignmentSettingData.AddressOriginValues.cumulativeconfiguration:
        print "Setting: %s" % settingdata.Caption

Obtaining setting details

Setting configuration is spread between the instances of LMI_IPAssignmentSettingData subclasses associated with the “master” setting:

settingdata = ns.LMI_IPAssignmentSettingData.first_instance({ "Caption": "eth0" })
for setting in settingdata.associators(AssocClass="LMI_OrderedIPAssignmentComponent"):
    if setting.classname == "LMI_DHCPSettingData":
        if setting.ProtocolIFType == ns.LMI_IPAssignmentSettingData.ProtocolIFTypeValues.IPv4:
            print "IPv4 DHCP"
        else:
            print "IPv6 DHCPv6"
    elif setting.classname == "LMI_ExtendedStaticIPAssignmentSettingData":
        for i in range(len(setting["IPAddresses"])):
            if setting["ProtocolIFType"] == ns.LMI_IPAssignmentSettingData.ProtocolIFTypeValues.IPv4:
                print "Static IPv4 address: %s/%s, Gateway %s" % (
                        setting["IPAddresses"][i],
                        setting["SubnetMasks"][i],
                        setting["GatewayAddresses"][i])
            else:
                print "Static IPv6 address: %s/%d, Gateway %s" % (
                        setting["IPAddresses"][i],
                        setting["IPv6SubnetPrefixLengths"][i],
                        setting["GatewayAddresses"][i])
    elif (setting.classname == "LMI_IPAssignmentSettingData" and
        setting["AddressOrigin"] == ns.LMI_IPAssignmentSettingData.AddressOriginValues.Stateless):
            print "IPv6 Stateless"

Create new setting

New setting is created by calling LMI_CreateIPSetting method on the instance of LMI_IPNetworkConnectionCapabilities, which is associated with LMI_IPNetworkConnection through LMI_IPNetworkConnectionElementCapabilities. It also has the ElementName property same as is the name of the network interface.

Created setting can be modified by using ModifyInstance intrinsic method (push() in the lmishell).

Let’s say we want to create a new setting with static IPv4 and stateless IPv6 configuration for given network interface:

capability = ns.LMI_IPNetworkConnectionCapabilities.first_instance({ 'ElementName': 'eth0' })
result = capability.LMI_CreateIPSetting(Caption='eth0 Static',
        IPv4Type=capability.LMI_CreateIPSetting.IPv4TypeValues.Static,
        IPv6Type=capability.LMI_CreateIPSetting.IPv6TypeValues.Stateless)
setting = result.rparams["SettingData"].to_instance()
for settingData in setting.associators(AssocClass="LMI_OrderedIPAssignmentComponent"):
    if setting.ProtocolIFType == ns.LMI_IPAssignmentSettingData.ProtocolIFTypeValues.IPv4:
        # Set static IPv4 address
        settingData.IPAddresses = ["192.168.1.100"]
        settingData.SubnetMasks = ["255.255.0.0"]
        settingData.GatewayAddresses = ["192.168.1.1"]
        settingData.push()

Set DNS servers for given setting

DNS server for given setting is stored in the DNSServerAddresses property of class LMI_DNSSettingData.

Following code adds IPv4 DNS server to the existing setting:

setting = ns.LMI_IPAssignmentSettingData.first_instance({ "Caption": "eth0 Static" })
for settingData in setting.associators(AssocClass="LMI_OrderedIPAssignmentComponent"):
    if (settingData.classname == "LMI_DNSSettingData" and
            settingData.ProtocolIFType == ns.LMI_IPAssignmentSettingData.ProtocolIFTypeValues.IPv4):
        settingData.DNSServerAddresses.append("192.168.1.1")
        settingData.push()

Manage static routes for given setting

Static route can be added by calling LMI_AddStaticIPRoute method on the instance of the LMI_IPAssignmentSettingData class:

setting = ns.LMI_IPAssignmentSettingData.first_instance({ "Caption": "eth0 Static" })
result = setting.LMI_AddStaticIPRoute(
        AddressType=setting.LMI_AddStaticIPRouteValues.IPv4,
        DestinationAddress="192.168.2.1",
        DestinationMask="255.255.255.0")
route = result.rparams["Route"]

Additional parameters can be set by modifying the instance of LMI_IPRouteSettingData. The route can be deleted by using DeleteInstance intrinsic method (delete() in lmishell).

Delete setting

For setting deletion just call DeleteInstance intrinsic method (delete() in the lmishell) to the instance of LMI_IPAssignmentSettingData:

setting = ns.LMI_IPAssignmentSettingData.first_instance({ 'Caption': 'eth0 Static' })
setting.delete()

Apply setting

The setting can by applied to the network interface by calling ApplySettingToIPNetworkConnection of the LMI_IPConfigurationService class.

This method is asynchronous and returns a job, but lmishell can call it synchronously:

setting = ns.LMI_IPAssignmentSettingData.first_instance({ "Caption": "eth0 Static" })
port = ns.LMI_IPNetworkConnection.first_instance({ 'ElementName': 'ens8' })
service = ns.LMI_IPConfigurationService.first_instance()
service.SyncApplySettingToIPNetworkConnection(SettingData=setting, IPNetworkConnection=port, Mode=32768)

Mode parameter affects how is the setting applied. Most commonly used values are:

  • Mode 1 – apply the setting now and make it auto-activated
  • Mode 2 – just make it auto-activated, don’t apply now
  • Mode 4 – disconnect and disable auto-activation
  • Mode 5 – don’t change the setting state, only disable auto-activation
  • Mode 32768 – apply the setting
  • Mode 32769 – disconnect

Bridging and bonding

Warning

Bridge, bond and vlan support needs to be explicitly enabled when using 0.8 version of NetworkManager as a backend (for example on RHEL-6). Add following line to the /etc/sysconfig/network file and restart NetworkManager

NM_BOND_BRIDGE_VLAN_ENABLED=yes

Setting up

Use following code to create and activate bond with eth0 and eth1 interfaces:

# Get the interfaces
interface1 = ns.LMI_IPNetworkConnection.first_instance({ 'ElementName': 'eth0' })
interface2 = ns.LMI_IPNetworkConnection.first_instance({ 'ElementName': 'eth1' })

# Get the capabilities
capability1 = interface1.first_associator(AssocClass="LMI_IPNetworkConnectionElementCapabilities",
        ResultClass="LMI_IPNetworkConnectionCapabilities")
capability2 = interface2.first_associator(AssocClass="LMI_IPNetworkConnectionElementCapabilities",
        ResultClass="LMI_IPNetworkConnectionCapabilities")
# Use one of the capabilities to create the bond
result = capability1.LMI_CreateIPSetting(Caption='Bond',
        Type=capability1.LMI_CreateIPSetting.TypeValues.Bonding,
        IPv4Type=capability1.LMI_CreateIPSetting.IPv4TypeValues.DHCP)
setting = result.rparams["SettingData"].to_instance()
# Get first slave setting
slave1setting = setting.first_associator_name(ResultClass="LMI_BondingSlaveSettingData",
            AssocClass="LMI_OrderedIPAssignmentComponent")
# Enslave the second interface using the second capability
result = capability2.LMI_CreateSlaveSetting(MasterSettingData=setting)
# Get second slave setting
slave2setting = result.rparams["SettingData"]
service = ns.LMI_IPConfigurationService.first_instance()
# Activate the bond
service.SyncApplySettingToIPNetworkConnection(
        SettingData=slave1setting,
        IPNetworkConnection=interface1,
        Mode=32768)
service.SyncApplySettingToIPNetworkConnection(
        SettingData=slave2setting,
        IPNetworkConnection=interface2,
        Mode=32768)

Displaying current state

Following code displays existing bonds and bonded interfaces:

for linkaggregation in ns.LMI_LinkAggregator8023ad.instances():
    print "Bond: %s" % linkaggregation.Name
    for lagport in linkaggregation.associators(AssocClass="LMI_LinkAggregationBindsTo",
            ResultClass="LMI_LAGPort8023ad"):
        print "Bonded interface: %s" % lagport.Name

Following code displays existing bridges and bridged interfaces:

for switchservice in ns.LMI_SwitchService.instances():
    print "Bridge: %s" % switchservice.Name
    for switchport in switchservice.associators(AssocClass="LMI_SwitchesAmong",
            ResultClass="LMI_SwitchPort"):
        print "Bridged interface: %s" % switchport.Name