diff --git a/.github/workflows/build_unittest.yml b/.github/workflows/build_unittest.yml index 90d7cb87b..1a61adda7 100755 --- a/.github/workflows/build_unittest.yml +++ b/.github/workflows/build_unittest.yml @@ -195,12 +195,14 @@ jobs: sudo sed -i 's/# tls-cert-file redis.crt/tls-cert-file \/etc\/redis\/redis.crt/' /etc/redis/6379.conf sudo sed -i 's/# tls-key-file redis.key/tls-key-file \/etc\/redis\/redis.key/' /etc/redis/6379.conf sudo sed -i 's/# tls-ca-cert-file ca.crt/tls-ca-cert-file \/etc\/redis\/ca.crt/' /etc/redis/6379.conf + sudo sed -i 's/# requirepass foobared/requirepass redis_password/' /etc/redis/6379.conf sudo sed -i '0,/port 6380/ s/port 6380/port 0/' /etc/redis/6380.conf sudo sed -i 's/# tls-port 6379/tls-port 6380/' /etc/redis/6380.conf sudo sed -i 's/# tls-cert-file redis.crt/tls-cert-file \/etc\/redis\/redis.crt/' /etc/redis/6380.conf sudo sed -i 's/# tls-key-file redis.key/tls-key-file \/etc\/redis\/redis.key/' /etc/redis/6380.conf sudo sed -i 's/# tls-ca-cert-file ca.crt/tls-ca-cert-file \/etc\/redis\/ca.crt/' /etc/redis/6380.conf + sudo sed -i 's/# requirepass foobared/requirepass redis_password/' /etc/redis/6380.conf sudo /etc/init.d/redis_6379 restart sleep 10s diff --git a/.github/workflows/odimra_deployment.yml b/.github/workflows/odimra_deployment.yml index cc7586c4a..ae820f525 100644 --- a/.github/workflows/odimra_deployment.yml +++ b/.github/workflows/odimra_deployment.yml @@ -14,6 +14,7 @@ jobs: - uses: actions/checkout@v2 - name: configure pre-req for odimra deployment run: | + set -x echo "[$(date)] -- INFO -- Start pre req conguration" echo @@ -29,6 +30,7 @@ jobs: echo export PASSWD=password + export REDIS_PASSWORD=redis_password echo "runner:${PASSWD}" > pass sudo chpasswd < pass @@ -102,6 +104,7 @@ jobs: pip3 install jmespath==0.9.5 pip3 install ruamel.yaml==0.16.10 pip3 install pyyaml==5.3.1 + pip3 install cryptography==3.4.8 echo echo "[$(date)] -- INFO -- installed python version" @@ -114,6 +117,9 @@ jobs: cp kube_deploy_nodes.yaml.tmpl kube_deploy_nodes.yaml echo ${PASSWD} > node_pass echo ${PASSWD} > vault_pass + echo ${REDIS_PASSWORD} > redis_inmemory_pass + echo ${REDIS_PASSWORD} > redis_ondisk_pass + ls -ltra echo @@ -127,13 +133,16 @@ jobs: echo "[$(date)] -- INFO -- encrypt passwords" ./odim-vault -encode ${ODIM_CONTROLLER_PATH}/scripts/vault_pass ./odim-vault -key ${ODIM_CONTROLLER_PATH}/scripts/vault_pass -encrypt ${ODIM_CONTROLLER_PATH}/scripts/node_pass - echo + ./odim-vault -key ${ODIM_CONTROLLER_PATH}/scripts/vault_pass -encrypt ${ODIM_CONTROLLER_PATH}/scripts/redis_inmemory_pass + ./odim-vault -key ${ODIM_CONTROLLER_PATH}/scripts/vault_pass -encrypt ${ODIM_CONTROLLER_PATH}/scripts/redis_ondisk_pass mkdir -p ${cur_path}/k8s_images ${cur_path}/odim_images ${cur_path}/odim_plugins export rootServiceUUID=$(uuidgen) export NODE_PASS_FILEPATH=${ODIM_CONTROLLER_PATH}/scripts/node_pass export VAULTKEY_FILEPATH=${ODIM_CONTROLLER_PATH}/scripts/vault_pass + export REDIS_INMEMORY_FILEPATH=${ODIM_CONTROLLER_PATH}/scripts/redis_inmemory_pass + export REDIS_ONDISK_FILEPATH=${ODIM_CONTROLLER_PATH}/scripts/redis_ondisk_pass export K8S_IMAGE_PATH=${cur_path}/k8s_images export ODIM_IMAGE_PATH=${cur_path}/odim_images export ODIM_PLUGIN_PATH=${cur_path}/odim_plugins @@ -141,6 +150,8 @@ jobs: sed -i "/Node[23]_/d; /kubernetesImagePath:/d; /odimraImagePath:/d; s#.*deploymentID.*#deploymentID: OneNodeDeployment#; \ s#.*httpProxy.*#httpProxy: \"\"#; s#.*httpsProxy.*#httpsProxy: \"\"#; s#.*noProxy.*#noProxy: \"\"#; \ s#.*nodePasswordFilePath.*#nodePasswordFilePath: ${NODE_PASS_FILEPATH}#; \ + s#.*redisInMemoryPasswordFilePath.*#redisInMemoryPasswordFilePath: ${REDIS_INMEMORY_FILEPATH}#; \ + s#.*redisOnDiskPasswordFilePath.*#redisOnDiskPasswordFilePath: ${REDIS_ONDISK_FILEPATH}#; \ s#.*odimControllerSrcPath.*#odimControllerSrcPath: ${ODIM_CONTROLLER_PATH}#; \ s#.*odimVaultKeyFilePath.*#odimVaultKeyFilePath: ${VAULTKEY_FILEPATH}#; \ s#.*odimCertsPath.*#odimCertsPath: \"\"#; s#.*odimPluginPath.*#odimPluginPath: ${ODIM_PLUGIN_PATH}#; \ @@ -191,7 +202,12 @@ jobs: kubectl get pods -n kube-system -o wide echo cd ${ODIM_SOURCE_PATH}/ + echo "$(df -h)" time ./build_images.sh + sleep 30 + echo "$(docker images)" + echo "$(df -h)" + cd ${ODIM_CONTROLLER_PATH}/scripts/ python3 odim-controller.py --deploy odimra --config ${ODIM_CONTROLLER_PATH}/scripts/kube_deploy_nodes.yaml @@ -206,6 +222,9 @@ jobs: count=$((count+1)) done kubectl get pods -n odim -o wide + + echo "$(df -h)" + echo "============Checking Node status================" kubectl get node -o wide @@ -216,9 +235,11 @@ jobs: echo "$VM_IP" + + echo "$(df -h)" echo " ====================== Adding URP Plugin ===================================" - + sudo mkdir -p /var/log/urplugin_logs/ sudo chown odimra:odimra /var/log/urplugin_logs/ @@ -236,7 +257,12 @@ jobs: helm package ${ODIM_CONTROLLER_PATH}/helmcharts/urplugin/urplugin -d ${ODIM_PLUGIN_PATH}/urplugin cp urplugin-config.yaml ${ODIM_PLUGIN_PATH}/urplugin + echo "$(df -h)" + echo "$(docker images)" + echo "$(docker inspect urplugin:3.0)" + echo "$(docker --version)" docker save urplugin -o ${ODIM_PLUGIN_PATH}/urplugin/urplugin.tar + echo "Docker save command executed successfully" cat urplugin-config.yaml cd ${ODIM_CONTROLLER_PATH}/scripts diff --git a/install/Docker/dockerfiles/Dockerfile.redis b/install/Docker/dockerfiles/Dockerfile.redis index c12e443e1..8d6d9f02a 100644 --- a/install/Docker/dockerfiles/Dockerfile.redis +++ b/install/Docker/dockerfiles/Dockerfile.redis @@ -23,7 +23,8 @@ RUN if [ -z "$ODIMRA_USER_ID" ] || [ -z "$ODIMRA_GROUP_ID" ]; then \ && groupadd -r -g $ODIMRA_GROUP_ID odimra \ && useradd -s /bin/bash -u $ODIMRA_USER_ID -m -d /home/odimra -r -g odimra odimra -RUN apt-get install bash sed +RUN apt-get -y update +RUN apt-get -y install openssl bash sed RUN mkdir /redis-master /redis-slave COPY --chown=odimra:odimra install/Docker/dockerfiles/scripts/redis-master.conf /redis-master/redis.conf diff --git a/install/Docker/dockerfiles/scripts/redis-checkdb.sh b/install/Docker/dockerfiles/scripts/redis-checkdb.sh index 421dbc71f..c9d5c0a1f 100755 --- a/install/Docker/dockerfiles/scripts/redis-checkdb.sh +++ b/install/Docker/dockerfiles/scripts/redis-checkdb.sh @@ -16,14 +16,8 @@ # Script is for generating certificate and private key # for Client mode connection usage only sleep 3 -if [[ -n ${REDIS_DEFAULT_PASSWORD} ]]; then echo "Checking if default entries already present" -redis-cli -a ${REDIS_DEFAULT_PASSWORD} -h ${master} -p ${REDIS_HA_REDIS_SERVICE_PORT} --tls --cert ${TLS_CERT_FILE} --key ${TLS_KEY_FILE} --cacert ${TLS_CA_CERT_FILE} < /dev/null` if [ $? -eq 0 ]; then echo "Updating the db with default entries" - if [[ -n ${REDIS_DEFAULT_PASSWORD} ]]; then - redis-cli -a ${REDIS_DEFAULT_PASSWORD} -h ${master} -p ${REDIS_HA_REDIS_SERVICE_PORT} --tls --cert ${TLS_CERT_FILE} --key ${TLS_KEY_FILE} --cacert ${TLS_CA_CERT_FILE} < insert_master_ip_and_default_entries.sh - else - echo "while true; do sleep 2; export master=\$(hostname -i | cut -d ' ' -f 1); echo \"Master IP is Me : \${master}\"; echo \"Setting STARTUP_MASTER_IP in redis\"; redis-cli -h \${master} --tls --cert ${TLS_CERT_FILE} --key ${TLS_KEY_FILE} --cacert ${TLS_CA_CERT_FILE} set STARTUP_MASTER_IP \${master}; if [ \$? == \"0\" ]; then echo \"Successfully set STARTUP_MASTER_IP\"; if [ \${REDIS_ONDISK_DB} == \"true\" ]; then bash \/createschema.sh; fi; break; fi; echo \"Connecting to master \${master} failed. Waiting...\"; sleep 5; done" > insert_master_ip_and_default_entries.sh - fi + redis_password=$(openssl pkeyutl -decrypt -in cipher -inkey ${ODIMRA_RSA_PRIVATE_FILE} -pkeyopt rsa_padding_mode:oaep -pkeyopt rsa_oaep_md:sha512) + echo "while true; do sleep 2; export master=\$(hostname -i | cut -d ' ' -f 1); echo \"Master IP is Me : \${master}\"; echo \"Setting STARTUP_MASTER_IP in redis\"; redis-cli -a ${redis_password} -h \${master} --tls --cert ${TLS_CERT_FILE} --key ${TLS_KEY_FILE} --cacert ${TLS_CA_CERT_FILE} set STARTUP_MASTER_IP \${master}; if [ \$? == \"0\" ]; then echo \"Successfully set STARTUP_MASTER_IP\"; if [ \${REDIS_ONDISK_DB} == \"true\" ]; then bash \/createschema.sh; fi; break; fi; echo \"Connecting to master \${master} failed. Waiting...\"; sleep 5; done" > insert_master_ip_and_default_entries.sh bash insert_master_ip_and_default_entries.sh & - sed -i "s/REDIS_DEFAULT_PASSWORD/${REDIS_DEFAULT_PASSWORD}/" /redis-master/redis.conf + sed -i "s/REDIS_DEFAULT_PASSWORD/${redis_password}/" /redis-master/redis.conf hostname=$(hostname -f) sed -i "s/%replica-announce-ip%/${hostname}/" /redis-master/redis.conf @@ -48,19 +45,20 @@ function launchsentinel() { sleep_for_rand_int=$(awk -v min=2 -v max=7 'BEGIN{srand(); print int(min+rand()*(max-min+1))}') sleep ${sleep_for_rand_int} + echo -n "${REDIS_DEFAULT_PASSWORD}" | base64 --decode > cipher + redis_password=$(openssl pkeyutl -decrypt -in cipher -inkey ${ODIMRA_RSA_PRIVATE_FILE} -pkeyopt rsa_padding_mode:oaep -pkeyopt rsa_oaep_md:sha512) + while true; do echo "Trying to connect to Sentinel Service" - master=$(redis-cli -h ${REDIS_HA_SENTINEL_SERVICE_HOST} -p ${REDIS_HA_SENTINEL_SERVICE_PORT} --tls --cert ${TLS_CERT_FILE} --key ${TLS_KEY_FILE} --cacert ${TLS_CA_CERT_FILE} --csv SENTINEL get-master-addr-by-name ${REDIS_MASTER_SET} | tr ',' ' ' | cut -d' ' -f1) + master=$(redis-cli -a ${redis_password} -h ${REDIS_HA_SENTINEL_SERVICE_HOST} -p ${REDIS_HA_SENTINEL_SERVICE_PORT} --tls --cert ${TLS_CERT_FILE} --key ${TLS_KEY_FILE} --cacert ${TLS_CA_CERT_FILE} --csv SENTINEL get-master-addr-by-name ${REDIS_MASTER_SET} | tr ',' ' ' | cut -d' ' -f1) + if [[ -n ${master} ]]; then echo "Connected to Sentinel Service and retrieved Redis Master IP as ${master}" master="${master//\"}" else echo "Unable to connect to Sentinel Service, probably because I am first Sentinel to start. I will try to find STARTUP_MASTER_IP from the redis service" - if [[ -n ${REDIS_DEFAULT_PASSWORD} ]]; then - master=$(redis-cli -a ${REDIS_DEFAULT_PASSWORD} -h ${REDIS_HA_REDIS_SERVICE_HOST} -p ${REDIS_HA_REDIS_SERVICE_PORT} --tls --cert ${TLS_CERT_FILE} --key ${TLS_KEY_FILE} --cacert ${TLS_CA_CERT_FILE} get STARTUP_MASTER_IP) - else - master=$(redis-cli -h ${REDIS_HA_REDIS_SERVICE_HOST} -p ${REDIS_HA_REDIS_SERVICE_PORT} --tls --cert ${TLS_CERT_FILE} --key ${TLS_KEY_FILE} --cacert ${TLS_CA_CERT_FILE} get STARTUP_MASTER_IP) - fi + master=$(redis-cli -a ${redis_password} -h ${REDIS_HA_REDIS_SERVICE_HOST} -p ${REDIS_HA_REDIS_SERVICE_PORT} --tls --cert ${TLS_CERT_FILE} --key ${TLS_KEY_FILE} --cacert ${TLS_CA_CERT_FILE} get STARTUP_MASTER_IP) + if [[ -n ${master} ]]; then echo "Retrieved Redis Master IP as ${master}" else @@ -69,12 +67,8 @@ function launchsentinel() { continue fi fi - if [[ -n ${REDIS_DEFAULT_PASSWORD} ]]; then - redis-cli -a ${REDIS_DEFAULT_PASSWORD} -h ${master} --tls --cert ${TLS_CERT_FILE} --key ${TLS_KEY_FILE} --cacert ${TLS_CA_CERT_FILE} INFO - else - redis-cli -h ${master} --tls --cert ${TLS_CERT_FILE} --key ${TLS_KEY_FILE} --cacert ${TLS_CA_CERT_FILE} INFO - fi + redis-cli -a ${redis_password} -h ${master} --tls --cert ${TLS_CERT_FILE} --key ${TLS_KEY_FILE} --cacert ${TLS_CA_CERT_FILE} INFO if [[ "$?" == "0" ]]; then break fi @@ -91,6 +85,8 @@ function launchsentinel() { echo "sentinel announce-ip ${hostname}" >> ${sentinel_conf} echo "sentinel announce-port ${REDIS_HA_SENTINEL_SERVICE_PORT}" >> ${sentinel_conf} echo "sentinel monitor ${REDIS_MASTER_SET} ${MASTER_HOST_NAME} ${REDIS_HA_REDIS_SERVICE_PORT} ${SENTINEL_QUORUM}" >> ${sentinel_conf} + echo "sentinel auth-pass ${REDIS_MASTER_SET} ${redis_password}" >> ${sentinel_conf} + echo "requirepass ${redis_password}" >> ${sentinel_conf} echo "sentinel down-after-milliseconds ${REDIS_MASTER_SET} ${DOWN_AFTER_MILLISECONDS}" >> ${sentinel_conf} echo "sentinel failover-timeout ${REDIS_MASTER_SET} ${FAILOVER_TIMEOUT}" >> ${sentinel_conf} echo "sentinel parallel-syncs ${REDIS_MASTER_SET} ${PARALLEL_SYNCS}" >> ${sentinel_conf} @@ -102,9 +98,6 @@ function launchsentinel() { echo "tls-cert-file /etc/odimra_certs/odimra_server.crt" >> ${sentinel_conf} echo "tls-key-file /etc/odimra_certs/odimra_server.key" >> ${sentinel_conf} echo "tls-ca-cert-file /etc/odimra_certs/rootCA.crt" >> ${sentinel_conf} - if [[ -n ${REDIS_DEFAULT_PASSWORD} ]]; then - echo "sentinel auth-pass ${REDIS_MASTER_SET} ${REDIS_DEFAULT_PASSWORD}" >> ${sentinel_conf} - fi redis-sentinel ${sentinel_conf} --protected-mode no } @@ -113,9 +106,13 @@ function launchsentinel() { function launchslave() { echo "Starting Redis instance as Slave , Master IP $1" + redis_password=$(openssl pkeyutl -decrypt -in cipher -inkey ${ODIMRA_RSA_PRIVATE_FILE} -pkeyopt rsa_padding_mode:oaep -pkeyopt rsa_oaep_md:sha512) + echo "slave: ${redis_password}" + while true; do echo "Trying to retrieve the Master IP again, in case of failover master ip would have changed." - master=$(redis-cli -h ${REDIS_HA_SENTINEL_SERVICE_HOST} -p ${REDIS_HA_SENTINEL_SERVICE_PORT} --tls --cert ${TLS_CERT_FILE} --key ${TLS_KEY_FILE} --cacert ${TLS_CA_CERT_FILE} --csv SENTINEL get-master-addr-by-name ${REDIS_MASTER_SET} | tr ',' ' ' | cut -d' ' -f1) + master=$(redis-cli -a ${redis_password} -h ${REDIS_HA_SENTINEL_SERVICE_HOST} -p ${REDIS_HA_SENTINEL_SERVICE_PORT} --tls --cert ${TLS_CERT_FILE} --key ${TLS_KEY_FILE} --cacert ${TLS_CA_CERT_FILE} --csv SENTINEL get-master-addr-by-name ${REDIS_MASTER_SET} | tr ',' ' ' | cut -d' ' -f1) + if [[ -n ${master} ]]; then master="${master//\"}" else @@ -123,11 +120,7 @@ function launchslave() { sleep 60 continue fi - if [[ -n ${REDIS_DEFAULT_PASSWORD} ]]; then - redis-cli -a ${REDIS_DEFAULT_PASSWORD} -h ${master} --tls --cert ${TLS_CERT_FILE} --key ${TLS_KEY_FILE} --cacert ${TLS_CA_CERT_FILE} INFO - else - redis-cli -h ${master} --tls --cert ${TLS_CERT_FILE} --key ${TLS_KEY_FILE} --cacert ${TLS_CA_CERT_FILE} INFO - fi + redis-cli -a ${redis_password} -h ${master} --tls --cert ${TLS_CERT_FILE} --key ${TLS_KEY_FILE} --cacert ${TLS_CA_CERT_FILE} INFO if [[ "$?" == "0" ]]; then break fi @@ -138,7 +131,7 @@ function launchslave() { hostname=$(hostname -f) sed -i "s/%master-ip%/${master}/" /redis-slave/redis.conf sed -i "s/%master-port%/${REDIS_HA_REDIS_SERVICE_PORT}/" /redis-slave/redis.conf - sed -i "s/REDIS_DEFAULT_PASSWORD/${REDIS_DEFAULT_PASSWORD}/" /redis-slave/redis.conf + sed -i "s/REDIS_DEFAULT_PASSWORD/${redis_password}/" /redis-slave/redis.conf sed -i "s/%replica-announce-ip%/${hostname}/" /redis-slave/redis.conf sed -i "s/%replicaof%/${master}/" /redis-slave/redis.conf @@ -151,11 +144,14 @@ function launchredis() { echo "Launching Redis instance" hostname=$(hostname -f) + echo -n "${REDIS_DEFAULT_PASSWORD}" | base64 --decode > cipher + redis_password=$(openssl pkeyutl -decrypt -in cipher -inkey ${ODIMRA_RSA_PRIVATE_FILE} -pkeyopt rsa_padding_mode:oaep -pkeyopt rsa_oaep_md:sha512) + # Loop till I am able to launch slave or master while true; do # I will check if sentinel is up or not by connecting to it. echo "Trying to connect to sentinel, to retireve master's ip" - master=$(redis-cli -h ${REDIS_HA_SENTINEL_SERVICE_HOST} -p ${REDIS_HA_SENTINEL_SERVICE_PORT} --tls --cert ${TLS_CERT_FILE} --key ${TLS_KEY_FILE} --cacert ${TLS_CA_CERT_FILE} --csv SENTINEL get-master-addr-by-name ${REDIS_MASTER_SET} | tr ',' ' ' | cut -d' ' -f1) + master=$(redis-cli -a ${redis_password} -h ${REDIS_HA_SENTINEL_SERVICE_HOST} -p ${REDIS_HA_SENTINEL_SERVICE_PORT} --tls --cert ${TLS_CERT_FILE} --key ${TLS_KEY_FILE} --cacert ${TLS_CA_CERT_FILE} --csv SENTINEL get-master-addr-by-name ${REDIS_MASTER_SET} | tr ',' ' ' | cut -d' ' -f1) # Is this instance marked as MASTER, it will matter only when the cluster is starting up for first time. if [[ "${MASTER}" == "true" ]]; then echo "MASTER is set to true" diff --git a/install/Docker/dockerfiles/scripts/redis-master.conf b/install/Docker/dockerfiles/scripts/redis-master.conf index 588f9aeda..15c10e9f2 100644 --- a/install/Docker/dockerfiles/scripts/redis-master.conf +++ b/install/Docker/dockerfiles/scripts/redis-master.conf @@ -403,7 +403,7 @@ slave-priority 100 # 150k passwords per second against a good box. This means that you should # use a very strong password otherwise it will be very easy to break. # -#requirepass REDIS_DEFAULT_PASSWORD +requirepass REDIS_DEFAULT_PASSWORD # Command renaming. # diff --git a/install/Docker/dockerfiles/scripts/redis-slave.conf b/install/Docker/dockerfiles/scripts/redis-slave.conf index 51012fafd..d259a8637 100644 --- a/install/Docker/dockerfiles/scripts/redis-slave.conf +++ b/install/Docker/dockerfiles/scripts/redis-slave.conf @@ -224,7 +224,7 @@ slaveof %master-ip% %master-port% # starting the replication synchronization process, otherwise the master will # refuse the slave request. # -#masterauth REDIS_DEFAULT_PASSWORD +masterauth REDIS_DEFAULT_PASSWORD # When a slave loses its connection with the master, or when the replication # is still in progress, the slave can act in two different ways: @@ -403,7 +403,7 @@ slave-priority 100 # 150k passwords per second against a good box. This means that you should # use a very strong password otherwise it will be very easy to break. # -#requirepass REDIS_DEFAULT_PASSWORD +requirepass REDIS_DEFAULT_PASSWORD # Command renaming. # diff --git a/lib-messagebus/datacommunicator/redisstreamcomm.go b/lib-messagebus/datacommunicator/redisstreamcomm.go index 23e78e336..ca18cca82 100644 --- a/lib-messagebus/datacommunicator/redisstreamcomm.go +++ b/lib-messagebus/datacommunicator/redisstreamcomm.go @@ -55,6 +55,8 @@ func getDBConnection() *redis.Client { dbConn = redis.NewClient(&redis.Options{ Addr: fmt.Sprintf("%s:%s", MQ.RedisStreams.RedisServerAddress, MQ.RedisStreams.RedisServerPort), TLSConfig: tlsConfig, + Password: string(config.Data.DBConf.RedisInMemoryPassword), + DB: 0, // use default DB }) } return dbConn diff --git a/lib-persistence-manager/persistencemgr/config.go b/lib-persistence-manager/persistencemgr/config.go index 891c613e9..b0c3bdfab 100644 --- a/lib-persistence-manager/persistencemgr/config.go +++ b/lib-persistence-manager/persistencemgr/config.go @@ -16,9 +16,10 @@ package persistencemgr import ( - "github.com/gomodule/redigo/redis" "sync" "time" + + "github.com/gomodule/redigo/redis" ) // Config is the configuration for db which is set by the wrapper package. @@ -33,6 +34,7 @@ type Config struct { Host string SentinelPort string MasterSet string + Password string } // ConnPool is the established connection diff --git a/lib-persistence-manager/persistencemgr/redis.go b/lib-persistence-manager/persistencemgr/redis.go index 746cab218..10708804e 100644 --- a/lib-persistence-manager/persistencemgr/redis.go +++ b/lib-persistence-manager/persistencemgr/redis.go @@ -153,7 +153,7 @@ func (p *ConnPool) setWritePool(config *Config) error { return fmt.Errorf("unable to retrieve master ip from sentinel master election") } log.Info("new write pool master IP found: " + currentMasterIP) - writePool, _ := getPool(currentMasterIP, currentMasterPort) + writePool, _ := getPool(currentMasterIP, currentMasterPort, config.Password) if writePool == nil { return fmt.Errorf("write pool creation failed") } @@ -182,6 +182,7 @@ func getInMemoryDBConfig() *Config { Host: config.Data.DBConf.InMemoryHost, SentinelPort: config.Data.DBConf.InMemorySentinelPort, MasterSet: config.Data.DBConf.InMemoryPrimarySet, + Password: string(config.Data.DBConf.RedisInMemoryPassword), } } @@ -192,6 +193,7 @@ func getOnDiskDBConfig() *Config { Host: config.Data.DBConf.OnDiskHost, SentinelPort: config.Data.DBConf.OnDiskSentinelPort, MasterSet: config.Data.DBConf.OnDiskPrimarySet, + Password: string(config.Data.DBConf.RedisOnDiskPassword), } } @@ -238,7 +240,7 @@ func GetDBConnection(dbFlag DbType) (*ConnPool, *errors.Error) { } //getPool is used is utility function to get the Connection Pool from DB. -func getPool(host, port string) (*redis.Pool, error) { +func getPool(host, port, password string) (*redis.Pool, error) { protocol := config.Data.DBConf.Protocol tlsConfig, err := getTLSConfig() if err != nil { @@ -255,6 +257,7 @@ func getPool(host, port string) (*redis.Pool, error) { c, err := redis.Dial(protocol, host+":"+port, redis.DialUseTLS(true), redis.DialTLSConfig(tlsConfig), + redis.DialPassword(password), ) return c, err }, @@ -304,7 +307,7 @@ func (c *Config) Connection() (*ConnPool, *errors.Error) { masterIP, masterPort = GetCurrentMasterHostPort(c) } - connPools.ReadPool, err = getPool(c.Host, c.Port) + connPools.ReadPool, err = getPool(c.Host, c.Port, c.Password) //Check if any connection error occured if err != nil { if errs, aye := isDbConnectError(err); aye { @@ -313,7 +316,7 @@ func (c *Config) Connection() (*ConnPool, *errors.Error) { } return nil, errors.PackError(errors.UndefinedErrorType, err) } - connPools.WritePool, err = getPool(masterIP, masterPort) + connPools.WritePool, err = getPool(masterIP, masterPort, c.Password) //Check if any connection error occured if err != nil { if errs, aye := isDbConnectError(err); aye { diff --git a/lib-persistence-manager/persistencemgr/unit_test_db_confighelp.go b/lib-persistence-manager/persistencemgr/unit_test_db_confighelp.go index 1ed67ee60..580b1e589 100644 --- a/lib-persistence-manager/persistencemgr/unit_test_db_confighelp.go +++ b/lib-persistence-manager/persistencemgr/unit_test_db_confighelp.go @@ -36,23 +36,25 @@ func MockDBConnection(t *testing.T) (*ConnPool, *errors.Error) { func GetMockDBConfig() (*Config, *errors.Error) { //Need to discuss more on this config.Data.DBConf = &config.DBConf{ - Protocol: config.DefaultDBProtocol, - OnDiskPort: "6380", - OnDiskHost: "localhost", - InMemoryHost: "localhost", - InMemoryPort: "6379", - RedisHAEnabled: false, - InMemorySentinelPort: "26379", - OnDiskSentinelPort: "26379", - InMemoryPrimarySet: "redisSentinel", - OnDiskPrimarySet: "redisSentinel", - MaxIdleConns: config.DefaultDBMaxIdleConns, - MaxActiveConns: config.DefaultDBMaxActiveConns, + Protocol: config.DefaultDBProtocol, + OnDiskPort: "6380", + OnDiskHost: "localhost", + InMemoryHost: "localhost", + InMemoryPort: "6379", + RedisHAEnabled: false, + InMemorySentinelPort: "26379", + OnDiskSentinelPort: "26379", + InMemoryPrimarySet: "redisSentinel", + OnDiskPrimarySet: "redisSentinel", + MaxIdleConns: config.DefaultDBMaxIdleConns, + MaxActiveConns: config.DefaultDBMaxActiveConns, + RedisInMemoryPassword: []byte("redis_password"), } config := &Config{ Port: config.Data.DBConf.InMemoryPort, Protocol: config.Data.DBConf.Protocol, Host: config.Data.DBConf.InMemoryHost, + Password: string(config.Data.DBConf.RedisInMemoryPassword), } return config, nil diff --git a/lib-utilities/common/mockconfig.go b/lib-utilities/common/mockconfig.go index c25454558..1a275ab48 100644 --- a/lib-utilities/common/mockconfig.go +++ b/lib-utilities/common/mockconfig.go @@ -16,9 +16,10 @@ package common import ( - "github.com/ODIM-Project/ODIM/lib-utilities/config" "os" "strings" + + "github.com/ODIM-Project/ODIM/lib-utilities/config" ) const localhost = "127.0.0.1" @@ -38,13 +39,15 @@ func SetUpMockConfig() error { } config.Data.RegistryStorePath = basePath + "/lib-utilities/etc/" config.Data.DBConf = &config.DBConf{ - InMemoryPort: "6379", - OnDiskPort: "6380", - Protocol: "tcp", - OnDiskHost: localhost, - InMemoryHost: localhost, - MaxIdleConns: 10, - MaxActiveConns: 120, + InMemoryPort: "6379", + OnDiskPort: "6380", + Protocol: "tcp", + OnDiskHost: localhost, + InMemoryHost: localhost, + MaxIdleConns: 10, + MaxActiveConns: 120, + RedisInMemoryPassword: []byte("redis_password"), + RedisOnDiskPassword: []byte("redis_password"), } config.Data.AuthConf = &config.AuthConf{ SessionTimeOutInMins: 30, diff --git a/lib-utilities/config/config.go b/lib-utilities/config/config.go index aab24c47a..8c3659e1b 100644 --- a/lib-utilities/config/config.go +++ b/lib-utilities/config/config.go @@ -16,7 +16,13 @@ package config import ( + "crypto/rand" + "crypto/rsa" + "crypto/sha512" + "crypto/x509" + "encoding/base64" "encoding/json" + "encoding/pem" "fmt" "io/ioutil" "os" @@ -62,18 +68,22 @@ type configModel struct { // DBConf holds all DB related configurations type DBConf struct { - Protocol string `json:"Protocol"` - InMemoryHost string `json:"InMemoryHost"` - InMemoryPort string `json:"InMemoryPort"` - OnDiskHost string `json:"OnDiskHost"` - OnDiskPort string `json:"OnDiskPort"` - MaxIdleConns int `json:"MaxIdleConns"` - MaxActiveConns int `json:"MaxActiveConns"` - RedisHAEnabled bool `json:"RedisHAEnabled"` - InMemorySentinelPort string `json:"InMemorySentinelPort"` - OnDiskSentinelPort string `json:"OnDiskSentinelPort"` - InMemoryPrimarySet string `json:"InMemoryPrimarySet"` - OnDiskPrimarySet string `json:"OnDiskPrimarySet"` + Protocol string `json:"Protocol"` + InMemoryHost string `json:"InMemoryHost"` + InMemoryPort string `json:"InMemoryPort"` + OnDiskHost string `json:"OnDiskHost"` + OnDiskPort string `json:"OnDiskPort"` + MaxIdleConns int `json:"MaxIdleConns"` + MaxActiveConns int `json:"MaxActiveConns"` + RedisHAEnabled bool `json:"RedisHAEnabled"` + InMemorySentinelPort string `json:"InMemorySentinelPort"` + OnDiskSentinelPort string `json:"OnDiskSentinelPort"` + InMemoryPrimarySet string `json:"InMemoryPrimarySet"` + OnDiskPrimarySet string `json:"OnDiskPrimarySet"` + RedisInMemoryPasswordFilePath string `json:"RedisInMemoryPasswordFilePath"` + RedisOnDiskPasswordFilePath string `json:"RedisOnDiskPasswordFilePath"` + RedisInMemoryPassword []byte + RedisOnDiskPassword []byte } // MessageBusConf holds all message bus configurations @@ -293,9 +303,57 @@ func checkDBConf() error { return err } } + var err error + if Data.DBConf.RedisInMemoryPasswordFilePath != "" && Data.KeyCertConf.RSAPrivateKeyPath != "" { + if Data.DBConf.RedisInMemoryPassword, err = decryptRSAOAEPEncryptedPasswords(Data.DBConf.RedisInMemoryPasswordFilePath); err != nil { + return fmt.Errorf("error: while decrypting password from the passwordFilePath:%s with %v", Data.DBConf.RedisInMemoryPasswordFilePath, err) + } + } + if Data.DBConf.RedisOnDiskPasswordFilePath != "" && Data.KeyCertConf.RSAPrivateKeyPath != "" { + if Data.DBConf.RedisOnDiskPassword, err = decryptRSAOAEPEncryptedPasswords(Data.DBConf.RedisOnDiskPasswordFilePath); err != nil { + return fmt.Errorf("error: while decrypting password from the passwordFilePath:%s with %v", Data.DBConf.RedisOnDiskPasswordFilePath, err) + } + } return nil } +func decryptRSAOAEPEncryptedPasswords(passwordFilePath string) ([]byte, error) { + privateKeyStr, err := ioutil.ReadFile(Data.KeyCertConf.RSAPrivateKeyPath) + if err != nil { + return nil, fmt.Errorf("value check failed for RSAPrivateKeyPath:%s with %v", Data.KeyCertConf.RSAPrivateKeyPath, err) + } + + block, _ := pem.Decode(privateKeyStr) + if block == nil { + return nil, fmt.Errorf("failed to parse PEM block containing the public key for the RSAPrivateKeyPath:%s", + Data.KeyCertConf.RSAPrivateKeyPath) + } + + privateKey, err := x509.ParsePKCS1PrivateKey(block.Bytes) + if err != nil { + return nil, fmt.Errorf("failed to parse DER encoded public key for the RSAPrivateKeyPath:%s with %v", + Data.KeyCertConf.RSAPrivateKeyPath, err) + } + + cipherText, err := ioutil.ReadFile(passwordFilePath) + if err != nil { + return nil, fmt.Errorf("value check failed for passwordFilePath:%s with %v", passwordFilePath, err) + } + + ct, err := base64.StdEncoding.DecodeString(string(cipherText)) + if err != nil { + return nil, fmt.Errorf("value check failed for passwordFilePath:%s with %v", passwordFilePath, err) + } + + rng := rand.Reader + password, err := rsa.DecryptOAEP(sha512.New(), rng, privateKey, ct, nil) + if err != nil { + return nil, fmt.Errorf("password decryption failed for the passwordFilePath:%s with %v", passwordFilePath, err) + } + + return password, nil +} + func checkMessageBusConf() error { if Data.MessageBusConf == nil { return fmt.Errorf("error: MessageBusConf is not provided") diff --git a/lib-utilities/config/config_test.go b/lib-utilities/config/config_test.go index 5202336d5..8d715a173 100644 --- a/lib-utilities/config/config_test.go +++ b/lib-utilities/config/config_test.go @@ -25,6 +25,66 @@ import ( const ( sampleFileContent = "A sample file for UT" sampleFileName = "file_for_ut.test" + rsaPrivateKey = `-----BEGIN RSA PRIVATE KEY----- +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 +-----END RSA PRIVATE KEY-----` + redisPassword = "F2n0YuRgavd/tYeanHI94cJR5r/C+FUaGQJBetQOxed1pLXxnWKAMmVLjs+jCBGq" + + "C66YfEZ+DK5ZIg9QmuQGEoahwSVWC+Pa8hNrqIDgBYXP4cyyEAE0XE0j8amyf049aqhxxTYXfzov5Km4t/" + + "Tzqru3CJ2CcUGzRmq1WfbfuMqx+tAZGw4UY1SW9IDoHwXaqsKld9uwiYq6lBqJpYzNGcCgrVyHwQg" + + "hTrYlypQocsDdVY7/bFzg3amIHdStmzF+mvpNolhtkgrXeq1ov7stepdgpzOF39Fe5DDO+OG53wyR" + + "4OMBAZ2NjX5LLQkhNEUpAA7GM8ajtOuJGecO506St2ASatcojJqRDHbIzNhzAxY3wtB0bx1S5TS1jl" + + "kW1VTFXqFNjnKd3j7Q/YZXJY5a+zX/PhIZLnCp+yWY2/qU7s4BZjex8jNRikFTRzhqDGfKP1hFar8" + + "qLr2D0FSRrDK4NtViUMUv5PaWygHtRk8e0fSnNhTSGv5kzr/fwEE4S/ayo5+9pqjgjr4iu+d6oRSq" + + "2dQVQIfdm25Lqfw8RnmeveVVKuQk7xT/T0pcKmwfYuN0R4UjJ44BiBXgI9e/pgVTHzOrzHfLT5ekk1" + + "eSx/fIuTMe38lxCD+L6mfhi4zsI/IkaQsjgvR70n5RlpsT8ndNLBtmfNS4NB3Ls2Cbp0AFyTY=" ) var cwdDir, _ = os.Getwd() @@ -37,11 +97,17 @@ func createFile(t *testing.T, fName, fContent string) { func TestSetConfiguration(t *testing.T) { var ( - sampleConfigFile = filepath.Join(cwdDir, "sample.json") - sampleTestFile = "/tmp/testFile.dat" + sampleConfigFile = filepath.Join(cwdDir, "sample.json") + sampleTestFile = "/tmp/testFile.dat" + sampleRSAPrivateKeyFile = "/tmp/rsa.private" + RedisInMemoryPasswordFilePath = "/tmp/redis_inmemory_password" + RedisOnDiskPasswordFilePath = "/tmp/redis_ondisk_password" ) createFile(t, sampleTestFile, sampleFileContent) + createFile(t, sampleRSAPrivateKeyFile, rsaPrivateKey) + createFile(t, RedisInMemoryPasswordFilePath, redisPassword) + createFile(t, RedisOnDiskPasswordFilePath, redisPassword) var sampleConfig = `{ "RootServiceUUID": "a9762fb2-b9dd-4ce8-818a-af6833ba19f6", @@ -53,7 +119,7 @@ func TestSetConfiguration(t *testing.T) { "RPCPrivateKeyPath": "/tmp/testFile.dat", "RPCCertificatePath": "/tmp/testFile.dat", "RSAPublicKeyPath": "/tmp/testFile.dat", - "RSAPrivateKeyPath": "/tmp/testFile.dat" + "RSAPrivateKeyPath": "/tmp/rsa.private" }, "APIGatewayConf": { "Host": "localhost", @@ -68,7 +134,9 @@ func TestSetConfiguration(t *testing.T) { "OnDiskHost": "localhost", "OnDiskPort": "6380", "MaxIdleConns": 10, - "MaxActiveConns": 120 + "MaxActiveConns": 120, + "RedisInMemoryPasswordFilePath": "/tmp/redis_inmemory_password", + "RedisOnDiskPasswordFilePath": "/tmp/redis_ondisk_password" }, "MessageBusConf": { "MessageBusConfigFilePath": "/tmp/testFile.dat", @@ -205,6 +273,9 @@ func TestSetConfiguration(t *testing.T) { os.Remove(sampleConfigFile) os.Remove(sampleConfigFile) os.Remove(sampleTestFile) + os.Remove(sampleRSAPrivateKeyFile) + os.Remove(RedisInMemoryPasswordFilePath) + os.Remove(RedisOnDiskPasswordFilePath) } func TestValidateConfigurationGroup1(t *testing.T) { diff --git a/lib-utilities/config/mockconfig.go b/lib-utilities/config/mockconfig.go index efcab916a..0c3020cc3 100644 --- a/lib-utilities/config/mockconfig.go +++ b/lib-utilities/config/mockconfig.go @@ -235,13 +235,15 @@ func SetUpMockConfig(t *testing.T) error { Data.LocalhostFQDN = "odim.test.com" Data.EnabledServices = []string{"SessionService", "AccountService", "EventService"} Data.DBConf = &DBConf{ - Protocol: "tcp", - InMemoryHost: localhost, - InMemoryPort: "6379", - OnDiskHost: localhost, - OnDiskPort: "6380", - MaxIdleConns: 10, - MaxActiveConns: 120, + Protocol: "tcp", + InMemoryHost: localhost, + InMemoryPort: "6379", + OnDiskHost: localhost, + OnDiskPort: "6380", + MaxIdleConns: 10, + MaxActiveConns: 120, + RedisInMemoryPassword: []byte("redis_password"), + RedisOnDiskPassword: []byte("redis_password"), } Data.MessageBusConf = &MessageBusConf{ MessageBusType: "Kafka", diff --git a/odim-controller/helmcharts/account-session/templates/deployment.yaml b/odim-controller/helmcharts/account-session/templates/deployment.yaml index 035eeac0f..7625965fc 100644 --- a/odim-controller/helmcharts/account-session/templates/deployment.yaml +++ b/odim-controller/helmcharts/account-session/templates/deployment.yaml @@ -59,6 +59,12 @@ spec: - key: odimra_rsaprivate path: odimra_rsa.private mode: 0444 + - key: redis_inmemory_password + path: redis_inmemory_password + mode: 0444 + - key: redis_ondisk_password + path: redis_ondisk_password + mode: 0444 {{- if eq .Values.odimra.messageBusType "Kafka" }} - key: odimra_kafka_clientcrt path: odimra_kafka_client.crt diff --git a/odim-controller/helmcharts/aggregation/templates/deployment.yaml b/odim-controller/helmcharts/aggregation/templates/deployment.yaml index cb277f8ec..c65261d59 100644 --- a/odim-controller/helmcharts/aggregation/templates/deployment.yaml +++ b/odim-controller/helmcharts/aggregation/templates/deployment.yaml @@ -59,6 +59,12 @@ spec: - key: odimra_rsaprivate path: odimra_rsa.private mode: 0444 + - key: redis_inmemory_password + path: redis_inmemory_password + mode: 0444 + - key: redis_ondisk_password + path: redis_ondisk_password + mode: 0444 {{- if eq .Values.odimra.messageBusType "Kafka" }} - key: odimra_kafka_clientcrt path: odimra_kafka_client.crt diff --git a/odim-controller/helmcharts/api/templates/deployment.yaml b/odim-controller/helmcharts/api/templates/deployment.yaml index b8783da42..ec1c03d59 100644 --- a/odim-controller/helmcharts/api/templates/deployment.yaml +++ b/odim-controller/helmcharts/api/templates/deployment.yaml @@ -59,6 +59,12 @@ spec: - key: odimra_rsaprivate path: odimra_rsa.private mode: 0444 + - key: redis_inmemory_password + path: redis_inmemory_password + mode: 0444 + - key: redis_ondisk_password + path: redis_ondisk_password + mode: 0444 {{- if eq .Values.odimra.messageBusType "Kafka" }} - key: odimra_kafka_clientcrt path: odimra_kafka_client.crt diff --git a/odim-controller/helmcharts/events/templates/deployment.yaml b/odim-controller/helmcharts/events/templates/deployment.yaml index 4e6647e3d..64eece241 100644 --- a/odim-controller/helmcharts/events/templates/deployment.yaml +++ b/odim-controller/helmcharts/events/templates/deployment.yaml @@ -59,6 +59,12 @@ spec: - key: odimra_rsaprivate path: odimra_rsa.private mode: 0444 + - key: redis_inmemory_password + path: redis_inmemory_password + mode: 0444 + - key: redis_ondisk_password + path: redis_ondisk_password + mode: 0444 {{- if eq .Values.odimra.messageBusType "Kafka" }} - key: odimra_kafka_clientcrt path: odimra_kafka_client.crt diff --git a/odim-controller/helmcharts/fabrics/templates/deployment.yaml b/odim-controller/helmcharts/fabrics/templates/deployment.yaml index 9a0fe7d75..20348ca2c 100644 --- a/odim-controller/helmcharts/fabrics/templates/deployment.yaml +++ b/odim-controller/helmcharts/fabrics/templates/deployment.yaml @@ -59,6 +59,12 @@ spec: - key: odimra_rsaprivate path: odimra_rsa.private mode: 0444 + - key: redis_inmemory_password + path: redis_inmemory_password + mode: 0444 + - key: redis_ondisk_password + path: redis_ondisk_password + mode: 0444 {{- if eq .Values.odimra.messageBusType "Kafka" }} - key: odimra_kafka_clientcrt path: odimra_kafka_client.crt diff --git a/odim-controller/helmcharts/licenses/templates/deployment.yaml b/odim-controller/helmcharts/licenses/templates/deployment.yaml index 29d8df293..40d647f75 100644 --- a/odim-controller/helmcharts/licenses/templates/deployment.yaml +++ b/odim-controller/helmcharts/licenses/templates/deployment.yaml @@ -59,6 +59,12 @@ spec: - key: odimra_rsaprivate path: odimra_rsa.private mode: 0444 + - key: redis_inmemory_password + path: redis_inmemory_password + mode: 0444 + - key: redis_ondisk_password + path: redis_ondisk_password + mode: 0444 {{- if eq .Values.odimra.messageBusType "Kafka" }} - key: odimra_kafka_clientcrt path: odimra_kafka_client.crt diff --git a/odim-controller/helmcharts/managers/templates/deployment.yaml b/odim-controller/helmcharts/managers/templates/deployment.yaml index 39eb564ce..52fd51f6b 100644 --- a/odim-controller/helmcharts/managers/templates/deployment.yaml +++ b/odim-controller/helmcharts/managers/templates/deployment.yaml @@ -59,6 +59,12 @@ spec: - key: odimra_rsaprivate path: odimra_rsa.private mode: 0444 + - key: redis_inmemory_password + path: redis_inmemory_password + mode: 0444 + - key: redis_ondisk_password + path: redis_ondisk_password + mode: 0444 {{- if eq .Values.odimra.messageBusType "Kafka" }} - key: odimra_kafka_clientcrt path: odimra_kafka_client.crt diff --git a/odim-controller/helmcharts/odimra-config/templates/configmaps.yaml b/odim-controller/helmcharts/odimra-config/templates/configmaps.yaml index e22cbd4c3..7b5b01f1a 100755 --- a/odim-controller/helmcharts/odimra-config/templates/configmaps.yaml +++ b/odim-controller/helmcharts/odimra-config/templates/configmaps.yaml @@ -31,6 +31,8 @@ data: }, "DBConf": { "Protocol": "tcp", + "RedisInMemoryPasswordFilePath": "/etc/odimra_certs/redis_inmemory_password", + "RedisOnDiskPasswordFilePath": "/etc/odimra_certs/redis_ondisk_password", {{ if eq .Values.odimra.haDeploymentEnabled false }} "InMemoryHost": "redis-inmemory", "OnDiskHost": "redis-ondisk", diff --git a/odim-controller/helmcharts/odimra-secret/templates/secret.yaml b/odim-controller/helmcharts/odimra-secret/templates/secret.yaml index 7bb9777c3..fba26025c 100644 --- a/odim-controller/helmcharts/odimra-secret/templates/secret.yaml +++ b/odim-controller/helmcharts/odimra-secret/templates/secret.yaml @@ -10,6 +10,8 @@ type: Opaque data: rootCAcrt: {{ .Values.odimra.rootCACert | b64enc }} odimra_servercrt: {{ .Values.odimra.odimraServerCert | b64enc }} + redis_inmemory_password: {{ .Values.odimra.redisInMemoryPassword | b64enc }} + redis_ondisk_password: {{ .Values.odimra.redisOnDiskPassword | b64enc }} odimra_serverkey: {{ .Values.odimra.odimraServerKey | b64enc }} odimra_rsapublic: {{ .Values.odimra.odimraRSAPublicKey | b64enc }} odimra_rsaprivate: {{ .Values.odimra.odimraRSAPrivateKey | b64enc }} diff --git a/odim-controller/helmcharts/odimra-secret/values.yaml b/odim-controller/helmcharts/odimra-secret/values.yaml index fe4237ea0..a09890e20 100644 --- a/odim-controller/helmcharts/odimra-secret/values.yaml +++ b/odim-controller/helmcharts/odimra-secret/values.yaml @@ -9,3 +9,5 @@ odimra: odimraKafkaClientKey: odimraEtcdServerCert: odimraEtcdServerKey: + redisInMemoryPassword: + redisOnDiskPassword: diff --git a/odim-controller/helmcharts/redis-ha/templates/redis-ha-inmemory-primary-statefulset.yaml b/odim-controller/helmcharts/redis-ha/templates/redis-ha-inmemory-primary-statefulset.yaml index 8f9c3abf9..16ad9af02 100644 --- a/odim-controller/helmcharts/redis-ha/templates/redis-ha-inmemory-primary-statefulset.yaml +++ b/odim-controller/helmcharts/redis-ha/templates/redis-ha-inmemory-primary-statefulset.yaml @@ -43,6 +43,12 @@ spec: - key: odimra_rsaprivate path: odimra_rsa.private mode: 0444 + - key: redis_inmemory_password + path: redis_inmemory_password + mode: 0444 + - key: redis_ondisk_password + path: redis_ondisk_password + mode: 0444 {{- if eq .Values.odimra.messageBusType "Kafka" }} - key: odimra_kafka_clientcrt path: odimra_kafka_client.crt @@ -102,7 +108,9 @@ spec: - name: REDIS_HA_REDIS_SERVICE_PORT value: "6379" - name: REDIS_DEFAULT_PASSWORD - value: "" + value: {{ .Values.odimra.redisInMemoryPassword }} + - name: ODIMRA_RSA_PRIVATE_FILE + value: "/etc/odimra_certs/odimra_rsa.private" - name: REDIS_HA_SENTINEL_SERVICE_PORT value: "26379" - name: REDIS_HA_SENTINEL_SERVICE_HOST @@ -136,7 +144,9 @@ spec: - name: REDIS_HA_REDIS_SERVICE_PORT value: "6379" - name: REDIS_DEFAULT_PASSWORD - value: "" + value: {{ .Values.odimra.redisInMemoryPassword }} + - name: ODIMRA_RSA_PRIVATE_FILE + value: "/etc/odimra_certs/odimra_rsa.private" - name: REDIS_HA_SENTINEL_SERVICE_PORT value: "26379" - name: REDIS_HA_SENTINEL_SERVICE_HOST diff --git a/odim-controller/helmcharts/redis-ha/templates/redis-ha-inmemory-secondary-statefulset.yaml b/odim-controller/helmcharts/redis-ha/templates/redis-ha-inmemory-secondary-statefulset.yaml index 57109a207..be712c3e2 100644 --- a/odim-controller/helmcharts/redis-ha/templates/redis-ha-inmemory-secondary-statefulset.yaml +++ b/odim-controller/helmcharts/redis-ha/templates/redis-ha-inmemory-secondary-statefulset.yaml @@ -43,6 +43,12 @@ spec: - key: odimra_rsaprivate path: odimra_rsa.private mode: 0444 + - key: redis_inmemory_password + path: redis_inmemory_password + mode: 0444 + - key: redis_ondisk_password + path: redis_ondisk_password + mode: 0444 {{- if eq .Values.odimra.messageBusType "Kafka" }} - key: odimra_kafka_clientcrt path: odimra_kafka_client.crt @@ -102,7 +108,9 @@ spec: - name: REDIS_HA_REDIS_SERVICE_PORT value: "6379" - name: REDIS_DEFAULT_PASSWORD - value: "" + value: {{ .Values.odimra.redisInMemoryPassword }} + - name: ODIMRA_RSA_PRIVATE_FILE + value: "/etc/odimra_certs/odimra_rsa.private" - name: REDIS_HA_SENTINEL_SERVICE_PORT value: "26379" - name: REDIS_HA_SENTINEL_SERVICE_HOST @@ -136,7 +144,9 @@ spec: - name: REDIS_HA_REDIS_SERVICE_PORT value: "6379" - name: REDIS_DEFAULT_PASSWORD - value: "" + value: {{ .Values.odimra.redisInMemoryPassword }} + - name: ODIMRA_RSA_PRIVATE_FILE + value: "/etc/odimra_certs/odimra_rsa.private" - name: REDIS_HA_SENTINEL_SERVICE_PORT value: "26379" - name: REDIS_HA_SENTINEL_SERVICE_HOST diff --git a/odim-controller/helmcharts/redis-ha/templates/redis-ha-ondisk-primary-statefulset.yaml b/odim-controller/helmcharts/redis-ha/templates/redis-ha-ondisk-primary-statefulset.yaml index 364f3f97f..e2e368bd9 100644 --- a/odim-controller/helmcharts/redis-ha/templates/redis-ha-ondisk-primary-statefulset.yaml +++ b/odim-controller/helmcharts/redis-ha/templates/redis-ha-ondisk-primary-statefulset.yaml @@ -46,6 +46,12 @@ spec: - key: odimra_rsaprivate path: odimra_rsa.private mode: 0444 + - key: redis_inmemory_password + path: redis_inmemory_password + mode: 0444 + - key: redis_ondisk_password + path: redis_ondisk_password + mode: 0444 {{- if eq .Values.odimra.messageBusType "Kafka" }} - key: odimra_kafka_clientcrt path: odimra_kafka_client.crt @@ -106,7 +112,9 @@ spec: - name: REDIS_HA_REDIS_SERVICE_PORT value: "6379" - name: REDIS_DEFAULT_PASSWORD - value: "" + value: {{ .Values.odimra.redisOnDiskPassword }} + - name: ODIMRA_RSA_PRIVATE_FILE + value: "/etc/odimra_certs/odimra_rsa.private" - name: REDIS_HA_SENTINEL_SERVICE_PORT value: "26379" - name: REDIS_HA_SENTINEL_SERVICE_HOST @@ -139,7 +147,9 @@ spec: - name: REDIS_HA_REDIS_SERVICE_PORT value: "6379" - name: REDIS_DEFAULT_PASSWORD - value: "" + value: {{ .Values.odimra.redisOnDiskPassword }} + - name: ODIMRA_RSA_PRIVATE_FILE + value: "/etc/odimra_certs/odimra_rsa.private" - name: REDIS_HA_SENTINEL_SERVICE_PORT value: "26379" - name: REDIS_HA_SENTINEL_SERVICE_HOST diff --git a/odim-controller/helmcharts/redis-ha/templates/redis-ha-ondisk-secondary-statefulset.yaml b/odim-controller/helmcharts/redis-ha/templates/redis-ha-ondisk-secondary-statefulset.yaml index 4fea2ffff..bfed39d5a 100644 --- a/odim-controller/helmcharts/redis-ha/templates/redis-ha-ondisk-secondary-statefulset.yaml +++ b/odim-controller/helmcharts/redis-ha/templates/redis-ha-ondisk-secondary-statefulset.yaml @@ -46,6 +46,12 @@ spec: - key: odimra_rsaprivate path: odimra_rsa.private mode: 0444 + - key: redis_inmemory_password + path: redis_inmemory_password + mode: 0444 + - key: redis_ondisk_password + path: redis_ondisk_password + mode: 0444 {{- if eq .Values.odimra.messageBusType "Kafka" }} - key: odimra_kafka_clientcrt path: odimra_kafka_client.crt @@ -106,7 +112,9 @@ spec: - name: REDIS_HA_REDIS_SERVICE_PORT value: "6379" - name: REDIS_DEFAULT_PASSWORD - value: "" + value: {{ .Values.odimra.redisOnDiskPassword }} + - name: ODIMRA_RSA_PRIVATE_FILE + value: "/etc/odimra_certs/odimra_rsa.private" - name: REDIS_HA_SENTINEL_SERVICE_PORT value: "26379" - name: REDIS_HA_SENTINEL_SERVICE_HOST @@ -140,7 +148,9 @@ spec: - name: REDIS_HA_REDIS_SERVICE_PORT value: "6379" - name: REDIS_DEFAULT_PASSWORD - value: "" + value: {{ .Values.odimra.redisOnDiskPassword }} + - name: ODIMRA_RSA_PRIVATE_FILE + value: "/etc/odimra_certs/odimra_rsa.private" - name: ALLOW_EMPTY_PASSWORD value: "yes" - name: REDIS_HA_SENTINEL_SERVICE_PORT diff --git a/odim-controller/helmcharts/redis-ha/values.yaml b/odim-controller/helmcharts/redis-ha/values.yaml index f784ae49c..4584718cd 100644 --- a/odim-controller/helmcharts/redis-ha/values.yaml +++ b/odim-controller/helmcharts/redis-ha/values.yaml @@ -10,3 +10,5 @@ odimra: redisDownAfterMilliseconds: 1000 redisFailoverTimeout: 3000 redisParallelSyncs: 1 + redisInMemoryPassword: + redisOnDiskPassword: diff --git a/odim-controller/helmcharts/redis/templates/redis-inmemory-statefulset.yaml b/odim-controller/helmcharts/redis/templates/redis-inmemory-statefulset.yaml index 7840e8ac9..c4cc270aa 100644 --- a/odim-controller/helmcharts/redis/templates/redis-inmemory-statefulset.yaml +++ b/odim-controller/helmcharts/redis/templates/redis-inmemory-statefulset.yaml @@ -41,6 +41,12 @@ spec: - key: odimra_rsaprivate path: odimra_rsa.private mode: 0444 + - key: redis_inmemory_password + path: redis_inmemory_password + mode: 0444 + - key: redis_ondisk_password + path: redis_ondisk_password + mode: 0444 {{- if eq .Values.odimra.messageBusType "Kafka" }} - key: odimra_kafka_clientcrt path: odimra_kafka_client.crt @@ -80,7 +86,9 @@ spec: - name: REDIS_HA_REDIS_SERVICE_PORT value: "6379" - name: REDIS_DEFAULT_PASSWORD - value: "" + value: {{ .Values.odimra.redisInMemoryPassword }} + - name: ODIMRA_RSA_PRIVATE_FILE + value: "/etc/odimra_certs/odimra_rsa.private" - name: ALLOW_EMPTY_PASSWORD value: "yes" - name: REDIS_HA_SENTINEL_SERVICE_PORT diff --git a/odim-controller/helmcharts/redis/templates/redis-ondisk-statefulset.yaml b/odim-controller/helmcharts/redis/templates/redis-ondisk-statefulset.yaml index 97c3d9e8d..613f698f2 100644 --- a/odim-controller/helmcharts/redis/templates/redis-ondisk-statefulset.yaml +++ b/odim-controller/helmcharts/redis/templates/redis-ondisk-statefulset.yaml @@ -41,6 +41,12 @@ spec: - key: odimra_rsaprivate path: odimra_rsa.private mode: 0444 + - key: redis_inmemory_password + path: redis_inmemory_password + mode: 0444 + - key: redis_ondisk_password + path: redis_ondisk_password + mode: 0444 {{- if eq .Values.odimra.messageBusType "Kafka" }} - key: odimra_kafka_clientcrt path: odimra_kafka_client.crt @@ -80,7 +86,9 @@ spec: - name: REDIS_HA_REDIS_SERVICE_PORT value: "6379" - name: REDIS_DEFAULT_PASSWORD - value: "" + value: {{ .Values.odimra.redisOnDiskPassword }} + - name: ODIMRA_RSA_PRIVATE_FILE + value: "/etc/odimra_certs/odimra_rsa.private" - name: ALLOW_EMPTY_PASSWORD value: "yes" - name: REDIS_HA_SENTINEL_SERVICE_PORT diff --git a/odim-controller/helmcharts/redis/values.yaml b/odim-controller/helmcharts/redis/values.yaml index 968e40c90..0f574e17a 100644 --- a/odim-controller/helmcharts/redis/values.yaml +++ b/odim-controller/helmcharts/redis/values.yaml @@ -2,3 +2,5 @@ odimra: namespace: groupID: redisImageTag: "2.1" + redisInMemoryPassword: + redisOnDiskPassword: diff --git a/odim-controller/helmcharts/systems/templates/deployment.yaml b/odim-controller/helmcharts/systems/templates/deployment.yaml index 7be6e1b6c..fe9908b6c 100644 --- a/odim-controller/helmcharts/systems/templates/deployment.yaml +++ b/odim-controller/helmcharts/systems/templates/deployment.yaml @@ -59,6 +59,12 @@ spec: - key: odimra_rsaprivate path: odimra_rsa.private mode: 0444 + - key: redis_inmemory_password + path: redis_inmemory_password + mode: 0444 + - key: redis_ondisk_password + path: redis_ondisk_password + mode: 0444 {{- if eq .Values.odimra.messageBusType "Kafka" }} - key: odimra_kafka_clientcrt path: odimra_kafka_client.crt diff --git a/odim-controller/helmcharts/task/templates/deployment.yaml b/odim-controller/helmcharts/task/templates/deployment.yaml index ebe6fea7c..e0cec9db5 100644 --- a/odim-controller/helmcharts/task/templates/deployment.yaml +++ b/odim-controller/helmcharts/task/templates/deployment.yaml @@ -59,6 +59,12 @@ spec: - key: odimra_rsaprivate path: odimra_rsa.private mode: 0444 + - key: redis_inmemory_password + path: redis_inmemory_password + mode: 0444 + - key: redis_ondisk_password + path: redis_ondisk_password + mode: 0444 {{- if eq .Values.odimra.messageBusType "Kafka" }} - key: odimra_kafka_clientcrt path: odimra_kafka_client.crt diff --git a/odim-controller/helmcharts/telemetry/templates/deployment.yaml b/odim-controller/helmcharts/telemetry/templates/deployment.yaml index 6df78adb6..215c6d0af 100644 --- a/odim-controller/helmcharts/telemetry/templates/deployment.yaml +++ b/odim-controller/helmcharts/telemetry/templates/deployment.yaml @@ -59,6 +59,12 @@ spec: - key: odimra_rsaprivate path: odimra_rsa.private mode: 0444 + - key: redis_inmemory_password + path: redis_inmemory_password + mode: 0444 + - key: redis_ondisk_password + path: redis_ondisk_password + mode: 0444 {{- if eq .Values.odimra.messageBusType "Kafka" }} - key: odimra_kafka_clientcrt path: odimra_kafka_client.crt diff --git a/odim-controller/helmcharts/update/templates/deployment.yaml b/odim-controller/helmcharts/update/templates/deployment.yaml index 7aa0cfc1b..1b57ddfee 100644 --- a/odim-controller/helmcharts/update/templates/deployment.yaml +++ b/odim-controller/helmcharts/update/templates/deployment.yaml @@ -59,6 +59,12 @@ spec: - key: odimra_rsaprivate path: odimra_rsa.private mode: 0444 + - key: redis_inmemory_password + path: redis_inmemory_password + mode: 0444 + - key: redis_ondisk_password + path: redis_ondisk_password + mode: 0444 {{- if eq .Values.odimra.messageBusType "Kafka" }} - key: odimra_kafka_clientcrt path: odimra_kafka_client.crt diff --git a/odim-controller/scripts/gen_odimra_certs.sh b/odim-controller/scripts/gen_odimra_certs.sh index 54952b2e7..0b0903c73 100644 --- a/odim-controller/scripts/gen_odimra_certs.sh +++ b/odim-controller/scripts/gen_odimra_certs.sh @@ -46,6 +46,7 @@ declare ODIMRA_VIRTUAL_IP declare NGINX_SERVER_CSR_PATH declare NGINX_SERVER_CRT_PATH declare NGINX_SERVER_KEY_PATH +declare REDIS_PASSWORD_FILE_PATH declare ODIMRA_MESSAGE_BUS_TYPE OPENSSL_BIN_PATH="/usr/bin/openssl" @@ -632,6 +633,10 @@ EOF chmod 0600 ${NGINX_SERVER_KEY_PATH} ${NGINX_SERVER_CRT_PATH} } +generate_redis_password() { + echo -n "redis_password" > ${REDIS_PASSWORD_FILE_PATH} +} + # read_config_value parses the config file # and fetches the value of the parameter passed read_config_value() @@ -736,6 +741,7 @@ read_config_file() NGINX_SERVER_CSR_PATH=${ODIMRA_CERT_DIR}/nginx_server.csr NGINX_SERVER_CRT_PATH=${ODIMRA_CERT_DIR}/nginx_server.crt NGINX_SERVER_KEY_PATH=${ODIMRA_CERT_DIR}/nginx_server.key + REDIS_PASSWORD_FILE_PATH=${ODIMRA_CERT_DIR}/redis_password } # validate_config_params is for validating @@ -853,6 +859,7 @@ generate_certs() generate_zookeeper_certs generate_etcd_certs generate_nginx_certs + generate_redis_password #create a temp file, to indicate certs were generated by this script touch ${ODIMRA_CERT_DIR}/.gen_odimra_certs.ok diff --git a/odim-controller/scripts/kube_deploy_nodes.yaml.tmpl b/odim-controller/scripts/kube_deploy_nodes.yaml.tmpl index ebfea30c2..2b04858eb 100644 --- a/odim-controller/scripts/kube_deploy_nodes.yaml.tmpl +++ b/odim-controller/scripts/kube_deploy_nodes.yaml.tmpl @@ -40,6 +40,8 @@ odimCertsPath: kubernetesImagePath: odimraImagePath: odimPluginPath: +redisInMemoryPasswordFilePath: +redisOnDiskPasswordFilePath: odimra: groupID: 2021 userID: 2021 diff --git a/odim-controller/scripts/odim-controller.py b/odim-controller/scripts/odim-controller.py index 8fd53d4e5..8c25fee8f 100755 --- a/odim-controller/scripts/odim-controller.py +++ b/odim-controller/scripts/odim-controller.py @@ -18,6 +18,12 @@ import os, sys, subprocess, grp, time import glob, shutil, copy, getpass, socket +import base64 +from cryptography.hazmat.primitives import hashes +from cryptography.hazmat.primitives.asymmetric import padding +from cryptography.hazmat.primitives.asymmetric.rsa import RSAPrivateKey +from cryptography.hazmat.primitives.serialization import load_pem_private_key + from yaml import SafeDumper from Crypto.PublicKey import RSA from os import path @@ -44,6 +50,8 @@ K8S_INVENTORY_FILE = "" ODIMRA_VAULT_KEY_FILE = "" ANSIBLE_SUDO_PW_FILE = "" +REDIS_INMEMORY_PW_FILE = "" +REDIS_ONDISK_PW_FILE = "" ANSIBLE_BECOME_PASS = "" DEPLOYMENT_ID = "" ODIMRA_SRC_PATH = "" @@ -160,6 +168,7 @@ def perform_checks(skip_opt_param_check=False): global CONTROLLER_BASE_PATH, ANSIBLE_SUDO_PW_FILE, DEPLOYMENT_SRC_DIR, ODIMRA_SRC_PATH global ODIMRA_VAULT_BIN, ODIMRA_VAULT_KEY_FILE global KUBERNETES_IMAGE_PATH, ODIMRA_IMAGE_PATH + global REDIS_INMEMORY_PW_FILE, REDIS_ONDISK_PW_FILE if 'deploymentID' not in CONTROLLER_CONF_DATA or CONTROLLER_CONF_DATA['deploymentID'] == None or CONTROLLER_CONF_DATA['deploymentID'] == "": logger.critical("deployment ID not configured, exiting!!!") @@ -226,6 +235,26 @@ def perform_checks(skip_opt_param_check=False): if not os.path.exists(ANSIBLE_SUDO_PW_FILE): logger.critical("%s does not exist, exiting!!!", ANSIBLE_SUDO_PW_FILE) + if 'redisInMemoryPasswordFilePath' not in CONTROLLER_CONF_DATA or \ + CONTROLLER_CONF_DATA['redisInMemoryPasswordFilePath'] == None or CONTROLLER_CONF_DATA['redisInMemoryPasswordFilePath'] == "": + REDIS_INMEMORY_PW_FILE = os.path.join(KUBESPRAY_SRC_PATH, 'inventory/k8s_cluster-' + DEPLOYMENT_ID, '.redis_in_memory_pw.dat') + if not os.path.exists(REDIS_INMEMORY_PW_FILE): + store_redis_password_in_vault(REDIS_INMEMORY_PW_FILE, "in_memory") + else: + REDIS_INMEMORY_PW_FILE = CONTROLLER_CONF_DATA['redisInMemoryPasswordFilePath'] + if not os.path.exists(REDIS_INMEMORY_PW_FILE): + logger.critical("%s does not exist, exiting!!!", REDIS_INMEMORY_PW_FILE) + + if 'redisOnDiskPasswordFilePath' not in CONTROLLER_CONF_DATA or \ + CONTROLLER_CONF_DATA['redisOnDiskPasswordFilePath'] == None or CONTROLLER_CONF_DATA['redisOnDiskPasswordFilePath'] == "": + REDIS_ONDISK_PW_FILE = os.path.join(KUBESPRAY_SRC_PATH, 'inventory/k8s_cluster-' + DEPLOYMENT_ID, '.redis_on_disk_pw.dat') + if not os.path.exists(REDIS_ONDISK_PW_FILE): + store_redis_password_in_vault(REDIS_ONDISK_PW_FILE, "on_disk") + else: + REDIS_ONDISK_PW_FILE = CONTROLLER_CONF_DATA['redisOnDiskPasswordFilePath'] + if not os.path.exists(REDIS_ONDISK_PW_FILE): + logger.critical("%s does not exist, exiting!!!", REDIS_ONDISK_PW_FILE) + cert_dir = os.path.join(CONTROLLER_SRC_PATH, 'certs') if not os.path.exists(cert_dir): os.mkdir(cert_dir, 0o700) @@ -800,6 +829,7 @@ def load_odimra_certs(isUpgrade): CONTROLLER_CONF_DATA['odimra']['rootCACert'] = read_file(os.path.join(cert_dir, 'rootCA.crt')) CONTROLLER_CONF_DATA['odimra']['odimraServerCert'] = read_file(os.path.join(cert_dir, 'odimra_server.crt')) CONTROLLER_CONF_DATA['odimra']['odimraServerKey'] = read_file(os.path.join(cert_dir, 'odimra_server.key')) + CONTROLLER_CONF_DATA['odimra']['redisPassword'] = read_file(os.path.join(cert_dir, 'redis_password')) if CONTROLLER_CONF_DATA['odimra']['messageBusType'] == 'RedisStreams': logger.info("RedisStreams is selected as messageBusType") else: @@ -822,9 +852,33 @@ def load_odimra_certs(isUpgrade): with open(CONTROLLER_CONF_FILE, 'w') as f: yaml.safe_dump(CONTROLLER_CONF_DATA, f, default_flow_style=False) +def load_redis_passwords(cur_dir): + redis_inmemory_pwd = get_password_from_vault(cur_dir, REDIS_INMEMORY_PW_FILE) + redis_ondisk_pwd = get_password_from_vault(cur_dir, REDIS_ONDISK_PW_FILE) + CONTROLLER_CONF_DATA['odimra']['redisInMemoryPassword'] = rsa_oaep_ecryption(redis_inmemory_pwd) + CONTROLLER_CONF_DATA['odimra']['redisOnDiskPassword'] = rsa_oaep_ecryption(redis_ondisk_pwd) + +def rsa_oaep_ecryption(password): + cert_dir = CONTROLLER_CONF_DATA['odimCertsPath'] + PRIVATE_KEY = read_file(os.path.join(cert_dir, 'odimra_rsa.private')) + private_key_bytes = PRIVATE_KEY.encode("utf-8") + private_key: RSAPrivateKey = load_pem_private_key(private_key_bytes, None) + + public_key = private_key.public_key() + password_bytes = bytes(password, "utf-8") + ciphertext = public_key.encrypt( + password_bytes, + padding.OAEP( + mgf=padding.MGF1(algorithm=hashes.SHA512()), + algorithm=hashes.SHA512(), + label=None + ) + ) + return base64.b64encode(ciphertext).decode("utf-8") + # perform pre-requisites required for # deploying ODIM-RA services -def perform_odimra_deploy_prereqs(): +def perform_odimra_deploy_prereqs(cur_dir): if 'odimCertsPath' not in CONTROLLER_CONF_DATA or \ CONTROLLER_CONF_DATA['odimCertsPath'] == None or \ CONTROLLER_CONF_DATA['odimCertsPath'] == "": @@ -843,7 +897,7 @@ def perform_odimra_deploy_prereqs(): if not os.path.isdir(CONTROLLER_CONF_DATA['odimCertsPath']): logger.critical("ODIM-RA certificates path does not exist") exit(1) - + load_redis_passwords(cur_dir) load_odimra_certs(False) # perform pre-requisites for HA deployment @@ -903,7 +957,7 @@ def operation_odimra(operation): if operation == "install": helm_config_file = os.path.join(ODIMRA_SRC_PATH, 'roles/pre-install/files/helmcharts/helm_config_values.yaml') odimra_config_file = os.path.join(ODIMRA_SRC_PATH, 'roles/odimra-copy-image/files/odimra_config_values.yaml') - perform_odimra_deploy_prereqs() + perform_odimra_deploy_prereqs(cur_dir) elif operation == "uninstall": helm_config_file = os.path.join(ODIMRA_SRC_PATH, 'roles/post-uninstall/files/odim_controller_config.yaml') odimra_config_file = os.path.join(ODIMRA_SRC_PATH, 'roles/odimra-delete-image/files/odimra_config_values.yaml') @@ -1098,6 +1152,25 @@ def store_password_in_vault(): ANSIBLE_BECOME_PASS = first_pw +def store_redis_password_in_vault(REDIS_PW_FILE_PATH, redis_db_name): + print("\nProvide password of the redis " + redis_db_name + " db") + pw_from_prompt = lambda: (getpass.getpass('Enter Password: '), getpass.getpass('Confirm Password: ')) + first_pw, second_pw = pw_from_prompt() + if first_pw != second_pw: + logger.critical("Passwords provided do not match") + exit(1) + + fd = open(REDIS_PW_FILE_PATH, "wb") + fd.write(first_pw.encode('utf-8')) + fd.close() + + encrypt_cmd = '{vault_bin} -key {key_file} -encrypt {data_file}'.format(vault_bin=ODIMRA_VAULT_BIN, + key_file=ODIMRA_VAULT_KEY_FILE, data_file=REDIS_PW_FILE_PATH) + ret = exec(encrypt_cmd, {}) + if ret != 0: + logger.critical("storing node password failed") + exit(1) + # load_password_from_vault loads the sudo password of nodes # of present cluster securely stored usign ansible vault def load_password_from_vault(cur_dir): @@ -1126,6 +1199,31 @@ def load_password_from_vault(cur_dir): ANSIBLE_BECOME_PASS = std_out.rstrip('\n') + +def get_password_from_vault(cur_dir, password_file_path): + decrypt_cmd = '{vault_bin} -key {key_file} -decrypt {data_file}'.format(vault_bin=ODIMRA_VAULT_BIN, + key_file=ODIMRA_VAULT_KEY_FILE, data_file=password_file_path) + + execHdlr = subprocess.Popen(decrypt_cmd, + stdin=subprocess.PIPE, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + shell=True, + universal_newlines=True) + + try: + std_out, std_err = execHdlr.communicate() + except TimeoutExpired: + execHdlr.kill() + + if execHdlr.returncode != 0 or std_out == "": + print(std_out.strip()) + logger.critical("failed to read the password from "+ password_file_path) + os.chdir(cur_dir) + exit(1) + + return std_out.rstrip('\n') + # check_extract_kubespray_src is used for invoking # a script, after checking and if not exists, to extract # kubespary source bundle