def import_connection( api_client: airbyte_api_client.ApiClient, workspace_id: str, resource_to_get: str, ) -> str: """Helper function to import connection. Args: api_client (airbyte_api_client.ApiClient): the Airbyte API client. workspace_id (str): current Airbyte workspace id. resource_to_get (str): the name or ID of the resource in the current Airbyte workspace id. Returns: str: The generated import message. """ remote_configuration = json.loads( get_json_representation(api_client, workspace_id, UnmanagedConnection, resource_to_get)) source_name, destination_name = remote_configuration["source"][ "name"], remote_configuration["destination"]["name"] source_configuration_path = renderers.ConnectorSpecificationRenderer.get_output_path( project_path=".", definition_type="source", resource_name=source_name) destination_configuration_path = renderers.ConnectorSpecificationRenderer.get_output_path( project_path=".", definition_type="destination", resource_name=destination_name) if not source_configuration_path.is_file(): raise MissingResourceDependencyError( f"The source {source_name} is not managed by octavia-cli, please import and apply it before importing your connection." ) elif not destination_configuration_path.is_file(): raise MissingResourceDependencyError( f"The destination {destination_name} is not managed by octavia-cli, please import and apply it before importing your connection." ) else: source = resources.factory(api_client, workspace_id, source_configuration_path) destination = resources.factory(api_client, workspace_id, destination_configuration_path) if not source.was_created: raise resources.NonExistingResourceError( f"The source defined at {source_configuration_path} does not exists. Please run octavia apply before creating this connection." ) if not destination.was_created: raise resources.NonExistingResourceError( f"The destination defined at {destination_configuration_path} does not exists. Please run octavia apply before creating this connection." ) connection_name, connection_id = remote_configuration[ "name"], remote_configuration["connection_id"] connection_renderer = renderers.ConnectionRenderer( connection_name, source, destination) new_configuration_path = connection_renderer.import_configuration( ".", remote_configuration) managed_resource, state = resources.factory( api_client, workspace_id, new_configuration_path).manage(connection_id) message = f"✅ - Imported connection {managed_resource.name} in {new_configuration_path}. State stored in {state.path}" click.echo(click.style(message, fg="green"))
def test_import_configuration(self, mocker, confirmed_overwrite, operations): configuration = {"foo": "bar", "bar": "foo", "operations": operations} mocker.patch.object(renderers.ConnectionRenderer, "KEYS_TO_REMOVE_FROM_REMOTE_CONFIGURATION", ["bar"]) mocker.patch.object(renderers.ConnectionRenderer, "_render") mocker.patch.object(renderers.ConnectionRenderer, "get_output_path") mocker.patch.object(renderers.yaml, "safe_load", mocker.Mock(return_value={})) mocker.patch.object(renderers.yaml, "safe_dump") mocker.patch.object(renderers.ConnectionRenderer, "_confirm_overwrite", mocker.Mock(return_value=confirmed_overwrite)) spec_renderer = renderers.ConnectionRenderer("my_resource_name", mocker.Mock(), mocker.Mock()) expected_output_path = renderers.ConnectionRenderer.get_output_path.return_value with patch("builtins.open", mock_open()) as mock_file: output_path = spec_renderer.import_configuration(project_path=".", configuration=configuration) spec_renderer._render.assert_called_once() renderers.yaml.safe_load.assert_called_with(spec_renderer._render.return_value) if operations: assert renderers.yaml.safe_load.return_value["configuration"] == {"foo": "bar", "operations": operations} else: assert renderers.yaml.safe_load.return_value["configuration"] == {"foo": "bar"} spec_renderer.get_output_path.assert_called_with(".", spec_renderer.definition.type, spec_renderer.resource_name) spec_renderer._confirm_overwrite.assert_called_with(expected_output_path) if confirmed_overwrite: mock_file.assert_called_with(expected_output_path, "wb") renderers.yaml.safe_dump.assert_called_with( renderers.yaml.safe_load.return_value, mock_file.return_value, default_flow_style=False, sort_keys=False, allow_unicode=True, encoding="utf-8", ) assert output_path == renderers.ConnectionRenderer.get_output_path.return_value
def test_write_yaml(self, mocker, mock_source, mock_destination, overwrite): mocker.patch.object(renderers.ConnectionRenderer, "get_output_path") mocker.patch.object(renderers.ConnectionRenderer, "catalog_to_yaml") mocker.patch.object(renderers.ConnectionRenderer, "TEMPLATE") mocker.patch.object(renderers.ConnectionRenderer, "_confirm_overwrite", mocker.Mock(return_value=overwrite)) connection_renderer = renderers.ConnectionRenderer("my_resource_name", mock_source, mock_destination) if overwrite: with patch("builtins.open", mock_open()) as mock_file: output_path = connection_renderer.write_yaml(".") connection_renderer.get_output_path.assert_called_with(".", renderers.ConnectionDefinition.type, "my_resource_name") connection_renderer.catalog_to_yaml.assert_called_with(mock_source.catalog) mock_file.assert_called_with(output_path, "w") mock_file.return_value.write.assert_called_with(connection_renderer.TEMPLATE.render.return_value) connection_renderer.TEMPLATE.render.assert_called_with( { "connection_name": connection_renderer.resource_name, "source_configuration_path": mock_source.configuration_path, "destination_configuration_path": mock_destination.configuration_path, "catalog": connection_renderer.catalog_to_yaml.return_value, "supports_normalization": connection_renderer.destination.definition.supports_normalization, "supports_dbt": connection_renderer.destination.definition.supports_dbt, } ) else: output_path = connection_renderer.write_yaml(".") assert output_path == connection_renderer.get_output_path.return_value
def test__render(self, mocker): mocker.patch.object(renderers.ConnectionRenderer, "catalog_to_yaml") mocker.patch.object(renderers.ConnectionRenderer, "TEMPLATE") connection_renderer = renderers.ConnectionRenderer("my_connection_name", mocker.Mock(), mocker.Mock()) rendered = connection_renderer._render() connection_renderer.catalog_to_yaml.assert_called_with(connection_renderer.source.catalog) connection_renderer.TEMPLATE.render.assert_called_with( { "connection_name": connection_renderer.resource_name, "source_configuration_path": connection_renderer.source.configuration_path, "destination_configuration_path": connection_renderer.destination.configuration_path, "catalog": connection_renderer.catalog_to_yaml.return_value, "supports_normalization": connection_renderer.destination.definition.supports_normalization, "supports_dbt": connection_renderer.destination.definition.supports_dbt, } ) assert rendered == connection_renderer.TEMPLATE.render.return_value
def test_init(self, mock_source, mock_destination): assert renderers.ConnectionRenderer.TEMPLATE == renderers.JINJA_ENV.get_template("connection.yaml.j2") connection_renderer = renderers.ConnectionRenderer("my_resource_name", mock_source, mock_destination) assert connection_renderer.resource_name == "my_resource_name" assert connection_renderer.source == mock_source assert connection_renderer.destination == mock_destination