def _get_coe_type(self, env_id): coe_type = '' env_obj = env_db.Environment().get(env_id) env_definition = ast.literal_eval(env_obj.env_definition) env_details = env_definition['environment'] coe_type = env_details['app_deployment']['type'] return coe_type
def delete_resource(self, env_id, resource): fmlogger.debug("GCloudHandler delete_resource") type = resource.type env_db.Environment().update(env_id, {'status': 'deleting_' + type}) for name, ext in GCloudHandler.res_mgr.items(): if name == type: ext.obj.delete(resource)
def get(self): fmlogging.debug("Received GET request for all resources.") resp_data = {} env_name = request.args.get('env_name') all_resources = '' if env_name: env_obj = env_db.Environment().get_by_name(env_name) if env_obj: all_resources = res_db.Resource().get_resources_for_env( env_obj.id) resp_data['data'] = [ res_db.Resource.to_json(res) for res in all_resources ] response = jsonify(**resp_data) response.status_code = 200 return response else: message = ( "Environment with name {env_name} does not exist").format( env_name=env_name) fmlogging.debug(message) resp_data = {'error': message} response = jsonify(**resp_data) response.status_code = 404 return response else: all_resources = res_db.Resource().get_all() resp_data['data'] = [ res_db.Resource.to_json(res) for res in all_resources ] response = jsonify(**resp_data) response.status_code = 200 return response
def get(self): fmlogging.debug("Received GET request for all environments") resp_data = {} all_envs = env_db.Environment().get_all() resp_data['data'] = [ env_db.Environment.to_json(env) for env in all_envs ] response = jsonify(**resp_data) response.status_code = 200 return response
def create_resources(self, env_id, resource_list): resource_details = '' ret_status_list = [] for resource_defs in resource_list: resource_details = resource_defs['resource'] type = resource_details['type'] env_db.Environment().update(env_id, {'status': 'creating_' + type}) for name, ext in AWSHandler.res_mgr.items(): if name == type: status = ext.obj.create(env_id, resource_details) if status: ret_status_list.append(status) return ret_status_list
def _delete_environment(self): env_db.Environment().update(self.env_id, {'status': 'deleting'}) resource_list = res_db.Resource().get_resources_for_env(self.env_id) for resource in resource_list: type = resource.type if type == 'ecs-cluster': EnvironmentHandler.registered_cloud_handlers['aws'].delete_cluster(self.env_id, self.environment_info, resource) if type == 'gke-cluster': EnvironmentHandler.registered_cloud_handlers['gcloud'].delete_cluster(self.env_id, self.environment_info, resource) if type in ['rds']: EnvironmentHandler.registered_cloud_handlers['aws'].delete_resource(self.env_id, resource) if type in ['cloudsql']: EnvironmentHandler.registered_cloud_handlers['gcloud'].delete_resource(self.env_id, resource) if type in ['mysql']: EnvironmentHandler.registered_cloud_handlers['local'].delete_resource(self.env_id, resource) env_db.Environment().delete(self.env_id)
def post(self, env_name): fmlogging.debug("Received POST request to run command on environment") args = request.get_json(force=True) response = jsonify() response.status_code = 201 args_dict = dict(args) resp_data = {} try: if 'command_string' not in args_dict: response.status_code = 400 else: command_string = args_dict['command_string'] environment_name = args_dict['environment_name'] env_obj = env_db.Environment().get_by_name(env_name) if not env_obj or env_obj.status == 'create-failed': response.status_code = 404 return response environment_def = env_obj.env_definition environment_info = {'name': env_name} commond_output = [] envhandler = environment_handler.EnvironmentHandler( env_obj.id, environment_def, environment_info, action='run_command') command_output = envhandler.run_command( env_name, command_string) resp_data['data'] = command_output response = jsonify(**resp_data) fmlogging.debug("Executing %s command on %s environment." % (command_string, environment_name)) except OSError as oe: fmlogging.error(oe) response.status_code = 503 return response
def get(self, env_name): resp_data = {} response = jsonify(**resp_data) env = env_db.Environment().get_by_name(env_name) if env: app_json = '' app_list = app_db.App().get_apps_for_env(env.id) if app_list: app_json = [ app_db.App.to_json_restricted(app) for app in app_list ] resp_data['data'] = env_db.Environment.to_json(env, app_json) response = jsonify(**resp_data) response.status_code = 200 else: response.status_code = 404 return response
def delete(self, env_name): fmlogging.debug("Received DELETE request for environment %s" % env_name) resp_data = {} response = jsonify(**resp_data) environment_info = {} env = env_db.Environment().get_by_name(env_name) if env: if not request.args.get("force"): app_list = app_db.App().get_apps_for_env(env.id) if app_list and len(app_list) > 0: response.status_code = 412 response.status_message = 'Environment cannot be deleted as there are applications still running on it.' return response environment_name = env.name environment_def = env.env_definition environment_info['name'] = environment_name environment_info['location'] = env.location request_handler_thread = environment_handler.EnvironmentHandler( env.id, environment_def, environment_info, action='delete') thread.start_new_thread(start_thread, (request_handler_thread, )) response.headers['location'] = ('/environments/{env_name}').format( env_name=environment_name) response.status_code = 202 # Check if this was GKE environment. If so, notify user that the VPC network needs to be deleted manually. env_dict = ast.literal_eval(environment_def) cloud = env_dict['environment']['app_deployment']['target'] if cloud == 'gcloud': resp_data = {} response = jsonify(**resp_data) response.status_code = 303 else: response.status_code = 404 return response
def delete_resource(self, env_id, resource): type = resource.type env_db.Environment().update(env_id, {'status': 'deleting_' + type}) for name, ext in AWSHandler.res_mgr.items(): if name == type: ext.obj.delete(resource)
def _create_environment(self): """Create environment. environment: resources: aws: - resource: type: rds configuration: engine: mysql flavor: db.m1.medium policy: access: open - resource: type: container name: nginx source: https://hub.docker.com/_/nginx/ app_deployment: target: aws type: ecs """ if not self.environment_def: fmlogging.debug("Environment definition is empty. Cannot create empty environment. Returning.") return env_details = self.environment_def['environment'] status_list = [] # First create ECS resources (cluster) if 'app_deployment' in env_details: app_deployment = env_details['app_deployment'] if app_deployment['target'] == 'aws': env_db.Environment().update(self.env_id, {'status': 'creating_ecs_cluster'}) status = EnvironmentHandler.registered_cloud_handlers['aws'].create_cluster(self.env_id, self.environment_info) status_list.append(status) if app_deployment['target'] == 'gcloud': env_db.Environment().update(self.env_id, {'status': 'creating_gke_cluster'}) status = EnvironmentHandler.registered_cloud_handlers['gcloud'].create_cluster(self.env_id, self.environment_info) status_list.append(status) # Then create other resources (as we want to set security-groups of other resources to # match does of the ECS cluster. if 'resources' in env_details: resources = env_details['resources'] resources_list = '' if 'aws' in resources: fmlogging.debug("Creating AWS resources") resources_list = resources['aws'] stat_list = EnvironmentHandler.registered_cloud_handlers['aws'].create_resources(self.env_id, resources_list) status_list.extend(stat_list) if 'gcloud' in resources: fmlogging.debug("Creating Google resources") resources_list = resources['gcloud'] stat_list = EnvironmentHandler.registered_cloud_handlers['gcloud'].create_resources(self.env_id, resources_list) status_list.extend(stat_list) if 'local' in resources: fmlogging.debug("Creating local resource containers") resources_list = resources['local'] stat_list = EnvironmentHandler.registered_cloud_handlers['local'].create_resources(self.env_id, resources_list) status_list.extend(stat_list) all_available = True for stat in status_list: if stat == 'available': all_available = all_available and True else: all_available = all_available and False if all_available: env_db.Environment().update(self.env_id, {'status': 'available'}) else: env_db.Environment().update(self.env_id, {'status': 'create-failed'}) fmlogging.debug("One or more resources in environment failed to provision.")
def post(self): fmlogging.debug("Received POST request to create environment") args = request.get_json(force=True) response = jsonify() response.status_code = 201 args_dict = dict(args) cloud_setup_done = common_functions.get_cloud_setup() if len(cloud_setup_done) == 0: resp_data = {} err_msg = 'No cloud setup found.' err_msg = err_msg + ' Run "cld setup aws" or "cld setup gcloud". Then restart cloudark server using the start-cloudark.sh script.' resp_data['error'] = err_msg response = jsonify(**resp_data) response.status_code = 412 return response try: if 'environment_def' not in args_dict: response.status_code = 400 else: environment_def = args_dict['environment_def'] environment_name = args_dict['environment_name'] env_version_stamp = common_functions.get_version_stamp() env_location = ( ENV_STORE_PATH + "/environments/{env_name}-{env_version_stamp}").format( env_name=environment_name, env_version_stamp=env_version_stamp) mkdir_env_location = ("mkdir {env_dir}").format( env_dir=env_location) os.system(mkdir_env_location) env_data = {} env_data['name'] = environment_name env_data['location'] = env_location env_data['env_version_stamp'] = env_version_stamp env_data['env_definition'] = environment_def env_id = '' try: env_id = env_db.Environment().insert(env_data) except Exception as e: fmlogging.error( "Failed inserting environment data in db: %s" % str(e)) message = ("Environment with name {env_name} already exists. Choose different name.").format(env_name=\ environment_name) fmlogging.debug(message) resp_data = {'error': message} response = jsonify(**resp_data) response.status_code = 400 return response environment_info = {} environment_info['name'] = environment_name environment_info['location'] = env_location request_handler_thread = environment_handler.EnvironmentHandler( env_id, environment_def, environment_info, action='create') # Check permissions here # permission_list = request_handler_thread.check_permissions() thread.start_new_thread(start_thread, (request_handler_thread, )) response.headers['location'] = ( '/environments/{env_name}').format( env_name=environment_name) except OSError as oe: fmlogging.error(oe) response.status_code = 503 return response
def post(self): fmlogging.debug("Received POST request to deploy app") args = request.get_json(force=True) response = jsonify() response.status_code = 201 args_dict = dict(args) try: if 'app_info' not in args_dict: response.status_code = 400 else: app_info = args_dict['app_info'] app_name = app_info['app_name'] env_name = app_info['env_name'] env_obj = env_db.Environment().get_by_name(env_name) if not env_obj: message = ( "Environment with name {env_name} does not exist" ).format(env_name=env_name) fmlogging.debug(message) resp_data = {'error': message} response = jsonify(**resp_data) response.status_code = 400 return response if not env_obj.status or env_obj.status != 'available': message = 'Environment not ready.' fmlogging.debug(message) resp_data = {'error': message} response = jsonify(**resp_data) response.status_code = 412 return response app_id = '' app_location = '' app_version = '' cloud = '' app_data = {} try: app_data['name'] = app_name app_data['location'] = app_location app_data['version'] = app_version app_data['dep_target'] = cloud app_data['env_id'] = env_obj.id app_data['env_name'] = env_obj.name app_id = app_db.App().insert(app_data) except Exception as e: fmlogging.debug(e) raise e if not app_id: message = ( "App with name {app_name} already exists. Choose different name." ).format(app_name=app_name) fmlogging.debug(message) resp_data = {'error': message} response = jsonify(**resp_data) response.status_code = 400 return response app_tar_name = app_info['app_tar_name'] content = app_info['app_content'] if 'target' in app_info: cloud = app_info['target'] else: env_dict = ast.literal_eval(env_obj.env_definition) cloud = env_dict['environment']['app_deployment']['target'] app_info['target'] = cloud app_location, app_version = common_functions.store_app_contents( app_name, app_tar_name, content) app_info['app_location'] = app_location app_info['app_version'] = app_version app_info['env_id'] = env_obj.id app_data['location'] = app_location app_data['version'] = app_version app_data['dep_target'] = cloud app_data['app_yaml_contents'] = str( common_functions.read_app_yaml(app_info)) app_db.App().update(app_id, app_data) try: validator.validate_app_deployment(app_info, app_data, env_obj) except exceptions.AppDeploymentValidationFailure as e: fmlogging.error(e) message = e.get_message() resp_data = {'error': message} response = jsonify(**resp_data) response.status_code = 400 return response request_handler_thread = app_handler.AppHandler( app_id, app_info, action='deploy') thread.start_new_thread(start_thread, (request_handler_thread, )) response.headers['location'] = ('/apps/{app_name}').format( app_name=app_name) except Exception as e: fmlogging.error(e) resp_data = {'error': str(e)} response = jsonify(**resp_data) response.status_code = 500 return response