Esempio n. 1
0
def get_composer_config():
    """Gets the configuration information of the Cloud Composer environment"""
    logger.log(
        logging.INFO,
        f"Entered get_composer_config -- {API_BASE_PATH_V1}/composer/config api GET method"
    )
    req_data = request.get_json()
    if req_data:
        logger.log(logging.DEBUG,
                   f"Request contains a json payload, validating: {req_data}")
        api_validator.validate_project_json(req_data)
        project_id, location, composer_environment = api_service.get_gcp_composer_details(
            req_data)
    else:
        logger.log(
            logging.DEBUG,
            f"Request does not contain a json payload, validating implicitly")
        project_id, location, composer_environment = api_service.get_gcp_composer_details(
            None)

    authenticated_session = auth_service.get_authenticated_session()
    airflow_config = airflow_service.AirflowService(
        authenticated_session, project_id, location,
        composer_environment).get_airflow_config()

    next_actions = {
        'list': f'{API_BASE_PATH_V1}/dag/list',
        'validate': f'{API_BASE_PATH_V1}/dag/validate',
        'deploy': f'{API_BASE_PATH_V1}/dag/deploy'
    }

    return jsonify(airflow_config=airflow_config, next_actions=next_actions)
Esempio n. 2
0
def get_composer_experimental_apì():
    """Gets the configuration information of the Cloud Composer experimental API"""
    logger.log(
        logging.INFO,
        f"Entered get_composer_experimental_apì -- {API_BASE_PATH_V1}/composer/api api GET method"
    )
    req_data = request.get_json()
    if req_data:
        logger.log(logging.DEBUG,
                   f"Request contains a json payload, validating: {req_data}")
        api_validator.validate_project_json(req_data)
        project_id, location, composer_environment = api_service.get_gcp_composer_details(
            req_data)
    else:
        logger.log(
            logging.DEBUG,
            f"Request does not contain a json payload, validating implicitly")
        project_id, location, composer_environment = api_service.get_gcp_composer_details(
            None)

    authenticated_session = auth_service.get_authenticated_session()
    airflow_uri, client_id = airflow_service.AirflowService(
        authenticated_session, project_id, location,
        composer_environment).get_airflow_experimental_api()

    return jsonify(airflow_uri=airflow_uri,
                   client_id=client_id,
                   next_actions=api_service.get_next_actions_experimental_api(
                       airflow_uri, client_id))
    def test_get_airflow_experimental_api(self, mock_six_parse,
                                          mock_requests_get,
                                          mock_flask_response,
                                          mock_auth_session):
        with open(
                os.path.join(os.path.dirname(Path(__file__)),
                             'airflow_config.json')) as json_file:
            airflow_config = json.load(json_file)

        # mock the objects
        mock_flask_response.json.return_value = airflow_config
        mock_six_parse.return_value = airflow_config['query_string']
        mock_auth_session.request.return_value = mock_flask_response
        headers = {
            'location': airflow_config['query_string']['redirect_uri'][0]
        }
        mock_requests_get.return_value = MockResponse({}, 200, headers)

        airflow_svc = airflow_service.AirflowService(
            mock_auth_session, os.environ.get('PROJECT_ID'),
            os.environ.get('GCP_LOCATION'),
            os.environ.get('COMPOSER_ENVIRONMENT'))

        airflow_ui, client_id = airflow_svc.get_airflow_experimental_api()
        assert airflow_ui is not None
        assert client_id is not None
        assert airflow_ui == 'https://sde120c7fa68ea00ep-tp.appspot.com/api/experimental'
        assert client_id == '401501771865-j04v42mav328ocngb267ts6mlh82j8uk.apps.googleusercontent.com'
Esempio n. 4
0
def trigger_dag(dag_name):
    """Triggers a specific, existing dag within a Cloud Composer environment"""
    logger.log(
        logging.INFO,
        f"Entered trigger_dag -- {API_BASE_PATH_V1}/dag/trigger/{dag_name} api PUT method"
    )
    req_data = request.get_json()
    if req_data:
        if 'conf' not in req_data or len(req_data['conf']) == 0:
            return {
                'error':
                "JSON payload provided but conf element is missing or empty"
            }, 500
        if 'project_id' in req_data:
            api_validator.validate_project_json(req_data)
            project_id, location, composer_environment = api_service.get_gcp_composer_details(
                req_data)
    else:
        project_id, location, composer_environment = api_service.get_gcp_composer_details(
            None)
    try:
        res = api_service.trigger_dag(project_id, location,
                                      composer_environment, dag_name)
    except:
        return {'error': traceback.print_exc()}, 500

    authenticated_session = auth_service.get_authenticated_session()
    airflow_uri, client_id = airflow_service.AirflowService(
        authenticated_session, project_id, location,
        composer_environment).get_airflow_experimental_api()

    return jsonify(api_response=res,
                   next_actions=api_service.get_next_actions_experimental_api(
                       airflow_uri, client_id))
    def test_get_airflow_config(self, mock_six_parse, mock_requests_get,
                                mock_flask_response, mock_auth_session):
        with open(
                os.path.join(os.path.dirname(Path(__file__)),
                             'airflow_config.json')) as json_file:
            airflow_config = json.load(json_file)

        # mock the objects
        mock_flask_response.json.return_value = airflow_config
        mock_six_parse.return_value = airflow_config['query_string']
        mock_auth_session.request.return_value = mock_flask_response
        headers = {
            'location': airflow_config['query_string']['redirect_uri'][0]
        }
        mock_requests_get.return_value = MockResponse({}, 200, headers)

        airflow_svc = airflow_service.AirflowService(
            mock_auth_session, os.environ.get('PROJECT_ID'),
            os.environ.get('GCP_LOCATION'),
            os.environ.get('COMPOSER_ENVIRONMENT'))
        composer_config = airflow_svc.get_airflow_config()
        assert composer_config is not None
        assert 'name' in composer_config
        assert composer_config['name'] == airflow_config['name']
        assert 'uuid' in composer_config
        assert composer_config['uuid'] == airflow_config['uuid']
        assert 'dagGcsPrefix' in composer_config['config']
        assert composer_config['config']['dagGcsPrefix'] == airflow_config[
            'config']['dagGcsPrefix']
        assert 'client_id' in composer_config['query_string']
        assert composer_config['query_string']['client_id'] == airflow_config[
            'query_string']['client_id']
 def test_trigger_dag(self, mock_request, mock_auth_service):
     mock_auth_service.return_value = 'fake_id_token'
     mock_request.return_value = MockResponse({}, 200, {},
                                              "mock_response_text")
     airflow_svc = airflow_service.AirflowService(
         'fake_auth_session', os.environ.get('PROJECT_ID'),
         os.environ.get('GCP_LOCATION'),
         os.environ.get('COMPOSER_ENVIRONMENT'))
     res_text = airflow_svc.trigger_dag('mock_dag_name', 'mock_airflow_ui',
                                        ',mock_client_id')
     assert res_text is not None
     assert res_text == "mock_response_text"
def __get_composer_environment(project_id, location, composer_environment):
    """
    Gets the configuration information for a Cloud Composer environment.
    Args:
        project_id (string): GCP Project Id of the Cloud Composer instance
        location (string): GCP Zone of the Cloud Composer instance
        composer_environment (string): Name of the Cloud Composer instance
    Returns:
        an instance of composer.airflow.AirflowService
    """
    logger.log(logging.DEBUG, "Getting the composer environment")
    authenticated_session = auth_service.get_authenticated_session()
    return airflow_service.AirflowService(authenticated_session, project_id,
                                          location, composer_environment)
def test_get_next_actions_experimental_api():
    authenticated_session = auth_service.get_authenticated_session()
    airflow_uri, client_id = airflow_service.AirflowService(
        authenticated_session,
        os.environ.get('PROJECT_ID'),
        os.environ.get('GCP_LOCATION'),
        os.environ.get('COMPOSER_ENVIRONMENT')
    ).get_airflow_experimental_api()
    next_actions = api_service.get_next_actions_experimental_api(airflow_uri, client_id)
    assert 'endpoints' in next_actions
    assert len(next_actions['endpoints']) > 0
    assert 'description' in next_actions['endpoints'][0]
    assert 'api_url' in next_actions['endpoints'][0]
    assert 'http_method' in next_actions['endpoints'][0]
    assert 'api_ref' in next_actions['endpoints'][0]
    assert 'client_id' in next_actions['endpoints'][0]
    def test_get_airflow_dag_gcs(self, mock_six_parse, mock_requests_get,
                                 mock_flask_response, mock_auth_session):
        with open(
                os.path.join(os.path.dirname(Path(__file__)),
                             'airflow_config.json')) as json_file:
            airflow_config = json.load(json_file)

        # mock the objects
        mock_flask_response.json.return_value = airflow_config
        mock_six_parse.return_value = airflow_config['query_string']
        mock_auth_session.request.return_value = mock_flask_response
        headers = {
            'location': airflow_config['query_string']['redirect_uri'][0]
        }
        mock_requests_get.return_value = MockResponse({}, 200, headers)

        airflow_svc = airflow_service.AirflowService(
            mock_auth_session, os.environ.get('PROJECT_ID'),
            os.environ.get('GCP_LOCATION'),
            os.environ.get('COMPOSER_ENVIRONMENT'))

        dag_gcs_path = airflow_svc.get_airflow_dag_gcs()
        assert dag_gcs_path is not None
        assert dag_gcs_path == 'gs://europe-west3-composer-1b28efe1-bucket/dags'