######### # Copyright (c) 2016 GigaSpaces Technologies Ltd. All rights reserved # # 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 subprocess import check_call from flask import request from flask_restful.reqparse import Argument from cloudify._compat import text_type from manager_rest.security import SecuredResource, premium_only from manager_rest.rest import rest_utils from manager_rest.storage import get_storage_manager, models from manager_rest.security.authorization import ( authorize, is_user_action_allowed ) from manager_rest.rest.rest_decorators import ( marshal_with, paginate ) try: from cloudify_premium import manager as manager_premium except ImportError: manager_premium = None DEFAULT_CONF_PATH = '/etc/nginx/conf.d/cloudify.conf' HTTP_PATH = '/etc/nginx/conf.d/http-external-rest-server.cloudify' HTTPS_PATH = '/etc/nginx/conf.d/https-external-rest-server.cloudify' class SSLConfig(SecuredResource): @authorize('ssl_set') def post(self): """ Enable/Disable SSL """ request_dict = rest_utils.get_json_and_verify_params({'state'}) state = rest_utils.verify_and_convert_bool('state', request_dict.get('state')) status = 'enabled' if state else 'disabled' if state == SSLConfig._is_enabled(): return 'SSL is already {0} on the manager'.format(status) else: self._set_ssl_state(state) return 'SSL is now {0} on the manager'.format(status) @authorize('ssl_get') def get(self): """ Get ssl state (enabled/disabled) """ return 'SSL {0}'.format( 'enabled' if SSLConfig._is_enabled() else 'disabled') @staticmethod def _is_enabled(): return request.scheme == 'https' @staticmethod def _set_ssl_state(state): flag = '--ssl-enabled' if state else '--ssl-disabled' check_call(['sudo', '/opt/manager/scripts/set-manager-ssl.py', flag]) # community base classes for the managers and brokers endpoints: # the http verbs that are implemented in premium, are made to throw a # "premium-only" exception here, so they throw that in community instead of # a 404. The method body should never be executed, because the @premium_only # decorator should prevent it. class _CommunityManagersBase(SecuredResource): @authorize('manager_manage') @marshal_with(models.Manager) @premium_only def post(self): raise NotImplementedError('Premium implementation only') class _CommunityManagersId(SecuredResource): @authorize('manager_manage') @marshal_with(models.Manager) @premium_only def put(self): raise NotImplementedError('Premium implementation only') @authorize('manager_manage') @marshal_with(models.Manager) @premium_only def delete(self): raise NotImplementedError('Premium implementation only') class _CommunityBrokersBase(SecuredResource): @authorize('broker_manage') @marshal_with(models.RabbitMQBroker) @premium_only def post(self): raise NotImplementedError('Premium implementation only') class _CommunityBrokersId(SecuredResource): @authorize('broker_manage') @marshal_with(models.Manager) @premium_only def put(self): raise NotImplementedError('Premium implementation only') @authorize('broker_manage') @marshal_with(models.Manager) @premium_only def delete(self): raise NotImplementedError('Premium implementation only') if manager_premium: managers_base = manager_premium.ManagersBase brokers_base = manager_premium.RabbitMQBrokersBase ManagersId = manager_premium.ManagersId RabbitMQBrokersId = manager_premium.RabbitMQBrokersId else: managers_base = _CommunityManagersBase brokers_base = _CommunityBrokersBase ManagersId = _CommunityManagersId RabbitMQBrokersId = _CommunityBrokersId class Managers(managers_base): @marshal_with(models.Manager) @paginate @authorize('manager_get') def get(self, pagination=None, _include=None): """ Get the list of managers in the database :param hostname: optional hostname to return only a specific manager :param _include: optional, what columns to include in the response """ args = rest_utils.get_args_and_verify_arguments([ Argument('hostname', type=text_type, required=False) ]) hostname = args.get('hostname') if hostname: return get_storage_manager().list( models.Manager, None, filters={'hostname': hostname} ) return get_storage_manager().list( models.Manager, include=_include ) class RabbitMQBrokers(brokers_base): @marshal_with(models.RabbitMQBroker) @paginate @authorize('broker_get') def get(self, pagination=None): """List brokers from the database.""" brokers = get_storage_manager().list(models.RabbitMQBroker) if not is_user_action_allowed('broker_credentials'): for broker in brokers: broker.username = None broker.password = None return brokers class DBNodes(SecuredResource): @marshal_with(models.DBNodes) @paginate @authorize('db_nodes_get') def get(self, pagination=None): """List DB nodes from database""" return get_storage_manager().list(models.DBNodes)