Chapter 22. OpenLMI
The Open Linux Management Infrastructure, commonly abbreviated as OpenLMI, is a common infrastructure for the management of Linux systems. It builds on top of existing tools and serves as an abstraction layer in order to hide much of the complexity of the underlying system from system administrators. OpenLMI is distributed with a set of services that can be accessed locally or remotely and provides multiple language bindings, standard APIs, and standard scripting interfaces that can be used to manage and monitor hardware, operating systems, and system services.
22.1. About OpenLMI
OpenLMI is designed to provide a common management interface to production servers running the Red Hat Enterprise Linux system on both physical and virtual machines. It consists of the following three components:
- System management agents — these agents are installed on a managed system and implement an object model that is presented to a standard object broker. The initial agents implemented in OpenLMI include storage configuration and network configuration, but later work will address additional elements of system management. The system management agents are commonly referred to as Common Information Model providers or CIM providers.
- A standard object broker — the object broker manages system management agents and provides an interface to them. The standard object broker is also known as a CIM Object Monitor or CIMOM.
- Client applications and scripts — the client applications and scripts call the system management agents through the standard object broker.
The OpenLMI project complements existing management initiatives by providing a low-level interface that can be used by scripts or system management consoles. Interfaces distributed with OpenLMI include C, C++, Python, Java, and an interactive command line client, and all of them offer the same full access to the capabilities implemented in each agent. This ensures that you always have access to exactly the same capabilities no matter which programming interface you decide to use.
22.1.1. Main Features
The following are key benefits of installing and using OpenLMI on your system:
- OpenLMI provides a standard interface for configuration, management, and monitoring of your local and remote systems.
- It allows you to configure, manage, and monitor production servers running on both physical and virtual machines.
- It is distributed with a collection of CIM providers that allow you to configure, manage, and monitor storage devices and complex networks.
- It allows you to call system management functions from C, C++, Python, and Java programs, and includes LMIShell, which provides a command line interface.
- It is free software based on open industry standards.
22.1.2. Management Capabilities
Key capabilities of OpenLMI include the management of storage devices, networks, system services, user accounts, hardware and software configuration, power management, and interaction with Active Directory. For a complete list of CIM providers that are distributed with Red Hat Enterprise Linux 7, see Table 22.1, “Available CIM Providers”.
Package Name | Description |
---|---|
openlmi-account | A CIM provider for managing user accounts. |
openlmi-logicalfile | A CIM provider for reading files and directories. |
openlmi-networking | A CIM provider for network management. |
openlmi-powermanagement | A CIM provider for power management. |
openlmi-service | A CIM provider for managing system services. |
openlmi-storage | A CIM provider for storage management. |
openlmi-fan | A CIM provider for controlling computer fans. |
openlmi-hardware | A CIM provider for retrieving hardware information. |
openlmi-realmd | A CIM provider for configuring realmd. |
openlmi-software[a] | A CIM provider for software management. |
[a]
In Red Hat Enterprise Linux 7, the OpenLMI Software provider is included as a Technology Preview. This provider is fully functional, but has a known performance scaling issue where listing large numbers of software packages may consume excessive amount of memory and time. To work around this issue, adjust package searches to return as few packages as possible.
|
22.2. Installing OpenLMI
OpenLMI is distributed as a collection of RPM packages that include the CIMOM, individual CIM providers, and client applications. This allows you distinguish between a managed and client system and install only those components you need.
22.2.1. Installing OpenLMI on a Managed System
A managed system is the system you intend to monitor and manage by using the OpenLMI client tools. To install OpenLMI on a managed system, complete the following steps:
Install the tog-pegasus package by typing the following at a shell prompt as
root
:yum install tog-pegasus
This command installs the OpenPegasus CIMOM and all its dependencies to the system and creates a user account for the
pegasus
user.Install required CIM providers by running the following command as
root
:yum install openlmi-{storage,networking,service,account,powermanagement}
This command installs the CIM providers for storage, network, service, account, and power management. For a complete list of CIM providers distributed with Red Hat Enterprise Linux 7, see Table 22.1, “Available CIM Providers”.
Edit the
/etc/Pegasus/access.conf
configuration file to customize the list of users that are allowed to connect to the OpenPegasus CIMOM. By default, only thepegasus
user is allowed to access the CIMOM both remotely and locally. To activate this user account, run the following command asroot
to set the user’s password:passwd pegasus
Start the OpenPegasus CIMOM by activating the
tog-pegasus.service
unit. To activate thetog-pegasus.service
unit in the current session, type the following at a shell prompt asroot
:systemctl start tog-pegasus.service
To configure the
tog-pegasus.service
unit to start automatically at boot time, type asroot
:systemctl enable tog-pegasus.service
If you intend to interact with the managed system from a remote machine, enable TCP communication on port
5989
(wbem-https
). To open this port in the current session, run the following command asroot
:firewall-cmd --add-port 5989/tcp
To open port
5989
for TCP communication permanently, type asroot
:firewall-cmd --permanent --add-port 5989/tcp
You can now connect to the managed system and interact with it by using the OpenLMI client tools as described in Section 22.4, “Using LMIShell”. If you intend to perform OpenLMI operations directly on the managed system, also complete the steps described in Section 22.2.2, “Installing OpenLMI on a Client System”.
22.2.2. Installing OpenLMI on a Client System
A client system is the system from which you intend to interact with the managed system. In a typical scenario, the client system and the managed system are installed on two separate machines, but you can also install the client tools on the managed system and interact with it directly.
To install OpenLMI on a client system, complete the following steps:
Install the openlmi-tools package by typing the following at a shell prompt as
root
:yum install openlmi-tools
This command installs LMIShell, an interactive client and interpreter for accessing CIM objects provided by OpenPegasus, and all its dependencies to the system.
- Configure SSL certificates for OpenPegasus as described in Section 22.3, “Configuring SSL Certificates for OpenPegasus”.
You can now use the LMIShell client to interact with the managed system as described in Section 22.4, “Using LMIShell”.
22.3. Configuring SSL Certificates for OpenPegasus
OpenLMI uses the Web-Based Enterprise Management (WBEM) protocol that functions over an HTTP transport layer. Standard HTTP Basic authentication is performed in this protocol, which means that the user name and password are transmitted alongside the requests.
Configuring the OpenPegasus CIMOM to use HTTPS for communication is necessary to ensure secure authentication. A Secure Sockets Layer (SSL) or Transport Layer Security (TLS) certificate is required on the managed system to establish an encrypted channel.
There are two ways of managing SSL/TLS certificates on a system:
- Self-signed certificates require less infrastructure to use, but are more difficult to deploy to clients and manage securely.
- Authority-signed certificates are easier to deploy to clients once they are set up, but may require a greater initial investment.
When using an authority-signed certificate, it is necessary to configure a trusted certificate authority on the client systems. The authority can then be used for signing all of the managed systems' CIMOM certificates. Certificates can also be part of a certificate chain, so the certificate used for signing the managed systems' certificates may in turn be signed by another, higher authority (such as Verisign, CAcert, RSA and many others).
The default certificate and trust store locations on the file system are listed in Table 22.2, “Certificate and Trust Store Locations”.
Configuration Option | Location | Description |
---|---|---|
|
| Public certificate of the CIMOM. |
|
| Private key known only to the CIMOM. |
|
| The file or directory providing the list of trusted certificate authorities. |
If you modify any of the files mentioned in Table 22.2, “Certificate and Trust Store Locations”, restart the tog-pegasus
service to make sure it recognizes the new certificates. To restart the service, type the following at a shell prompt as root
:
systemctl restart tog-pegasus.service
For more information on how to manage system services in Red Hat Enterprise Linux 7, see Chapter 10, Managing Services with systemd.
22.3.1. Managing Self-signed Certificates
A self-signed certificate uses its own private key to sign itself and it is not connected to any chain of trust. On a managed system, if certificates have not been provided by the administrator prior to the first time that the tog-pegasus
service is started, a set of self-signed certificates will be automatically generated using the system’s primary host name as the certificate subject.
The automatically generated self-signed certificates are valid by default for 10 years, but they have no automatic-renewal capability. Any modification to these certificates will require manually creating new certificates following guidelines provided by the OpenSSL or Mozilla NSS documentation on the subject.
To configure client systems to trust the self-signed certificate, complete the following steps:
Copy the
/etc/Pegasus/server.pem
certificate from the managed system to the/etc/pki/ca-trust/source/anchors/
directory on the client system. To do so, type the following at a shell prompt asroot
:scp root@hostname:/etc/Pegasus/server.pem /etc/pki/ca-trust/source/anchors/pegasus-hostname.pem
Replace hostname with the host name of the managed system. Note that this command only works if the
sshd
service is running on the managed system and is configured to allow theroot
user to log in to the system over the SSH protocol. For more information on how to install and configure thesshd
service and use thescp
command to transfer files over the SSH protocol, see Chapter 12, OpenSSH.Verify the integrity of the certificate on the client system by comparing its check sum with the check sum of the original file. To calculate the check sum of the
/etc/Pegasus/server.pem
file on the managed system, run the following command asroot
on that system:sha1sum /etc/Pegasus/server.pem
To calculate the check sum of the
/etc/pki/ca-trust/source/anchors/pegasus-hostname.pem
file on the client system, run the following command on this system:sha1sum /etc/pki/ca-trust/source/anchors/pegasus-hostname.pem
Replace hostname with the host name of the managed system.
Update the trust store on the client system by running the following command as
root
:update-ca-trust extract
22.3.2. Managing Authority-signed Certificates with Identity Management (Recommended)
The Identity Management feature of Red Hat Enterprise Linux provides a domain controller which simplifies the management of SSL certificates within systems joined to the domain. Among others, the Identity Management server provides an embedded Certificate Authority. See the Red Hat Enterprise Linux 7 Linux Domain Identity, Authentication, and Policy Guide or the FreeIPA documentation for information on how to join the client and managed systems to the domain.
It is necessary to register the managed system to Identity Management; for client systems the registration is optional.
The following steps are required on the managed system:
- Install the ipa-client package and register the system to Identity Management as described in the Red Hat Enterprise Linux 7 Linux Domain Identity, Authentication, and Policy Guide.
Copy the Identity Management signing certificate to the trusted store by typing the following command as
root
:cp /etc/ipa/ca.crt /etc/pki/ca-trust/source/anchors/ipa.crt
Update the trust store by running the following command as
root
:update-ca-trust extract
Register Pegasus as a service in the Identity Management domain by running the following command as a privileged domain user:
ipa service-add CIMOM/hostname
Replace hostname with the host name of the managed system.
This command can be run from any system in the Identity Management domain that has the ipa-admintools package installed. It creates a service entry in Identity Management that can be used to generate signed SSL certificates.
-
Back up the PEM files located in the
/etc/Pegasus/
directory (recommended). Retrieve the signed certificate by running the following command as
root
:ipa-getcert request -f /etc/Pegasus/server.pem -k /etc/Pegasus/file.pem -N CN=hostname -K CIMOM/hostname
Replace hostname with the host name of the managed system.
The certificate and key files are now kept in proper locations. The
certmonger
daemon installed on the managed system by theipa-client-install
script ensures that the certificate is kept up-to-date and renewed as necessary.For more information, see the Red Hat Enterprise Linux 7 Linux Domain Identity, Authentication, and Policy Guide.
To register the client system and update the trust store, follow the steps below.
- Install the ipa-client package and register the system to Identity Management as described in the Red Hat Enterprise Linux 7 Linux Domain Identity, Authentication, and Policy Guide.
Copy the Identity Management signing certificate to the trusted store by typing the following command as
root
:cp /etc/ipa/ca.crt /etc/pki/ca-trust/source/anchors/ipa.crt
Update the trust store by running the following command as
root
:update-ca-trust extract
If the client system is not meant to be registered in Identity Management, complete the following steps to update the trust store.
-
Copy the
/etc/ipa/ca.crt
file securely from any other system joined to the same Identity Management domain to the trusted store/etc/pki/ca-trust/source/anchors/
directory asroot
. Update the trust store by running the following command as
root
:update-ca-trust extract
22.3.3. Managing Authority-signed Certificates Manually
Managing authority-signed certificates with other mechanisms than Identity Management requires more manual configuration.
It is necessary to ensure that all of the clients trust the certificate of the authority that will be signing the managed system certificates:
- If a certificate authority is trusted by default, it is not necessary to perform any particular steps to accomplish this.
If the certificate authority is not trusted by default, the certificate has to be imported on the client and managed systems.
Copy the certificate to the trusted store by typing the following command as
root
:cp /path/to/ca.crt /etc/pki/ca-trust/source/anchors/ca.crt
Update the trust store by running the following command as
root
:update-ca-trust extract
On the managed system, complete the following steps:
Create a new SSL configuration file
/etc/Pegasus/ssl.cnf
to store information about the certificate. The contents of this file must be similar to the following example:[ req ] distinguished_name = req_distinguished_name prompt = no [ req_distinguished_name ] C = US ST = Massachusetts L = Westford O = Fedora OU = Fedora OpenLMI CN = hostname
Replace hostname with the fully qualified domain name of the managed system.
Generate a private key on the managed system by using the following command as
root
:openssl genrsa -out /etc/Pegasus/file.pem 1024
Generate a certificate signing request (CSR) by running this command as
root
:openssl req -config /etc/Pegasus/ssl.cnf -new -key /etc/Pegasus/file.pem -out /etc/Pegasus/server.csr
-
Send the
/etc/Pegasus/server.csr
file to the certificate authority for signing. The detailed procedure of submitting the file depends on the particular certificate authority. -
When the signed certificate is received from the certificate authority, save it as
/etc/Pegasus/server.pem
. Copy the certificate of the trusted authority to the Pegasus trust store to make sure that Pegasus is capable of trusting its own certificate by running as
root
:cp /path/to/ca.crt /etc/Pegasus/client.pem
After accomplishing all the described steps, the clients that trust the signing authority are able to successfully communicate with the managed server’s CIMOM.
Unlike the Identity Management solution, if the certificate expires and needs to be renewed, all of the described manual steps have to be carried out again. It is recommended to renew the certificates before they expire.
22.4. Using LMIShell
LMIShell is an interactive client and non-interactive interpreter that can be used to access CIM objects provided by the OpenPegasus CIMOM. It is based on the Python interpreter, but also implements additional functions and classes for interacting with CIM objects.
22.4.1. Starting, Using, and Exiting LMIShell
Similarly to the Python interpreter, you can use LMIShell either as an interactive client, or as a non-interactive interpreter for LMIShell scripts.
Starting LMIShell in Interactive Mode
To start the LMIShell interpreter in interactive mode, run the lmishell
command with no additional arguments:
lmishell
By default, when LMIShell attempts to establish a connection with a CIMOM, it validates the server-side certificate against the Certification Authorities trust store. To disable this validation, run the lmishell
command with the --noverify
or -n
command line option:
lmishell --noverify
Using Tab Completion
When running in interactive mode, the LMIShell interpreter allows you press the Tab key to complete basic programming structures and CIM objects, including namespaces, classes, methods, and object properties.
Browsing History
By default, LMIShell stores all commands you type at the interactive prompt in the ~/.lmishell_history
file. This allows you to browse the command history and re-use already entered lines in interactive mode without the need to type them at the prompt again. To move backward in the command history, press the Up Arrow key or the Ctrl+p key combination. To move forward in the command history, press the Down Arrow key or the Ctrl+n key combination.
LMIShell also supports an incremental reverse search. To look for a particular line in the command history, press Ctrl+r and start typing any part of the command. For example:
> (reverse-i-search)`connect
': c = connect("server.example.com", "pegasus")
To clear the command history, use the clear_history()
function as follows:
clear_history
()
You can configure the number of lines that are stored in the command history by changing the value of the history_length
option in the ~/.lmishellrc
configuration file. In addition, you can change the location of the history file by changing the value of the history_file
option in this configuration file. For example, to set the location of the history file to ~/.lmishell_history
and configure LMIShell to store the maximum of 1000
lines in it, add the following lines to the ~/.lmishellrc
file:
history_file = "~/.lmishell_history" history_length = 1000
Handling Exceptions
By default, the LMIShell interpreter handles all exceptions and uses return values. To disable this behavior in order to handle all exceptions in the code, use the use_exceptions()
function as follows:
use_exceptions
()
To re-enable the automatic exception handling, use:
use_exception
(False
)
You can permanently disable the exception handling by changing the value of the use_exceptions
option in the ~/.lmishellrc
configuration file to True
:
use_exceptions = True
Configuring a Temporary Cache
With the default configuration, LMIShell connection objects use a temporary cache for storing CIM class names and CIM classes in order to reduce network communication. To clear this temporary cache, use the clear_cache()
method as follows:
object_name.clear_cache
()
Replace object_name with the name of a connection object.
To disable the temporary cache for a particular connection object, use the use_cache()
method as follows:
object_name.use_cache
(False
)
To enable it again, use:
object_name.use_cache
(True
)
You can permanently disable the temporary cache for connection objects by changing the value of the use_cache
option in the ~/.lmishellrc
configuration file to False
:
use_cache = False
Exiting LMIShell
To terminate the LMIShell interpreter and return to the shell prompt, press the Ctrl+d key combination or issue the quit()
function as follows:
> quit()
~]$
Running an LMIShell Script
To run an LMIShell script, run the lmishell
command as follows:
lmishell file_name
Replace file_name with the name of the script. To inspect an LMIShell script after its execution, also specify the --interact
or -i
command line option:
lmishell --interact file_name
The preferred file extension of LMIShell scripts is .lmi
.
22.4.2. Connecting to a CIMOM
LMIShell allows you to connect to a CIMOM that is running either locally on the same system, or on a remote machine accessible over the network.
Connecting to a Remote CIMOM
To access CIM objects provided by a remote CIMOM, create a connection object by using the connect()
function as follows:
connect
(host_name, user_name, password)
Replace host_name with the host name of the managed system, user_name with the name of a user that is allowed to connect to the OpenPegasus CIMOM running on that system, and password with the user’s password. If the password is omitted, LMIShell prompts the user to enter it. The function returns an LMIConnection
object.
Example 22.1. Connecting to a Remote CIMOM
To connect to the OpenPegasus CIMOM running on server.example.com
as user pegasus
, type the following at the interactive prompt:
> c = connect("server.example.com", "pegasus")
password:
>
Connecting to a Local CIMOM
LMIShell allows you to connect to a local CIMOM by using a Unix socket. For this type of connection, you must run the LMIShell interpreter as the root
user and the /var/run/tog-pegasus/cimxml.socket
socket must exist.
To access CIM objects provided by a local CIMOM, create a connection object by using the connect()
function as follows:
connect
(host_name)
Replace host_name with localhost
, 127.0.0.1
, or ::1
. The function returns an LMIConnection
object or None
.
Example 22.2. Connecting to a Local CIMOM
To connect to the OpenPegasus CIMOM running on localhost
as the root
user, type the following at the interactive prompt:
> c = connect("localhost")
>
Verifying a Connection to a CIMOM
The connect()
function returns either an LMIConnection
object, or None
if the connection could not be established. In addition, when the connect()
function fails to establish a connection, it prints an error message to standard error output.
To verify that a connection to a CIMOM has been established successfully, use the isinstance()
function as follows:
isinstance
(object_name,LMIConnection
)
Replace object_name with the name of the connection object. This function returns True
if object_name is an LMIConnection
object, or False
otherwise.
Example 22.3. Verifying a Connection to a CIMOM
To verify that the c
variable created in Example 22.1, “Connecting to a Remote CIMOM” contains an LMIConnection
object, type the following at the interactive prompt:
> isinstance(c, LMIConnection)
True
>
Alternatively, you can verify that c
is not None
:
> c is None
False
>
22.4.3. Working with Namespaces
LMIShell namespaces provide a natural means of organizing available classes and serve as a hierarchic access point to other namespaces and classes. The root
namespace is the first entry point of a connection object.
Listing Available Namespaces
To list all available namespaces, use the print_namespaces()
method as follows:
object_name.print_namespaces
()
Replace object_name with the name of the object to inspect. This method prints available namespaces to standard output.
To get a list of available namespaces, access the object attribute namespaces
:
object_name.namespaces
This returns a list of strings.
Example 22.4. Listing Available Namespaces
To inspect the root
namespace object of the c
connection object created in Example 22.1, “Connecting to a Remote CIMOM” and list all available namespaces, type the following at the interactive prompt:
> c.root.print_namespaces() cimv2 interop PG_InterOp PG_Internal >
To assign a list of these namespaces to a variable named root_namespaces
, type:
> root_namespaces = c.root.namespaces >
Accessing Namespace Objects
To access a particular namespace object, use the following syntax:
object_name.namespace_name
Replace object_name with the name of the object to inspect and namespace_name with the name of the namespace to access. This returns an LMINamespace
object.
Example 22.5. Accessing Namespace Objects
To access the cimv2
namespace of the c
connection object created in Example 22.1, “Connecting to a Remote CIMOM” and assign it to a variable named ns
, type the following at the interactive prompt:
> ns = c.root.cimv2
>
22.4.4. Working with Classes
LMIShell classes represent classes provided by a CIMOM. You can access and list their properties, methods, instances, instance names, and ValueMap properties, print their documentation strings, and create new instances and instance names.
Listing Available Classes
To list all available classes in a particular namespace, use the print_classes()
method as follows:
namespace_object.print_classes()
Replace namespace_object with the namespace object to inspect. This method prints available classes to standard output.
To get a list of available classes, use the classes()
method:
namespace_object.classes
()
This method returns a list of strings.
Example 22.6. Listing Available Classes
To inspect the ns
namespace object created in Example 22.5, “Accessing Namespace Objects” and list all available classes, type the following at the interactive prompt:
> ns.print_classes() CIM_CollectionInSystem CIM_ConcreteIdentity CIM_ControlledBy CIM_DeviceSAPImplementation CIM_MemberOfStatusCollection ... >
To assign a list of these classes to a variable named cimv2_classes
, type:
> cimv2_classes = ns.classes() >
Accessing Class Objects
To access a particular class object that is provided by the CIMOM, use the following syntax:
namespace_object.class_name
Replace namespace_object with the name of the namespace object to inspect and class_name with the name of the class to access.
Example 22.7. Accessing Class Objects
To access the LMI_IPNetworkConnection
class of the ns
namespace object created in Example 22.5, “Accessing Namespace Objects” and assign it to a variable named cls
, type the following at the interactive prompt:
> cls = ns.LMI_IPNetworkConnection >
Examining Class Objects
All class objects store information about their name and the namespace they belong to, as well as detailed class documentation. To get the name of a particular class object, use the following syntax:
class_object.classname
Replace class_object with the name of the class object to inspect. This returns a string representation of the object name.
To get information about the namespace a class object belongs to, use:
class_object.namespace
This returns a string representation of the namespace.
To display detailed class documentation, use the doc()
method as follows:
class_object.doc
()
Example 22.8. Examining Class Objects
To inspect the cls
class object created in Example 22.7, “Accessing Class Objects” and display its name and corresponding namespace, type the following at the interactive prompt:
> cls.classname 'LMI_IPNetworkConnection' > cls.namespace 'root/cimv2' >
To access class documentation, type:
> cls.doc() Class: LMI_IPNetworkConnection SuperClass: CIM_IPNetworkConnection [qualifier] string UMLPackagePath: 'CIM::Network::IP' [qualifier] string Version: '0.1.0' ...
Listing Available Methods
To list all available methods of a particular class object, use the print_methods()
method as follows:
class_object.print_methods
()
Replace class_object with the name of the class object to inspect. This method prints available methods to standard output.
To get a list of available methods, use the methods()
method:
class_object.methods()
This method returns a list of strings.
Example 22.9. Listing Available Methods
To inspect the cls
class object created in Example 22.7, “Accessing Class Objects” and list all available methods, type the following at the interactive prompt:
> cls.print_methods() RequestStateChange >
To assign a list of these methods to a variable named service_methods
, type:
> service_methods = cls.methods() >
Listing Available Properties
To list all available properties of a particular class object, use the print_properties()
method as follows:
class_object.print_properties
()
Replace class_object with the name of the class object to inspect. This method prints available properties to standard output.
To get a list of available properties, use the properties()
method:
class_object.properties
()
This method returns a list of strings.
Example 22.10. Listing Available Properties
To inspect the cls
class object created in Example 22.7, “Accessing Class Objects” and list all available properties, type the following at the interactive prompt:
> cls.print_properties() RequestedState HealthState StatusDescriptions TransitioningToState Generation ... >
To assign a list of these classes to a variable named service_properties
, type:
> service_properties = cls.properties() >
Listing and Viewing ValueMap Properties
CIM classes may contain ValueMap properties in their Managed Object Format (MOF) definition. ValueMap properties contain constant values, which may be useful when calling methods or checking returned values.
To list all available ValueMap properties of a particular class object, use the print_valuemap_properties()
method as follows:
class_object.print_valuemap_properties
()
Replace class_object with the name of the class object to inspect. This method prints available ValueMap properties to standard output:
To get a list of available ValueMap properties, use the valuemap_properties()
method:
class_object.valuemap_properties
()
This method returns a list of strings.
Example 22.11. Listing ValueMap Properties
To inspect the cls
class object created in Example 22.7, “Accessing Class Objects” and list all available ValueMap properties, type the following at the interactive prompt:
> cls.print_valuemap_properties() RequestedState HealthState TransitioningToState DetailedStatus OperationalStatus ... >
To assign a list of these ValueMap properties to a variable named service_valuemap_properties
, type:
> service_valuemap_properties = cls.valuemap_properties() >
To access a particular ValueMap property, use the following syntax:
class_object.valuemap_propertyValues
Replace valuemap_property with the name of the ValueMap property to access.
To list all available constant values, use the print_values()
method as follows:
class_object.valuemap_propertyValues
.print_values
()
This method prints available named constant values to standard output. You can also get a list of available constant values by using the values()
method:
class_object.valuemap_propertyValues
.values
()
This method returns a list of strings.
Example 22.12. Accessing ValueMap Properties
Example 22.11, “Listing ValueMap Properties” mentions a ValueMap property named RequestedState
. To inspect this property and list available constant values, type the following at the interactive prompt:
> cls.RequestedStateValues.print_values() Reset NoChange NotApplicable Quiesce Unknown ... >
To assign a list of these constant values to a variable named requested_state_values
, type:
> requested_state_values = cls.RequestedStateValues.values() >
To access a particular constant value, use the following syntax:
class_object.valuemap_propertyValues
.constant_value_name
Replace constant_value_name with the name of the constant value. Alternatively, you can use the value()
method as follows:
class_object.valuemap_propertyValues
.value
("constant_value_name")
To determine the name of a particular constant value, use the value_name()
method:
class_object.valuemap_propertyValues
.value_name
("constant_value")
This method returns a string.
Example 22.13. Accessing Constant Values
Example 22.12, “Accessing ValueMap Properties” shows that the RequestedState
property provides a constant value named Reset
. To access this named constant value, type the following at the interactive prompt:
>cls.RequestedStateValues.Reset
11 >cls.RequestedStateValues.value("Reset")
11 >
To determine the name of this constant value, type:
> cls.RequestedStateValues.value_name(11) u'Reset' >
Fetching a CIMClass Object
Many class methods do not require access to a CIMClass
object, which is why LMIShell only fetches this object from the CIMOM when a called method actually needs it. To fetch the CIMClass
object manually, use the fetch()
method as follows:
class_object.fetch
()
Replace class_object with the name of the class object. Note that methods that require access to a CIMClass
object fetch it automatically.
22.4.5. Working with Instances
LMIShell instances represent instances provided by a CIMOM. You can get and set their properties, list and call their methods, print their documentation strings, get a list of associated or association objects, push modified objects to the CIMOM, and delete individual instances from the CIMOM.
Accessing Instances
To get a list of all available instances of a particular class object, use the instances()
method as follows:
class_object.instances
()
Replace class_object with the name of the class object to inspect. This method returns a list of LMIInstance
objects.
To access the first instance of a class object, use the first_instance()
method:
class_object.first_instance
()
This method returns an LMIInstance
object.
In addition to listing all instances or returning the first one, both instances()
and first_instance()
support an optional argument to allow you to filter the results:
class_object.instances
(criteria)
class_object.first_instance
(criteria)
Replace criteria with a dictionary consisting of key-value pairs, where keys represent instance properties and values represent required values of these properties.
Example 22.14. Accessing Instances
To find the first instance of the cls
class object created in Example 22.7, “Accessing Class Objects” that has the ElementName
property equal to eth0
and assign it to a variable named device
, type the following at the interactive prompt:
> device = cls.first_instance({"ElementName": "eth0"}) >
Examining Instances
All instance objects store information about their class name and the namespace they belong to, as well as detailed documentation about their properties and values. In addition, instance objects allow you to retrieve a unique identification object.
To get the class name of a particular instance object, use the following syntax:
instance_object.classname
Replace instance_object with the name of the instance object to inspect. This returns a string representation of the class name.
To get information about the namespace an instance object belongs to, use:
instance_object.namespace
This returns a string representation of the namespace.
To retrieve a unique identification object for an instance object, use:
instance_object.path
This returns an LMIInstanceName
object.
Finally, to display detailed documentation, use the doc()
method as follows:
instance_object.doc
()
Example 22.15. Examining Instances
To inspect the device
instance object created in Example 22.14, “Accessing Instances” and display its class name and the corresponding namespace, type the following at the interactive prompt:
> device.classname u'LMI_IPNetworkConnection' > device.namespace 'root/cimv2' >
To access instance object documentation, type:
> device.doc() Instance of LMI_IPNetworkConnection [property] uint16 RequestedState = '12' [property] uint16 HealthState [property array] string [] StatusDescriptions ...
Creating New Instances
Certain CIM providers allow you to create new instances of specific classes objects. To create a new instance of a class object, use the create_instance()
method as follows:
class_object.create_instance
(properties)
Replace class_object with the name of the class object and properties with a dictionary that consists of key-value pairs, where keys represent instance properties and values represent property values. This method returns an LMIInstance
object.
Example 22.16. Creating New Instances
The LMI_Group
class represents system groups and the LMI_Account
class represents user accounts on the managed system. To use the ns
namespace object created in Example 22.5, “Accessing Namespace Objects”, create instances of these two classes for the system group named pegasus
and the user named lmishell-user
, and assign them to variables named group
and user
, type the following at the interactive prompt:
> group = ns.LMI_Group.first_instance({"Name" : "pegasus"}) > user = ns.LMI_Account.first_instance({"Name" : "lmishell-user"}) >
To get an instance of the LMI_Identity
class for the lmishell-user
user, type:
> identity = user.first_associator(ResultClass="LMI_Identity") >
The LMI_MemberOfGroup
class represents system group membership. To use the LMI_MemberOfGroup
class to add the lmishell-user
to the pegasus
group, create a new instance of this class as follows:
> ns.LMI_MemberOfGroup.create_instance({ ... "Member" : identity.path, ... "Collection" : group.path}) LMIInstance(classname="LMI_MemberOfGroup", ...) >
Deleting Individual Instances
To delete a particular instance from the CIMOM, use the delete()
method as follows:
instance_object.delete
()
Replace instance_object with the name of the instance object to delete. This method returns a boolean. Note that after deleting an instance, its properties and methods become inaccessible.
Example 22.17. Deleting Individual Instances
The LMI_Account
class represents user accounts on the managed system. To use the ns
namespace object created in Example 22.5, “Accessing Namespace Objects”, create an instance of the LMI_Account
class for the user named lmishell-user
, and assign it to a variable named user
, type the following at the interactive prompt:
> user = ns.LMI_Account.first_instance({"Name" : "lmishell-user"}) >
To delete this instance and remove the lmishell-user
from the system, type:
> user.delete()
True
>
Listing and Accessing Available Properties
To list all available properties of a particular instance object, use the print_properties()
method as follows:
instance_object.print_properties
()
Replace instance_object with the name of the instance object to inspect. This method prints available properties to standard output.
To get a list of available properties, use the properties()
method:
instance_object.properties
()
This method returns a list of strings.
Example 22.18. Listing Available Properties
To inspect the device
instance object created in Example 22.14, “Accessing Instances” and list all available properties, type the following at the interactive prompt:
> device.print_properties() RequestedState HealthState StatusDescriptions TransitioningToState Generation ... >
To assign a list of these properties to a variable named device_properties
, type:
> device_properties = device.properties() >
To get the current value of a particular property, use the following syntax:
instance_object.property_name
Replace property_name with the name of the property to access.
To modify the value of a particular property, assign a value to it as follows:
instance_object.property_name = value
Replace value with the new value of the property. Note that in order to propagate the change to the CIMOM, you must also execute the push()
method:
instance_object.push
()
This method returns a three-item tuple consisting of a return value, return value parameters, and an error string.
Example 22.19. Accessing Individual Properties
To inspect the device
instance object created in Example 22.14, “Accessing Instances” and display the value of the property named SystemName
, type the following at the interactive prompt:
> device.SystemName
u'server.example.com'
>
Listing and Using Available Methods
To list all available methods of a particular instance object, use the print_methods()
method as follows:
instance_object.print_methods
()
Replace instance_object with the name of the instance object to inspect. This method prints available methods to standard output.
To get a list of available methods, use the method()
method:
instance_object.methods
()
This method returns a list of strings.
Example 22.20. Listing Available Methods
To inspect the device
instance object created in Example 22.14, “Accessing Instances” and list all available methods, type the following at the interactive prompt:
> device.print_methods() RequestStateChange >
To assign a list of these methods to a variable named network_device_methods
, type:
> network_device_methods = device.methods() >
To call a particular method, use the following syntax:
instance_object.method_name( parameter=value, ...)
Replace instance_object with the name of the instance object to use, method_name with the name of the method to call, parameter with the name of the parameter to set, and value with the value of this parameter. Methods return a three-item tuple consisting of a return value, return value parameters, and an error string.
LMIInstance
objects do not automatically refresh their contents (properties, methods, qualifiers, and so on). To do so, use the refresh()
method as described below.
Example 22.21. Using Methods
The PG_ComputerSystem
class represents the system. To create an instance of this class by using the ns
namespace object created in Example 22.5, “Accessing Namespace Objects” and assign it to a variable named sys
, type the following at the interactive prompt:
> sys = ns.PG_ComputerSystem.first_instance() >
The LMI_AccountManagementService
class implements methods that allow you to manage users and groups in the system. To create an instance of this class and assign it to a variable named acc
, type:
> acc = ns.LMI_AccountManagementService.first_instance() >
To create a new user named lmishell-user
in the system, use the CreateAccount()
method as follows:
> acc.CreateAccount(Name="lmishell-user", System=sys) LMIReturnValue(rval=0, rparams=NocaseDict({u'Account': LMIInstanceName(classname="LMI_Account"...), u'Identities': [LMIInstanceName(classname="LMI_Identity"...), LMIInstanceName(classname="LMI_Identity"...)]}), errorstr='')
LMIShell support synchronous method calls: when you use a synchronous method, LMIShell waits for the corresponding Job object to change its state to "finished" and then returns the return parameters of this job. LMIShell is able to perform a synchronous method call if the given method returns an object of one of the following classes:
-
LMI_StorageJob
-
LMI_SoftwareInstallationJob
-
LMI_NetworkJob
LMIShell first tries to use indications as the waiting method. If it fails, it uses a polling method instead.
To perform a synchronous method call, use the following syntax:
instance_object.Sync
method_name(
parameter=value,
...)
Replace instance_object with the name of the instance object to use, method_name with the name of the method to call, parameter with the name of the parameter to set, and value with the value of this parameter. All synchronous methods have the Sync
prefix in their name and return a three-item tuple consisting of the job’s return value, job’s return value parameters, and job’s error string.
You can also force LMIShell to use only polling method. To do so, specify the PreferPolling
parameter as follows:
instance_object.Sync
method_name(PreferPolling
=True
parameter=value, ...)
Listing and Viewing ValueMap Parameters
CIM methods may contain ValueMap parameters in their Managed Object Format (MOF) definition. ValueMap parameters contain constant values.
To list all available ValueMap parameters of a particular method, use the print_valuemap_parameters()
method as follows:
instance_object.method_name.print_valuemap_parameters
()
Replace instance_object with the name of the instance object and method_name with the name of the method to inspect. This method prints available ValueMap parameters to standard output.
To get a list of available ValueMap parameters, use the valuemap_parameters()
method:
instance_object.method_name.valuemap_parameters
()
This method returns a list of strings.
Example 22.22. Listing ValueMap Parameters
To inspect the acc
instance object created in Example 22.21, “Using Methods” and list all available ValueMap parameters of the CreateAccount()
method, type the following at the interactive prompt:
> acc.CreateAccount.print_valuemap_parameters() CreateAccount >
To assign a list of these ValueMap parameters to a variable named create_account_parameters
, type:
> create_account_parameters = acc.CreateAccount.valuemap_parameters() >
To access a particular ValueMap parameter, use the following syntax:
instance_object.method_name.valuemap_parameterValues
Replace valuemap_parameter with the name of the ValueMap parameter to access.
To list all available constant values, use the print_values()
method as follows:
instance_object.method_name.valuemap_parameterValues
.print_values
()
This method prints available named constant values to standard output. You can also get a list of available constant values by using the values()
method:
instance_object.method_name.valuemap_parameterValues
.values
()
This method returns a list of strings.
Example 22.23. Accessing ValueMap Parameters
Example 22.22, “Listing ValueMap Parameters” mentions a ValueMap parameter named CreateAccount
. To inspect this parameter and list available constant values, type the following at the interactive prompt:
> acc.CreateAccount.CreateAccountValues.print_values() Operationunsupported Failed Unabletosetpasswordusercreated Unabletocreatehomedirectoryusercreatedandpasswordset Operationcompletedsuccessfully >
To assign a list of these constant values to a variable named create_account_values
, type:
> create_account_values = acc.CreateAccount.CreateAccountValues.values() >
To access a particular constant value, use the following syntax:
instance_object.method_name.valuemap_parameterValues
.constant_value_name
Replace constant_value_name with the name of the constant value. Alternatively, you can use the value()
method as follows:
instance_object.method_name.valuemap_parameterValues
.value
("constant_value_name")
To determine the name of a particular constant value, use the value_name()
method:
instance_object.method_name.valuemap_parameterValues
.value_name
("constant_value")
This method returns a string.
Example 22.24. Accessing Constant Values
Example 22.23, “Accessing ValueMap Parameters” shows that the CreateAccount
ValueMap parameter provides a constant value named Failed
. To access this named constant value, type the following at the interactive prompt:
>acc.CreateAccount.CreateAccountValues.Failed
2 >acc.CreateAccount.CreateAccountValues.value("Failed")
2 >
To determine the name of this constant value, type:
> acc.CreateAccount.CreateAccountValues.value_name(2) u'Failed' >
Refreshing Instance Objects
Local objects used by LMIShell, which represent CIM objects at CIMOM side, can get outdated, if such objects change while working with LMIShell’s ones. To update the properties and methods of a particular instance object, use the refresh()
method as follows:
instance_object.refresh
()
Replace instance_object with the name of the object to refresh. This method returns a three-item tuple consisting of a return value, return value parameter, and an error string.
Example 22.25. Refreshing Instance Objects
To update the properties and methods of the device
instance object created in Example 22.14, “Accessing Instances”, type the following at the interactive prompt:
> device.refresh()
LMIReturnValue(rval=True, rparams=NocaseDict({}), errorstr='')
>
Displaying MOF Representation
To display the Managed Object Format (MOF) representation of an instance object, use the tomof()
method as follows:
instance_object.tomof
()
Replace instance_object with the name of the instance object to inspect. This method prints the MOF representation of the object to standard output.
Example 22.26. Displaying MOF Representation
To display the MOF representation of the device
instance object created in Example 22.14, “Accessing Instances”, type the following at the interactive prompt:
> device.tomof() instance of LMI_IPNetworkConnection { RequestedState = 12; HealthState = NULL; StatusDescriptions = NULL; TransitioningToState = 12; ...
22.4.6. Working with Instance Names
LMIShell instance names are objects that hold a set of primary keys and their values. This type of an object exactly identifies an instance.
Accessing Instance Names
CIMInstance
objects are identified by CIMInstanceName
objects. To get a list of all available instance name objects, use the instance_names()
method as follows:
class_object.instance_names
()
Replace class_object with the name of the class object to inspect. This method returns a list of LMIInstanceName
objects.
To access the first instance name object of a class object, use the first_instance_name()
method:
class_object.first_instance_name
()
This method returns an LMIInstanceName
object.
In addition to listing all instance name objects or returning the first one, both instance_names()
and first_instance_name()
support an optional argument to allow you to filter the results:
class_object.instance_names
(criteria)
class_object.first_instance_name
(criteria)
Replace criteria with a dictionary consisting of key-value pairs, where keys represent key properties and values represent required values of these key properties.
Example 22.27. Accessing Instance Names
To find the first instance name of the cls
class object created in Example 22.7, “Accessing Class Objects” that has the Name
key property equal to eth0
and assign it to a variable named device_name
, type the following at the interactive prompt:
> device_name = cls.first_instance_name({"Name": "eth0"}) >
Examining Instance Names
All instance name objects store information about their class name and the namespace they belong to.
To get the class name of a particular instance name object, use the following syntax:
instance_name_object.classname
Replace instance_name_object with the name of the instance name object to inspect. This returns a string representation of the class name.
To get information about the namespace an instance name object belongs to, use:
instance_name_object.namespace
This returns a string representation of the namespace.
Example 22.28. Examining Instance Names
To inspect the device_name
instance name object created in Example 22.27, “Accessing Instance Names” and display its class name and the corresponding namespace, type the following at the interactive prompt:
> device_name.classname u'LMI_IPNetworkConnection' > device_name.namespace 'root/cimv2' >
Creating New Instance Names
LMIShell allows you to create a new wrapped CIMInstanceName
object if you know all primary keys of a remote object. This instance name object can then be used to retrieve the whole instance object.
To create a new instance name of a class object, use the new_instance_name()
method as follows:
class_object.new_instance_name
(key_properties)
Replace class_object with the name of the class object and key_properties with a dictionary that consists of key-value pairs, where keys represent key properties and values represent key property values. This method returns an LMIInstanceName
object.
Example 22.29. Creating New Instance Names
The LMI_Account
class represents user accounts on the managed system. To use the ns
namespace object created in Example 22.5, “Accessing Namespace Objects” and create a new instance name of the LMI_Account
class representing the lmishell-user
user on the managed system, type the following at the interactive prompt:
> instance_name = ns.LMI_Account.new_instance_name({ ... "CreationClassName" : "LMI_Account", ... "Name" : "lmishell-user", ... "SystemCreationClassName" : "PG_ComputerSystem", ... "SystemName" : "server"}) >
Listing and Accessing Key Properties
To list all available key properties of a particular instance name object, use the print_key_properties()
method as follows:
instance_name_object.print_key_properties
()
Replace instance_name_object with the name of the instance name object to inspect. This method prints available key properties to standard output.
To get a list of available key properties, use the key_properties()
method:
instance_name_object.key_properties
()
This method returns a list of strings.
Example 22.30. Listing Available Key Properties
To inspect the device_name
instance name object created in Example 22.27, “Accessing Instance Names” and list all available key properties, type the following at the interactive prompt:
> device_name.print_key_properties() CreationClassName SystemName Name SystemCreationClassName >
To assign a list of these key properties to a variable named device_name_properties
, type:
> device_name_properties = device_name.key_properties() >
To get the current value of a particular key property, use the following syntax:
instance_name_object.key_property_name
Replace key_property_name with the name of the key property to access.
Example 22.31. Accessing Individual Key Properties
To inspect the device_name
instance name object created in Example 22.27, “Accessing Instance Names” and display the value of the key property named SystemName
, type the following at the interactive prompt:
> device_name.SystemName u'server.example.com' >
Converting Instance Names to Instances
Each instance name can be converted to an instance. To do so, use the to_instance()
method as follows:
instance_name_object.to_instance
()
Replace instance_name_object with the name of the instance name object to convert. This method returns an LMIInstance
object.
Example 22.32. Converting Instance Names to Instances
To convert the device_name
instance name object created in Example 22.27, “Accessing Instance Names” to an instance object and assign it to a variable named device
, type the following at the interactive prompt:
> device = device_name.to_instance() >
22.4.7. Working with Associated Objects
The Common Information Model defines an association relationship between managed objects.
Accessing Associated Instances
To get a list of all objects associated with a particular instance object, use the associators()
method as follows:
instance_object.associators
(
AssocClass=class_name,
ResultClass=class_name,
ResultRole=role,
IncludeQualifiers=include_qualifiers,
IncludeClassOrigin=include_class_origin,
PropertyList=property_list)
To access the first object associated with a particular instance object, use the first_associator()
method:
instance_object.first_associator
(
AssocClass=class_name,
ResultClass=class_name,
ResultRole=role,
IncludeQualifiers=include_qualifiers,
IncludeClassOrigin=include_class_origin,
PropertyList=property_list)
Replace instance_object with the name of the instance object to inspect. You can filter the results by specifying the following parameters:
-
AssocClass
— Each returned object must be associated with the source object through an instance of this class or one of its subclasses. The default value isNone
. -
ResultClass
— Each returned object must be either an instance of this class or one of its subclasses, or it must be this class or one of its subclasses. The default value isNone
. -
Role
— Each returned object must be associated with the source object through an association in which the source object plays the specified role. The name of the property in the association class that refers to the source object must match the value of this parameter. The default value isNone
. -
ResultRole
— Each returned object must be associated with the source object through an association in which the returned object plays the specified role. The name of the property in the association class that refers to the returned object must match the value of this parameter. The default value isNone
.
The remaining parameters refer to:
-
IncludeQualifiers
— A boolean indicating whether all qualifiers of each object (including qualifiers on the object and on any returned properties) should be included as QUALIFIER elements in the response. The default value isFalse
. -
IncludeClassOrigin
— A boolean indicating whether the CLASSORIGIN attribute should be present on all appropriate elements in each returned object. The default value isFalse
. -
PropertyList
— The members of this list define one or more property names. Returned objects will not include elements for any properties missing from this list. IfPropertyList
is an empty list, no properties are included in returned objects. If it isNone
, no additional filtering is defined. The default value isNone
.
Example 22.33. Accessing Associated Instances
The LMI_StorageExtent
class represents block devices available in the system. To use the ns
namespace object created in Example 22.5, “Accessing Namespace Objects”, create an instance of the LMI_StorageExtent
class for the block device named /dev/vda
, and assign it to a variable named vda
, type the following at the interactive prompt:
> vda = ns.LMI_StorageExtent.first_instance({ ... "DeviceID" : "/dev/vda"}) >
To get a list of all disk partitions on this block device and assign it to a variable named vda_partitions
, use the associators()
method as follows:
> vda_partitions = vda.associators(ResultClass="LMI_DiskPartition") >
Accessing Associated Instance Names
To get a list of all associated instance names of a particular instance object, use the associator_names()
method as follows:
instance_object.associator_names
(
AssocClass=class_name,
ResultClass=class_name,
Role=role,
ResultRole=role)
To access the first associated instance name of a particular instance object, use the first_associator_name()
method:
instance_object.first_associator_name
(
AssocClass=class_object,
ResultClass=class_object,
Role=role,
ResultRole=role)
Replace instance_object with the name of the instance object to inspect. You can filter the results by specifying the following parameters:
-
AssocClass
— Each returned name identifies an object that must be associated with the source object through an instance of this class or one of its subclasses. The default value isNone
. -
ResultClass
— Each returned name identifies an object that must be either an instance of this class or one of its subclasses, or it must be this class or one of its subclasses. The default value isNone
. -
Role
— Each returned name identifies an object that must be associated with the source object through an association in which the source object plays the specified role. The name of the property in the association class that refers to the source object must match the value of this parameter. The default value isNone
. -
ResultRole
— Each returned name identifies an object that must be associated with the source object through an association in which the returned named object plays the specified role. The name of the property in the association class that refers to the returned object must match the value of this parameter. The default value isNone
.
Example 22.34. Accessing Associated Instance Names
To use the vda
instance object created in Example 22.33, “Accessing Associated Instances”, get a list of its associated instance names, and assign it to a variable named vda_partitions
, type:
> vda_partitions = vda.associator_names(ResultClass="LMI_DiskPartition") >
22.4.8. Working with Association Objects
The Common Information Model defines an association relationship between managed objects. Association objects define the relationship between two other objects.
Accessing Association Instances
To get a list of association objects that refer to a particular target object, use the references()
method as follows:
instance_object.references
(
ResultClass=class_name,
Role=role,
IncludeQualifiers=include_qualifiers,
IncludeClassOrigin=include_class_origin,
PropertyList=property_list)
To access the first association object that refers to a particular target object, use the first_reference()
method:
instance_object.first_reference
(
... ResultClass=class_name,
... Role=role,
... IncludeQualifiers=include_qualifiers,
... IncludeClassOrigin=include_class_origin,
... PropertyList=property_list)
>
Replace instance_object with the name of the instance object to inspect. You can filter the results by specifying the following parameters:
-
ResultClass
— Each returned object must be either an instance of this class or one of its subclasses, or it must be this class or one of its subclasses. The default value isNone
. -
Role
— Each returned object must refer to the target object through a property with a name that matches the value of this parameter. The default value isNone
.
The remaining parameters refer to:
-
IncludeQualifiers
— A boolean indicating whether each object (including qualifiers on the object and on any returned properties) should be included as a QUALIFIER element in the response. The default value isFalse
. -
IncludeClassOrigin
— A boolean indicating whether the CLASSORIGIN attribute should be present on all appropriate elements in each returned object. The default value isFalse
. -
PropertyList
— The members of this list define one or more property names. Returned objects will not include elements for any properties missing from this list. IfPropertyList
is an empty list, no properties are included in returned objects. If it isNone
, no additional filtering is defined. The default value isNone
.
Example 22.35. Accessing Association Instances
The LMI_LANEndpoint
class represents a communication endpoint associated with a certain network interface device. To use the ns
namespace object created in Example 22.5, “Accessing Namespace Objects”, create an instance of the LMI_LANEndpoint
class for the network interface device named eth0, and assign it to a variable named lan_endpoint
, type the following at the interactive prompt:
> lan_endpoint = ns.LMI_LANEndpoint.first_instance({ ... "Name" : "eth0"}) >
To access the first association object that refers to an LMI_BindsToLANEndpoint
object and assign it to a variable named bind
, type:
> bind = lan_endpoint.first_reference( ... ResultClass="LMI_BindsToLANEndpoint") >
You can now use the Dependent
property to access the dependent LMI_IPProtocolEndpoint
class that represents the IP address of the corresponding network interface device:
> ip = bind.Dependent.to_instance() > print ip.IPv4Address 192.168.122.1 >
Accessing Association Instance Names
To get a list of association instance names of a particular instance object, use the reference_names()
method as follows:
instance_object.reference_names
(
ResultClass=class_name,
Role=role)
To access the first association instance name of a particular instance object, use the first_reference_name()
method:
instance_object.first_reference_name
(
ResultClass=class_name,
Role=role)
Replace instance_object with the name of the instance object to inspect. You can filter the results by specifying the following parameters:
-
ResultClass
— Each returned object name identifies either an instance of this class or one of its subclasses, or this class or one of its subclasses. The default value isNone
. -
Role
— Each returned object identifies an object that refers to the target instance through a property with a name that matches the value of this parameter. The default value isNone
.
Example 22.36. Accessing Association Instance Names
To use the lan_endpoint
instance object created in Example 22.35, “Accessing Association Instances”, access the first association instance name that refers to an LMI_BindsToLANEndpoint
object, and assign it to a variable named bind
, type:
> bind = lan_endpoint.first_reference_name( ... ResultClass="LMI_BindsToLANEndpoint")
You can now use the Dependent
property to access the dependent LMI_IPProtocolEndpoint
class that represents the IP address of the corresponding network interface device:
> ip = bind.Dependent.to_instance() > print ip.IPv4Address 192.168.122.1 >
22.4.9. Working with Indications
Indication is a reaction to a specific event that occurs in response to a particular change in data. LMIShell can subscribe to an indication in order to receive such event responses.
Subscribing to Indications
To subscribe to an indication, use the subscribe_indication()
method as follows:
connection_object.subscribe_indication
( QueryLanguage="WQL"
, Query='SELECT * FROM CIM_InstModification'
, Name="cpu"
, CreationNamespace="root/interop"
, SubscriptionCreationClassName="CIM_IndicationSubscription"
, FilterCreationClassName="CIM_IndicationFilter"
, FilterSystemCreationClassName="CIM_ComputerSystem"
, FilterSourceNamespace="root/cimv2"
, HandlerCreationClassName="CIM_IndicationHandlerCIMXML"
, HandlerSystemCreationClassName="CIM_ComputerSystem"
, Destination="http://host_name:5988"
)
Alternatively, you can use a shorter version of the method call as follows:
connection_object.subscribe_indication
( Query='SELECT * FROM CIM_InstModification'
, Name="cpu"
, Destination="http://host_name:5988"
)
Replace connection_object with a connection object and host_name with the host name of the system you want to deliver the indications to.
By default, all subscriptions created by the LMIShell interpreter are automatically deleted when the interpreter terminates. To change this behavior, pass the Permanent=True
keyword parameter to the subscribe_indication()
method call. This will prevent LMIShell from deleting the subscription.
Example 22.37. Subscribing to Indications
To use the c
connection object created in Example 22.1, “Connecting to a Remote CIMOM” and subscribe to an indication named cpu
, type the following at the interactive prompt:
> c.subscribe_indication( ... QueryLanguage="WQL", ... Query='SELECT * FROM CIM_InstModification', ... Name="cpu", ... CreationNamespace="root/interop", ... SubscriptionCreationClassName="CIM_IndicationSubscription", ... FilterCreationClassName="CIM_IndicationFilter", ... FilterSystemCreationClassName="CIM_ComputerSystem", ... FilterSourceNamespace="root/cimv2", ... HandlerCreationClassName="CIM_IndicationHandlerCIMXML", ... HandlerSystemCreationClassName="CIM_ComputerSystem", ... Destination="http://server.example.com:5988") LMIReturnValue(rval=True, rparams=NocaseDict({}), errorstr='') >
Listing Subscribed Indications
To list all the subscribed indications, use the print_subscribed_indications()
method as follows:
connection_object.print_subscribed_indications
()
Replace connection_object with the name of the connection object to inspect. This method prints subscribed indications to standard output.
To get a list of subscribed indications, use the subscribed_indications()
method:
connection_object.subscribed_indications
()
This method returns a list of strings.
Example 22.38. Listing Subscribed Indications
To inspect the c
connection object created in Example 22.1, “Connecting to a Remote CIMOM” and list all subscribed indications, type the following at the interactive prompt:
> c.print_subscribed_indications() >
To assign a list of these indications to a variable named indications
, type:
> indications = c.subscribed_indications() >
Unsubscribing from Indications
By default, all subscriptions created by the LMIShell interpreter are automatically deleted when the interpreter terminates. To delete an individual subscription sooner, use the unsubscribe_indication()
method as follows:
connection_object.unsubscribe_indication
(indication_name)
Replace connection_object with the name of the connection object and indication_name with the name of the indication to delete.
To delete all subscriptions, use the unsubscribe_all_indications()
method:
connection_object.unsubscribe_all_indications
()
Example 22.39. Unsubscribing from Indications
To use the c
connection object created in Example 22.1, “Connecting to a Remote CIMOM” and unsubscribe from the indication created in Example 22.37, “Subscribing to Indications”, type the following at the interactive prompt:
> c.unsubscribe_indication('cpu') LMIReturnValue(rval=True, rparams=NocaseDict({}), errorstr='') >
Implementing an Indication Handler
The subscribe_indication()
method allows you to specify the host name of the system you want to deliver the indications to. The following example shows how to implement an indication handler:
> def handler(ind, arg1, arg2, kwargs): ... exported_objects = ind.exported_objects() ... do_something_with(exported_objects) > listener = LmiIndicationListener("0.0.0.0", listening_port) > listener.add_handler("indication-name-XXXXXXXX", handler, arg1, arg2, kwargs)
> listener.start()
>
The first argument of the handler is an LmiIndication
object, which contains a list of methods and objects exported by the indication. Other parameters are user specific: those arguments need to be specified when adding a handler to the listener.
In the example above, the add_handler()
method call uses a special string with eight "X" characters. These characters are replaced with a random string that is generated by listeners in order to avoid a possible handler name collision. To use the random string, start the indication listener first and then subscribe to an indication so that the Destination
property of the handler object contains the following value: schema://host_name/random_string
.
Example 22.40. Implementing an Indication Handler
The following script illustrates how to write a handler that monitors a managed system located at 192.168.122.1
and calls the indication_callback()
function whenever a new user account is created:
#!/usr/bin/lmishell import sys from time import sleep from lmi.shell.LMIUtil import LMIPassByRef from lmi.shell.LMIIndicationListener import LMIIndicationListener # These are passed by reference to indication_callback var1 = LMIPassByRef("some_value") var2 = LMIPassByRef("some_other_value") def indication_callback(ind, var1, var2): # Do something with ind, var1 and var2 print ind.exported_objects() print var1.value print var2.value c = connect("hostname", "username", "password") listener = LMIIndicationListener("0.0.0.0", 65500) unique_name = listener.add_handler( "demo-XXXXXXXX", # Creates a unique name for me indication_callback, # Callback to be called var1, # Variable passed by ref var2 # Variable passed by ref ) listener.start() print c.subscribe_indication( Name=unique_name, Query="SELECT * FROM LMI_AccountInstanceCreationIndication WHERE SOURCEINSTANCE ISA LMI_Account", Destination="192.168.122.1:65500" ) try: while True: sleep(60) except KeyboardInterrupt: sys.exit(0)
22.4.10. Example Usage
This section provides a number of examples for various CIM providers distributed with the OpenLMI packages. All examples in this section use the following two variable definitions:
c = connect("host_name", "user_name", "password") ns = c.root.cimv2
Replace host_name with the host name of the managed system, user_name with the name of user that is allowed to connect to OpenPegasus CIMOM running on that system, and password with the user’s password.
Using the OpenLMI Service Provider
The openlmi-service package installs a CIM provider for managing system services. The examples below illustrate how to use this CIM provider to list available system services and how to start, stop, enable, and disable them.
Example 22.41. Listing Available Services
To list all available services on the managed machine along with information regarding whether the service has been started (TRUE
) or stopped (FALSE
) and the status string, use the following code snippet:
for service in ns.LMI_Service.instances(): print "%s:\t%s" % (service.Name, service.Status)
To list only the services that are enabled by default, use this code snippet:
cls = ns.LMI_Service for service in cls.instances(): if service.EnabledDefault == cls.EnabledDefaultValues.Enabled: print service.Name
Note that the value of the EnabledDefault
property is equal to 2
for enabled services and 3
for disabled services.
To display information about the cups
service, use the following:
cups = ns.LMI_Service.first_instance({"Name": "cups.service"}) cups.doc()
Example 22.42. Starting and Stopping Services
To start and stop the cups
service and to see its current status, use the following code snippet:
cups = ns.LMI_Service.first_instance({"Name": "cups.service"}) cups.StartService() print cups.Status cups.StopService() print cups.Status
Example 22.43. Enabling and Disabling Services
To enable and disable the cups
service and to display its EnabledDefault
property, use the following code snippet:
cups = ns.LMI_Service.first_instance({"Name": "cups.service"}) cups.TurnServiceOff() print cups.EnabledDefault cups.TurnServiceOn() print cups.EnabledDefault
Using the OpenLMI Networking Provider
The openlmi-networking package installs a CIM provider for networking. The examples below illustrate how to use this CIM provider to list IP addresses associated with a certain port number, create a new connection, configure a static IP address, and activate a connection.
Example 22.44. Listing IP Addresses Associated with a Given Port Number
To list all IP addresses associated with the eth0 network interface, use the following code snippet:
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)
This code snippet uses the LMI_IPProtocolEndpoint
class associated with a given LMI_IPNetworkConnection
class.
To display the default gateway, use this code snippet:
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
The default gateway is represented by an LMI_NetworkRemoteServiceAccessPoint
instance with the AccessContext
property equal to DefaultGateway
.
To get a list of DNS servers, the object model needs to be traversed as follows:
-
Get the
LMI_IPProtocolEndpoint
instances associated with a givenLMI_IPNetworkConnection
usingLMI_NetworkSAPSAPDependency
. -
Use the same association for the
LMI_DNSProtocolEndpoint
instances.
The LMI_NetworkRemoteServiceAccessPoint
instances with the AccessContext
property equal to the DNS Server associated through LMI_NetworkRemoteAccessAvailableToElement
have the DNS server address in the AccessInfo
property.
There can be more possible paths to get to the RemoteServiceAccessPath
and entries can be duplicated. The following code snippet uses the set()
function to remove duplicate entries from 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)
Example 22.45. Creating a New Connection and Configuring a Static IP Address
To create a new setting with a static IPv4 and stateless IPv6 configuration for network interface eth0, use the following code snippet:
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()
This code snippet creates a new setting by calling the LMI_CreateIPSetting()
method on the instance of LMI_IPNetworkConnectionCapabilities
, which is associated with LMI_IPNetworkConnection
through LMI_IPNetworkConnectionElementCapabilities
. It also uses the push()
method to modify the setting.
Example 22.46. Activating a Connection
To apply a setting to the network interface, call the ApplySettingToIPNetworkConnection()
method of the LMI_IPConfigurationService
class. This method is asynchronous and returns a job. The following code snippets illustrates how to call this method 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)
The Mode
parameter affects how the setting is applied. The most commonly used values of this parameter are as follows:
-
1
— apply the setting now and make it auto-activated. -
2
— make the setting auto-activated and do not apply it now. -
4
— disconnect and disable auto-activation. -
5
— do not change the setting state, only disable auto-activation. -
32768
— apply the setting. -
32769
— disconnect.
Using the OpenLMI Storage Provider
The openlmi-storage package installs a CIM provider for storage management. The examples below illustrate how to use this CIM provider to create a volume group, create a logical volume, build a file system, mount a file system, and list block devices known to the system.
In addition to the c
and ns
variables, these examples use the following variable definitions:
MEGABYTE = 1024*1024 storage_service = ns.LMI_StorageConfigurationService.first_instance() filesystem_service = ns.LMI_FileSystemConfigurationService.first_instance()
Example 22.47. Creating a Volume Group
To create a new volume group located in /dev/myGroup/
that has three members and the default extent size of 4 MB, use the following code snippet:
# Find the devices to add to the volume group # (filtering the CIM_StorageExtent.instances() # call would be faster, but this is easier to read): sda1 = ns.CIM_StorageExtent.first_instance({"Name": "/dev/sda1"}) sdb1 = ns.CIM_StorageExtent.first_instance({"Name": "/dev/sdb1"}) sdc1 = ns.CIM_StorageExtent.first_instance({"Name": "/dev/sdc1"}) # Create a new volume group: (ret, outparams, err) = storage_service.SyncCreateOrModifyVG( ElementName="myGroup", InExtents=[sda1, sdb1, sdc1]) vg = outparams['Pool'].to_instance() print "VG", vg.PoolID, \ "with extent size", vg.ExtentSize, \ "and", vg.RemainingExtents, "free extents created."
Example 22.48. Creating a Logical Volume
To create two logical volumes with the size of 100 MB, use this code snippet:
# Find the volume group: vg = ns.LMI_VGStoragePool.first_instance({"Name": "/dev/mapper/myGroup"}) # Create the first logical volume: (ret, outparams, err) = storage_service.SyncCreateOrModifyLV( ElementName="Vol1", InPool=vg, Size=100 * MEGABYTE) lv = outparams['TheElement'].to_instance() print "LV", lv.DeviceID, \ "with", lv.BlockSize * lv.NumberOfBlocks,\ "bytes created." # Create the second logical volume: (ret, outparams, err) = storage_service.SyncCreateOrModifyLV( ElementName="Vol2", InPool=vg, Size=100 * MEGABYTE) lv = outparams['TheElement'].to_instance() print "LV", lv.DeviceID, \ "with", lv.BlockSize * lv.NumberOfBlocks, \ "bytes created."
Example 22.49. Creating a File System
To create an ext3
file system on logical volume lv
from Example 22.48, “Creating a Logical Volume”, use the following code snippet:
(ret, outparams, err) = filesystem_service.SyncLMI_CreateFileSystem( FileSystemType=filesystem_service.LMI_CreateFileSystem.FileSystemTypeValues.EXT3, InExtents=[lv])
Example 22.50. Mounting a File System
To mount the file system created in Example 22.49, “Creating a File System”, use the following code snippet:
# Find the file system on the logical volume: fs = lv.first_associator(ResultClass="LMI_LocalFileSystem") mount_service = ns.LMI_MountConfigurationService.first_instance() (rc, out, err) = mount_service.SyncCreateMount( FileSystemType='ext3', Mode=32768, # just mount FileSystem=fs, MountPoint='/mnt/test', FileSystemSpec=lv.Name)
Example 22.51. Listing Block Devices
To list all block devices known to the system, use the following code snippet:
devices = ns.CIM_StorageExtent.instances() for device in devices: if lmi_isinstance(device, ns.CIM_Memory): # Memory and CPU caches are StorageExtents too, do not print them continue print device.classname, print device.DeviceID, print device.Name, print device.BlockSize*device.NumberOfBlocks
Using the OpenLMI Hardware Provider
The openlmi-hardware package installs a CIM provider for monitoring hardware. The examples below illustrate how to use this CIM provider to retrieve information about CPU, memory modules, PCI devices, and the manufacturer and model of the machine.
Example 22.52. Viewing CPU Information
To display basic CPU information such as the CPU name, the number of processor cores, and the number of hardware threads, use the following code snippet:
cpu = ns.LMI_Processor.first_instance() cpu_cap = cpu.associators(ResultClass="LMI_ProcessorCapabilities")[0] print cpu.Name print cpu_cap.NumberOfProcessorCores print cpu_cap.NumberOfHardwareThreads
Example 22.53. Viewing Memory Information
To display basic information about memory modules such as their individual sizes, use the following code snippet:
mem = ns.LMI_Memory.first_instance() for i in mem.associators(ResultClass="LMI_PhysicalMemory"): print i.Name
Example 22.54. Viewing Chassis Information
To display basic information about the machine such as its manufacturer or its model, use the following code snippet:
chassis = ns.LMI_Chassis.first_instance() print chassis.Manufacturer print chassis.Model
Example 22.55. Listing PCI Devices
To list all PCI devices known to the system, use the following code snippet:
for pci in ns.LMI_PCIDevice.instances(): print pci.Name
22.5. Using OpenLMI Scripts
The LMIShell interpreter is built on top of Python modules that can be used to develop custom management tools. The OpenLMI Scripts project provides a number of Python libraries for interfacing with OpenLMI providers. In addition, it is distributed with lmi
, an extensible utility that can be used to interact with these libraries from the command line.
To install OpenLMI Scripts on your system, type the following at a shell prompt:
easy_install --user openlmi-scripts
This command installs the Python modules and the lmi
utility in the ~/.local/
directory. To extend the functionality of the lmi
utility, install additional OpenLMI modules by using the following command:
easy_install --user package_name
For a complete list of available modules, see the Python website. For more information about OpenLMI Scripts, see the official OpenLMI Scripts documentation.
22.6. Additional Resources
For more information about OpenLMI and system management in general, see the resources listed below.
Installed Documentation
-
lmishell(1) — The manual page for the
lmishell
client and interpreter provides detailed information about its execution and usage.
Online Documentation
- Red Hat Enterprise Linux 7 Networking Guide — The Networking Guide for Red Hat Enterprise Linux 7 documents relevant information regarding the configuration and administration of network interfaces and network services on the system.
- Red Hat Enterprise Linux 7 Storage Administration Guide — The Storage Administration Guide for Red Hat Enterprise Linux 7 provides instructions on how to manage storage devices and file systems on the system.
- Red Hat Enterprise Linux 7 Power Management Guide — The Power Management Guide for Red Hat Enterprise Linux 7 explains how to manage power consumption of the system effectively. It discusses different techniques that lower power consumption for both servers and laptops, and explains how each technique affects the overall performance of the system.
- Red Hat Enterprise Linux 7 Linux Domain Identity, Authentication, and Policy Guide — The Linux Domain Identity, Authentication, and Policy Guide for Red Hat Enterprise Linux 7 covers all aspects of installing, configuring, and managing IPA domains, including both servers and clients. The guide is intended for IT and systems administrators.
- FreeIPA Documentation — The FreeIPA Documentation serves as the primary user documentation for using the FreeIPA Identity Management project.
- OpenSSL Home Page — The OpenSSL home page provides an overview of the OpenSSL project.
- Mozilla NSS Documentation — The Mozilla NSS Documentation serves as the primary user documentation for using the Mozilla NSS project.
See Also
- Chapter 4, Managing Users and Groups documents how to manage system users and groups in the graphical user interface and on the command line.
- Chapter 9, Yum describes how to use the Yum package manager to search, install, update, and uninstall packages on the command line.
-
Chapter 10, Managing Services with systemd provides an introduction to
systemd
and documents how to use thesystemctl
command to manage system services, configure systemd targets, and execute power management commands. -
Chapter 12, OpenSSH describes how to configure an SSH server and how to use the
ssh
,scp
, andsftp
client utilities to access it.