Example #1
0
    def check_for_write_conflict(key: str) -> None:
        """
        Logs a warning if a variable exists outside of the metastore.

        If we try to write a variable to the metastore while the same key
        exists in an environment variable or custom secrets backend, then
        subsequent reads will not read the set value.

        :param key: Variable Key
        """
        for secrets_backend in ensure_secrets_loaded():
            if not isinstance(secrets_backend, MetastoreBackend):
                try:
                    var_val = secrets_backend.get_variable(key=key)
                    if var_val is not None:
                        log.warning(
                            "The variable {key} is defined in the {cls} secrets backend, which takes "
                            "precedence over reading from the database. The value in the database will be "
                            "updated, but to read it you have to delete the conflicting variable "
                            "from {cls}".format(
                                key=key,
                                cls=secrets_backend.__class__.__name__))
                        return
                except Exception:
                    log.exception(
                        'Unable to retrieve variable from secrets backend (%s). '
                        'Checking subsequent secrets backend.',
                        type(secrets_backend).__name__,
                    )
            return None
Example #2
0
    def get_variable_from_secrets(key: str) -> Optional[str]:
        """
        Get Airflow Variable by iterating over all Secret Backends.

        :param key: Variable Key
        :return: Variable Value
        """
        for secrets_backend in ensure_secrets_loaded():
            var_val = secrets_backend.get_variable(key=key)
            if var_val is not None:
                return var_val
        return None
Example #3
0
    def get_connection_from_secrets(cls, conn_id: str) -> 'Connection':
        """
        Get connection by conn_id.

        :param conn_id: connection id
        :return: connection
        """
        for secrets_backend in ensure_secrets_loaded():
            conn = secrets_backend.get_connection(conn_id=conn_id)
            if conn:
                return conn
        raise AirflowNotFoundException(f"The conn_id `{conn_id}` isn't defined")
Example #4
0
    def get_connections_from_secrets(cls, conn_id: str) -> List['Connection']:
        """
        Get all connections as an iterable.

        :param conn_id: connection id
        :return: array of connections
        """
        for secrets_backend in ensure_secrets_loaded():
            conn_list = secrets_backend.get_connections(conn_id=conn_id)
            if conn_list:
                return list(conn_list)
        raise AirflowNotFoundException("The conn_id `{0}` isn't defined".format(conn_id))
Example #5
0
    def test_backend_fallback_to_env_var(self, mock_get_uri):
        mock_get_uri.return_value = None

        backends = ensure_secrets_loaded()
        backend_classes = [backend.__class__.__name__ for backend in backends]
        self.assertIn('SystemsManagerParameterStoreBackend', backend_classes)

        uri = Connection.get_connections_from_secrets(conn_id="test_mysql")

        # Assert that SystemsManagerParameterStoreBackend.get_conn_uri was called
        mock_get_uri.assert_called_once_with(conn_id='test_mysql')

        self.assertEqual('mysql://*****:*****@host:5432/airflow', uri[0].get_uri())
Example #6
0
    def get_variable_from_secrets(key: str) -> Optional[str]:
        """
        Get Airflow Variable by iterating over all Secret Backends.

        :param key: Variable Key
        :return: Variable Value
        """
        for secrets_backend in ensure_secrets_loaded():
            try:
                var_val = secrets_backend.get_variable(key=key)
                if var_val is not None:
                    return var_val
            except Exception:  # pylint: disable=broad-except
                log.exception(
                    'Unable to retrieve variable from secrets backend (%s). '
                    'Checking subsequent secrets backend.',
                    type(secrets_backend).__name__,
                )
        return None
Example #7
0
    def get_connection_from_secrets(cls, conn_id: str) -> 'Connection':
        """
        Get connection by conn_id.

        :param conn_id: connection id
        :return: connection
        """
        for secrets_backend in ensure_secrets_loaded():
            try:
                conn = secrets_backend.get_connection(conn_id=conn_id)
                if conn:
                    return conn
            except Exception:
                log.exception(
                    'Unable to retrieve connection from secrets backend (%s). '
                    'Checking subsequent secrets backend.',
                    type(secrets_backend).__name__,
                )

        raise AirflowNotFoundException(f"The conn_id `{conn_id}` isn't defined")