Customized deployment

The following are the most common changes needed for a production deployment:

  • Specify persistent volumes
  • Change admin credentials
  • Configure a database
  • Configure an SMTP server
  • Configure an LDAP
  • Define Custom Service Configurations
  • Modify Leap properties

Encoding passwords

All passwords passed in the .yaml file should be encoded. You can encode a password using a utility provided by Open Liberty. To access this utility in your kubernetes environment use the command:
kubectl -n dxns exec -it leap-deployment-leap-0 -- /opt/openliberty/wlp/bin/securityUtility encode <thePassword>

The result of the command will be a string value like {xor}Kzc6Dz4sLCgwLTs=. Use this encoded value when specifying a password.

Change server Admin credentials

This is optional. The credentials supplied below are used in the container startup to run configuration tasks and setup Leap.

The default credentials are set to leapadmin for username and password.

To change the default admin, add this snippet to your .yaml file and update the adminUser and adminPassword properties.
security: 
  leap: 
    adminUser: "leapadmin" 
    adminPassword: "leapadmin"

SAML configuration

The Leap Helm chart and container offer a basic SAML configuration through the Helm values. This can be used to enable SAML, deploy the WebSphereSamlSP.ear, configure the ACS URL, pass the IdP Metadata of the identity provider and add trusted realms.

Note: Please note that this configuration can currently only be used to enable the SAML TAI SSO. To disable it, please set the enabled flag to false and remove the Trust Association manually in WebSphere.

The idpMetadata accepts IdP Metadata in xml format. Please use the multiline string feature of Helm to pass this value.

The ssoId9999 is used to create the SAML TAI SSO.Example configuration:
security:
  leap:
    saml:
      enabled: true
      acsUrl: "https://native-kube-kevin.team-q-dev.com:9443/samlsps/acs"
        idpMetadata: |
          <EntityDescriptor xmlns="urn:oasis:names:tc:SAML:2.0:metadata" ID="SAMLtestIdP" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:shibmd="urn:mace:shibboleth:metadata:1.0" xmlns:xml="http://www.w3.org/XML/1998/namespace" xmlns:mdui="urn:oasis:names:tc:SAML:metadata:ui" validUntil="2100-01-01T00:00:42Z" entityID="https://samltest.id/saml/idp">
             <IDPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol urn:oasis:names:tc:SAML:1.1:protocol urn:mace:shibboleth:1.0">
               <Extensions>
                 <shibmd:Scope regexp="false">samltest.id</shibmd:Scope>
                 <mdui:UIInfo>
                   <mdui:DisplayName xml:lang="en">SAMLtest IdP</mdui:DisplayName>
                   <mdui:Description xml:lang="en">A free and basic IdP for testing SAML deployments</mdui:Description>
                   <mdui:Logo height="90" width="225">https://samltest.id/saml/logo.png</mdui:Logo>
                 </mdui:UIInfo>
               </Extensions>
               <KeyDescriptor use="signing">
                 <ds:KeyInfo>
                   <ds:X509Data>
                     <ds:X509Certificate>
                       ...
                     </ds:X509Certificate>
                   </ds:X509Data>
                 </ds:KeyInfo>
               </KeyDescriptor>
               <ArtifactResolutionService Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP" Location="https://samltest.id/idp/profile/SAML2/SOAP/ArtifactResolution" index="1" />
               <SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://samltest.id/idp/profile/SAML2/Redirect/SLO"/>
               <SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://samltest.id/idp/profile/SAML2/POST/SLO"/>
               <SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST-SimpleSign" Location="https://samltest.id/idp/profile/SAML2/POST-SimpleSign/SLO"/>
               <SingleSignOnService Binding="urn:mace:shibboleth:1.0:profiles:AuthnRequest" Location="https://samltest.id/idp/profile/Shibboleth/SSO"/>
               <SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://samltest.id/idp/profile/SAML2/POST/SSO"/>
               <SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST-SimpleSign"  Location="https://samltest.id/idp/profile/SAML2/POST-SimpleSign/SSO"/>
               <SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://samltest.id/idp/profile/SAML2/Redirect/SSO"/>
               <SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP" Location="https://samltest.id/idp/profile/SAML2/SOAP/ECP"/>
             </IDPSSODescriptor>
         </EntityDescriptor>

Certificates

The customCertificateSecrets parameter can be used to reference certificates or keys that might be required for SSL communication to the Leap server, the LDAP server, the database, or other services. Changes to the keystores require a restart of the container.

The following is an example of creating a new Secret from TLS Key and Certificate files:
kubectl create secret tls myTlsCertSecret --key="certificate.key" --cert="certificate.crt"
The following is an example of adding a DB2 SSL certificate to another Secret:
kubectl create secret generic myDb2SslSecret --from-file=mydbservercert.arm 
configuration: 
  leap: 
    customCertificateSecrets: 
      myTlsCertSecret: "myTlsCertSecret" 
      myDb2SslSecret: "myDb2SslSecret"

This adds the certificates and key to the keystore with the id defaultKeyStore which can then be referenced in the server.xml or any overrides. The defaultKeyStore is also used as the default by many configuration elements in Open Liberty that require a keystore.

Open Liberty server customizations

The configOverrideFiles parameter allows configuration snippets to be passed to the Leap server. The snippets are merged into the Open Liberty server.xml. After making changes to the .yaml, apply them using the helm upgrade ... command. Changes are picked up by Open Liberty and applied at runtime - this does not require a restart.

Note: The name of the customization (myCustomOverride1 in the following snippet) can be any string, but you may want it to be descriptive of what is being provided.
configuration: 
  leap: 
    configOverrideFiles: 
      myCustomOverride1: | 
        <server description="leapServer"> 
          <basicregistry id="leapRegistry" realm="basicRealm"> 
            <user name="newuser1" password="passw0rd" 
          </basicRegistry> 
        </server>

There are several configuration changes that you may need to add to complete your deployment: SMTP, Database, LDAP. Sample snippets have been provided, which will need to be updated with your specific details.

Connecting to a DB2 Instance

The DB2 jdbc driver has been included and can be found at ${server.config.dir}/lib.

configuration: 
  leap: 
    configOverrideFiles: 
      db2Override: |  
        <server description="leapServer"> 
          <authData id="db2AuthAlias" user="db2inst1" password="diet4coke" /> 
          <library id="jdbcDB2" > 
            <fileset dir ="${server.config.dir}/lib" includes="db2jcc4.jar db2jcc_license_cu.jar" /> 
          </library> 
          <dataSource id="febDataSource" jndiName="jdbc/BuilderDataSource" statementCacheSize="30" containerAuthDataRef="db2AuthAlias"> 
            <properties.db2.jcc  
                databaseName="LEAPDB"  
                driverType="4" 
                serverName="db2server.acme.com"  
                portNumber="50000" 
                fullyMaterializeLobData="false"  
                progressiveStreaming="2" 
                sslConnection="true" 
                streamBufferSize="2097152"
                isolationLevel="2"
            /> 
            <jdbcDriver libraryRef="jdbcDB2"/> 
            <connectionManager connectionTimeout="180" maxPoolSize="10" minPoolSize="1" reapTime="180" maxIdleTime="1800" agedTimeout="7200" purgePolicy="EntirePool"/> 
          </dataSource> 
        </server>

Connecting to an Oracle Instance

The oracle jdbc driver has been included and can be found at ${server.config.dir}/lib.

Note: To connect over SSL, complete the following steps:
  1. change the URL to:
    jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS=(PROTOCOL=TCPS)(PORT=2484)(HOST=leap-oracle-db.example.com))(CONNECT_DATA=(SERVICE_NAME=orclpdb1)))

    You will need to update the host and service name for your database instance.

  2. Create a secret for the SSL certificate used by the Oracle instance.
  3. Specify the connection properties that point to the trust or key store that contain the certificate used by your Oracle instance ${shared.resource.dir}/security/key.p12
Below is an example snippet for configuring the Leap application to use an Oracle database.
configuration: 
  leap: 
    configOverrideFiles: 
      oracleOverride: | 
        <server description="leapServer"> 
            <library id="jdbcOracle" >
                <fileset dir="${server.config.dir}/lib" includes='ojdbc8.jar' />
            </library>
            <dataSource id="leapDataSource" jndiName="jdbc/BuilderDataSource" containerAuthDataRef="oracleAuthAlias"> 
                <jdbcDriver libraryRef="jdbcOracle"/> 
                <properties.oracle URL="jdbc:oracle:thin:@leap-oracle-db.example.com:1521/orclpdb1"/> 
                <connectionManager  
                    minPoolSize="0" maxPoolSize="10" maxIdleTime="10m" 
                    purgePolicy="ValidateAllConnections" 
                /> 
            </dataSource> 
            <authData id="oracleAuthAlias" user="leap_admin" password="{xor}KDozPDAyOm5tbA==" /> 
        </server>

Connecting to an STMP Server
Below is an example snippet of configuring Leap to use a mail server. The smtphost will need to be replaced with the proper hostname of the mail server. If authentication is required to communicate with the mail server then replace smtpUser and smtpPassword with the correct values, otherwise remove those likes from the snippet.
configuration: 
  leap: 
    configOverrideFiles: 
      mailOverride: | 
        <server description="leapServer"> 
            <mailSession  
                host="smtphost.com"  
                from="no-reply@smtphost.com"  
                jndiName="mail/BuilderMailSession"  
                description="Leap MailSession"  
                mailSessionID="leapMail" 
                user="smtpUser" 
                password="smtpPassword"> 
                <property name="mail.smtp.auth" value="false" /> 
                <property name="mail.smtp.port" value="25" /> 
            </mailSession> 
        </server>

Connecting to an LDAP Server
Below is an example snippet of configuring Leap to use an LDAP server as part of a federated repository. The baseDN, bindDN and bindPassword will need to be replaced with the proper values. The searchBase for the ldap entity types will also need to be updated. The participatingBaseEntry will need to match the baseDN defined in the LDAP server snippet.
Note: The userSecurityNameMapping and groupSecurityNameMapping are required. These properties control how users and groups are displayed while using Leap.
Note: For Leap to be able to send mail the loginProperty must be set to mail.
configuration: 
  leap: 
    configOverrideFiles: 
      ldapOverride: | 
        <server description="leapServer"> 
           <federatedRepository id="fedrepo"> 
             <primaryRealm name="FEDREALM"> 
               <participatingBaseEntry name="dc=Acme"/> 
               <userSecurityNameMapping outputProperty="mail" /> 
               <groupSecurityNameMapping outputProperty="cn" /> 
             </primaryRealm> 
           </federatedRepository>
           <ldapRegistry id="OpenLdap" 
              name="dc=Acme" 
              ldapType="Custom" 
              host="ldaphost.acme.com" port="389" 
              baseDN="dc=Acme" 
              searchTimeout="8m" 
              ignoreCase="true" 
              bindDN="cn=Manager,dc=Acme" 
              bindPassword="secret" 
              sslEnabled="false" 
              derefAliases="never"> 
                <loginProperty name="mail"></loginProperty> 
                <ldapEntityType name="PersonAccount"> 
                  <objectClass>inetOrgPerson</objectClass> 
                  <searchBase>ou=People,dc=Acme</searchBase> 
                </ldapEntityType> 
                <ldapEntityType name="Group"> 
                  <objectClass>groupOfUniqueNames</objectClass> 
                  <searchBase>ou=Groups,dc=Acme</searchBase> 
                </ldapEntityType> 
                <customFilters userIdMap="*:mail" groupIdMap="*:cn" groupMemberIdMap="*:uniqueMember" userFilter="(&amp;(mail=%v)(objectclass=inetOrgPerson))" groupFilter="(&amp;(cn=%v)(objectclass=groupOfUniqueNames))"/> 
           </ldapRegistry> 
        </server>

Configure SSL behavior
The default behavior of Open Liberty is that it will not trust any default certificates, which are typically included in all mainstream browsers. By providing this config setting, the default certificates will be trusted enabling communication with third-party services.
configuration:
  leap:
    configOverrideFiles:
      sslOverride: |
         <ssl id="defaultSSLConfig" trustDefaultCerts="true" />

Service Catalog

The serviceCatalog parameter can be used to pass service descriptions to Leap, which will be picked up by Leap automatically.

Each service definition in the .yaml is made up of a label and the xml content of the service description. The XML content will be copied into a file and placed in the service catalog.

For more information on creating service descriptions, see Service Description.

Example:
configuration:
  leap:
    serviceCatalog:
       sampleServiceDescription.xml: |
         <?xml version="1.0" encoding="utf-8"?>
         <serviceDescription>
         <id>sample-service-description</id>
         <defaultLocale>en</defaultLocale>
         <transportId>HTTPServiceTransport</transportId>
         <name xml:lang="en">Sample service Description</name>
         <description xml:lang="en"></description>
            . . . 
         </serviceDescription>

Leap Properties

The leapProperties parameter can be used to add or modify properties to Leap.
Note: The property ibm.nitro.NitroConfig.loginIdIsEmail must be added and set to true.
Below is an example snippet of setting leap-specific properties:
configuration:
   leap:
     leapProperties: | 
        ibm.nitro.InfoEntryPoint.dailyInfo = <div>Welcome to <b>HCL Leap 9.3.2</b> in Kubernetes!</div> 
        ibm.nitro.NitroConfig.serverURI=http://myleapserver.example.com
        ibm.nitro.NitroConfig.loginIdIsEmail = true

For more information, see Configuration properties.

JVM options

JVM options can be specified by passing them as environment variables. The snippet below sets the maximum jvm memory usage to 2GB.
environment:
   pod:
     leap:
       name:  JVM_MAX
       value: "-Xmx2048m"

Changing the log level

Sometimes you may need to increase the log level to troubleshoot unexpected behavior. Below is an example of how to change the log level.
logging:
  leap:
    level: Leap:*=detail:com.ibm.form.nitro.*=finest

Assigning User's to Leap Roles

Leap has several application-level roles that control who can access different features. You must map Administrative users and Edit Application users to an appropriate realm.

  • SuperAdminUsers - Super Administrative Users are users, or groups, with administrator privileges for all Leap applications without explicit security settings.
  • AdministrativeUsers - Administrative users are able to set up the Leap server. You must have an Administrative User to complete the installation process.
  • EditApplicationUsers - Authenticated users that can design, deploy, and use Leap applications.
  • UseApplicationsUsers - Authenticated users that can use deployed Leap applications. All users in the AdministrativeUsers, and EditApplicationUsers automatically have access to use deployed applications. Only adjust this setting if you want to allow a broader set of users than those listed in the AdministrativeUsers, and EditApplicationUsers roles. Otherwise, leave this role unmapped.
configuration:
  leap:
    roleMapping:
      SuperAdminUsers:
        Everyone: false
        AllAuthenticated: false
        MappedUsers:
          - leapadmin
        MappedGroups: []
        AllAuthenticatedInTrustedRealms: false
        MappedUsersAccessIDs: []
        MappedGroupsAccessIDs: []
      EditApplicationsUsers:
        Everyone: false
        AllAuthenticated: false
        MappedUsers:
          - leapadmin
        MappedGroups: []
        AllAuthenticatedInTrustedRealms: false
        MappedUsersAccessIDs: []
        MappedGroupsAccessIDs: []
      AdministrativeUsers:
        Everyone: false
        AllAuthenticated: false
        MappedUsers:
          - leapadmin
        MappedGroups: []
        AllAuthenticatedInTrustedRealms: false
        MappedUsersAccessIDs: []
        MappedGroupsAccessIDs: []
      UseApplicationsUsers:
        Everyone: false
        AllAuthenticated: false
        MappedUsers: []
        MappedGroups: []
        AllAuthenticatedInTrustedRealms: true
        MappedUsersAccessIDs: []
        MappedGroupsAccessIDs: []