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" . 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 : 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 : 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 the pegasus user is allowed to access the CIMOM both remotely and locally. To activate this user account, run the following command as root to set the user's password: Start the OpenPegasus CIMOM by activating the tog-pegasus.service unit. To activate the tog-pegasus.service unit in the current session, type the following at a shell prompt as root : To configure the tog-pegasus.service unit to start automatically at boot time, type as root : 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 as root : To open port 5989 for TCP communication permanently, type as root : 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 : 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" . Table 22.2. Certificate and Trust Store Locations Configuration Option Location Description sslCertificateFilePath /etc/Pegasus/server.pem Public certificate of the CIMOM. sslKeyFilePath /etc/Pegasus/file.pem Private key known only to the CIMOM. sslTrustStore /etc/Pegasus/client.pem The file or directory providing the list of trusted certificate authorities. Important 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 : 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. Important 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 as root : 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 the root user to log in to the system over the SSH protocol. For more information on how to install and configure the sshd service and use the scp 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 as root on that system: 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: 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 : 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 : Update the trust store by running the following command as root : Register Pegasus as a service in the Identity Management domain by running the following command as a privileged domain user: 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 : 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 the ipa-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 : Update the trust store by running the following command as root : 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 as root . Update the trust store by running the following command as root : 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 : Update the trust store by running the following command as root : 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: 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 : Generate a certificate signing request (CSR) by running this command as root : 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 : After accomplishing all the described steps, the clients that trust the signing authority are able to successfully communicate with the managed server's CIMOM. Important 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: 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: 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: To clear the command history, use the clear_history() function as follows: 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: 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: To re-enable the automatic exception handling, use: You can permanently disable the exception handling by changing the value of the use_exceptions option in the ~/.lmishellrc configuration file to 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: 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: To enable it again, use: 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 : 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: Running an LMIShell Script To run an LMIShell script, run the lmishell command as follows: 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: 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: 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: 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: 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: 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: 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: Alternatively, you can verify that c is not None : 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: 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 : 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: To assign a list of these namespaces to a variable named root_namespaces , type: Accessing Namespace Objects To access a particular namespace object, use the following syntax: 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: 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: 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: 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: To assign a list of these classes to a variable named cimv2_classes , type: Accessing Class Objects To access a particular class object that is provided by the CIMOM, use the following syntax: 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: 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: 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: This returns a string representation of the namespace. To display detailed class documentation, use the doc() method as follows: 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: To access class documentation, type: Listing Available Methods To list all available methods of a particular class object, use the print_methods() method as follows: 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: 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: To assign a list of these methods to a variable named service_methods , type: Listing Available Properties To list all available properties of a particular class object, use the print_properties() method as follows: 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: 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: To assign a list of these classes to a variable named service_properties , type: 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: 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: 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: To assign a list of these ValueMap properties to a variable named service_valuemap_properties , type: To access a particular ValueMap property, use the following syntax: 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: 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: 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: To assign a list of these constant values to a variable named requested_state_values , type: To access a particular constant value, use the following syntax: Replace constant_value_name with the name of the constant value. Alternatively, you can use the value() method as follows: To determine the name of a particular constant value, use the value_name() method: 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: To determine the name of this constant value, type: 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: 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: 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: 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: 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: 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: 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: This returns a string representation of the namespace. To retrieve a unique identification object for an instance object, use: This returns an LMIInstanceName object. Finally, to display detailed documentation, use the doc() method as follows: 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: To access instance object documentation, type: 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: 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: To get an instance of the LMI_Identity class for the lmishell-user user, type: 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: Deleting Individual Instances To delete a particular instance from the CIMOM, use the delete() method as follows: 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: To delete this instance and remove the lmishell-user from the system, type: Listing and Accessing Available Properties To list all available properties of a particular instance object, use the print_properties() method as follows: 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: 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: To assign a list of these properties to a variable named device_properties , type: To get the current value of a particular property, use the following syntax: 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: 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: 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: Listing and Using Available Methods To list all available methods of a particular instance object, use the print_methods() method as follows: 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: 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: To assign a list of these methods to a variable named network_device_methods , type: To call a particular method, use the following syntax: 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. Important 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: 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: To create a new user named lmishell-user in the system, use the CreateAccount() method as follows: 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: 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: 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: 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: 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: To assign a list of these ValueMap parameters to a variable named create_account_parameters , type: To access a particular ValueMap parameter, use the following syntax: 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: 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: 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: To assign a list of these constant values to a variable named create_account_values , type: To access a particular constant value, use the following syntax: Replace constant_value_name with the name of the constant value. Alternatively, you can use the value() method as follows: To determine the name of a particular constant value, use the value_name() method: 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: To determine the name of this constant value, type: 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: 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: Displaying MOF Representation To display the Managed Object Format ( MOF ) representation of an instance object, use the tomof() method as follows: 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: 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: 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: 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: 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: 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: 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: 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: 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: 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: 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: 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: 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: To assign a list of these key properties to a variable named device_name_properties , type: To get the current value of a particular key property, use the following syntax: 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: Converting Instance Names to Instances Each instance name can be converted to an instance. To do so, use the to_instance() method as follows: 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: 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: To access the first object associated with a particular instance object, use the first_associator() method: 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 is None . 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 is None . 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 is None . 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 is None . 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 is False . IncludeClassOrigin - A boolean indicating whether the CLASSORIGIN attribute should be present on all appropriate elements in each returned object. The default value is False . 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. If PropertyList is an empty list, no properties are included in returned objects. If it is None , no additional filtering is defined. The default value is None . 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: 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: 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: To access the first associated instance name of a particular instance object, use the first_associator_name() method: 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 is None . 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 is None . 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 is None . 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 is None . 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: 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: To access the first association object that refers to a particular target object, use the first_reference() method: 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 is None . 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 is None . 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 is False . IncludeClassOrigin - A boolean indicating whether the CLASSORIGIN attribute should be present on all appropriate elements in each returned object. The default value is False . 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. If PropertyList is an empty list, no properties are included in returned objects. If it is None , no additional filtering is defined. The default value is None . 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: To access the first association object that refers to an LMI_BindsToLANEndpoint object and assign it to a variable named bind , type: 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: Accessing Association Instance Names To get a list of association instance names of a particular instance object, use the reference_names() method as follows: To access the first association instance name of a particular instance object, use the first_reference_name() method: 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 is None . 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 is None . 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: 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: 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: Alternatively, you can use a shorter version of the method call as follows: 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: Listing Subscribed Indications To list all the subscribed indications, use the print_subscribed_indications() method as follows: 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: 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: To assign a list of these indications to a variable named indications , type: 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: 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: 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: 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: 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: 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: 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: To list only the services that are enabled by default, use this code snippet: 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: 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: 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: 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: This code snippet uses the LMI_IPProtocolEndpoint class associated with a given LMI_IPNetworkConnection class. To display the default gateway, use this code snippet: 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 given LMI_IPNetworkConnection using LMI_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: 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: 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: 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: 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: Example 22.48. Creating a Logical Volume To create two logical volumes with the size of 100 MB, use this code snippet: 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: 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: Example 22.51. Listing Block Devices To list all block devices known to the system, use the following code snippet: 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: Example 22.53. Viewing Memory Information To display basic information about memory modules such as their individual sizes, use the following code snippet: 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: Example 22.55. Listing PCI Devices To list all PCI devices known to the system, use the following code snippet: 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: 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: 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 the systemctl 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 , and sftp client utilities to access it.

Commands:
install tog-pegasus
install openlmi-{storage,networking,service,account,powermanagement}
passwd pegasus
systemctl start tog-pegasus.service
systemctl enable tog-pegasus.service
firewall-cmd --add-port 5989/tcp
firewall-cmd --permanent --add-port 5989/tcp
install openlmi-tools
systemctl restart tog-pegasus.service
scp root@ hostname :/etc/Pegasus/server.pem /etc/pki/ca-trust/source/anchors/pegasus- hostname .pem
sha1sum /etc/Pegasus/server.pem
sha1sum /etc/pki/ca-trust/source/anchors/pegasus- hostname .pem
update-ca-trust extract
cp /etc/ipa/ca.crt /etc/pki/ca-trust/source/anchors/ipa.crt
update-ca-trust extract
ipa service-add CIMOM/ hostname
ipa-getcert request -f /etc/Pegasus/server.pem -k /etc/Pegasus/file.pem -N CN= hostname -K CIMOM/ hostname
cp /etc/ipa/ca.crt /etc/pki/ca-trust/source/anchors/ipa.crt
update-ca-trust extract
update-ca-trust extract
cp /path/to/ca.crt /etc/pki/ca-trust/source/anchors/ca.crt
update-ca-trust extract
[ req ] distinguished_name = req_distinguished_name prompt = no [ req_distinguished_name ] C = US ST = Massachusetts L = Westford O = Fedora OU = Fedora OpenLMI CN = hostname
openssl genrsa -out /etc/Pegasus/file.pem 1024
openssl req -config /etc/Pegasus/ssl.cnf -new -key /etc/Pegasus/file.pem -out /etc/Pegasus/server.csr
cp /path/to/ca.crt /etc/Pegasus/client.pem
lmishell
lmishell --noverify
> (reverse-i-search)` connect ': c = connect("server.example.com", "pegasus")
clear_history ()
history_file = "~/.lmishell_history" history_length = 1000
use_exceptions ()
use_exception ( False )
use_exceptions = True
object_name . clear_cache ()
object_name . use_cache ( False )
object_name . use_cache ( True )
use_cache = False
> quit() ~]USD
lmishell file_name
lmishell --interact file_name
connect ( host_name , user_name , password )
> c = connect("server.example.com", "pegasus") password: >
connect ( host_name )
> c = connect("localhost") >
isinstance ( object_name , LMIConnection )
> isinstance(c, LMIConnection) True >
> c is None False >
object_name . print_namespaces ()
object_name . namespaces
> c.root.print_namespaces() cimv2 interop PG_InterOp PG_Internal >
> root_namespaces = c.root.namespaces >
object_name . namespace_name
> ns = c.root.cimv2 >
namespace_object . print_classes()
namespace_object . classes ()
> ns.print_classes() CIM_CollectionInSystem CIM_ConcreteIdentity CIM_ControlledBy CIM_DeviceSAPImplementation CIM_MemberOfStatusCollection >
> cimv2_classes = ns.classes() >
namespace_object . class_name
> cls = ns.LMI_IPNetworkConnection >
class_object . classname
class_object . namespace
class_object . doc ()
> cls.classname 'LMI_IPNetworkConnection' > cls.namespace 'root/cimv2' >
> cls.doc() Class: LMI_IPNetworkConnection SuperClass: CIM_IPNetworkConnection [qualifier] string UMLPackagePath: 'CIM::Network::IP' [qualifier] string Version: '0.1.0'
class_object . print_methods ()
class_object . methods()
> cls.print_methods() RequestStateChange >
> service_methods = cls.methods() >
class_object . print_properties ()
class_object . properties ()
> cls.print_properties() RequestedState HealthState StatusDescriptions TransitioningToState Generation >
> service_properties = cls.properties() >
class_object . print_valuemap_properties ()
class_object . valuemap_properties ()
> cls.print_valuemap_properties() RequestedState HealthState TransitioningToState DetailedStatus OperationalStatus >
> service_valuemap_properties = cls.valuemap_properties() >
class_object . valuemap_property Values
class_object . valuemap_property Values . print_values ()
class_object . valuemap_property Values . values ()
> cls.RequestedStateValues.print_values() Reset NoChange NotApplicable Quiesce Unknown >
> requested_state_values = cls.RequestedStateValues.values() >
class_object . valuemap_property Values . constant_value_name
class_object . valuemap_property Values . value (" constant_value_name ")
class_object . valuemap_property Values . value_name (" constant_value ")
> cls.RequestedStateValues.Reset 11 > cls.RequestedStateValues.value("Reset") 11 >
> cls.RequestedStateValues.value_name(11) u'Reset' >
class_object . fetch ()
class_object . instances ()
class_object . first_instance ()
class_object . instances ( criteria )
class_object . first_instance ( criteria )
> device = cls.first_instance({"ElementName": "eth0"}) >
instance_object . classname
instance_object . namespace
instance_object . path
instance_object . doc ()
> device.classname u'LMI_IPNetworkConnection' > device.namespace 'root/cimv2' >
> device.doc() Instance of LMI_IPNetworkConnection [property] uint16 RequestedState = '12' [property] uint16 HealthState [property array] string [] StatusDescriptions
class_object . create_instance ( properties )
> group = ns.LMI_Group.first_instance({"Name" : "pegasus"}) > user = ns.LMI_Account.first_instance({"Name" : "lmishell-user"}) >
> identity = user.first_associator(ResultClass="LMI_Identity") >
> ns.LMI_MemberOfGroup.create_instance({ ... "Member" : identity.path, ... "Collection" : group.path}) LMIInstance(classname="LMI_MemberOfGroup", ...) >
instance_object . delete ()
> user = ns.LMI_Account.first_instance({"Name" : "lmishell-user"}) >
> user.delete() True >
instance_object . print_properties ()
instance_object . properties ()
> device.print_properties() RequestedState HealthState StatusDescriptions TransitioningToState Generation >
> device_properties = device.properties() >
instance_object . property_name
instance_object . property_name = value
instance_object . push ()
> device.SystemName u'server.example.com' >
instance_object . print_methods ()
instance_object . methods ()
> device.print_methods() RequestStateChange >
> network_device_methods = device.methods() >
instance_object . method_name ( parameter = value , ...)
> sys = ns.PG_ComputerSystem.first_instance() >
> acc = ns.LMI_AccountManagementService.first_instance() >
> 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='')
instance_object . Sync method_name ( parameter = value , ...)
instance_object . Sync method_name ( PreferPolling = True parameter = value , ...)
instance_object . method_name . print_valuemap_parameters ()
instance_object . method_name . valuemap_parameters ()
> acc.CreateAccount.print_valuemap_parameters() CreateAccount >
> create_account_parameters = acc.CreateAccount.valuemap_parameters() >
instance_object . method_name . valuemap_parameter Values
instance_object . method_name . valuemap_parameter Values . print_values ()
instance_object . method_name . valuemap_parameter Values . values ()
> acc.CreateAccount.CreateAccountValues.print_values() Operationunsupported Failed Unabletosetpasswordusercreated Unabletocreatehomedirectoryusercreatedandpasswordset Operationcompletedsuccessfully >
> create_account_values = acc.CreateAccount.CreateAccountValues.values() >
instance_object . method_name . valuemap_parameter Values . constant_value_name
instance_object . method_name . valuemap_parameter Values . value (" constant_value_name ")
instance_object . method_name . valuemap_parameter Values . value_name (" constant_value ")
> acc.CreateAccount.CreateAccountValues.Failed 2 > acc.CreateAccount.CreateAccountValues.value("Failed") 2 >
> acc.CreateAccount.CreateAccountValues.value_name(2) u'Failed' >
instance_object . refresh ()
> device.refresh() LMIReturnValue(rval=True, rparams=NocaseDict({}), errorstr='') >
instance_object . tomof ()
> device.tomof() instance of LMI_IPNetworkConnection { RequestedState = 12; HealthState = NULL; StatusDescriptions = NULL; TransitioningToState = 12;
class_object . instance_names ()
class_object . first_instance_name ()
class_object . instance_names ( criteria )
class_object . first_instance_name ( criteria )
> device_name = cls.first_instance_name({"Name": "eth0"}) >
instance_name_object . classname
instance_name_object . namespace
> device_name.classname u'LMI_IPNetworkConnection' > device_name.namespace 'root/cimv2' >
class_object . new_instance_name ( key_properties )
> instance_name = ns.LMI_Account.new_instance_name({ ... "CreationClassName" : "LMI_Account", ... "Name" : "lmishell-user", ... "SystemCreationClassName" : "PG_ComputerSystem", ... "SystemName" : "server"}) >
instance_name_object . print_key_properties ()
instance_name_object . key_properties ()
> device_name.print_key_properties() CreationClassName SystemName Name SystemCreationClassName >
> device_name_properties = device_name.key_properties() >
instance_name_object . key_property_name
> device_name.SystemName u'server.example.com' >
instance_name_object . to_instance ()
> device = device_name.to_instance() >
instance_object . associators ( AssocClass= class_name , ResultClass= class_name , ResultRole= role , IncludeQualifiers= include_qualifiers , IncludeClassOrigin= include_class_origin , PropertyList= property_list )
instance_object . first_associator ( AssocClass= class_name , ResultClass= class_name , ResultRole= role , IncludeQualifiers= include_qualifiers , IncludeClassOrigin= include_class_origin , PropertyList= property_list )
> vda = ns.LMI_StorageExtent.first_instance({ ... "DeviceID" : "/dev/vda"}) >
> vda_partitions = vda.associators(ResultClass="LMI_DiskPartition") >
instance_object . associator_names ( AssocClass= class_name , ResultClass= class_name , Role= role , ResultRole= role )
instance_object . first_associator_name ( AssocClass= class_object , ResultClass= class_object , Role= role , ResultRole= role )
> vda_partitions = vda.associator_names(ResultClass="LMI_DiskPartition") >
instance_object . references ( ResultClass= class_name , Role= role , IncludeQualifiers= include_qualifiers , IncludeClassOrigin= include_class_origin , PropertyList= property_list )
instance_object . first_reference ( ... ResultClass= class_name , ... Role= role , ... IncludeQualifiers= include_qualifiers , ... IncludeClassOrigin= include_class_origin , ... PropertyList= property_list ) >
> lan_endpoint = ns.LMI_LANEndpoint.first_instance({ ... "Name" : "eth0"}) >
> bind = lan_endpoint.first_reference( ... ResultClass="LMI_BindsToLANEndpoint") >
> ip = bind.Dependent.to_instance() > print ip.IPv4Address 192.168.122.1 >
instance_object . reference_names ( ResultClass= class_name , Role= role )
instance_object . first_reference_name ( ResultClass= class_name , Role= role )
> bind = lan_endpoint.first_reference_name( ... ResultClass="LMI_BindsToLANEndpoint")
> ip = bind.Dependent.to_instance() > print ip.IPv4Address 192.168.122.1 >
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" )
connection_object . subscribe_indication ( Query= 'SELECT * FROM CIM_InstModification' , Name= "cpu" , Destination= "http://host_name:5988" )
> 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='') >
connection_object . print_subscribed_indications ()
connection_object . subscribed_indications ()
> c.print_subscribed_indications() >
> indications = c.subscribed_indications() >
connection_object . unsubscribe_indication ( indication_name )
connection_object . unsubscribe_all_indications ()
> c.unsubscribe_indication('cpu') LMIReturnValue(rval=True, rparams=NocaseDict({}), errorstr='') >
> 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() >
#!/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)
c = connect("host_name", "user_name", "password") ns = c.root.cimv2
for service in ns.LMI_Service.instances(): print "%s:\t%s" % (service.Name, service.Status)
cls = ns.LMI_Service for service in cls.instances(): if service.EnabledDefault == cls.EnabledDefaultValues.Enabled: print service.Name
cups = ns.LMI_Service.first_instance({"Name": "cups.service"}) cups.doc()
cups = ns.LMI_Service.first_instance({"Name": "cups.service"}) cups.StartService() print cups.Status cups.StopService() print cups.Status
cups = ns.LMI_Service.first_instance({"Name": "cups.service"}) cups.TurnServiceOff() print cups.EnabledDefault cups.TurnServiceOn() print cups.EnabledDefault
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)
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
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)
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()
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)
MEGABYTE = 1024*1024 storage_service = ns.LMI_StorageConfigurationService.first_instance() filesystem_service = ns.LMI_FileSystemConfigurationService.first_instance()
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."
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."
(ret, outparams, err) = filesystem_service.SyncLMI_CreateFileSystem( FileSystemType=filesystem_service.LMI_CreateFileSystem.FileSystemTypeValues.EXT3, InExtents=[lv])
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)
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
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
mem = ns.LMI_Memory.first_instance() for i in mem.associators(ResultClass="LMI_PhysicalMemory"): print i.Name
chassis = ns.LMI_Chassis.first_instance() print chassis.Manufacturer print chassis.Model
for pci in ns.LMI_PCIDevice.instances(): print pci.Name
easy_install --user openlmi-scripts
easy_install --user package_name