From 3cb797197b1492433202a6b313f47ebc5b2fa813 Mon Sep 17 00:00:00 2001 From: Yichen Wang Date: Tue, 15 Sep 2015 23:35:39 -0700 Subject: [PATCH] Add support to update configs via Rest API Change-Id: I77f6b0fe5b7311b7409e43119082ae7151a8fcc1 --- kb_server/kb_server/controllers/api_cfg.py | 108 ++++++++++++--------- kb_server/kloudbuster-swagger.yaml | 29 +++++- kloudbuster/kb_config.py | 2 + 3 files changed, 86 insertions(+), 53 deletions(-) diff --git a/kb_server/kb_server/controllers/api_cfg.py b/kb_server/kb_server/controllers/api_cfg.py index f008be4..b6076a2 100644 --- a/kb_server/kb_server/controllers/api_cfg.py +++ b/kb_server/kb_server/controllers/api_cfg.py @@ -32,11 +32,41 @@ from pecan import response class ConfigController(object): + def update_config(self, kb_config, user_config): + # Parsing server and client configs from application input + # Save the public key into a temporary file + if 'public_key' in user_config['kb_cfg']: + pubkey_filename = '/tmp/kb_public_key.pub' + f = open(pubkey_filename, 'w') + f.write(user_config['kb_cfg']['public_key_file']) + f.close() + kb_config.config_scale['public_key_file'] = pubkey_filename + + if 'prompt_before_run' in user_config['kb_cfg']: + kb_config.config_scale['prompt_before_run'] = False + + if user_config['kb_cfg']: + alt_config = Configuration.from_dict(user_config['kb_cfg']).configure() + kb_config.config_scale = kb_config.config_scale.merge(alt_config) + + # Parsing topology configs from application input + if 'topo_cfg' in user_config: + topo_cfg = Configuration.from_string(user_config['topo_cfg']).configure() + else: + topo_cfg = None + + # Parsing tenants configs from application input + if 'tenants_list' in user_config: + tenants_list = Configuration.from_string(user_config['tenants_list']).configure() + else: + tenants_list = None + + kb_config.update_with_rest_api(topo_cfg=topo_cfg, tenants_list=tenants_list) + @expose(generic=True) def default_config(self): kb_config = KBConfig() pdict = eval(str(kb_config.config_scale)) - # Normally we don't allow the clients to change below configs return json.dumps(pdict) @expose(generic=True) @@ -44,7 +74,7 @@ class ConfigController(object): if len(args): session_id = args[0] else: - response.status = 400 + response.status = 404 response.text = u"Please specify the session_id." return response.text if KBSessionManager.has(session_id): @@ -64,11 +94,11 @@ class ConfigController(object): try: # Expectation: # { - # 'credentials': {'tested-rc': '', 'tested-passwd': '', - # 'testing-rc': '', 'testing-passwd': ''}, - # 'kb_cfg': {}, - # 'topo_cfg': {} - # 'tenants_cfg': {} + # 'credentials': {'tested-rc': '', 'tested-passwd': '', + # 'testing-rc': '', 'testing-passwd': ''}, + # 'kb_cfg': {}, + # 'topo_cfg': {} + # 'tenants_cfg': {} # } user_config = json.loads(arg) @@ -84,40 +114,12 @@ class ConfigController(object): # Use the same openrc file for both cases cred_testing = cred_tested - session_id = hashlib.md5(str(cred_config)).hexdigest() kb_config = KBConfig() + session_id = hashlib.md5(str(cred_config)).hexdigest() if KBSessionManager.has(session_id): response.status = 403 response.text = u"Session is already existed." return response.text - - # Parsing server and client configs from application input - # Save the public key into a temporary file - if 'public_key' in user_config['kb_cfg']: - pubkey_filename = '/tmp/kb_public_key.pub' - f = open(pubkey_filename, 'w') - f.write(user_config['kb_cfg']['public_key_file']) - f.close() - kb_config.config_scale['public_key_file'] = pubkey_filename - - if 'prompt_before_run' in user_config['kb_cfg']: - kb_config.config_scale['prompt_before_run'] = False - - if user_config['kb_cfg']: - alt_config = Configuration.from_string(user_config['kb_cfg']).configure() - kb_config.config_scale = kb_config.config_scale.merge(alt_config) - - # Parsing topology configs from application input - if 'topo_cfg' in user_config: - topo_cfg = Configuration.from_string(user_config['topo_cfg']).configure() - else: - topo_cfg = None - - # Parsing tenants configs from application input - if 'tenants_list' in user_config: - tenants_list = Configuration.from_string(user_config['tenants_list']).configure() - else: - tenants_list = None except Exception: response.status = 400 response.text = u"Error while parsing configurations: \n%s" % (traceback.format_exc) @@ -125,9 +127,8 @@ class ConfigController(object): logging.setup("kloudbuster", logfile="/tmp/kb_log_%s" % session_id) kb_config.init_with_rest_api(cred_tested=cred_tested, - cred_testing=cred_testing, - topo_cfg=topo_cfg, - tenants_list=tenants_list) + cred_testing=cred_testing) + self.update_config(kb_config, user_config) kb_session = KBSession() kb_session.kb_config = kb_config @@ -136,20 +137,31 @@ class ConfigController(object): return str(session_id) @running_config.when(method='PUT') - def running_config_PUT(self, *args): - # @TODO(Not completed! ENOTSUP) + def running_config_PUT(self, *args, **kwargs): if len(args): session_id = args[0] else: - response.status = 400 + response.status = 404 response.text = u"Please specify the session_id." return response.text if KBSessionManager.has(session_id): - # kb_session = KBSessionManager.get(session_id) - # - # - # - return "OK!" + status = KBSessionManager.get(session_id).kb_status + if status == "READY": + # Expectation: + # { + # 'kb_cfg': {}, + # 'topo_cfg': {} + # 'tenants_cfg': {} + # } + kb_config = KBConfig() + KBSessionManager.get(session_id).kb_config = kb_config + user_config = json.loads(kwargs['arg']) + self.update_config(kb_config, user_config) + return "OK!" + else: + response.status = 403 + response.text = u"Cannot update configuration if KloudBuster is not at READY" + return response.text else: response.status = 404 response.text = u"Session ID is not found or invalid." @@ -160,7 +172,7 @@ class ConfigController(object): if len(args): session_id = args[0] else: - response.status = 400 + response.status = 404 response.text = u"Please specify the session_id." return response.text if KBSessionManager.has(session_id): diff --git a/kb_server/kloudbuster-swagger.yaml b/kb_server/kloudbuster-swagger.yaml index 5dbefea..3d8d804 100644 --- a/kb_server/kloudbuster-swagger.yaml +++ b/kb_server/kloudbuster-swagger.yaml @@ -80,7 +80,6 @@ paths: put: description: | - (NOT IMPLEMENTED) Update KloudBuster configuration for an existing session parameters: - name: session_id @@ -95,17 +94,23 @@ paths: description: The configuration to be updated required: true schema: - # @TODO: Adding Configuration_Update - $ref: '#/definitions/Configuration_New' + $ref: '#/definitions/Configuration_Update' tags: - config responses: 200: description: | Configuration of given session is updated successfully - 405: + 400: + description: Error while parsing the configuration file + schema: + type: string + description: Errors in details + 403: description: | - Cannot change configuration while KloudBuster is running + Cannot update configuration if KloudBuster is not at READY + 404: + description: The session_id is not found or invalid delete: description: | Terminate the given session in KloudBuster server @@ -257,3 +262,17 @@ definitions: type: string format: json description: Tenant and User list for reusing + Configuration_Update: + properties: + kb_cfg: + type: string + format: json + description: User overrided configs + topo_cfg: + type: string + format: json + description: Topology config + tenants_cfg: + type: string + format: json + description: Tenant and User list for reusing diff --git a/kloudbuster/kb_config.py b/kloudbuster/kb_config.py index 1e6e5a1..31b3dc3 100644 --- a/kloudbuster/kb_config.py +++ b/kloudbuster/kb_config.py @@ -124,6 +124,8 @@ class KBConfig(object): def init_with_rest_api(self, **kwargs): self.cred_tested = kwargs['cred_tested'] self.cred_testing = kwargs['cred_testing'] + + def update_with_rest_api(self, **kwargs): self.topo_cfg = kwargs['topo_cfg'] self.tenants_list = kwargs['tenants_list'] self.update_configs()