published on in bash IT JVM scripting Weblogic WLST
tags: web

WLST – Scripting para WebLogic vía bash (I)

WLS…qué?

Desde hace ya algún tiempo tenía en mente hacer una serie de posts sobre como automatizar tareas en Oracle WebLogic® con WLST (WebLogic Scripting Tool) vía bash.

Desde las versiones 9.x de WebLogic, este componente viene por defecto. Para 8.x, existía un jar que se podía descargar en las páginas del Dev2Dev de Bea, pero tras su adquisición por Oracle, perdí la pista a esa página y, por tanto, también a la posibilidad de correr WLST en esa versión.

Básicamente, lo que WLST nos ofrece es un entorno de scripting para gestionar los dominios de WebLogic basado en jython (implementación de python en java).  Al ejecutar la consola de WLST tendremos un intérprete de jython con una serie de funciones predefinidas para administrar WebLogic, de forma que podremos arrancar o parar servidores, crear JDBC pools…lo que sea!

La idea es que se pueden realizar todas las tares administrativas que se hacen desde la consola de administración vía a) línea de comandos o b) vía clases de java. Personalmente, la idea de este post es ver cómo integrar scripts escritos en python/jython con scripts en bash, de forma que se puedan ejecutar desde un shell de cualquier *NIX (tambíen se podría usar desde sistemas “Next,Next,Finish” pero no es algo que me interese mucho 😉 )

En definitiva, la idea es usar Bash y Python (a través de jython) para gestionar dominios o servidores de WebLogic.

Definir el entorno

Lo primero de todo es ver qué necesitamos para poder usar WLST…

  1. Una máquina Linux o UNIX y claro, una cuenta de usuario 😉
  2. Un dominio de WebLogic: esto es, al menos un Admin Server y un Managed Server (el NodeManager es opcional y en mi trabajo nuestros expertos en WL prefieren no usarlos). Por ahora vamos a suponer que todo esto ya existe, ya habrá tiempo de ver cómo crear dominios y servidores con WLST.
  3. Definir las necesarias variables de entorno apra poder ejecutar nuestros scripts de jython.

Los puntos 1. y 2. son un poco de perogrullo, así que mejor nos centramos en el punto 3. “..variables de entorno..” y no podría ser más fácil, ya que el propio WebLogic nos provee un script que carga dichas variables.

Supongamos que tenemos un WebLogic 10.3 (podría ser cualquier otra versión por encima de 9) , que nuestra instalación de WebLogic se encuentra en el directorio

/opt/bea103

que pertenece al usuario ‘weblogic‘, y que tenemos un dominio llamado ‘midominio‘ y unos servidores  ‘admin‘ y ‘server1‘, donde ‘admin‘ es el servidor de Administración y ‘server1‘ es nuestro servidor administrado (vamos, un alarde de imaginación)

/opt/bea103

Bueno, posiblemente tengas una ruta como la siguiente:

/opt/bea103/user_projects/domains/midominio/bin

Genial! Si miras dentro de ese directorio, vas a ver un archivo llamado ‘setDomainEnv.sh’, que se encarga de cargar todas las variables de entorno que necesitaremos para trabajar. ¿Cómo hacemos esto? Chupado: sólo tenemos que cargarlo (ojo! lo cargamos, no lo ejecutamos) mediante el comando ‘source’:

weblogic:~> source /opt/bea103/user_projects/domains/midominio/bin/setDomainEnv.sh

Otra opción es usar el atajo ‘.’ (sí, un puntito):

weblogic:~> . /opt/bea103/user_projects/domains/midominio/bin/setDomainEnv.sh

Aparentemente no ha pasado nada, pero un buen número de variables de entorno se han definido, como son JAVA_HOME, CLASSPATH, WEBLOGIC_CLASSPATH y muchas otras (puedes ejecutar el comando set antes y después de cargar el script setDomainEnv.sh para ver las diferencias.

Bueno, una vez cargadas todas las variables de entorno necesarias, sólo nos queda probar a lanzar la consola de jython. Si todo ha ido bien, tendremos una JVM de la que podemos ver su versión:

weblogic:~> ${JAVA_HOME}/bin/java -version
java version "1.6.0_19"
Java(TM) SE Runtime Environment (build 1.6.0_19-b04)
Java HotSpot(TM) Server VM (build 16.2-b04, mixed mode)

## Conectándonos

Vamos a probar este comando:

weblogic:~> ${JAVA_HOME}/bin/java -Dpython.cachedir=/tmp weblogic.WLST

Fijaos que le decimos a la JVM que use /tmp como el directorio para el almacenamiento de archivos temporales. Podéis usar cualquier otro que queráis.

Deberíais ver este mensaje…

Initializing WebLogic Scripting Tool (WLST) ...

…y si es la primera vez que arrancáis la consola, este otro también aparecerá:

Jython scans all the jar files it can find at first startup. Depending on the system, this process may take a few minutes to complete, and WLST may not return a prompt right away.

Después de un rato, debería aparecer la consola:

Welcome to WebLogic Server Administration Scripting Shell

Type help() for help on available commands

wls:/offline>

Por ahora vemos que nos aparece la palabra offline. Esto es debido a que todavía no nos hemos conectado a ningún Admin Server. Ese será el siguiente paso 🙂

Antes de nada, para salir, usa el comando exit()

wls:/offline> exit()
Exiting WebLogic Scripting Tool.

Vale, pues lanzamos la consola y vamos a conectarlos al Admin Server ‘admin‘. Para ello, necesitamos saber algunas cosas del servidor de administración, como son la URL donde este escucha (ya sea por HTTP, HTTPS, T3 o T3S) y las credenciales de administración. Por ahora, supongamos que tenemos estos valores:

  • EL Admin Server está escuchando de forma no segura en t3://localhost:7001
  • Usuario administrador: ‘_admin_user_‘
  • Clave: ‘_password4admin_user_ (en sistemas de verdad, usa algo mejor que esta clave 😉 )

Con todo esto ya podríamos conectarnos mediate la la función connect‘ de WLST. Pero no, vamos a hacer un paso previo. La idea es que uno se puede conectar al Admin Server de tres formar: 1) usando un usuario y su clave de administración 2) Usando el archivo boot.properties (si estamos en el directorio donde este está) o 3) Usando los archivos de autentificación creados mediante storeUserConfig. Vamos a por esta tercera opción y crearemos esos ficheros de autentificación invocaremos usando el viejo y querido weblogic.Admin. Vamos a trabajar en un directorio que llamaremos scripts, dentro de nuestro HOME.

weblogic:~> mkdir scripts && cd scripts
weblogic:~/scripts>${JAVA_HOME}/bin/java weblogic.Admin -username admin_user -userconfigfile /tmp/userconfig.properties -userkeyfile /tmp/userkey.properties STOREUSERCONFIG
Enter the password for user admin_user :
Creating the key file can reduce the security of your system if it is not kept in a secured location after it is created. Do you want to create the key file? y or ny
weblogic@:~/scripts>ls user*
userconfig.properties  userkey.properties
weblogic@:~/scripts>chmod 600 user*
weblogic@:~/scripts>

Hemos creado los ficheros de autentificación y les hemos asignado permisos sólo para nuestro usuario.

weblogic:~> ${JAVA_HOME}/bin/java -Dpython.cachedir=/tmp weblogic.WLST

Welcome to WebLogic Server Administration Scripting Shell

Type help() for help on available commands

wls:/offline> connect (userConfigFile='userconfig.properties', userKeyFile='userkey.properties', url='t3://localhost:7001')
Connecting to t3://localhost:7001 with userid admin_user ...
Successfully connected to Admin Server 'admin' that belongs to domain 'midominio'.

wls:/midominio/serverConfig>disconnect()
Disconnected from weblogic server: admin
wls:/offline> exit()

Exiting WebLogic Scripting Tool.

weblogic:~/scripts>

Bueno, nos hemos conectado al Admin Server y nos hemos desconectado. No es que hayamos hecho nada útil, pero ya tenemos la idea de como acceder al servidor.

En caso de que uséis SSL, es posible que necesitéis decirle a la JVM donde se encuentran los CAs de confianza ó que estáis usando el DemoCA que viene de paquete en WebLogic.

-Dweblogic.security.SSL.ignoreHostnameVerification=true

Esta definición le dice al WebLogic que la IP donde está corriendo el servidor no está ascioada al FQDN del certificado (algo de lo más común)

-Dweblogic.security.TrustKeyStore=DemoTrust

Esta opción avisa a la JVM de que estáis usando el certificado que viene con WebLogic (DemoTrust).

-Dweblogic.security.SSL.trustedCAKeyStore=/ruta/hacia/el/keystore/trust.jks

Si habéis creado vuestro propio certificado con viestra propia CA, tendréis que decirle a la JVM dónde se encuentra.

Ejemplo 1: Estado de los servidores

Fijaos que al entrar al admin, nos ha metido automáticamente en la rama de configuración llamada serverConfig. Digamos que el entorno de WLST no es más que un navegador de Mangement Beans (MBeans) y hay, para andar por casa, son dos ramas principales o dominios (no confundir con el dominio de instancias de WebLogic). Estos dominios son el de configuración (domainConfig), y el de runtime (domainRuntime) ó, si hablamos de instancias exclusivamente, serverConfig y serverRuntime.

El primero (domainConfig) es donde se almacenan los parámetros de configuración que los servidores usarán, por ejemplo, al arrancar. El segundo (domainRuntime), es donde se almacenan los parámetros y configuraciones cuando alguno de los componentes de WebLogic está en ejecución. Por poner un ejemplo, dentro de la rama domainConfig podemos tener definido que un JDBC Pool tenga un máximo de 30 conexiones contra una base de datos, de forma que al arrancarlo, este es el valor por defecto, pero quizá, mientras el servicio está en ejecución, deseemos cambiarlo “en caliente” a 40, teniendo que modificarlo en la rama domainRuntime.

Bueno, para hacer un ejemplo, vayamos con algo útil y facilito. Intentaremos obtener el nombre de las instancias de nuestro dominio y ver si están corriendo o no (más adelante veremos una forma bastante mejor de obtener esta información). La rama en la que aparecíamos cuando accedíamos era serverConfig (que hace referencia sólo al servidor al que nos hemos conectado, admin). Podemos ver sus contenidos mediante la función ls(). Si probamos, nos saldrán chorropotocientas cosas, pero una de ellas es la que no interesa, un directorio llamado Servers. Vamos a por él (ojo a la sintáxis python):

weblogic:~/scripts> ${JAVA_HOME}/bin/java -Dpython.cachedir=/tmp weblogic.WLST
Welcome to WebLogic Server Administration Scripting Shell

Type help() for help on available commands

wls:/offline> connect (userConfigFile='userconfig.properties', userKeyFile='userkey.properties', url='t3://localhost:7001')
Connecting to t3://localhost:7001 with userid admin_user ...
Successfully connected to Admin Server 'admin' that belongs to domain 'midominio'.

wls:/midominio/serverConfig> domainConfig()
Location changed to serverRuntime tree. This is a read-only tree with DomainMBean as the root.
For more help, use help(domainConfig)

wls:/midominio/domainConfig> cmo.getServers()
array([[MBeanServerInvocationHandler]com.bea:Name=admin,Location=midominio,Type=Server, [MBeanServerInvocationHandler]com.bea:Name=server1,Location=midominio,Type=Server, weblogic.management.configuration.ServerMBean)
wls:/midominio/domainConfig> domainRuntime()
Location changed to domainRuntime tree. This is a read-only tree with DomainMBean as the root.
For more help, use help(domainRuntime)

wls:/midominio/domainRuntime> cd('/ServerRuntimes/admin')
wls:/midominio/domainRuntime/ServerRuntimes/admin> cmo.getState()
'RUNNING'
wls:/midominio/domainRuntime/ServerRuntimes/admin> cd('/ServerRuntimes/server1')
wls:/midominio/domainRuntime/ServerRuntimes/server1> cmo.getState()
'RUNNING'
wls:/midominio/domainRuntime/ServerRuntimes/server1> disconnect()
Disconnected from weblogic server: admin
wls:/offline> exit()

Exiting WebLogic Scripting Tool.

weblogic:~/scripts>

Tachán, ahí está el estado de nuestras instancias, en este caso, todas están funcionando en modo RUNNING. Los comandos anteriores, interactivamente, van a la rama de configuración para obtener un array de Python con los nombres de los servidores y luego, a través de la rama de Runtime, obtienen el estado actual de los servidores.

Todo dentro de un programa

Vamos a meter todo lo anterior en un archivo de Python de forma que se ejecute automáticamente. La idea la siguiente:

  1. Conectarnos
  2. Recorrer las instancias
  3. comprobar si están en RUNNING mode
#------------------------------------------------------------------------------

# Description

# Shows the running servers

#

# Usage:

# java -Dpython.cachedir=/tmp/wlst weblogic.WLST \

# getRunningServers.py

#

#------------------------------------------------------------------------------

# Author: Carlos Carus - Kus - kus_at_kus.es

#

#------------------------------------------------------------------------------

# List of changes#   2010-09-05 Initial release


#

#-----------------------------------------------------------------------------


import sys, getopt, tempfile, os

#--------------------------------------------------------------------------

# Functions

#--------------------------------------------------------------------------


def connectToAdmin(userFile, keyFile, consoleURL):
    try:
        #print '[INFO] Connecting to the Admin Instance'

        connect (userConfigFile=userFile, userKeyFile=keyFile, url=consoleURL)
    except ConnectionException:
        print "[INFO] Unable to connect to the Admin server via " + consoleURL + "\nError :"
        print ConnectionException
        sys.exit(1)

def getRunningServerNames():
    domainConfig()
    serverList=cmo.getServers()
    domainRuntime()
    serverRunningList = []
    for server in serverList:
        try:
            serverName=server.getName()
            cd('/ServerRuntimes/' + serverName)
            if cmo.getState() == 'RUNNING':
                serverRunningList.append(server)
                print '[INFO] The server ' + serverName + ' is running'
            else:
                print '[INFO] The server ' + serverName + ' is not running'
        except:
            print '[INFO] The server ' + serverName + ' is not created, skipping'
            continue
    return serverRunningList

#--------------------------------------------------------------------------

# Main logic

#--------------------------------------------------------------------------    


# parse command line options

try:
    opts, args = getopt.getopt(sys.argv[1:], "h", ["help"])
except getopt.error, msg:
    print "[WLST] getRunningServers.py: for help use --help"
    sys.exit(2)
# process options

for o, a in opts:
    if o in ("-h", "--help"):
        print ("[INFO] Usage:\n getRunningServers.py   ")
        sys.exit(1)
if (len (sys.argv) != 4):
    print "[INFO] getRunningServers.py: Missing arguments. Use --help"
    sys.exit(1)

# process arguments

try:
    userFile=args[0]
    keyFile=args[1]
    consoleURL=args[2]
except WLSTException,e:
    print "[INFO] getRunningServers.py: Invalid arguments. Use --help"
    print e
    sys.exit(1)

#Connect and get data!

connectToAdmin(userFile,keyFile,consoleURL)
getRunningServerNames()

#Don't think it is needed, but, it is nice 🙂

cd('/')
disconnect()

#Exit

sys.exit(0)

Ejecutándolo:

${JAVA_HOME}/bin/java -Dpython.cachedir=/tmp weblogic.WLST getRunningservers.py userconfig.properties userkey.properties t3://localhost:7001

Initializing WebLogic Scripting Tool (WLST) ...

Welcome to WebLogic Server Administration Scripting Shell

Type help() for help on available commands

Connecting to http://localhost:7001 with userid admin_user ...
Successfully connected to Admin Server 'admin' that belongs to domain 'midominio'.

Location changed to serverRuntime tree. This is a read-only tree with DomainMBean as the root.
For more help, use help(domainConfig)

Location changed to domainRuntime tree. This is a read-only tree with DomainMBean as the root.
For more help, use help(domainRuntime)

[INFO] The server admin is running
[INFO] The server server1 is running
Disconnected from weblogic server: admin
weblogic:~/scripts>

Por hoy, estamos. Todavía nos queda ver como hacer algo más útil con el WLST y cómo integrarlo en un script de bash, pero para el primer día no está mal, ¿verdad?

comments powered by Disqus