From 6f55cd9922280ee5f4d119aa4a9924a51dea8068 Mon Sep 17 00:00:00 2001
From: Charles Short <charles.short@windriver.com>
Date: Tue, 15 Feb 2022 15:59:20 +0000
Subject: [PATCH] Add stx support

Apply Centos 7 patches to the debian packaging.

Signed-off-by: Charles Short <charles.short@windriver.com>
---
 debian/control                                |   2 +
 debian/keystone.dirs                          |   1 +
 debian/keystone.install                       |   4 +
 debian/keystone.logrotate                     |   8 -
 debian/keystone.postinst.in                   |  10 +-
 debian/python3-keystone.install               |   1 +
 debian/rules                                  |   6 +
 debian/stx/keystone-all                       | 156 ++++++++++++++++++
 debian/stx/keystone-fernet-keys-rotate-active |  64 +++++++
 debian/stx/keystone.service                   |  14 ++
 debian/stx/password-rules.conf                |  34 ++++
 debian/stx/public.py                          |  21 +++
 12 files changed, 304 insertions(+), 17 deletions(-)
 delete mode 100644 debian/keystone.logrotate
 create mode 100644 debian/stx/keystone-all
 create mode 100644 debian/stx/keystone-fernet-keys-rotate-active
 create mode 100644 debian/stx/keystone.service
 create mode 100644 debian/stx/password-rules.conf
 create mode 100644 debian/stx/public.py

diff --git a/debian/control b/debian/control
index 9d0a3a41f..9a67234fa 100644
--- a/debian/control
+++ b/debian/control
@@ -31,6 +31,8 @@ Build-Depends-Indep:
  python3-jwt,
  python3-keystoneclient,
  python3-keystonemiddleware (>= 7.0.0),
+ python3-keyring,
+ python3-keyrings.alt,
  python3-ldap,
  python3-ldappool,
  python3-lxml (>= 4.5.0),
diff --git a/debian/keystone.dirs b/debian/keystone.dirs
index a4b3a9e86..6c6e31faf 100644
--- a/debian/keystone.dirs
+++ b/debian/keystone.dirs
@@ -2,3 +2,4 @@
 /var/lib/keystone
 /var/lib/keystone/cache
 /var/log/keystone
+usr/share/keystone
diff --git a/debian/keystone.install b/debian/keystone.install
index c0d62c45b..8d68859c0 100644
--- a/debian/keystone.install
+++ b/debian/keystone.install
@@ -1,3 +1,7 @@
 debian/keystone-uwsgi.ini	/etc/keystone
 etc/default_catalog.templates	/etc/keystone
 etc/logging.conf.sample	/usr/share/doc/keystone
+debian/stx/keystone-fernet-keys-rotate-active usr/bin
+debian/stx/password-rules.conf /etc/keystone
+debian/stx/keystone.service lib/systemd/system
+debian/stx/keystone-all usr/bin
diff --git a/debian/keystone.logrotate b/debian/keystone.logrotate
deleted file mode 100644
index 2709c72aa..000000000
--- a/debian/keystone.logrotate
+++ /dev/null
@@ -1,8 +0,0 @@
-/var/log/keystone/*.log {
-    daily
-    missingok
-    rotate 5
-    compress
-    minsize 100k
-    copytruncate
-}
\ No newline at end of file
diff --git a/debian/keystone.postinst.in b/debian/keystone.postinst.in
index 207cbc22e..4b464a236 100755
--- a/debian/keystone.postinst.in
+++ b/debian/keystone.postinst.in
@@ -170,15 +170,7 @@ if [ "$1" = "configure" ] ; then
 		su keystone -s /bin/sh -c 'keystone-manage credential_setup --keystone-user keystone --keystone-group keystone'
 	fi
 
-	chown keystone:adm /var/log/keystone
-
-	if [ -n $(which systemctl)"" ] ; then
-		systemctl enable keystone
-	fi
-	if [ -n $(which update-rc.d)"" ] ; then
-		update-rc.d keystone defaults
-	fi
-	invoke-rc.d keystone start
+	chown -R keystone:keystone /var/log/keystone
 
 	db_get keystone/create-admin-tenant
 	if [ "$RET" = "true" ] ; then
diff --git a/debian/python3-keystone.install b/debian/python3-keystone.install
index 44d7fcb64..3c76ffb99 100644
--- a/debian/python3-keystone.install
+++ b/debian/python3-keystone.install
@@ -1,2 +1,3 @@
 usr/bin/*
 usr/lib/python3/*
+debian/stx/public.py usr/share/keystone
diff --git a/debian/rules b/debian/rules
index 3744142f9..f827d1b68 100755
--- a/debian/rules
+++ b/debian/rules
@@ -106,6 +106,12 @@ ifeq (,$(findstring nodocs, $(DEB_BUILD_OPTIONS)))
 	dh_installman
 endif
 
+override_dh_installsystemd:
+	dh_installsystemd --no-enable --no-start
+
+override_dh_installinit:
+	dh_installinit --no-enable --no-start
+
 override_dh_python3:
 	dh_python3 --shebang=/usr/bin/python3
 
diff --git a/debian/stx/keystone-all b/debian/stx/keystone-all
new file mode 100644
index 000000000..de339caa6
--- /dev/null
+++ b/debian/stx/keystone-all
@@ -0,0 +1,156 @@
+#!/bin/sh
+# Copyright (c) 2013-2018 Wind River Systems, Inc.
+#
+# SPDX-License-Identifier: Apache-2.0
+#
+
+### BEGIN INIT INFO
+# Provides:          OpenStack Keystone-wsgi
+# Required-Start:    networking
+# Required-Stop:     networking
+# Default-Start:     2 3 4 5
+# Default-Stop:      0 1 6
+# Short-Description: OpenStack Keystone
+# Description:       Openstack Identitiy service running on WSGI compatable gunicorn web server
+#
+### END INIT INFO
+
+RETVAL=0
+#public 5000
+
+DESC_PUBLIC="openstack-keystone"
+
+PIDFILE_PUBLIC="/var/run/$DESC_PUBLIC.pid"
+
+PYTHON=`which python`
+
+source /etc/keystone/keystone-extra.conf
+source /etc/platform/platform.conf
+
+if [ -n ${@:2:1} ] ; then
+        if [ ${@:2:1}="--public-bind-addr" ] ; then
+                PUBLIC_BIND_ADDR_CMD=${@:3:1}
+        fi
+fi
+
+
+###
+EXEC="/usr/bin/gunicorn"
+
+WORKER="eventlet"
+# Increased timeout to facilitate large image uploads
+TIMEOUT="200"
+
+# Calculate the no of workers based on the number of workers retrieved by
+# Platform Eng which is retreived from the keystone-extra.conf
+
+if [ "$system_type" == "All-in-one" ]; then
+    TIS_WORKERS_FACTOR=1
+else
+    TIS_WORKERS_FACTOR=1.5
+fi
+TIS_WORKERS=$(echo "${TIS_WORKERS_FACTOR}*${TIS_PUBLIC_WORKERS}"|bc )
+TIS_WORKERS=${TIS_WORKERS%.*}
+
+#--max-requests , --max-requests-jitter Configuration
+#--max-requests = The max number of requests a worker will process before restarting
+#--max-requests-jitter = The maximum jitter to add to the max_requests setting.
+MAX_REQUESTS=100000
+MAX_REQ_JITTER_CAP_FACTOR=0.5
+MAX_REQ_JITTER_PUBLIC=$(echo "${TIS_WORKERS}*${MAX_REQ_JITTER_CAP_FACTOR}+1"|bc)
+MAX_REQ_JITTER_PUBLIC=${MAX_REQ_JITTER_PUBLIC%.*}
+
+
+start()
+{
+    # Got proper no of workers . Starting gunicorn now
+    echo -e "Initialising keystone service using gunicorn .. \n"
+
+    if [ -z "$PUBLIC_BIND_ADDR" ]; then
+        echo "Keystone floating ip not found . Cannot start services. Exiting .."
+        exit 1
+    fi
+    BIND_PUBLIC=$PUBLIC_BIND_ADDR:5000
+
+    if [ -e $PIDFILE_PUBLIC ]; then
+        PIDDIR=/proc/$(cat $PIDFILE_PUBLIC)
+        if [ -d ${PIDDIR} ]; then
+            echo "$DESC_PUBLIC already running."
+            exit 1
+        else
+            echo "Removing stale PID file $PIDFILE_PUBLIC"
+            rm -f $PIDFILE_PUBLIC
+        fi
+    fi
+
+    echo -e "Starting $DESC_PUBLIC...\n";
+    echo -e "Worker is ${WORKER} --workers ${TIS_WORKERS} --timeout ${TIMEOUT} --max_requests ${MAX_REQUESTS} --max_request_jitter public ${MAX_REQ_JITTER_PUBLIC}\n" ;
+
+    echo -e "Starting keystone process at port 5000 \n" ;
+
+    start-stop-daemon --start --quiet --background --pidfile ${PIDFILE_PUBLIC} \
+        --make-pidfile --exec ${PYTHON} -- ${EXEC} --bind ${BIND_PUBLIC} \
+        --worker-class ${WORKER} --workers ${TIS_WORKERS} --timeout ${TIMEOUT} \
+        --max-requests ${MAX_REQUESTS}  --max-requests-jitter ${MAX_REQ_JITTER_PUBLIC} \
+        --log-syslog  \
+        --pythonpath '/usr/share/keystone' public:application --name keystone-public
+
+    RETVAL=$?
+    if [ $RETVAL -eq 0 ]; then
+        echo -e "Keystone started at port 5000... \n"
+    else
+        echo -e "Failed to start Keystone .. \n"
+    fi
+}
+
+stop()
+{
+    if [  -e $PIDFILE_PUBLIC ]; then
+	start-stop-daemon --stop --quiet --pidfile $PIDFILE_PUBLIC
+	RETVAL_PUBLIC=$?
+	    if [ $RETVAL_PUBLIC -eq 0 ]; then
+        	echo "Stopped $DESC_PUBLIC."
+	    else
+        	echo "Stopping failed - $PIDFILE_PUBLIC"
+	    fi
+	    rm -f $PIDFILE_PUBLIC
+    else
+	echo "Already stopped - $PIDFILE_PUBLIC"
+    fi
+}
+
+status()
+{
+    pid_public=`cat $PIDFILE_PUBLIC 2>/dev/null`
+
+    if [ -n "$pid_public" ]; then
+        echo -e "\033[32m $DESC_PUBLIC  is running..\033[0m"
+    else
+        echo -e "\033[31m $DESC_PUBLIC  is not running..\033[0m"
+    fi
+}
+
+
+
+case "$1" in
+    start)
+        start
+        ;;
+    stop)
+        stop
+        ;;
+    restart|force-reload|reload)
+        stop
+        start
+        ;;
+    status)
+	status
+        ;;
+    *)
+        #echo "Usage: $0 {start|stop|force-reload|restart|reload|status} OR {/usr/bin/keystone-all start --public-bind-addr xxx.xxx.xxx}"
+	start
+        #RETVAL=1
+        ;;
+esac
+
+exit $RETVAL
diff --git a/debian/stx/keystone-fernet-keys-rotate-active b/debian/stx/keystone-fernet-keys-rotate-active
new file mode 100644
index 000000000..e2124eee3
--- /dev/null
+++ b/debian/stx/keystone-fernet-keys-rotate-active
@@ -0,0 +1,64 @@
+#!/bin/bash
+
+#
+# Wrapper script to rotate keystone fernet keys on active controller only
+#
+KEYSTONE_KEYS_ROTATE_INFO="/var/run/keystone-keys-rotate.info"
+KEYSTONE_KEYS_ROTATE_CMD="/usr/bin/nice -n 2 /usr/bin/keystone-manage fernet_rotate --keystone-user keystone --keystone-group keystone"
+
+function is_active_pgserver()
+{
+    # Determine whether we're running on the same controller as the service.
+    local service=postgres
+    local enabledactive=$(/usr/bin/sm-query service $service| grep enabled-active)
+    if [ "x$enabledactive" == "x" ]
+    then
+        # enabled-active not found for that service on this controller
+        return 1
+    else
+        # enabled-active found for that resource
+        return 0
+    fi
+}
+
+if is_active_pgserver
+then
+    if [ ! -f ${KEYSTONE_KEYS_ROTATE_INFO} ]
+    then
+        echo delay_count=0 > ${KEYSTONE_KEYS_ROTATE_INFO}
+    fi
+
+    source ${KEYSTONE_KEYS_ROTATE_INFO}
+    sudo -u postgres psql -d fm -c "SELECT alarm_id, entity_instance_id from alarm;" | grep -P "^(?=.*100.101)(?=.*${HOSTNAME})" &>/dev/null
+    if [ $? -eq 0 ]
+    then
+        source /etc/platform/platform.conf
+        if [ "${system_type}" = "All-in-one" ]
+        then
+            source /etc/init.d/task_affinity_functions.sh
+            idle_core=$(get_most_idle_core)
+            if [ "$idle_core" -ne "0" ]
+            then
+                sh -c "exec taskset -c $idle_core ${KEYSTONE_KEYS_ROTATE_CMD}"
+                sed -i "/delay_count/s/=.*/=0/" ${KEYSTONE_KEYS_ROTATE_INFO}
+                exit 0
+            fi
+        fi
+
+        if [ "$delay_count" -lt "3" ]
+        then
+            newval=$(($delay_count+1))
+            sed -i "/delay_count/s/=.*/=$newval/" ${KEYSTONE_KEYS_ROTATE_INFO}
+            (sleep 3600; /usr/bin/keystone-fernet-keys-rotate-active) &
+            exit 0
+        fi
+
+    fi
+
+    eval ${KEYSTONE_KEYS_ROTATE_CMD}
+    sed -i "/delay_count/s/=.*/=0/" ${KEYSTONE_KEYS_ROTATE_INFO}
+
+fi
+
+exit 0
+
diff --git a/debian/stx/keystone.service b/debian/stx/keystone.service
new file mode 100644
index 000000000..a72aa84be
--- /dev/null
+++ b/debian/stx/keystone.service
@@ -0,0 +1,14 @@
+[Unit]
+Description=OpenStack Identity Service (code-named Keystone)
+After=syslog.target network.target
+
+[Service]
+Type=forking
+#ReminAfterExit is set to yes as we have 2 pids to monitor
+RemainAfterExit=yes
+ExecStart=/usr/bin/keystone-all start
+ExecStop=/usr/bin/keystone-all stop
+ExecReload=/usr/bin/keystone-all reload
+
+[Install]
+WantedBy=multi-user.target
diff --git a/debian/stx/password-rules.conf b/debian/stx/password-rules.conf
new file mode 100644
index 000000000..e7ce65602
--- /dev/null
+++ b/debian/stx/password-rules.conf
@@ -0,0 +1,34 @@
+# The password rules captures the [security_compliance]
+# section of the generic Keystone configuration (keystone.conf)
+# This configuration is used to statically define the password
+# rules for password validation in pre-Keystone environments
+#
+# N.B: Only set non-default keys here (default commented configuration
+# items not needed)
+
+[security_compliance]
+
+#
+# From keystone
+#
+
+# This controls the number of previous user password iterations to keep in
+# history, in order to enforce that newly created passwords are unique. Setting
+# the value to one (the default) disables this feature. Thus, to enable this
+# feature, values must be greater than 1. This feature depends on the `sql`
+# backend for the `[identity] driver`. (integer value)
+# Minimum value: 1
+unique_last_password_count = 3
+
+# The regular expression used to validate password strength requirements. By
+# default, the regular expression will match any password. The following is an
+# example of a pattern which requires at least 1 letter, 1 digit, and have a
+# minimum length of 7 characters: ^(?=.*\d)(?=.*[a-zA-Z]).{7,}$ This feature
+# depends on the `sql` backend for the `[identity] driver`. (string value)
+password_regex = ^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[!@#$%^&*()<>{}+=_\\\[\]\-?|~`,.;:]).{7,}$
+
+# Describe your password regular expression here in language for humans. If a
+# password fails to match the regular expression, the contents of this
+# configuration variable will be returned to users to explain why their
+# requested password was insufficient. (string value)
+password_regex_description = Password must have a minimum length of 7 characters, and must contain at least 1 upper case, 1 lower case, 1 digit, and 1 special character
diff --git a/debian/stx/public.py b/debian/stx/public.py
new file mode 100644
index 000000000..d3a29f3b3
--- /dev/null
+++ b/debian/stx/public.py
@@ -0,0 +1,21 @@
+# Copyright (c) 2013-2017 Wind River Systems, Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+
+from keystone.server import wsgi as wsgi_server
+
+import sys
+sys.argv = sys.argv[:1]
+
+application = wsgi_server.initialize_public_application()
-- 
2.34.1