def test_login_with_specific_login_domain_for_multiple_ov(
            self, get_authentication_mode, get_oneview_multiple_ips,
            oneview_client_mockup):

        get_authentication_mode.return_value = 'session'
        tokens_ov = collections.OrderedDict({
            '10.0.0.1': 'abc',
            '10.0.0.2': 'def',
            '10.0.0.3': 'ghi'
        })
        list_ips = list(tokens_ov.keys())

        client_session.init_map_clients()

        get_oneview_multiple_ips.return_value = list_ips

        client_session.login('SOME_DOMAIN\\user', 'password123')

        oneview_client_mockup.assert_any_call({
            'ip': '10.0.0.1',
            'credentials': {
                'userName': '******',
                'password': '******',
                'authLoginDomain': 'SOME_DOMAIN'
            },
            'api_version': 600
        })
예제 #2
0
    def _build_common_sessions(self, uuid_mock):
        uuid_mock.uuid4.side_effect = self.session_ids

        client_session.init_map_clients()
        client_session._set_new_client_by_token('abc', '10.0.0.1')
        client_session._set_new_client_by_token('def', '10.0.0.2')
        client_session._set_new_client_by_token('ghi', '10.0.0.3')
예제 #3
0
    def setUp(self):
        # Initializing caches
        multiple_oneview.init_map_resources()
        client_session.init_map_clients()
        category_resource.init_map_category_resources()

        self.config_obj = configparser.ConfigParser()
        self.config_obj.add_section('oneview_config')
        self.config_obj.add_section('redfish')
    def test_map_token_redfish_for_multiple_ov(self, get_authentication_mode,
                                               get_oneview_multiple_ips,
                                               oneview_client_mockup,
                                               uuid_mock):
        get_authentication_mode.return_value = 'session'
        mocked_rf_token = "abc"
        session_id = '123456'
        list_ips = ['10.0.0.1', '10.0.0.2', '10.0.0.3']
        conn_1 = mock.MagicMock()

        connection_list = [conn_1, mock.MagicMock(), mock.MagicMock()]

        connections_ov = collections.OrderedDict({
            'client_ov_by_ip': {
                list_ips[0]: connection_list[0],
                list_ips[1]: connection_list[1],
                list_ips[2]: connection_list[2]
            },
            'session_id': session_id
        })

        uuid_mock.uuid4.return_value = session_id

        iter_conns_ov = iter(connection_list)

        client_session.init_map_clients()

        get_oneview_multiple_ips.return_value = list_ips

        def function_returning_token(ov_config):
            return next(iter_conns_ov)

        oneview_client_mockup.side_effect = function_returning_token
        conn_1.connection.get_session_id.return_value = mocked_rf_token

        # Check if redfish token return is one of the OneView's token
        rf_token, _ = client_session.login('user', 'password')
        oneview_client_mockup.assert_any_call({
            'ip': '10.0.0.1',
            'credentials': {
                'userName': '******',
                'password': '******'
            },
            'api_version': 600
        })
        self.assertEqual(rf_token, mocked_rf_token)

        # Check if cached connection map has the Redfish token return on login
        map_clients = client_session._get_map_clients()
        self.assertTrue(rf_token in map_clients)

        # Check if cached connection map has the correct
        # OneViewIp/OneViewConnection tuples
        for ov_ip, ov_conn in map_clients[rf_token].items():
            self.assertEqual(connections_ov[ov_ip], ov_conn)
예제 #5
0
    def test_post_session(self, get_authentication_mode, oneview_client_mockup,
                          uuid_mock):
        """Tests post Session"""

        # Loading Session mockup result
        with open('oneview_redfish_toolkit/mockups/redfish/Session.json') as f:
            expected_session_mockup = json.load(f)

        client_session.init_map_clients()
        multiple_oneview.init_map_appliances()
        get_authentication_mode.return_value = 'session'

        # Create mock response
        uuid_mock.uuid4.return_value = self.session_id
        oneview_client = oneview_client_mockup()
        oneview_client.connection.get_session_id.return_value = self.token_id

        # POST Session
        response = self.client.post("/redfish/v1/SessionService/Sessions",
                                    data=json.dumps(
                                        dict(UserName="******",
                                             Password="******")),
                                    content_type='application/json')

        # Gets json from response
        result = json.loads(response.data.decode("utf-8"))

        # Tests response
        self.assertEqual(status.HTTP_200_OK, response.status_code)
        self.assertEqual("application/json", response.mimetype)
        self.assertEqualMockup(expected_session_mockup, result)
        self.assertIn("/redfish/v1/SessionService/Sessions/" + self.session_id,
                      response.headers["Location"])
        self.assertEqual(self.token_id, response.headers["X-Auth-Token"])
        oneview_client_mockup.assert_called_with({
            'ip':
            config.get_oneview_multiple_ips()[0],
            'credentials': {
                'userName': '******',
                'password': '******'
            },
            'api_version':
            config.get_api_version()
        })

        # gets the session by id
        response_of_get = self.client.get(response.headers["Location"],
                                          content_type='application/json')

        result_of_get = json.loads(response_of_get.data.decode("utf-8"))

        self.assertEqual(status.HTTP_200_OK, response_of_get.status_code)
        self.assertEqual(self.session_id, result_of_get["Id"])
예제 #6
0
    def test_get_session_when_is_not_cached(self, _, uuid_mock):
        """Tests get a specific Session when session id is not present"""

        uuid_mock.uuid4.return_value = '709cf49b-f367-417e-af70-ede782e0fa3c'

        client_session.init_map_clients()
        client_session._set_new_client_by_token('abc', '10.0.0.1')

        response = self.client.get(
            "/redfish/v1/SessionService/Sessions/"
            "e2807c0b-87d6-4304-a773-6ec33521fb1c",
            content_type='application/json')

        self.assertEqual(status.HTTP_404_NOT_FOUND, response.status_code)
        self.assertEqual("application/json", response.mimetype)
예제 #7
0
    def test_get_session_collection_when_is_empty(self, _, __):
        """Tests get Session Collection when active session list is empty"""
        with open('oneview_redfish_toolkit/mockups/redfish/'
                  'SessionCollectionEmpty.json') as f:
            expected_session_collection = json.load(f)

        client_session.init_map_clients()

        response = self.client.get("/redfish/v1/SessionService/Sessions",
                                   content_type='application/json')

        result = json.loads(response.data.decode("utf-8"))

        self.assertEqual(status.HTTP_200_OK, response.status_code)
        self.assertEqual("application/json", response.mimetype)
        self.assertEqualMockup(expected_session_collection, result)
    def test_post_session_with_login_domain_data(self, get_authentication_mode,
                                                 oneview_client_mockup,
                                                 uuid_mock):
        """Tests post Session when UserName has login domain information"""

        with open('oneview_redfish_toolkit/mockups/redfish/'
                  'SessionForLoginWithDomain.json') as f:
            expected_session_mockup = json.load(f)

        client_session.init_map_clients()
        multiple_oneview.init_map_appliances()
        get_authentication_mode.return_value = 'session'

        # Create mock response
        uuid_mock.uuid4.return_value = self.session_id
        oneview_client = oneview_client_mockup()
        oneview_client.connection.get_session_id.return_value = self.token_id

        # POST Session
        response = self.client.post("/redfish/v1/SessionService/Sessions",
                                    data=json.dumps(
                                        dict(UserName="******",
                                             Password="******")),
                                    content_type='application/json')

        # Gets json from response
        result = json.loads(response.data.decode("utf-8"))

        # Tests response
        self.assertEqual(status.HTTP_201_CREATED, response.status_code)
        self.assertEqual("application/json", response.mimetype)
        self.assertEqualMockup(expected_session_mockup, result)
        self.assertIn("/redfish/v1/SessionService/Sessions/" + self.session_id,
                      response.headers["Location"])
        self.assertEqual(self.token_id, response.headers["X-Auth-Token"])
        oneview_client_mockup.assert_called_with({
            'ip':
            config.get_oneview_multiple_ips()[0],
            'credentials': {
                'userName': '******',
                'password': '******',
                'authLoginDomain': 'LOCAL'
            },
            'api_version':
            config.get_api_version()
        })
예제 #9
0
    def test_get_session(self, _, uuid_mock):
        """Tests get a specific Session"""

        with open('oneview_redfish_toolkit/mockups/redfish/Session.json') as f:
            expected_session = json.load(f)

        uuid_mock.uuid4.side_effect = self.session_ids

        client_session.init_map_clients()
        client_session._set_new_client_by_token('abc', '10.0.0.1')
        client_session._set_new_client_by_token('def', '10.0.0.2')

        response = self.client.get("/redfish/v1/SessionService/Sessions/" +
                                   expected_session["Id"],
                                   content_type='application/json')

        result = json.loads(response.data.decode("utf-8"))

        self.assertEqual(status.HTTP_200_OK, response.status_code)
        self.assertEqual("application/json", response.mimetype)
        self.assertEqualMockup(expected_session, result)
예제 #10
0
    def test_post_many_sessions(self, oneview_client_mockup, uuid_mock):
        """Tests post many Sessions and gets them"""

        with open('oneview_redfish_toolkit/mockups/redfish/'
                  'SessionCollection.json') as f:
            expected_session_collection = json.load(f)

        client_session.init_map_clients()
        multiple_oneview.init_map_appliances()

        session_ids = self.session_ids
        uuid_mock.uuid4.side_effect = session_ids

        oneview_client = oneview_client_mockup()
        oneview_client.connection.get_session_id.side_effect = [
            'abc', 'def', 'ghi'
        ]

        self.client.post("/redfish/v1/SessionService/Sessions",
                         data=json.dumps(
                             dict(UserName="******", Password="******")),
                         content_type='application/json')

        self.client.post("/redfish/v1/SessionService/Sessions",
                         data=json.dumps(
                             dict(UserName="******", Password="******")),
                         content_type='application/json')

        self.client.post("/redfish/v1/SessionService/Sessions",
                         data=json.dumps(
                             dict(UserName="******", Password="******")),
                         content_type='application/json')

        response = self.client.get('/redfish/v1/SessionService/Sessions',
                                   content_type='application/json')
        result = json.loads(response.data.decode("utf-8"))

        self.assertEqual(status.HTTP_200_OK, response.status_code)
        self.assertEqual(expected_session_collection, result)
 def setUp(self):
     client_session.init_map_clients()
     multiple_oneview.init_map_appliances()
def main(config_file_path,
         logging_config_file_path,
         is_dev_env=False,
         is_debug_mode=False):
    # Load config file, schemas and creates a OV connection
    try:
        config.configure_logging(logging_config_file_path)
        config.load_config(config_file_path)
    except Exception as e:
        logging.exception('Failed to load app configuration')
        logging.exception(e)
        exit(1)

    # Check auth mode
    auth_mode = config.get_authentication_mode()

    if auth_mode not in ["conf", "session"]:
        logging.error("Invalid authentication_mode. Please check your conf"
                      " file. Valid values are 'conf' or 'session'")

    # Flask application
    app = Flask(__name__)

    app.url_map.strict_slashes = False

    # Register blueprints
    app.register_blueprint(redfish_base, url_prefix="/redfish/")
    app.register_blueprint(service_root, url_prefix='/redfish/v1/')
    app.register_blueprint(event_service)
    app.register_blueprint(session_service)
    app.register_blueprint(chassis_collection)
    app.register_blueprint(computer_system_collection)
    app.register_blueprint(computer_system)
    app.register_blueprint(composition_service)
    app.register_blueprint(chassis)
    app.register_blueprint(ethernet_interface)
    app.register_blueprint(ethernet_interface_collection)
    app.register_blueprint(manager_collection)
    app.register_blueprint(manager)
    app.register_blueprint(metadata)
    app.register_blueprint(odata)
    app.register_blueprint(storage)
    app.register_blueprint(thermal)
    app.register_blueprint(storage_collection)
    app.register_blueprint(network_adapter_collection)
    app.register_blueprint(network_interface_collection)
    app.register_blueprint(network_port_collection)
    app.register_blueprint(network_device_function_collection)
    app.register_blueprint(network_device_function)
    app.register_blueprint(network_interface)
    app.register_blueprint(network_adapter)
    app.register_blueprint(network_port)
    app.register_blueprint(processor)
    app.register_blueprint(processor_collection)
    app.register_blueprint(storage_for_resource_block)
    app.register_blueprint(resource_block_collection)
    app.register_blueprint(resource_block)
    app.register_blueprint(vlan_network_interface)
    app.register_blueprint(zone_collection)
    app.register_blueprint(zone)

    # Init cached data
    client_session.init_map_clients()
    client_session.init_gc_for_expired_sessions()
    multiple_oneview.init_map_resources()
    multiple_oneview.init_map_appliances()
    category_resource.init_map_category_resources()

    if auth_mode == "conf":
        app.register_blueprint(subscription_collection)
        app.register_blueprint(subscription)

        client_session.login_conf_mode()
    else:
        app.register_blueprint(session)

    @app.before_request
    def init_performance_data():
        if logging.getLogger().isEnabledFor(logging.DEBUG):
            g.start_time_req = time.time()
            g.elapsed_time_ov = 0

    @app.before_request
    def check_authentication():
        # If authenticating do not check for anything
        if request.url_rule and \
           request.url_rule.rule == SessionCollection.BASE_URI and \
           request.method == "POST":
            return None

        if connection.is_service_root():
            return None

        if config.auth_mode_is_session():
            x_auth_token = request.headers.get('x-auth-token')
            client_session.check_authentication(x_auth_token)

        g.oneview_client = \
            handler_multiple_oneview.MultipleOneViewResource()

    @app.before_request
    def has_odata_version_header():
        """Deny request that specify a different OData-Version than 4.0"""
        odata_version_header = request.headers.get("OData-Version")

        if odata_version_header is None:
            pass
        elif odata_version_header != "4.0":
            abort(
                status.HTTP_412_PRECONDITION_FAILED,
                "The request specify a different OData-Version "
                "header then 4.0. This server also responds "
                "to requests without the OData-Version header")

    @app.after_request
    def set_odata_version_header(response):
        """Set OData-Version header for all responses"""
        response.headers["OData-Version"] = "4.0"
        return response

    @app.after_request
    def log_performance_data(response):
        if logging.getLogger().isEnabledFor(logging.DEBUG):
            end_time = time.time()
            req_time = end_time - g.start_time_req
            logging.getLogger(PERFORMANCE_LOGGER_NAME).debug(
                "OneView process: " + str(g.elapsed_time_ov))
            logging.getLogger(PERFORMANCE_LOGGER_NAME).debug(
                "Redfish process: " + str(req_time - g.elapsed_time_ov))
            logging.getLogger(PERFORMANCE_LOGGER_NAME).debug(
                "Total process: " + str(req_time))
        return response

    @app.errorhandler(status.HTTP_400_BAD_REQUEST)
    def bad_request(error):
        """Creates a Bad Request Error response"""
        logging.error(error.description)

        return ResponseBuilder.error_400(error)

    @app.errorhandler(status.HTTP_401_UNAUTHORIZED)
    def unauthorized_error(error):
        """Creates a Unauthorized Error response"""
        logging.error(error.description)

        return ResponseBuilder.error_401(error)

    @app.errorhandler(status.HTTP_403_FORBIDDEN)
    def forbidden(error):
        """Creates a Forbidden Error response"""
        logging.error(error.description)

        return ResponseBuilder.error_403(error)

    @app.errorhandler(status.HTTP_404_NOT_FOUND)
    def not_found(error):
        """Creates a Not Found Error response"""
        logging.error(error.description)

        return ResponseBuilder.error_404(error)

    @app.errorhandler(status.HTTP_500_INTERNAL_SERVER_ERROR)
    def internal_server_error(error):
        """Creates an Internal Server Error response"""
        logging.error(error)

        return ResponseBuilder.error_500(error)

    @app.errorhandler(status.HTTP_501_NOT_IMPLEMENTED)
    def not_implemented(error):
        """Creates a Not Implemented Error response"""
        logging.error(error.description)

        return ResponseBuilder.error_501(error)

    @app.errorhandler(HPOneViewException)
    def hp_oneview_client_exception(exception):
        logging.exception(exception)
        response = ResponseBuilder.error_by_hp_oneview_exception(exception)

        # checking if session has expired on Oneview
        if config.auth_mode_is_session() and \
                response.status_code == status.HTTP_401_UNAUTHORIZED:
            token = request.headers.get('x-auth-token')
            client_session.clear_session_by_token(token)

        return response

    @app.errorhandler(OneViewRedfishException)
    def oneview_redfish_exception(exception):
        logging.exception(exception)

        return ResponseBuilder.oneview_redfish_exception(exception)

    scmb.init_event_service()

    app_config = config.get_config()

    try:
        host = app_config["redfish"]["redfish_host"]

        # Gets the correct IP type based on the string
        ipaddress.ip_address(host)
    except ValueError:
        logging.error("Informed IP is not valid. Check the "
                      "variable 'redfish_host' on your config file.")
        exit(1)

    try:
        port = int(app_config["redfish"]["redfish_port"])
    except Exception:
        logging.exception(
            "Port must be an integer number between 1 and 65536.")
        exit(1)
    # Checking port range
    if port < 1 or port > 65536:
        logging.error("Port must be an integer number between 1 and 65536.")
        exit(1)

    if app_config["ssl"]["SSLType"] in ("self-signed", "adhoc"):
        logging.warning("Server is starting with a self-signed certificate.")
    if app_config["ssl"]["SSLType"] == "disabled":
        logging.warning(
            "Server is starting in HTTP mode. This is an insecure mode. "
            "Running the server with HTTPS enabled is highly recommended.")

    ssl_type = app_config["ssl"]["SSLType"]
    # Check SSLType:
    if ssl_type not in ('disabled', 'adhoc', 'certs', 'self-signed'):
        logging.error("Invalid SSL type: {}. Must be one of: disabled, adhoc, "
                      "self-signed or certs".format(ssl_type))
        exit(1)

    if ssl_type == 'disabled':
        app.run(host=host, port=port, debug=is_debug_mode)
    elif ssl_type == 'adhoc':
        app.run(host=host, port=port, debug=is_debug_mode, ssl_context="adhoc")
    else:
        # We should use certs file provided by the user
        ssl_cert_file = app_config["ssl"]["SSLCertFile"]
        ssl_key_file = app_config["ssl"]["SSLKeyFile"]

        # Generating cert files if they don't exists
        if ssl_type == "self-signed":
            if not os.path.exists(ssl_cert_file) and not \
                    os.path.exists(ssl_key_file):
                logging.warning("Generating self-signed certs")
                # Generate certificates
                util.generate_certificate(os.path.dirname(ssl_cert_file),
                                          "self-signed", 2048)
            else:
                logging.warning("Using existing self-signed certs")
        elif ssl_cert_file == "" or ssl_key_file == "":
            logging.error(
                "SSL type: is 'cert' but one of the files are missing on"
                "the config file. SSLCertFile: {}, SSLKeyFile: {}.".format(
                    ssl_cert_file, ssl_key_file))

        if is_dev_env and is_debug_mode:
            ssl_context = (ssl_cert_file, ssl_key_file)
            app.run(host=host,
                    port=port,
                    debug=is_debug_mode,
                    ssl_context=ssl_context)
        else:
            start_cherrypy(app,
                           host=host,
                           port=port,
                           ssl_cert_file=ssl_cert_file,
                           ssl_key_file=ssl_key_file,
                           is_dev_env=is_dev_env)