Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hide sensitive connection args #9192

Merged
merged 25 commits into from
May 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
12 changes: 5 additions & 7 deletions mindsdb/api/executor/command_executor.py
Original file line number Diff line number Diff line change
Expand Up @@ -527,21 +527,19 @@ def execute_command(self, statement, database_name: str = None) -> ExecuteAnswer
value = statement.value.value

if param == "profiling":
if value in (1, True):
self.session.profiling = value in (1, True)
if self.session.profiling is True:
profiler.enable()
self.session.profiling = True
else:
profiler.disable()
self.session.profiling = False
elif param == "predictor_cache":
if value in (1, True):
self.session.predictor_cache = True
else:
self.session.predictor_cache = False
self.session.predictor_cache = value in (1, True)
elif param == "context":
if value in (0, False, None):
# drop context
query_context_controller.drop_query_context(None)
elif param == "show_secrets":
self.session.show_secrets = value in (1, True)

return ExecuteAnswer(ANSWER_TYPE.OK)
elif category == "autocommit":
Expand Down
9 changes: 1 addition & 8 deletions mindsdb/api/executor/controllers/__init__.py
Original file line number Diff line number Diff line change
@@ -1,8 +1 @@
import os

from .session_controller import (
SessionController,
ServerSessionContorller,
)
if os.environ.get("MINDSDB_EXECUTOR_SERVICE_HOST") and os.environ.get("MINDSDB_EXECUTOR_SERVICE_PORT"):
SessionController = ServerSessionContorller
from .session_controller import SessionController
38 changes: 1 addition & 37 deletions mindsdb/api/executor/controllers/session_controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,6 @@
* permission of MindsDB Inc
*******************************************************
"""

import os
from uuid import uuid4

import requests

from mindsdb.api.executor.datahub.datahub import init_datahub
from mindsdb.utilities.config import Config
from mindsdb.interfaces.agents.agents_controller import AgentsController
Expand Down Expand Up @@ -59,6 +53,7 @@ def __init__(self, api_type='http') -> object:
self.packet_sequence_number = 0
self.profiling = False
self.predictor_cache = True
self.show_secrets = False

def inc_packet_sequence_number(self):
self.packet_sequence_number = (self.packet_sequence_number + 1) % 256
Expand Down Expand Up @@ -88,34 +83,3 @@ def to_json(self):
def from_json(self, updated):
for key in updated:
setattr(self, key, updated[key])


class ServerSessionContorller(SessionController):
"""SessionController implementation for case of Executor service.
The difference with SessionController is that there is an id in this one.
The instance uses the id to synchronize its settings with the appropriate
ServiceSessionController instance on the Executor side."""

def __init__(self):
super().__init__()
self.id = f"session_{uuid4()}"
self.executor_url = os.environ.get("MINDSDB_EXECUTOR_URL", None)
self.executor_host = os.environ.get("MINDSDB_EXECUTOR_SERVICE_HOST", None)
self.executor_port = os.environ.get("MINDSDB_EXECUTOR_SERVICE_PORT", None)
if (self.executor_host is None or self.executor_port is None) and self.executor_url is None:
raise Exception(f"""{self.__class__.__name__} can be used only in modular mode of MindsDB.
Use Executor as a service and specify MINDSDB_EXECUTOR_URL env variable""")
logger.info(
"%s.__init__: executor url - %s", self.__class__.__name__, self.executor_url
)

def __del__(self):
"""Terminate the appropriate ServiceSessionController instance as well."""
if self.executor_url is not None:
url = self.executor_url + "/" + "session"
logger.info(
"%s.__del__: delete an appropriate ServiceSessionController with, id - %s on the Executor service side",
self.__class__.__name__,
self.id,
)
requests.delete(url, json={"id": self.id})
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,6 @@ def get_projects_names(self):
return [x.lower() for x in projects]

def get_tables(self):

return {
name: table
for name, table in self.tables.items()
Expand All @@ -161,7 +160,7 @@ def query(self, query: ASTNode, session=None):
tbl = self.tables[table_name]

if hasattr(tbl, 'get_data'):
dataframe = tbl.get_data(query=query, inf_schema=self)
dataframe = tbl.get_data(query=query, inf_schema=self, session=self.session)
else:
dataframe = self._get_empty_table(tbl)
data = query_df(dataframe, query, session=self.session)
Expand Down
58 changes: 28 additions & 30 deletions mindsdb/api/executor/datahub/datanodes/mindsdb_tables.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,38 +65,36 @@ class ModelsTable(MdbTable):
]

@classmethod
def get_data(cls, inf_schema=None, **kwargs):
def get_data(cls, session, inf_schema, **kwargs):
data = []
for project_name in inf_schema.get_projects_names():
project = inf_schema.database_controller.get_project(name=project_name)
project_models = project.get_models(active=None)
project_models = project.get_models(active=None, with_secrets=session.show_secrets)
for row in project_models:
table_name = row["name"]
table_meta = row["metadata"]

data.append(
[
table_name,
table_meta["engine"],
project_name,
table_meta["active"],
table_meta["version"],
table_meta["status"],
table_meta["accuracy"],
table_meta["predict"],
table_meta["update_status"],
table_meta["mindsdb_version"],
table_meta["error"],
table_meta["select_data_query"],
to_json(table_meta["training_options"]),
table_meta["current_training_phase"],
table_meta["total_training_phases"],
table_meta["training_phase_name"],
table_meta["label"],
row["created_at"],
table_meta["training_time"],
]
)
data.append([
table_name,
table_meta["engine"],
project_name,
table_meta["active"],
table_meta["version"],
table_meta["status"],
table_meta["accuracy"],
table_meta["predict"],
table_meta["update_status"],
table_meta["mindsdb_version"],
table_meta["error"],
table_meta["select_data_query"],
to_json(table_meta["training_options"]),
table_meta["current_training_phase"],
table_meta["total_training_phases"],
table_meta["training_phase_name"],
table_meta["label"],
row["created_at"],
table_meta["training_time"],
])
# TODO optimise here
# if target_table is not None and target_table != project_name:
# continue
Expand All @@ -110,9 +108,9 @@ class DatabasesTable(MdbTable):
columns = ["NAME", "TYPE", "ENGINE", "CONNECTION_DATA"]

@classmethod
def get_data(cls, inf_schema=None, **kwargs):
def get_data(cls, session, inf_schema, **kwargs):

project = inf_schema.database_controller.get_list()
project = inf_schema.database_controller.get_list(with_secrets=session.show_secrets)
data = [
[x["name"], x["type"], x["engine"], to_json(x.get("connection_data"))]
for x in project
Expand All @@ -129,9 +127,9 @@ class MLEnginesTable(MdbTable):
]

@classmethod
def get_data(cls, inf_schema=None, **kwargs):
def get_data(cls, session, inf_schema, **kwargs):

integrations = inf_schema.integration_controller.get_all()
integrations = inf_schema.integration_controller.get_all(show_secrets=session.show_secrets)
ml_integrations = {
key: val for key, val in integrations.items() if val["type"] == "ml"
}
Expand All @@ -158,7 +156,7 @@ class HandlersTable(MdbTable):
]

@classmethod
def get_data(cls, inf_schema=None, **kwargs):
def get_data(cls, inf_schema, **kwargs):

handlers = inf_schema.integration_controller.get_handlers_import_status()

Expand Down
6 changes: 3 additions & 3 deletions mindsdb/api/http/namespaces/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ class ListIntegration(Resource):
@api_endpoint_metrics('GET', '/config/integrations')
def get(self):
return {
'integrations': [k for k in ca.integration_controller.get_all(sensitive_info=False)]
'integrations': [k for k in ca.integration_controller.get_all(show_secrets=False)]
}


Expand All @@ -97,7 +97,7 @@ class AllIntegration(Resource):
@ns_conf.doc('get_all_integrations')
@api_endpoint_metrics('GET', '/config/all_integrations')
def get(self):
integrations = ca.integration_controller.get_all(sensitive_info=False)
integrations = ca.integration_controller.get_all(show_secrets=False)
return integrations


Expand All @@ -107,7 +107,7 @@ class Integration(Resource):
@ns_conf.doc('get_integration')
@api_endpoint_metrics('GET', '/config/integrations/integration')
def get(self, name):
integration = ca.integration_controller.get(name, sensitive_info=False)
integration = ca.integration_controller.get(name, show_secrets=False)
if integration is None:
abort(404, f'Can\'t find database integration: {name}')
integration = copy.deepcopy(integration)
Expand Down
2 changes: 1 addition & 1 deletion mindsdb/api/http/namespaces/sql.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ def post(self):
error_code = query_response.get("error_code")
error_text = query_response.get("error_message")

context = mysql_proxy.get_context(context)
context = mysql_proxy.get_context()

query_response["context"] = context

Expand Down
8 changes: 6 additions & 2 deletions mindsdb/api/mysql/mysql_proxy/mysql_proxy.py
Original file line number Diff line number Diff line change
Expand Up @@ -851,9 +851,13 @@ def set_context(self, context):
self.session.profiling = context["profiling"]
if "predictor_cache" in context:
self.session.predictor_cache = context["predictor_cache"]
if "show_secrets" in context:
self.session.show_secrets = context["show_secrets"]

def get_context(self, context):
context = {}
def get_context(self):
context = {
"show_secrets": self.session.show_secrets
}
if self.session.database is not None:
context["db"] = self.session.database
if self.session.profiling is True:
Expand Down
7 changes: 2 additions & 5 deletions mindsdb/integrations/handlers/access_handler/__init__.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
from mindsdb.integrations.libs.const import HANDLER_TYPE

from .__about__ import __version__ as version, __description__ as description
from .connection_args import connection_args_example, connection_args
try:
from .access_handler import (
AccessHandler as Handler,
connection_args_example,
connection_args
)
from .access_handler import AccessHandler as Handler
import_error = None
except Exception as e:
Handler = None
Expand Down
14 changes: 0 additions & 14 deletions mindsdb/integrations/handlers/access_handler/access_handler.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
from typing import Optional
from collections import OrderedDict

import pandas as pd
import pyodbc
Expand All @@ -17,7 +16,6 @@
HandlerResponse as Response,
RESPONSE_TYPE
)
from mindsdb.integrations.libs.const import HANDLER_CONNECTION_ARG_TYPE as ARG_TYPE

logger = log.getLogger(__name__)

Expand Down Expand Up @@ -197,15 +195,3 @@ def get_columns(self, table_name: str) -> StatusResponse:
)

return response


connection_args = OrderedDict(
db_file={
'type': ARG_TYPE.STR,
'description': 'The database file where the data will be stored.'
}
)

connection_args_example = OrderedDict(
db_file='C:\\Users\\minurap\\Documents\\example_db.accdb'
)
15 changes: 15 additions & 0 deletions mindsdb/integrations/handlers/access_handler/connection_args.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
from collections import OrderedDict

from mindsdb.integrations.libs.const import HANDLER_CONNECTION_ARG_TYPE as ARG_TYPE


connection_args = OrderedDict(
db_file={
'type': ARG_TYPE.STR,
'description': 'The database file where the data will be stored.'
}
)

connection_args_example = OrderedDict(
db_file='C:\\Users\\minurap\\Documents\\example_db.accdb'
)
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
from .__about__ import __description__ as description
from .__about__ import __version__ as version

from .connection_args import connection_args, connection_args_example
try:
from .aerospike_handler import AerospikeHandler as Handler
from .aerospike_handler import connection_args, connection_args_example
import_error = None
except Exception as e:
Handler = None
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
from typing import Optional
from collections import OrderedDict
import pandas as pd
import aerospike
import re
from typing import Optional

import duckdb
import aerospike
import pandas as pd
# from sqlalchemy import create_engine

from mindsdb_sql import parse_sql
Expand All @@ -16,7 +16,6 @@
HandlerResponse as Response,
RESPONSE_TYPE
)
from mindsdb.integrations.libs.const import HANDLER_CONNECTION_ARG_TYPE as ARG_TYPE


class AerospikeHandler(DatabaseHandler):
Expand Down Expand Up @@ -235,45 +234,3 @@ def get_columns(self, table_name: str) -> Response:
self.disconnect()

return response


connection_args = OrderedDict(
user={
'type': ARG_TYPE.STR,
'description': 'The user name used to authenticate with the Aerospike server.',
'required': False,
'label': 'User'
},
password={
'type': ARG_TYPE.STR,
'description': 'The password to authenticate the user with the Aerospike server.',
'required': False,
'label': 'Password'
},
host={
'type': ARG_TYPE.STR,
'description': 'The host name or IP address of the Aerospike server. NOTE: use \'127.0.0.1\' instead of \'localhost\' to connect to local server.',
'required': True,
'label': 'Host'
},
port={
'type': ARG_TYPE.INT,
'description': 'The TCP/IP port of the Aerospike server. Must be an integer.',
'required': True,
'label': 'Port'
},
namespace={
'type': ARG_TYPE.STR,
'description': 'The namespace name to use for the query in the Aerospike server.',
'required': True,
'label': 'namespace'
}
)

connection_args_example = OrderedDict(
user="demo_user",
password="demo_password",
host='127.0.0.1',
port=3000,
namespace="demo",
)