Integración de IT PAM y Webform de Drupal
Después de haberme pegado bastante con ello, lo dejo aquí por si vale para alguien en el futuro, y le ahorro algún disgusto
NOTA: Tengo poca idea de PHP, SOAP, WSDL, etc., pero creo que al final no me ha quedado del todo mal….
PROBLEMA:
Se quiere integrar un formulario de Drupal (alta de nueva máquina virtual), con un proceso de IT PAM, que crea la máquina virtual, da el alta en la CMDB, etc.
El problema viene en como notificar al IT PAM que hay un nuevo formulario. La primera idea, es crear un proceso que cada X tiempo, verifique si hay un formulario nuevo en base de datos, y si lo hay, procesarlo. Obviamente este comportamiento es un poco “chapucero” y nada elegante.
Investigando un poco el tema, hemos averiguado que IT PAM tiene un servicio web que puede ser consumido, enviandole la petición adecuada, usuario, proceso a desencadenar, etc.
Este servicio web se puede consultar en
http://<itpamhost>:8080/itpam/soap
con ?wsdl al final, para ver el xml.
Se probó a consumir el servicio web utilizando curl, funcionando de manera satisfactoria, creando un xml como este:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:itp="http://www.ca.com/itpam"> <soapenv:Header/> <soapenv:Body> <itp:executeStartRequest> <itp:auth> <itp:user>USUARIO</itp:user> <itp:password>PASSWORD</itp:password> </itp:auth> <itp:objLocation> <itp:name>NOMBRE_PROCESO</itp:name> <itp:path>PATH_PROCESO</itp:path> </itp:objLocation> </itp:executeStartRequest> </soapenv:Body> </soapenv:Envelope>
Sin embargo, consumirlo con curl tenía los mismos problemas que el anterior supuesto (habría que comprobar de alguna manera que ha sido actualizada la base de datos), y ejecutar un proceso con un trigger de mysql no es nada recomendable (problemas de seguridad, locking,…)
SOLUCION:
Se creó un fichero .php que realizaba el proceso “manualmente” de manera correcta:
<?php
// include soap file
require_once('nusoap/nusoap.php');
// set end point
$endpoint = "http://<ITPAMHOST>:8080/itpam/soap";
// create client
$client = new nusoap_client($endpoint);
if ( $client->getError() ) {
print "Soap Constructor Error: ";
print_r($client->getError());
}
// Human readable
$request = <<<HEREDOC
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:itp="http://www.ca.com/itpam">
<soapenv:Header/>
<soapenv:Body>
<itp:executeStartRequest>
<itp:auth>
<itp:user>USUARIO</itp:user>
<itp:password>PASSWORD</itp:password>
</itp:auth>
<itp:objLocation>
<itp:name>NOMBRE_PROCESO</itp:name>
<itp:path>PATH_PROCESO</itp:path>
</itp:objLocation>
</itp:executeStartRequest>
</soapenv:Body>
</soapenv:Envelope>
HEREDOC;
$msg = $client->serializeEnvelope($request, '', array(), 'document', 'encoded', '');
$result = $client->send($msg,"executeStartRequest");
if ( $client->fault ) { //soap_fault
print "Soap Fault :";
print_r($client->fault->faultcode);
print_r($client->fault->faultstring);
}
elseif ( $client->getError() ) {
print "Soap Error :";
print_r($client->getError());
}
else {
print "Result: ";
print_r($result);
}
?>
Aprovechando que Drupal es opensource, y teniendo el codigo, se intentó modificar parte del codigo del modulo encargado de la gestión de modulos (webform), sin exito.
Investigando un poco más, se vió que el modulo Webform, tiene una API, que permite ejecutar “cosas” en distintos puntos del proceso (antes de entrar en base de datos, al actualizar, etc.)
Por lo tanto, solo quedaba encontrar como utilizar esa característica para nuestros propositos.
La solución más elegante (y la que se ha usado), es crear un modulo de Drupal nuevo, llamado “itpam”, que utiliza el “hook” _webform_submission_insert cuyo contenido es:
itpam/itpam.info:
; $Id: $ name = ITPAM description = "Module for notify IT PAM" package = Administration core = 6.x php = 5.1
itpam/itpam.module:
<?php
function itpam_webform_submission_insert ($node, $submission){
if ($node->nid == 104){
// include soap file
require_once('nusoap/nusoap.php');
// set end point
$endpoint = "http://itpamhost:8080/itpam/soap";
// create client
$client = new nusoap_client($endpoint);
if ( $client->getError() ) {
print "Soap Constructor Error: ";
print_r($client->getError());
}
// Human readable
$request = <<<HEREDOC
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:itp="http://www.ca.com/itpam">
<soapenv:Header/>
<soapenv:Body>
<itp:executeStartRequest>
<itp:auth>
<itp:user>USUARIO</itp:user>
<itp:password>PASSWORD</itp:password>
</itp:auth>
<itp:objLocation>
<itp:name>NOMBRE_PROCESO</itp:name>
<itp:path>PATH_PROCESO/</itp:path>
</itp:objLocation>
</itp:executeStartRequest>
</soapenv:Body>
</soapenv:Envelope>
HEREDOC;
$msg = $client->serializeEnvelope($request, '', array(), 'document', 'encoded', '');
$result = $client->send($msg,"executeStartRequest");
if ( $client->fault ) { //soap_fault
print "Soap Fault :";
print_r($client->fault->faultcode);
print_r($client->fault->faultstring);
}
elseif ( $client->getError() ) {
print "Soap Error :";
print_r($client->getError());
}
else {
print "Result: ";
print_r($result);
}
}
}
?>
Este modulo se activa cuando se inserta un registro nuevo en la base de datos (se ha añadido el chequeo $node->nid == 104, que es el correspondiente en este caso, al alta de máquina virtual)
Una vez creado el modulo, y con los permisos adecuados, se activa el modulo desde la interfaz de administración de Drupal, é voilá!
PD.- Falta cambiar un par de detalles, pero como “guia” vale
minWi on septiembre 23rd 2011 in programación, sysadmin













