Resiliancy issue with config_* scripts

Prevent config_controller, config_region and config_subcloud from being
run in ssh unless the --allow-ssh flag is used.

Change-Id: I00e3fa11afe8f35afdc9e4817645ecf90f71809b
Signed-off-by: Kristine Bujold <kristine.bujold@windriver.com>
This commit is contained in:
Kristine Bujold
2018-05-11 14:06:22 -04:00
parent 9ce6bc6f74
commit e81737c4d2
6 changed files with 78 additions and 54 deletions

View File

@@ -1,5 +1,5 @@
#
# Copyright (c) 2016-2017 Wind River Systems, Inc.
# Copyright (c) 2016-2018 Wind River Systems, Inc.
#
# SPDX-License-Identifier: Apache-2.0
#
@@ -91,3 +91,8 @@ DEFAULT_MGMT_ON_LOOPBACK_SUBNET_IPV4 = '127.168.204.0/24'
DEFAULT_REGION_NAME = "RegionOne"
DEFAULT_SERVICE_PROJECT_NAME = "services"
SSH_WARNING_MESSAGE = "WARNING: Command should only be run from the " \
"console. Continuing with this terminal may cause " \
"loss of connectivity and configuration failure."
SSH_ERROR_MESSAGE = "ERROR: Command should only be run from the console."

View File

@@ -1,5 +1,5 @@
"""
Copyright (c) 2014-2017 Wind River Systems, Inc.
Copyright (c) 2014-2018 Wind River Systems, Inc.
SPDX-License-Identifier: Apache-2.0
@@ -76,21 +76,6 @@ def prompt_for(prompt_text, default_input, validator):
return user_input
def check_for_ssh_parent():
"""Determine if current process is started from a ssh session"""
command = ('pstree -s %d' % (os.getpid()))
try:
cmd_output = subprocess.check_output(command, shell=True)
if "ssh" in cmd_output:
print textwrap.fill(
"WARNING: Command should only be run from the console. "
"Continuing with this terminal may cause loss of connectivity "
"and configuration failure", 80)
print
except subprocess.CalledProcessError:
return
def is_interface_up(interface_name):
arg = '/sys/class/net/' + interface_name + '/operstate'
try:

View File

@@ -1,5 +1,5 @@
"""
Copyright (c) 2015-2017 Wind River Systems, Inc.
Copyright (c) 2015-2018 Wind River Systems, Inc.
SPDX-License-Identifier: Apache-2.0
@@ -10,13 +10,14 @@ import os
import sys
import textwrap
import time
import utils
import uuid
from common import constants
from common import log
from common import rest_api_utils as rutils
from common.exceptions import KeystoneFail
from configutilities.common import utils
from configutilities.common import utils as cutils
from configutilities.common.configobjects import REGION_CONFIG, SUBCLOUD_CONFIG
from configutilities import ConfigFail
from configassistant import ConfigAssistant
@@ -397,18 +398,18 @@ def validate_region_one_keystone_config(region_config, token, api_url, users,
# Verify that region two endpoints & services match our requirements,
# optionally creating missing entries
public_address = utils.get_optional(region_config, 'CAN_NETWORK',
'CAN_IP_START_ADDRESS')
public_address = cutils.get_optional(region_config, 'CAN_NETWORK',
'CAN_IP_START_ADDRESS')
if not public_address:
public_address = utils.get_optional(region_config, 'CAN_NETWORK',
'CAN_IP_FLOATING_ADDRESS')
public_address = cutils.get_optional(region_config, 'CAN_NETWORK',
'CAN_IP_FLOATING_ADDRESS')
if not public_address:
public_address = utils.get_optional(region_config, 'OAM_NETWORK',
'IP_START_ADDRESS')
public_address = cutils.get_optional(region_config, 'OAM_NETWORK',
'IP_START_ADDRESS')
if not public_address:
# AIO-SX configuration
public_address = utils.get_optional(region_config, 'OAM_NETWORK',
'IP_ADDRESS')
public_address = cutils.get_optional(region_config, 'OAM_NETWORK',
'IP_ADDRESS')
if not public_address:
public_address = region_config.get('OAM_NETWORK',
'IP_FLOATING_ADDRESS')
@@ -420,17 +421,17 @@ def validate_region_one_keystone_config(region_config, token, api_url, users,
internal_address = region_config.get('MGMT_NETWORK',
'IP_START_ADDRESS')
internal_infra_address = utils.get_optional(
internal_infra_address = cutils.get_optional(
region_config, 'BLS_NETWORK', 'BLS_IP_START_ADDRESS')
if not internal_infra_address:
internal_infra_address = utils.get_optional(
internal_infra_address = cutils.get_optional(
region_config, 'INFRA_NETWORK', 'IP_START_ADDRESS')
for endpoint in expected_region_2_endpoints:
service_name = utils.get_service(region_config, 'REGION_2_SERVICES',
endpoint[SERVICE_NAME])
service_type = utils.get_service(region_config, 'REGION_2_SERVICES',
endpoint[SERVICE_TYPE])
service_name = cutils.get_service(region_config, 'REGION_2_SERVICES',
endpoint[SERVICE_NAME])
service_type = cutils.get_service(region_config, 'REGION_2_SERVICES',
endpoint[SERVICE_TYPE])
expected_public_url = endpoint[PUBLIC_URL].format(public_address)
@@ -669,6 +670,8 @@ def show_help_region():
print textwrap.fill(
"Perform region configuration using the region "
"configuration from CONFIG_FILE.", 80)
print ("--allow-ssh Allow configuration to be executed in "
"ssh\n")
def show_help_subcloud():
@@ -676,9 +679,12 @@ def show_help_subcloud():
print textwrap.fill(
"Perform subcloud configuration using the subcloud "
"configuration from CONFIG_FILE.", 80)
print ("--allow-ssh Allow configuration to be executed in "
"ssh\n")
def config_main(config_type=REGION_CONFIG):
allow_ssh = False
if config_type == REGION_CONFIG:
config_file = "/home/wrsroot/region_config"
elif config_type == SUBCLOUD_CONFIG:
@@ -694,6 +700,8 @@ def config_main(config_type=REGION_CONFIG):
else:
show_help_subcloud()
exit(1)
elif sys.argv[arg] == "--allow-ssh":
allow_ssh = True
elif arg == len(sys.argv) - 1:
config_file = sys.argv[arg]
else:
@@ -703,6 +711,15 @@ def config_main(config_type=REGION_CONFIG):
log.configure()
# Check if that the command is being run from the console
if utils.is_ssh_parent():
if allow_ssh:
print textwrap.fill(constants.SSH_WARNING_MESSAGE, 80)
print
else:
print textwrap.fill(constants.SSH_ERROR_MESSAGE, 80)
exit(1)
if not os.path.isfile(config_file):
print "Config file %s does not exist." % config_file
exit(1)

View File

@@ -18,7 +18,7 @@ from configutilities import lag_mode_to_str, Network, validate
from configutilities import ConfigFail
from configutilities import DEFAULT_CONFIG, REGION_CONFIG, SUBCLOUD_CONFIG
from configutilities import MGMT_TYPE, HP_NAMES, DEFAULT_NAMES
from configassistant import ConfigAssistant, check_for_ssh_parent
from configassistant import ConfigAssistant
import backup_restore
import utils
import clone
@@ -264,7 +264,7 @@ def show_help():
print ("Usage: %s\n"
"Perform system configuration\n"
"\nThe default action is to perform the initial configuration for "
"the system. The following options are also available:\n"
"the system.\nThe following options are also available:\n"
"--config-file <name> Perform configuration using INI file\n"
"--backup <name> Backup configuration using the given "
"name\n"
@@ -278,9 +278,11 @@ def show_help():
"--restore-images <name> Restore images from backup file with the "
"given name,\n"
" full path required\n"
"--restore-compute Restore controller-0 compute function "
"for All-In-One system,\n"
" controller-0 will reboot\n"
"--restore-compute Restore controller-0 compute function for"
" All-In-One\n"
" system, controller-0 will reboot\n"
"--allow-ssh Allow configuration to be executed in "
"ssh\n"
% sys.argv[0])
@@ -319,6 +321,7 @@ def main():
do_non_interactive = False
do_provision = False
system_config_file = "/home/wrsroot/system_config"
allow_ssh = False
# Disable completion as the default completer shows python commands
readline.set_completer(no_complete)
@@ -401,6 +404,8 @@ def main():
exit(1)
elif sys.argv[arg] == "--provision":
do_provision = True
elif sys.argv[arg] == "--allow-ssh":
allow_ssh = True
else:
print "Invalid option. Use --help for more information."
exit(1)
@@ -428,6 +433,16 @@ def main():
log.configure()
if not do_backup and not do_clone:
# Check if that the command is being run from the console
if utils.is_ssh_parent():
if allow_ssh:
print textwrap.fill(constants.SSH_WARNING_MESSAGE, 80)
print
else:
print textwrap.fill(constants.SSH_ERROR_MESSAGE, 80)
exit(1)
# Reduce the printk console log level to avoid noise during configuration
printk_levels = ''
with open('/proc/sys/kernel/printk', 'r') as f:
@@ -437,9 +452,6 @@ def main():
with open('/proc/sys/kernel/printk', 'w') as f:
f.write(temp_printk_levels)
if not do_backup and not do_clone:
check_for_ssh_parent()
try:
if do_backup:
backup_restore.backup(backup_name, archive_dir)

View File

@@ -1800,18 +1800,10 @@ def simplex_main():
log.configure()
# Enforce that the command is being run from the console
# TODO : R6 Merge this code with the check_for_ssh_parent used by the
# system restore
command = ('pstree -s %d' % (os.getpid()))
try:
cmd_output = subprocess.check_output(command, shell=True)
if "ssh" in cmd_output:
print "This command must be run from the console."
exit(1)
except subprocess.CalledProcessError as e:
LOG.exception(e)
print ("Error attempting upgrade. Ensure this command is run from the"
" console.")
if cutils.is_ssh_parent():
print (
"Error attempting upgrade. Ensure this command is run from the"
" console.")
exit(1)
if not backup_file:

View File

@@ -1,5 +1,5 @@
#
# Copyright (c) 2014-2017 Wind River Systems, Inc.
# Copyright (c) 2014-2018 Wind River Systems, Inc.
#
# SPDX-License-Identifier: Apache-2.0
#
@@ -883,3 +883,16 @@ def progress(steps, step, action, result, newline=False):
def touch(fname):
with open(fname, 'a'):
os.utime(fname, None)
def is_ssh_parent():
"""Determine if current process is started from a ssh session"""
command = ('pstree -s %d' % (os.getpid()))
try:
cmd_output = subprocess.check_output(command, shell=True)
if "ssh" in cmd_output:
return True
else:
return False
except subprocess.CalledProcessError:
return False