Adding New Functions to the UA Bash extension – Part 3

Adding New Functions to the UA Bash extension – Part 3

Fernando Freitas of NTS fame wrote a great shell script extension to support the RBPM SOAP functions. Get it here:
BASH functions to perform SOAP calls to RBPM

The problem is he only implemented the Role service WSDL functions and there are many more in User App that might be needed.

Specifically I need the createResource function from the Resource service WSDL. So how to extend it? Read this series, and continue on as I work through that process.

When last we left off, you should have gotten the RBPM script from the URL above, gotten the WSDL you are interested in, opened it in SOAP UI and copied out the text of the function you care about. Then we worked through the parts of the function in the WSDL that we probably need to specify information about.

To keep it clear in our minds, our example is createResource whose SOAP call looks like this:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ser="http://www.novell.com/resource/service">
<soapenv:Header/>
<soapenv:Body>
<ser:createResourceRequest>
<!--Optional:-->
<ser:resource>
<ser:active>?</ser:active>
<ser:allowOverride>?</ser:allowOverride>
<ser:allowedMulty>?</ser:allowedMulty>
<ser:description>?</ser:description>
<ser:entitlementRef>
<!--Zero or more repetitions:-->
<ser:nrfentitlementref>
<ser:entitlementCorrelationId>?</ser:entitlementCorrelationId>
<ser:entitlementDn>?</ser:entitlementDn>
<ser:entitlementParameters>?</ser:entitlementParameters>
<ser:src>?</ser:src>
</ser:nrfentitlementref>
</ser:entitlementRef>
<ser:entityKey>?</ser:entityKey>
<ser:grantApprovers>
<!--Zero or more repetitions:-->
<ser:approver>
<ser:approverDN>?</ser:approverDN>
<ser:sequence>?</ser:sequence>
</ser:approver>
</ser:grantApprovers>
<ser:grantQuorum>?</ser:grantQuorum>
<ser:grantRequestDef>?</ser:grantRequestDef>
<ser:name>?</ser:name>
<ser:owners>
<!--Zero or more repetitions:-->
<ser:dnstring>
<ser:dn>?</ser:dn>
</ser:dnstring>
</ser:owners>
<ser:parameters>
<!--Zero or more repetitions:-->
<ser:resourceparameter>
<ser:codemapKey>?</ser:codemapKey>
<ser:entitlementDn>?</ser:entitlementDn>
<ser:hiddenFlag>?</ser:hiddenFlag>
<ser:key>?</ser:key>
<ser:paramLabel>?</ser:paramLabel>
<ser:staticFlag>?</ser:staticFlag>
<ser:type>?</ser:type>
<ser:value>?</ser:value>
<ser:valueLabel>?</ser:valueLabel>
</ser:resourceparameter>
</ser:parameters>

<ser:resourceCategoryKeys>
<!--Zero or more repetitions:-->
<ser:categorykey>
<ser:categoryKey>?</ser:categoryKey>
</ser:categorykey>
</ser:resourceCategoryKeys>
<ser:revokeApprovers>
<!--Zero or more repetitions:-->
<ser:approver>
<ser:approverDN>?</ser:approverDN>
<ser:sequence>?</ser:sequence>
</ser:approver>
</ser:revokeApprovers>
<ser:revokeQuorum>?</ser:revokeQuorum>
<ser:revokeRequestDef>?</ser:revokeRequestDef>
</ser:resource>
</ser:createResourceRequest>
</soapenv:Body>
</soapenv:Envelope>


We will copy the createRole and convert it to createResource from Fernando's script, so lets show a copy here:


### Function: createRole
# Usage:
# createRole $username $password $rbpm_url $output_file $rolename $description $rolelevel $category $correlation_id
# if the $correlation_id is omitted, will call createRoleRequest, otherwise will call createRoleAidRequest
# if the category is omitted with use the value "default"
# Order of parameters is important, it is not possible to use the correlation_id and skip category
#
createRole()
{

USAGE="Function Usage:

createRole username password rbpm_url output_file rolename description rolelevel category correlation_id
if the correlation_id is omitted, will call createRoleRequest, otherwise will call createRoleAidRequest
if the category is omitted with use the value "default"
Order of parameters is important, it is not possible to provide a correlation_id and skip category at the same time
rbpm_url should be in the format:
protocol://server:port/servicename
for example:
https://rbpm.lab.novell.com:8543/IDMProv";

if [[ "X$_RBPM_SOAP_ROLE_DEBUG" = "Xtrue" ]]
then
dbgparams=$#
dbgparam=1
while [ "$dbgparam" -le "$dbgparams" ]
do
echo -n "Parameter "
echo -n \$$dbgparam
echo -n " = "
eval echo \$$dbgparam
(( dbgparam++ ))
done
fi

# Initial Parameters check
if [[ -z "$1" || -z "$2" || -z "$3" || -z "$4" || -z "$5" || -z "$6" || -z "$7" ]]
then
echo "$USAGE"
return 1
fi

if [[ -z "$8" ]]
then
CAT=default
else
CAT="$8"
fi

if [[ -z "$9" ]]
then
NOCID=true
else
NOCID=false
CID="$9"
fi

if [[ "X$2" = "X-W" ]]
then
read -sp "Please enter the password for user $1: " SENHA
echo
else
SENHA=$2
fi

# Setup for the SOAP call
URL="${3}/role/service"

if [[ "$NOCID" = "true" ]]
then
ACTION="SOAPAction: 'http://www.novell.com/role/service/createRole'"
SOAPCALL=createRoleRequest
else
ACTION="SOAPAction: 'http://www.novell.com/role/service/createRoleAid'"
SOAPCALL=createRoleAidRequest
fi
CTYPE='Content-Type: text/xml;charset=UTF-8'

# Build SOAP XML envelope and call to be issued
POST="<soapenv:Envelope xmlns:soapenv='http://schemas.xmlsoap.org/soap/envelope/' xmlns:ser='http://www.novell.com/role/service'>\
<soapenv:Header/>\
<soapenv:Body>\
<ser:${SOAPCALL}>\
<ser:role>\
<ser:approvers/>\
<ser:container/>\
<ser:description>${6}</ser:description>\
<ser:entityKey/>\
<ser:name>${5}</ser:name>\
<ser:owners/>\
<ser:quorum/>\
<ser:requestDef/>\
<ser:revokeRequestDef/>\
<ser:roleCategoryKeys>\
<ser:categorykey>\
<ser:categoryKey>${CAT}</ser:categoryKey>\
</ser:categorykey>\
</ser:roleCategoryKeys>\
<ser:roleLevel>${7}</ser:roleLevel>\
<ser:systemRole>false</ser:systemRole>\
</ser:role>"

if [[ "$NOCID" = "false" ]]
then
POST="${POST}<ser:correlationId>${CID}</ser:correlationId>"
fi

POST="${POST}</ser:${SOAPCALL}>\
</soapenv:Body>\
</soapenv:Envelope>"

if [[ "X$_RBPM_SOAP_ROLE_DEBUG" = "Xtrue" ]]
then
echo
echo POST data:
echo $POST
echo
fi

# Issue the request
curl $_CURL_OPTIONS -k -u "$1:$SENHA" -H "$CTYPE" -H "$ACTION" -d "$POST" "$URL" -o "$4"
}


At the end of last article, we decided that the command line would look something like this:
createResource $username $password $rbpm_url $output_file $resourcename $description $allowoverride $allowedMulty $entitlementDN $entitlementParam $category $correlation_id

You can see at the beginning of the script there are two usage sections, basically copies of each other. The first is all in comments, the second is returned when you type the command name with an invalid option. Make sure to edit that with much more appropriate text, since it is really good to keep the Usage up to date.

My suggestion is something like this:

### Function: createResource
# Usage:
# createResource $username $password $rbpm_url $output_file $resourcename $description $allowoverride $allowedMulty $entitlementDN $entitlementParam $category $correlation_id
# if the $correlation_id is omitted, will call createresourceRequest, otherwise will call createresourceAidRequest
# allowoverride is a boolean (true/false)
# allowedMulty is a boolean (true/false)
# entitlementDN should be in LDAP format
# entitlementParam should be in JSON format if your entitlement is idm4, and a string if it is a legacy entitlement.
#
createResource()
{


USAGE="Function Usage:

createResource username password rbpm_url output_file resourcename description allowoverride allowedMulty entitlementDN entitlementParam category correlation_id
if the correlation_id is omitted, will call createresourceRequest, otherwise will call createresourceAidRequest
allowoverride is a boolean (true/false)
allowedMulty is a boolean (true/false)
entitlementDN should be in LDAP format
entitlementParam should be in JSON format if your entitlement is idm4, and a string if it is a legacy entitlement.


rbpm_url should be in the format:

protocol://server:port/servicename

for example:
https://rbpm.lab.novell.com:8543/IDMProv";


The code block for handling Debug mode, starts with this IF test, and is probably fine left as is.

if [[ "X$_RBPM_SOAP_ROLE_DEBUG" = "Xtrue" ]]


This nicely traces out the command line parameters sent in, and later there is a code block that looks much the same, that traces out the final SOAP document, which is also fine as is.

The next major thing to change is the validation of the input parameters. Currently it looks like:

# Initial Parameters check
if [[ -z "$1" || -z "$2" || -z "$3" || -z "$4" || -z "$5" || -z "$6" || -z "$7" ]]
then
echo "$USAGE"
return 1
fi


We need to add some more parameter changes, since we are now at 12 needed parameters, so this needs to look more like:

# Initial Parameters check
if [[ -z "$1" || -z "$2" || -z "$3" || -z "$4" || -z "$5" || -z "$6" || -z "$7" || -z "$8" || -z "$9" || -z "$10" || -z "$11" ]]
then
echo "$USAGE"
return 1
fi


Next up is a check of category, and setting a default value if it is missing, is probably a good idea. definitely worked when for the createRole, I am not sure if that will work for createResource, but lets try and find out. However it was the 8th parameter before, now it is the 10th parameter, so a change from $8 to $10 will suffice.

if [[ -z "$8" ]]
then
CAT=default
else
CAT="$8"
fi


Then we have a check for the correlation ID as the last parameter if it is present then set a variable which will be used to change the function name used (createRole vs createRoleAid) and handle adding in the value of the correlationId into the SOAP document. But again we need to change from the 9th position to the 11th position.

if [[ -z "$9" ]]
then
NOCID=true
else
NOCID=false
CID="$9"
fi


This does have a consequence in terms of whether you can skip the category and still

So those two above get changes to:

if [[ -z "$10" ]]
then
CAT=default
else
CAT="$10"
fi

if [[ -z "$11" ]]
then
NOCID=true
else
NOCID=false
CID="$11"
fi


The next segment about the password is a nice way of handling -X to mean prompt for the password, or else taking the value of the password from the command line. A nice enhancement might be to support prompting in my parent script to ask for the password once, but that is not a big enough deal for me right now to implement. I would probably just steal the code from Fernando to ask for the password, and then set the variable internally once, and always use the variable in each successive call for any line in the CSV after the first line.

Next change is the endpoint of the URL, we need to change the /role/service below to /resource/service which will change us to the proper endpoint. There are a number of endpoints that User App exposes for different services. Role and resources are two obvious ones, there is a provisioning one, and finally a vdx (virtual data layer). There is an additional forgotten password endpoint but that works fairly different than this set.

# Setup for the SOAP call
URL="${3}/role/service"


Thus this becomes:

# Setup for the SOAP call
URL="${3}/resource/service"


Now we set one of the headers we will use, ACTION, and the name of the SOAPCALL, which is used in building the SOAP document later.

if [[ "$NOCID" = "true" ]]
then
ACTION="SOAPAction: 'http://www.novell.com/role/service/createRole'"
SOAPCALL=createRoleRequest
else
ACTION="SOAPAction: 'http://www.novell.com/role/service/createRoleAid'"
SOAPCALL=createRoleAidRequest
fi


These are specific to the correlationID, if we have one it is a createResourceAid, if we don't it is a createResource function call. Here we need to change from createRole* to createResource* as appropriate. The SOAPAction is important, since some web services require the SOAPAction to match the content of the document. The Cisco Unified Call Messenger (CUCM) does something slightly more interesting with this, since it includes a version of the API for the call. This means that they can now update an API in the SOAP interface, but only in one version and not others. Cisco at least is very good about tracking in their documentation the differences between the various versions of the API which makes it much more usable. However, it does mean you have to be careful to understand the specific version you are working with.

You can read more on my thoughts on the Cisco CUCM SOAP API in these articles. If anyone needs such a SOAP driver, I have implemented it several times now, and contact me.
https://www.netiq.com/communities/cool-solutions/working-with-cisco-unified-call-manager-via-idm-part-1
https://www.netiq.com/communities/cool-solutions/working-with-cisco-unified-call-manager-via-idm-part-2

Thus this would become:
if [[ "$NOCID" = "true" ]]
then
ACTION="SOAPAction: 'http://www.novell.com/resource/service/createResource'"
SOAPCALL=createResourceRequest
else
ACTION="SOAPAction: 'http://www.novell.com/resource/service/createResourceAid'"
SOAPCALL=createResourceAidRequest
fi


The next header is for content type, which is not really different between the case of a Role or a Resource creation, they are all SOAP, and all XML. Some REST API's will allow to use the Content-Type HTTP header to specify if you want to get a response in XML or JSON, which can be handy to know, if it is supported.

CTYPE='Content-Type: text/xml;charset=UTF-8'


Finally we get to the somewhat tricky part now. We need to build the rest of the SOAP document, filling in all the needed fields with data we collected on the command line.

First to remind us, here is what the createRole script version has:

# Build SOAP XML envelope and call to be issued
POST="<soapenv:Envelope xmlns:soapenv='http://schemas.xmlsoap.org/soap/envelope/' xmlns:ser='http://www.novell.com/role/service'>\
<soapenv:Header/>\
<soapenv:Body>\
<ser:${SOAPCALL}>\
<ser:role>\
<ser:approvers/>\
<ser:container/>\
<ser:description>${6}</ser:description>\
<ser:entityKey/>\
<ser:name>${5}</ser:name>\
<ser:owners/>\
<ser:quorum/>\
<ser:requestDef/>\
<ser:revokeRequestDef/>\
<ser:roleCategoryKeys>\
<ser:categorykey>\
<ser:categoryKey>${CAT}</ser:categoryKey>\
</ser:categorykey>\
</ser:roleCategoryKeys>\
<ser:roleLevel>${7}</ser:roleLevel>\
<ser:systemRole>false</ser:systemRole>\
</ser:role>"

if [[ "$NOCID" = "false" ]]
then
POST="${POST}<ser:correlationId>${CID}</ser:correlationId>"
fi

POST="${POST}</ser:${SOAPCALL}>\
</soapenv:Body>\
</soapenv:Envelope>"


This is basically the createRole SOAP call, with white space removed at the beginning of the lines, and a backslash character (\) used at the end of the line to concatenate them all into one long single line that is stored in the variable POST. If you look up earlier at the top of this article, you will see the SOAP document we need is the Envelope node and down. Remember to change the namespace declaration (xmlns: part) from role/service to resource/service in the first line of the variable). Then we can keep the <ser:${SOAPCALL}> line to use the variable we set a bit earlier. This is the one that differs if we have a correlationId or not.

So basically after that, we throw away most of the text, and take our flattened (white space removed) XML instead. Then we use the variable notation of ${4} to specify a command line parameter (4th in this case of course). My first pass, ended up looking something like this. I used the various variables for command line features to fill in values as needed.

# Build SOAP XML envelope and call to be issued
POST="<soapenv:Envelope xmlns:soapenv='http://schemas.xmlsoap.org/soap/envelope/' xmlns:ser='http://www.novell.com/resource/service'>\
<soapenv:Header/>\
<soapenv:Body>\
<ser:${SOAPCALL}>\
<ser:resource>\
<ser:active>true</ser:active>\
<ser:allowOverride>${7}</ser:allowOverride>\
<ser:allowedMulty>${8}<ser:allowedMulty>\
<ser:description>${6}</ser:description>\
<ser:entitlementRef>\
<ser:nrfentitlementref>\
<ser:entitlementCorrelationId/>\
<ser:entitlementDn>${9}</ser:entitlementDn>\
<ser:entitlementParameters>${10}</ser:entitlementParameters>\
<ser:src>UA</ser:src>\
</ser:nrfentitlementref>\
</ser:entitlementRef>\
<ser:entityKey></ser:entityKey>\
<ser:grantApprovers/>\
<ser:grantQuorum></ser:grantQuorum>\
<ser:grantRequestDef></ser:grantRequestDef>\
<ser:name>${5}</ser:name>\
<ser:owners/>\
<ser:parameters/>\
<ser:resourceCategoryKeys>\
<ser:categorykey>\
<ser:categoryKey>${11}</ser:categoryKey>\
</ser:categorykey>\
</ser:resourceCategoryKeys>\
<ser:revokeApprovers/>\
<ser:revokeQuorum/>\
<ser:revokeRequestDef/>\
</ser:resource>"

if [[ "$NOCID" = "false" ]]
then
POST="${POST}<ser:correlationId>${CID}</ser:correlationId>"
fi

POST="${POST}</ser:${SOAPCALL}>\
</soapenv:Body>\
</soapenv:Envelope>"


I hard coded in some values, like the src value:

	<ser:src>UA</ser:src>


I think this is the <src> node in the Entitlement XML that is mostly useless as far as I can tell. I probably could put something unique for me in there, like my initials to be funny. I know that there are several common values set, I once tried to track them all down, but of course it was not documented anywhere I could find. I found NRF, UA, and AF I think. This makes me think they are just strings that are not really used.

I skipped the ability to set an owner for the role. If you need it, where I have the line:

	<ser:owners/>\


You would need to work with the XML from the SOAP call of:

    <ser:owners>
<!--Zero or more repetitions:-->
<ser:dnstring>
<ser:dn>?</ser:dn>
</ser:dnstring>
</ser:owners>


Then you could probably add another parameter to the command line, leaving category and correlationId at the end, and remember to shuffle all values for them since there is now a 12th value, and provide the DN of the owner object. I do not have a use case for Owner, so I did not bother, since most of the time it would be blank for me, and it is only easy to do 1 or 2 blank fields. However as I think about it, I would probably define a known string for blank, like 'null' and test to see if something is null, and then like the correlationId is handled later in the example, add it in, if we have a non-null value and leave an empty node, if we got null on the command line. I leave that for the reader who needs it to implement.

This is a good example of how you can extend this yourself, if you need any additional features that I did not consider important. If you look at the various SOAP calls that Fernando implemented, there are a number of features he skipped, because they are low usage, or not obvious that everyone would want them. You are of course free to add in what you need.

The same is true for grant approver, revoke approver, and quorum settings for both, if you need them. This is probably less an issue for Resources, since we usually require approvals at the Role level not the Resource level. But it is worth noting that these are not supported in the current state of Fernando's createRole function. That might be a fun example to go through the same way and update to support approvers. (Hmm, more articles to write! Yay!)

This makes me think that a nice enhancement to that script would be to simply paste in the raw SOAP call example, as commented out text so you can see if some stuff was missed or not in the actual call.

What I did notice is that the Entitlement values, appear to be referenced twice. It is my understanding only one is needed to be used.

The one I used was the node that looks like:

    <ser:entitlementRef>
<!--Zero or more repetitions:-->
<ser:nrfentitlementref>
<ser:entitlementCorrelationId>?</ser:entitlementCorrelationId>
<ser:entitlementDn>?</ser:entitlementDn>
<ser:entitlementParameters>?</ser:entitlementParameters>
<ser:src>?</ser:src>
</ser:nrfentitlementref>
</ser:entitlementRef>


The later nodes seem like they were either an earlier or older attempt so I basically ignored them. (I checked a PRD using a SOAP based Integration Activity we used to use to do this, and it used the nodes above, not the ones below and it works properly).

    <ser:parameters>
<!--Zero or more repetitions:-->
<ser:resourceparameter>
<ser:codemapKey>?</ser:codemapKey>
<ser:entitlementDn>?</ser:entitlementDn>
<ser:hiddenFlag>?</ser:hiddenFlag>
<ser:key>?</ser:key>
<ser:paramLabel>?</ser:paramLabel>
<ser:staticFlag>?</ser:staticFlag>
<ser:type>?</ser:type>
<ser:value>?</ser:value>
<ser:valueLabel>?</ser:valueLabel>
</ser:resourceparameter>
</ser:parameters>


Now you might figure out just when these parameters nodes are meant to be used and why, and if you do, please post and explain as a comment on this article! If so, as above, you could easily add them as needed. I just did not, since it seems like a duplication I can do without.

Finally we have the DEBUG setting, which if true (set inside the script near the top) will trace out the XML you will be sending in the event. This is great for debugging errors that return from the web service that are due to typos. You can grab the XML that the script dumps out in this setting, paste it into SOAP UI and work on it there until you find the error and then fix the script. As you can imagine that is pretty common working on stuff like this.

if [[ "X$_RBPM_SOAP_ROLE_DEBUG" = "Xtrue" ]]
then
echo
echo POST data:
echo $POST
echo
fi



As you can see, not every single feature in the SOAP API is exposed in the script from Fernando, nor is every endpoint that the User Application offers supported. But once you understand what Fernando is doing in his script, it is pretty easy to extend it to add new functions and extend it to add features that you need, but he did not implement support.

That about wraps it up, and here is the final block of the entire code you would need to add at the bottom of your copy of Fernando's script to support createResource. If you find any typos, or have ideas for improving this, please comment on this article.

### Function: createResource
# Usage:
# createResource $username $password $rbpm_url $output_file $resourcename $description $allowoverride $allowMulty $entitlementDN $entitlementParam $category $correlation_id
# if the $correlation_id is omitted, will call createresourceRequest, otherwise will call createresourceAidRequest
# allowoverride is a boolean (true/false)
# allowMulty is a boolean (true/false)
# Order of parameters is important, it is not possible to use the correlation_id and skip category
#
createResource()
{

USAGE="Function Usage:

createResource username password rbpm_url output_file resourcename description allowoverride allowMulty entitlementDN entitlementParam category correlation_id
if the correlation_id is omitted, will call createresourceRequest, otherwise will call createresourceAidRequest
allowoverride is a boolean (true/false)
allowMulty is a boolean (true/false)
Order of parameters is important, it is not possible to provide a correlation_id and skip category at the same time
rbpm_url should be in the format:
protocol://server:port/servicename
for example:
https://rbpm.lab.novell.com:8543/IDMProv";

if [[ "X$_RBPM_SOAP_ROLE_DEBUG" = "Xtrue" ]]
then
dbgparams=$#
dbgparam=1
while [ "$dbgparam" -le "$dbgparams" ]
do
echo -n "Parameter "
echo -n \$$dbgparam
echo -n " = "
eval echo \$$dbgparam
(( dbgparam++ ))
done
fi

# Initial Parameters check
if [[ -z "$1" || -z "$2" || -z "$3" || -z "$4" || -z "$5" || -z "$6" || -z "$7" || -z "$8" || -z "$9" || -z "$10" || -z "$11" ]]
then
echo "$USAGE"
return 1
fi

#if [[ -z "$8" ]]
#then
# CAT=default
#else
# CAT="$8"
#fi

if [[ -z "$11" ]]
then
NOCID=true
else
NOCID=false
CID="$11"
fi

if [[ "X$2" = "X-W" ]]
then
read -sp "Please enter the password for user $1: " SENHA
echo
else
SENHA=$2
fi

# Setup for the SOAP call
URL="${3}/resource/service"

if [[ "$NOCID" = "true" ]]
then
ACTION="SOAPAction: 'http://www.novell.com/resource/service/createResource'"
SOAPCALL=createResourceRequest
else
ACTION="SOAPAction: 'http://www.novell.com/resource/service/createResourceAid'"
SOAPCALL=createResourceAidRequest
fi
CTYPE='Content-Type: text/xml;charset=UTF-8'

# Build SOAP XML envelope and call to be issued
POST="<soapenv:Envelope xmlns:soapenv='http://schemas.xmlsoap.org/soap/envelope/' xmlns:ser='http://www.novell.com/resource/service'>\
<soapenv:Header/>\
<soapenv:Body>\
<ser:${SOAPCALL}>\
<ser:resource>\
<ser:active>true</ser:active>\
<ser:allowOverride>${7}</ser:allowOverride>\
<ser:allowedMulty>${8}<ser:allowedMulty>\
<ser:description>${6}</ser:description>\
<ser:entitlementRef>\
<ser:nrfentitlementref>\
<ser:entitlementCorrelationId/>\
<ser:entitlementDn>${9}</ser:entitlementDn>\
<ser:entitlementParameters>${10}</ser:entitlementParameters>\
<ser:src>UA</ser:src>\
</ser:nrfentitlementref>\
</ser:entitlementRef>\
<ser:entityKey></ser:entityKey>\
<ser:grantApprovers/>\
<ser:grantQuorum></ser:grantQuorum>\
<ser:grantRequestDef></ser:grantRequestDef>\
<ser:name>${5}</ser:name>\
<ser:owners/>\
<ser:parameters/>\
<ser:resourceCategoryKeys>\
<ser:categorykey>\
<ser:categoryKey>${11}</ser:categoryKey>\
</ser:categorykey>\
</ser:resourceCategoryKeys>\
<ser:revokeApprovers/>\
<ser:revokeQuorum/>\
<ser:revokeRequestDef/>\
</ser:resource>"

if [[ "$NOCID" = "false" ]]
then
POST="${POST}<ser:correlationId>${CID}</ser:correlationId>"
fi

POST="${POST}</ser:${SOAPCALL}>\
</soapenv:Body>\
</soapenv:Envelope>"

if [[ "X$_RBPM_SOAP_ROLE_DEBUG" = "Xtrue" ]]
then
echo
echo POST data:
echo $POST
echo
fi

# Issue the request
curl $_CURL_OPTIONS -k -u "$1:$SENHA" -H "$CTYPE" -H "$ACTION" -d "$POST" "$URL" -o "$4"
}









Tags (2)

DISCLAIMER:

Some content on Community Tips & Information pages is not officially supported by Micro Focus. Please refer to our Terms of Use for more detail.
Comments
Fixed twothree typos. The line that checks if we got all the command line parameters has to end with -z "$11" ]] that is a space between the close quotation mark and the two close square brackets. This oddly breaks everything. Go figure.

Also, in the XML I had the open node of allowedMulty but a close node of allowOverride, which clearly won't work.

Then it turns out, I copied createRole, and left behind the provisioningRequestDef line, which is actually replaced with grantRequestDef and revokeRequestDef. That breaks it with an IO error on the UA side. Very uninformative error.

Geez, you would think I never actually tried this script in real life. Sshh! Don't tell anyone!
You could simplify the command line parameter check to:

if [[ -z "$11" ]]
then
echo "$USAGE"
return 1
fi

because logically if $11 exists, then $1 through $10 must also exist.
Top Contributors
Version history
Revision #:
1 of 1
Last update:
‎2016-02-12 20:39
Updated by:
 
The opinions expressed above are the personal opinions of the authors, not of Micro Focus. By using this site, you accept the Terms of Use and Rules of Participation. Certain versions of content ("Material") accessible here may contain branding from Hewlett-Packard Company (now HP Inc.) and Hewlett Packard Enterprise Company. As of September 1, 2017, the Material is now offered by Micro Focus, a separately owned and operated company. Any reference to the HP and Hewlett Packard Enterprise/HPE marks is historical in nature, and the HP and Hewlett Packard Enterprise/HPE marks are the property of their respective owners.