Add optional silent install and config of ldap to devstack

Edited initial ldap entries and olcdb template file as recommended by Brant.

Change-Id: I1404cc5c754f878e32a2d10254840d092211e6e6
diff --git a/files/apts/ldap b/files/apts/ldap
new file mode 100644
index 0000000..81a00f2
--- /dev/null
+++ b/files/apts/ldap
@@ -0,0 +1,3 @@
+ldap-utils
+slapd # NOPRIME
+python-ldap
diff --git a/files/ldap/manager.ldif.in b/files/ldap/manager.ldif.in
new file mode 100644
index 0000000..e522150
--- /dev/null
+++ b/files/ldap/manager.ldif.in
@@ -0,0 +1,10 @@
+dn: olcDatabase={${LDAP_OLCDB_NUMBER}}hdb,cn=config
+changetype: modify
+replace: olcSuffix
+olcSuffix: dc=openstack,dc=org
+-
+replace: olcRootDN
+olcRootDN: dc=Manager,dc=openstack,dc=org
+-
+${LDAP_ROOTPW_COMMAND}: olcRootPW
+olcRootPW: ${SLAPPASS}
diff --git a/files/ldap/openstack.ldif b/files/ldap/openstack.ldif
new file mode 100644
index 0000000..287fda4
--- /dev/null
+++ b/files/ldap/openstack.ldif
@@ -0,0 +1,21 @@
+dn: dc=openstack,dc=org
+dc: openstack
+objectClass: dcObject
+objectClass: organizationalUnit
+ou: openstack
+
+dn: ou=Groups,dc=openstack,dc=org
+objectClass: organizationalUnit
+ou: Groups
+
+dn: ou=Users,dc=openstack,dc=org
+objectClass: organizationalUnit
+ou: Users
+
+dn: ou=Roles,dc=openstack,dc=org
+objectClass: organizationalUnit
+ou: Roles
+
+dn: ou=Projects,dc=openstack,dc=org
+objectClass: organizationalUnit
+ou: Projects
diff --git a/files/rpms/ldap b/files/rpms/ldap
new file mode 100644
index 0000000..2f7ab5d
--- /dev/null
+++ b/files/rpms/ldap
@@ -0,0 +1,3 @@
+openldap-servers
+openldap-clients
+python-ldap
diff --git a/lib/keystone b/lib/keystone
index 5714670..866c62e 100644
--- a/lib/keystone
+++ b/lib/keystone
@@ -94,6 +94,17 @@
     local dburl
     database_connection_url dburl keystone
 
+    if is_service_enabled ldap; then
+        #Set all needed ldap values
+        iniset $KEYSTONE_CONF ldap password  $LDAP_PASSWORD
+        iniset $KEYSTONE_CONF ldap user "dc=Manager,dc=openstack,dc=org"
+        iniset $KEYSTONE_CONF ldap suffix "dc=openstack,dc=org"
+    fi
+
+    if [[  "$KEYSTONE_IDENTITY_BACKEND" == "ldap"  ]]; then
+        iniset $KEYSTONE_CONF identity driver "keystone.identity.backends.ldap.Identity"
+    fi
+
     if is_service_enabled tls-proxy; then
         # Set the service ports for a proxy to take the originals
         iniset $KEYSTONE_CONF DEFAULT public_port $KEYSTONE_SERVICE_PORT_INT
@@ -283,6 +294,10 @@
 
 # install_keystone() - Collect source and prepare
 function install_keystone() {
+    # only install ldap if the service has been enabled
+    if is_service_enabled ldap; then
+        install_ldap
+    fi
     git_clone $KEYSTONE_REPO $KEYSTONE_DIR $KEYSTONE_BRANCH
 }
 
diff --git a/lib/ldap b/lib/ldap
new file mode 100644
index 0000000..5cb4534
--- /dev/null
+++ b/lib/ldap
@@ -0,0 +1,74 @@
+# lib/ldap
+# Functions to control the installation and configuration of **ldap**
+
+# ``stack.sh`` calls the entry points in this order:
+#
+
+# Save trace setting
+XTRACE=$(set +o | grep xtrace)
+set +o xtrace
+
+# install_ldap
+# install_ldap() - Collect source and prepare
+function install_ldap() {
+    echo "Installing LDAP inside function"
+    echo "LDAP_PASSWORD is $LDAP_PASSWORD"
+    echo "os_VENDOR is $os_VENDOR"
+    printf "installing"
+    if is_ubuntu; then
+        echo "os vendor is Ubuntu"
+        LDAP_OLCDB_NUMBER=1
+        LDAP_ROOTPW_COMMAND=replace
+        sudo DEBIAN_FRONTEND=noninteractive apt-get install slapd ldap-utils
+        #automatically starts LDAP on ubuntu so no need to call start_ldap
+    elif is_fedora; then
+        echo "os vendor is Fedora"
+        LDAP_OLCDB_NUMBER=2
+        LDAP_ROOTPW_COMMAND=add
+        start_ldap
+    fi
+
+    printf "generate password file"
+    SLAPPASS=`slappasswd -s $LDAP_PASSWORD`
+
+    printf "secret is $SLAPPASS\n"
+    #create manager.ldif
+    TMP_MGR_DIFF_FILE=`mktemp -t manager_ldiff.$$.XXXXXXXXXX.ldif`
+    sed -e "s|\${LDAP_OLCDB_NUMBER}|$LDAP_OLCDB_NUMBER|" -e "s|\${SLAPPASS}|$SLAPPASS|" -e "s|\${LDAP_ROOTPW_COMMAND}|$LDAP_ROOTPW_COMMAND|" $FILES/ldap/manager.ldif.in >> $TMP_MGR_DIFF_FILE
+
+    #update ldap olcdb
+    sudo ldapmodify -Y EXTERNAL -H ldapi:/// -f $TMP_MGR_DIFF_FILE
+
+    # add our top level ldap nodes
+    if ldapsearch -x -w $LDAP_PASSWORD -H ldap://localhost -D dc=Manager,dc=openstack,dc=org -x -b dc=openstack,dc=org | grep -q "Success" ; then
+        printf "LDAP already configured for OpenStack\n"
+        if [[ "$KEYSTONE_CLEAR_LDAP" == "yes" ]]; then
+            # clear LDAP state
+            clear_ldap_state
+            # reconfigure LDAP for OpenStack
+            ldapadd -c -x -H ldap://localhost -D dc=Manager,dc=openstack,dc=org -w $LDAP_PASSWORD -f  $FILES/ldap/openstack.ldif
+        fi
+    else
+        printf "Configuring LDAP for OpenStack\n"
+        ldapadd -c -x -H ldap://localhost -D dc=Manager,dc=openstack,dc=org -w $LDAP_PASSWORD -f  $FILES/ldap/openstack.ldif
+    fi
+}
+
+# start_ldap() - Start LDAP
+function start_ldap() {
+    sudo service slapd restart
+}
+
+
+# stop_ldap() - Stop LDAP
+function stop_ldap() {
+    sudo service slapd stop
+}
+
+# clear_ldap_state() - Clear LDAP State
+function clear_ldap_state() {
+    ldapdelete -x -w $LDAP_PASSWORD -H ldap://localhost -D dc=Manager,dc=openstack,dc=org -x -r "dc=openstack,dc=org"
+}
+
+# Restore xtrace
+$XTRACE
diff --git a/stack.sh b/stack.sh
index 4608648..0521ced 100755
--- a/stack.sh
+++ b/stack.sh
@@ -306,6 +306,7 @@
 source $TOP_DIR/lib/heat
 source $TOP_DIR/lib/quantum
 source $TOP_DIR/lib/baremetal
+source $TOP_DIR/lib/ldap
 
 # Set the destination directories for OpenStack projects
 HORIZON_DIR=$DEST/horizon
@@ -475,6 +476,20 @@
 read_password SERVICE_PASSWORD "ENTER A SERVICE_PASSWORD TO USE FOR THE SERVICE AUTHENTICATION."
 # Horizon currently truncates usernames and passwords at 20 characters
 read_password ADMIN_PASSWORD "ENTER A PASSWORD TO USE FOR HORIZON AND KEYSTONE (20 CHARS OR LESS)."
+# Keystone can now optionally install OpenLDAP by adding ldap to the list
+# of enabled services in the localrc file (e.g. ENABLED_SERVICES=key,ldap).
+# If OpenLDAP has already been installed but you need to clear out
+# the Keystone contents of LDAP set KEYSTONE_CLEAR_LDAP to yes
+# (e.g. KEYSTONE_CLEAR_LDAP=yes ) in the localrc file.  To enable the
+# Keystone Identity Driver (keystone.identity.backends.ldap.Identity)
+# set KEYSTONE_IDENTITY_BACKEND to ldap (e.g. KEYSTONE_IDENTITY_BACKEND=ldap)
+# in the localrc file.
+
+
+# only request ldap password if the service is enabled
+if is_service_enabled ldap; then
+    read_password LDAP_PASSWORD "ENTER A PASSWORD TO USE FOR LDAP"
+fi
 
 # Set the tenant for service accounts in Keystone
 SERVICE_TENANT_NAME=${SERVICE_TENANT_NAME:-service}