feat(influxdb3): add influxdb 3 engine over http
This commit is contained in:
1 parent
613c4f7ca3
commit
264f5c4836
25 files changed
+741
-19
No files matched your search
@@ -1409,22 +1409,26 @@ function buildMqttExternalConfig(): MqttConnectionConfig {
|
||||
};
|
||||
}
|
||||
|
||||
const INFLUXDB_V1V2_DEFAULT_PORT = 8086;
|
||||
const INFLUXDB_V3_DEFAULT_PORT = 8181;
|
||||
|
||||
const influxDbVersion = ref<InfluxDbVersion>("1");
|
||||
const influxDbOrg = ref("");
|
||||
const victoriaMetricsApiPath = ref("/prometheus");
|
||||
const victoriaMetricsLookback = ref("1h");
|
||||
|
||||
function resetInfluxDbFields(config?: Partial<InfluxDbExternalConfig>) {
|
||||
influxDbVersion.value = config?.version === "2" ? "2" : "1";
|
||||
function resetInfluxDbFields(config?: Partial<InfluxDbExternalConfig>, versionHint?: InfluxDbVersion) {
|
||||
const version = versionHint ?? (config?.version === "2" ? "2" : config?.version === "3" ? "3" : "1");
|
||||
influxDbVersion.value = version;
|
||||
influxDbOrg.value = config?.org?.trim() || "";
|
||||
}
|
||||
|
||||
function hydrateInfluxDbFields(value: unknown) {
|
||||
function hydrateInfluxDbFields(value: unknown, versionHint?: InfluxDbVersion) {
|
||||
if (!value || typeof value !== "object") {
|
||||
resetInfluxDbFields();
|
||||
resetInfluxDbFields(undefined, versionHint);
|
||||
return;
|
||||
}
|
||||
resetInfluxDbFields(value as Partial<InfluxDbExternalConfig>);
|
||||
resetInfluxDbFields(value as Partial<InfluxDbExternalConfig>, versionHint);
|
||||
}
|
||||
|
||||
function resetHiveKerberosFields(config?: Pick<ConnectionConfig, "url_params" | "agent_java_options">) {
|
||||
@@ -1442,6 +1446,9 @@ function resetDamengJvmOptions(config?: Pick<ConnectionConfig, "agent_java_optio
|
||||
}
|
||||
|
||||
function buildInfluxDbExternalConfig(): InfluxDbExternalConfig {
|
||||
// InfluxDB 3 Core can run with --without-auth; the driver treats an empty
|
||||
// password as "no Authorization header", so the token stays optional here.
|
||||
if (influxDbVersion.value === "3") return { version: "3" };
|
||||
if (influxDbVersion.value !== "2") return { version: "1" };
|
||||
const org = influxDbOrg.value.trim();
|
||||
if (!org) throw new Error("InfluxDB 2.x organization is required");
|
||||
@@ -1477,11 +1484,17 @@ function buildVictoriaMetricsExternalConfig(): VictoriaMetricsExternalConfig {
|
||||
return { apiPath, lookback };
|
||||
}
|
||||
|
||||
watch(influxDbVersion, (version) => {
|
||||
watch(influxDbVersion, (version, previousVersion) => {
|
||||
if (form.value.db_type !== "influxdb") return;
|
||||
if (version === "2") {
|
||||
if (version === "2" || version === "3") {
|
||||
form.value.username = "";
|
||||
}
|
||||
const port = form.value.port;
|
||||
if (version === "3" && (!port || port === INFLUXDB_V1V2_DEFAULT_PORT)) {
|
||||
form.value.port = INFLUXDB_V3_DEFAULT_PORT;
|
||||
} else if (previousVersion === "3" && port === INFLUXDB_V3_DEFAULT_PORT) {
|
||||
form.value.port = INFLUXDB_V1V2_DEFAULT_PORT;
|
||||
}
|
||||
});
|
||||
|
||||
function requireMqField(value: string, message: string): string {
|
||||
@@ -2556,8 +2569,15 @@ watch(
|
||||
} else {
|
||||
resetMqttFields();
|
||||
}
|
||||
if (config.db_type === "influxdb") {
|
||||
hydrateInfluxDbFields(config.external_config);
|
||||
if (config.db_type === "influxdb" || config.db_type === "influxdb3") {
|
||||
// The influxdb3 engine is presented as the InfluxDB card with
|
||||
// version = 3. Save-side (`applyConnectionFormToConfig`) swaps
|
||||
// db_type back to `influxdb3` when saving.
|
||||
const versionHint: InfluxDbVersion | undefined = config.db_type === "influxdb3" ? "3" : undefined;
|
||||
hydrateInfluxDbFields(config.external_config, versionHint);
|
||||
if (config.db_type === "influxdb3") {
|
||||
form.value.db_type = "influxdb";
|
||||
}
|
||||
} else {
|
||||
resetInfluxDbFields();
|
||||
}
|
||||
@@ -2831,7 +2851,9 @@ function jdbcProductCategory(profileId: string): DbCategoryKey {
|
||||
return category;
|
||||
}
|
||||
|
||||
const dbOptions: DbOption[] = [...CONNECTION_PICKER_OPTIONS, ...jdbcProductPickerOptions().map((option) => ({ ...option, category: jdbcProductCategory(option.value) }))];
|
||||
// `influxdb3` is presented as a version option inside the InfluxDB card
|
||||
// (see the version <Select> below), not as a standalone picker entry.
|
||||
const dbOptions: DbOption[] = [...CONNECTION_PICKER_OPTIONS.filter((option) => option.value !== "influxdb3"), ...jdbcProductPickerOptions().map((option) => ({ ...option, category: jdbcProductCategory(option.value) }))];
|
||||
|
||||
const dbCategoryDefinitions = dbCategoryMetadata.map((category) => ({
|
||||
...category,
|
||||
@@ -3934,11 +3956,17 @@ function connectionConfigForSubmit(id: string, generatedName = ""): ConnectionCo
|
||||
} else if (config.db_type === "influxdb") {
|
||||
config.external_config = buildInfluxDbExternalConfig();
|
||||
config.connection_string = undefined;
|
||||
if (influxDbVersion.value === "2") {
|
||||
if (influxDbVersion.value === "2" || influxDbVersion.value === "3") {
|
||||
config.username = "";
|
||||
config.password = config.password.trim();
|
||||
config.database = config.database?.trim() || undefined;
|
||||
}
|
||||
// Swap db_type to the standalone influxdb3 engine when the version
|
||||
// picker is on 3; the form keeps db_type = influxdb so the same card
|
||||
// renders every InfluxDB flavor.
|
||||
if (influxDbVersion.value === "3") {
|
||||
config.db_type = "influxdb3";
|
||||
}
|
||||
} else if (config.db_type === "victoriametrics") {
|
||||
config.external_config = buildVictoriaMetricsExternalConfig();
|
||||
config.connection_string = undefined;
|
||||
@@ -7218,6 +7246,7 @@ function openExternalUrl(url: string) {
|
||||
<SelectContent>
|
||||
<SelectItem value="1">InfluxDB 1.x</SelectItem>
|
||||
<SelectItem value="2">InfluxDB 2.x</SelectItem>
|
||||
<SelectItem value="3">InfluxDB 3.x</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
@@ -7247,6 +7276,16 @@ function openExternalUrl(url: string) {
|
||||
<PasswordInput v-model="form.password" class="col-span-3" />
|
||||
</div>
|
||||
</template>
|
||||
<template v-else-if="influxDbVersion === '3'">
|
||||
<div class="grid grid-cols-4 items-center gap-4">
|
||||
<Label :class="connectionLabelClass">{{ t("connection.database") }}</Label>
|
||||
<Input v-model="form.database" class="col-span-3" placeholder="my-database" />
|
||||
</div>
|
||||
<div class="grid grid-cols-4 items-center gap-4">
|
||||
<Label :class="connectionLabelClass">Token</Label>
|
||||
<PasswordInput v-model="form.password" class="col-span-3" />
|
||||
</div>
|
||||
</template>
|
||||
<template v-else>
|
||||
<div class="grid grid-cols-4 items-center gap-4">
|
||||
<Label :class="connectionLabelClass">{{ t("connection.user") }}</Label>
|
||||
@@ -7263,7 +7302,7 @@ function openExternalUrl(url: string) {
|
||||
</template>
|
||||
<div class="grid grid-cols-4 items-center gap-4">
|
||||
<Label :class="connectionLabelClass">{{ t("connection.urlParams") }}</Label>
|
||||
<Input v-model="form.url_params" class="col-span-3" :placeholder="influxDbVersion === '2' ? 'precision=ns' : 'epoch=ms'" />
|
||||
<Input v-model="form.url_params" class="col-span-3" :placeholder="influxDbVersion === '2' ? 'precision=ns' : influxDbVersion === '3' ? '' : 'epoch=ms'" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -113,6 +113,7 @@ const assetIcons: Record<string, string> = {
|
||||
consul: "consul",
|
||||
iris: "iris",
|
||||
influxdb: "influxdb",
|
||||
influxdb3: "influxdb",
|
||||
victoriametrics: "victoriametrics.png",
|
||||
zookeeper: "zookeeper",
|
||||
oscar: "oscar.png",
|
||||
|
||||
@@ -263,6 +263,9 @@ export function connectionUrlPlaceholder(dbType: DatabaseType): string {
|
||||
case "influxdb":
|
||||
return "influxdb://user:password@host:port/database";
|
||||
|
||||
case "influxdb3":
|
||||
return "influxdb3://token@host:8181/database";
|
||||
|
||||
case "victoriametrics":
|
||||
return "http://user:password@host:port/prometheus";
|
||||
|
||||
|
||||
@@ -229,7 +229,7 @@ export function supportsObjectBrowserTreeNode(dbType: DatabaseType | undefined,
|
||||
}
|
||||
|
||||
export function supportsTableTruncate(dbType?: DatabaseType): boolean {
|
||||
return !!dbType && dbType !== "impala" && dbType !== "sqlite" && dbType !== "rqlite" && dbType !== "turso" && dbType !== "cloudflare-d1" && dbType !== "duckdb" && dbType !== "influxdb" && dbType !== "victoriametrics" && dbType !== "manticoresearch";
|
||||
return !!dbType && dbType !== "impala" && dbType !== "sqlite" && dbType !== "rqlite" && dbType !== "turso" && dbType !== "cloudflare-d1" && dbType !== "duckdb" && dbType !== "influxdb" && dbType !== "influxdb3" && dbType !== "victoriametrics" && dbType !== "manticoresearch";
|
||||
}
|
||||
|
||||
export function supportsTableVacuum(dbType?: DatabaseType): boolean {
|
||||
|
||||
@@ -90,6 +90,7 @@ export const DATABASE_NAMESPACE_CREATION_MATRIX = {
|
||||
zookeeper: { deferred: "key-value namespaces are not databases" },
|
||||
iris: { database: "schema" },
|
||||
influxdb: { connection: "database" },
|
||||
influxdb3: { deferred: "database creation on InfluxDB 3.x goes through the /api/v3/configure/database admin endpoint, which is not part of the SQL execution path" },
|
||||
victoriametrics: { deferred: "metric namespaces are managed by VictoriaMetrics deployment configuration" },
|
||||
jdbc: { deferred: "generic JDBC does not expose a reliable dialect-specific create target" },
|
||||
mq: { deferred: "message queue namespaces are handled by MQ admin panels" },
|
||||
|
||||
@@ -92,6 +92,7 @@ const DATABASE_TYPE_OBJECTS = new Map<DatabaseType, SidebarObjectKind[]>([
|
||||
["neo4j", TABLE_VIEW_OBJECTS],
|
||||
// others
|
||||
["influxdb", ["TABLE"]],
|
||||
["influxdb3", ["TABLE"]],
|
||||
["victoriametrics", ["TABLE"]],
|
||||
["hbase", ["TABLE"]],
|
||||
["questdb", ["TABLE", "VIEW", "MATERIALIZED_VIEW"]],
|
||||
|
||||
@@ -90,6 +90,7 @@ export const DATABASE_PROPERTY_EDITING_MATRIX = {
|
||||
zookeeper: { deferred: "key-value namespaces are not databases" },
|
||||
iris: { deferred: "schema properties need product-specific handling" },
|
||||
influxdb: { deferred: "database retention policies need a dedicated workflow" },
|
||||
influxdb3: { deferred: "database retention policies need a dedicated workflow" },
|
||||
victoriametrics: { deferred: "metric and retention settings are managed by VictoriaMetrics deployment configuration" },
|
||||
jdbc: { deferred: "generic JDBC does not expose reliable dialect-specific properties" },
|
||||
mq: { deferred: "message queue namespaces are handled by MQ admin panels" },
|
||||
|
||||
@@ -102,6 +102,12 @@ const capabilityByType: Partial<Record<DatabaseType, Partial<TableMetadataCapabi
|
||||
triggers: false,
|
||||
ddl: false,
|
||||
},
|
||||
influxdb3: {
|
||||
indexes: false,
|
||||
foreignKeys: false,
|
||||
triggers: false,
|
||||
ddl: false,
|
||||
},
|
||||
influxdb: {
|
||||
indexes: false,
|
||||
foreignKeys: false,
|
||||
|
||||
@@ -117,6 +117,7 @@ export const CONNECTION_PROFILES = {
|
||||
mqtt: { type: "mqtt", port: 1883, user: "", label: "MQTT", icon: "mqtt", host: "127.0.0.1" },
|
||||
iris: { type: "iris", port: 1972, user: "_SYSTEM", label: "IRIS", icon: "iris" },
|
||||
influxdb: { type: "influxdb", port: 8086, user: "", label: "InfluxDB", icon: "InfluxDB" },
|
||||
influxdb3: { type: "influxdb3", port: 8181, user: "", label: "InfluxDB 3.x", icon: "InfluxDB" },
|
||||
victoriametrics: { type: "victoriametrics", port: 8428, user: "", label: "VictoriaMetrics", icon: "victoriametrics" },
|
||||
custom_mysql: { type: "mysql", port: 3306, user: "root", label: "Custom", icon: "mysql", urlParams: "" },
|
||||
dolt: { type: "mysql", port: 3306, user: "root", label: "Dolt", icon: "dolt", urlParams: "" },
|
||||
@@ -221,6 +222,7 @@ export const CONNECTION_PROFILE_ICONS = {
|
||||
mqtt: "mqtt",
|
||||
iris: "iris",
|
||||
influxdb: "influxdb",
|
||||
influxdb3: "influxdb",
|
||||
victoriametrics: "victoriametrics",
|
||||
custom_mysql: "mysql",
|
||||
dolt: "dolt",
|
||||
@@ -319,6 +321,7 @@ export const CONNECTION_PICKER_OPTIONS = [
|
||||
{ value: "mqtt", label: "MQTT", category: "mq" },
|
||||
{ value: "iris", label: "IRIS", category: "sql" },
|
||||
{ value: "influxdb", label: "InfluxDB", category: "timeseries" },
|
||||
{ value: "influxdb3", label: "InfluxDB 3.x", category: "timeseries" },
|
||||
{ value: "victoriametrics", label: "VictoriaMetrics", category: "timeseries" },
|
||||
{ value: "custom_mysql", label: "Custom (MySQL)", category: "sql" },
|
||||
{ value: "dolt", label: "Dolt", category: "sql" },
|
||||
|
||||
@@ -76,6 +76,7 @@ export const DATABASE_TYPES = [
|
||||
"iotdb",
|
||||
"iris",
|
||||
"influxdb",
|
||||
"influxdb3",
|
||||
"victoriametrics",
|
||||
"jdbc",
|
||||
"spark",
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
export type InfluxDbVersion = "1" | "2";
|
||||
export type InfluxDbVersion = "1" | "2" | "3";
|
||||
|
||||
export interface InfluxDbExternalConfig {
|
||||
version?: InfluxDbVersion;
|
||||
|
||||
Reference in new issue
Block a user