-
Notifications
You must be signed in to change notification settings - Fork 121
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
Implementation backend part of plugin in TypeScript #594
Open
lunaticusgreen
wants to merge
72
commits into
v3.3
Choose a base branch
from
be-plugin-ts
base: v3.3
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 4 commits
Commits
Show all changes
72 commits
Select commit
Hold shift + click to select a range
b484d6d
initial migration commit
lunaticusgreen 515879f
initial migration commit
lunaticusgreen c0024d9
add binary builds
lunaticusgreen ef3f85b
fix tsconfig.json
lunaticusgreen 1ecbb81
Add alerts data processing
lunaticusgreen 13728b3
packages cleanup
lunaticusgreen 068d4e5
packages cleanup
lunaticusgreen b9004f2
packages cleanup
lunaticusgreen 8b0f07b
packages cleanup
lunaticusgreen 46d4a64
packages cleanup
lunaticusgreen 1ab8cbd
packages cleanup
lunaticusgreen 250faa0
packages cleanup
lunaticusgreen d4ac99b
fix type
lunaticusgreen f3a0d2c
fix type
lunaticusgreen 8500693
bugfixes
lunaticusgreen 6df689b
bugfixes
lunaticusgreen f911620
fix data transformation
lunaticusgreen 62af727
fix data transformation
lunaticusgreen 80a1033
fix data transformation
lunaticusgreen 8057687
fix data transformation
lunaticusgreen 42d6ccb
Merge branch 'master' into be-plugin-ts
lunaticusgreen b3affa8
Merge branch 'be-plugin-ts' of github.com:Altinity/clickhouse-grafana…
Slach eb9f98f
package-lock.json after npm install
Slach 9d64f5d
fix Invalid interpolation format for "command" option in service "ba…
Slach f7343ab
add PKG_CACHE_PATH to backend_builder
Slach 8544934
return back grafana-clickhouse-datasource and upgrade external instal…
Slach d66ad19
try to debug testflows failures
Slach 000bb74
added healthchecks to proper selenium-standalone works
Slach 87cd379
we don't need grafana_external_install, return -o classic back
Slach ff43a37
why i need to struggle with testflows instead of develop plugin
Slach 9daaacf
add healthcheck to mysql and postgres docker-compose.yaml services
Slach 2dce9f0
add more logging to failed tests and add trickster to selenium-standa…
Slach 3384e7e
change GF_UNIFIED_ALERTING_ENABLED: false, GF_ALERTING_ENABLED:…
Slach 568ab1b
add Show machine IP
Slach 19b1131
Merge branch 'master' of github.com:Altinity/clickhouse-grafana into …
Slach 69a140b
continue merge with master
Slach 487f21c
remove wrong double `-d` arg in docker-compose up
Slach aa0f90d
Merge branch 'master' into be-plugin-ts
Slach f48b182
Merge branch 'master' into be-plugin-ts
Slach 39ae837
Merge branch 'master' into be-plugin-ts
Slach dd5ea47
Merge branch 'be-plugin-ts' of github.com:Altinity/clickhouse-grafana…
Slach 5ffba51
FIx data processing
lunaticusgreen f18780c
FIx data processing
lunaticusgreen ac4349e
FIx data processing
lunaticusgreen 08e20b2
FIx data processing
lunaticusgreen 8dd7a20
Update.
antip00 fd585ed
Merge https://github.com/Altinity/clickhouse-grafana
antip00 da610e7
Update.
antip00 369fd08
merge with master
Slach accf84f
Merge branch 'be-plugin-ts' of github.com:Altinity/clickhouse-grafana…
Slach d85e3ea
sync package.json with package-lock.json
Slach 0aa590b
Merge branch 'v3.3' into be-plugin-ts
Slach c8c51bc
run CI and testflows in any PR
Slach b9c2a4b
run CI and testflows in any PR
Slach 0ed5e45
Update.
antip00 404046a
Bump dompurify from 2.5.1 to 2.5.6
dependabot[bot] 26233b4
Adding tests for legacy alerts.
antip00 a1fd944
Update.
antip00 cd1233e
Merge https://github.com/Altinity/clickhouse-grafana
antip00 feddd4c
Update.
antip00 fdc5498
Update.
antip00 c14f507
Bump github.com/grafana/grafana-plugin-sdk-go from 0.228.0 to 0.250.0
dependabot[bot] 47a0cbb
Merge pull request #629 from Altinity/dependabot/go_modules/github.co…
Slach 7e3158d
Merge pull request #627 from Altinity/dependabot/npm_and_yarn/dompuri…
Slach 6562289
Merge pull request #628 from antip00/master
Slach d7a27f7
merge master with be-plugin-ts, resolved conflicts
Slach e4c7e23
return ffails back
Slach cfd1cf1
Fix incorrect import
lunaticusgreen e65cb15
Adding tests for default values.
antip00 cc4158f
Update.
antip00 453760e
Merge pull request #631 from antip00/master
Slach 68113d7
merged with master, resolve conflicts
Slach File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,222 @@ | ||
// @ts-nocheck | ||
const datePrefix = "Date"; | ||
const dateTimePrefix = "DateTime"; | ||
const dateTime64Prefix = "DateTime64"; | ||
const timeZonePrefix = "('"; | ||
const timeZone64Separator = ","; | ||
const dateTZPrefix = datePrefix + timeZonePrefix; | ||
const dateTimeTZPrefix = dateTimePrefix + timeZonePrefix; | ||
const dateTime64TZPrefix = dateTime64Prefix + timeZonePrefix; | ||
|
||
const dateLayout = "yyyy-MM-dd"; | ||
const dateTimeLayout = `${dateLayout} HH:mm:ss`; | ||
const dateTime64Layout3 = `${dateTimeLayout}.SSS`; | ||
const dateTime64Layout6 = `${dateTimeLayout}.SSSSSS`; | ||
|
||
const dateTimeTypeRE = /(Date\([^)]+\)|DateTime\([^)]+\)|DateTime64\([^)]+\))/; | ||
|
||
function parseTimeZone(tz) { | ||
try { | ||
return new Intl.DateTimeFormat('en-US', { timeZone: tz }).resolvedOptions().timeZone; | ||
} catch (err) { | ||
return "UTC"; | ||
} | ||
} | ||
|
||
function extractTimeZoneNameFromFieldType(fieldType) { | ||
let tz = ""; | ||
if (fieldType.startsWith(dateTZPrefix)) { | ||
tz = fieldType.slice(dateTZPrefix.length + 1, -2); | ||
} else if (fieldType.startsWith(dateTimeTZPrefix)) { | ||
tz = fieldType.slice(dateTimeTZPrefix.length + 1, -2); | ||
} else if (fieldType.startsWith(dateTime64TZPrefix) && fieldType.includes(timeZone64Separator)) { | ||
tz = fieldType.slice(fieldType.indexOf(timeZone64Separator) + 3, -2); | ||
} else if (dateTimeTypeRE.test(fieldType)) { | ||
const matches = fieldType.match(dateTimeTypeRE); | ||
if (matches.length > 0) { | ||
return extractTimeZoneNameFromFieldType(matches[0]); | ||
} | ||
} | ||
return tz.trim(); | ||
} | ||
|
||
function fetchTimeZoneFromFieldType(fieldType, tzFromServer) { | ||
const tz = extractTimeZoneNameFromFieldType(fieldType); | ||
return tz !== "" ? parseTimeZone(tz) : tzFromServer; | ||
} | ||
|
||
function newDataFieldByType(fieldName, fieldType) { | ||
if (fieldType.startsWith("LowCardinality")) { | ||
fieldType = fieldType.slice("LowCardinality(".length, -1); | ||
} | ||
|
||
const isNullable = fieldType.includes("Nullable"); | ||
fieldType = fieldType.replace("Nullable(", "").replace(")", ""); | ||
|
||
switch (fieldType) { | ||
case "String": | ||
case "UUID": | ||
case "IPv6": | ||
case "IPv4": | ||
return newStringField(fieldName, isNullable); | ||
case "UInt8": | ||
case "UInt16": | ||
case "UInt32": | ||
case "Int8": | ||
case "Int16": | ||
case "Int32": | ||
case "Float32": | ||
case "Float64": | ||
return newFloat64Field(fieldName, isNullable); | ||
case "UInt64": | ||
if (fieldName === "t" && !isNullable) { | ||
return newTimeField(fieldName, false); | ||
} | ||
return isNullable ? [] : []; | ||
case "Int64": | ||
return isNullable ? [] : []; | ||
default: | ||
if (fieldType.startsWith("Decimal")) { | ||
return newFloat64Field(fieldName, isNullable); | ||
} else if (fieldType.startsWith("FixedString") || fieldType.startsWith("Enum")) { | ||
return newStringField(fieldName, isNullable); | ||
} else if (fieldType.startsWith(dateTime64Prefix) || fieldType.startsWith(dateTimePrefix) || fieldType.startsWith(datePrefix)) { | ||
return newTimeField(fieldName, isNullable); | ||
} else { | ||
return newStringField(fieldName, isNullable); | ||
} | ||
} | ||
} | ||
|
||
function newTimeField(fieldName, isNullable) { | ||
return isNullable ? [] : []; | ||
} | ||
|
||
function newFloat64Field(fieldName, isNullable) { | ||
return isNullable ? [] : []; | ||
} | ||
|
||
function newStringField(fieldName, isNullable) { | ||
return isNullable ? [] : []; | ||
} | ||
|
||
function parseFloatValue(value, isNullable) { | ||
if (value != null) { | ||
const floatValue = parseFloat(value); | ||
return isNullable ? floatValue : floatValue; | ||
} | ||
return isNullable ? null : 0.0; | ||
} | ||
|
||
function parseStringValue(value, isNullable) { | ||
if (value != null) { | ||
const stringValue = String(value); | ||
return isNullable ? stringValue : stringValue; | ||
} | ||
return isNullable ? null : ""; | ||
} | ||
|
||
function parseMapValue(value, isNullable) { | ||
if (value instanceof Object) { | ||
try { | ||
return JSON.stringify(value); | ||
} catch (err) { | ||
return null; | ||
} | ||
} | ||
return isNullable ? null : ""; | ||
} | ||
|
||
function parseUInt64Value(value, isNullable) { | ||
if (value != null) { | ||
const uint64Value = BigInt(value); | ||
return isNullable ? uint64Value : uint64Value; | ||
} | ||
return isNullable ? null : BigInt(0); | ||
} | ||
|
||
function parseInt64Value(value, isNullable) { | ||
if (value != null) { | ||
const int64Value = BigInt(value); | ||
return isNullable ? int64Value : int64Value; | ||
} | ||
return isNullable ? null : BigInt(0); | ||
} | ||
|
||
function parseTimestampValue(value, isNullable) { | ||
if (value != null) { | ||
const intValue = BigInt(value); | ||
const timeValue = new Date(Number(intValue)); | ||
return isNullable ? timeValue : timeValue; | ||
} | ||
return isNullable ? null : new Date(0); | ||
} | ||
|
||
function parseDateTimeValue(value, layout, timezone, isNullable) { | ||
if (value != null) { | ||
const dateTimeValue = new Date(`${value} ${timezone}`); | ||
return isNullable ? dateTimeValue : dateTimeValue; | ||
} | ||
return isNullable ? null : new Date(0); | ||
} | ||
|
||
export const parseValue = (fieldName, fieldType, tz, value, isNullable) => { | ||
if (fieldType.startsWith("Nullable")) { | ||
return parseValue(fieldName, fieldType.slice("Nullable(".length, -1), tz, value, true); | ||
} else if (fieldType.startsWith("LowCardinality")) { | ||
return parseValue(fieldName, fieldType.slice("LowCardinality(".length, -1), tz, value, isNullable); | ||
} else if (fieldType.startsWith("Map(") && fieldType.endsWith(")")) { | ||
return parseMapValue(value, isNullable); | ||
} else { | ||
switch (fieldType) { | ||
case "String": | ||
case "UUID": | ||
case "IPv4": | ||
case "IPv6": | ||
return parseStringValue(value, isNullable); | ||
case "UInt8": | ||
case "UInt16": | ||
case "UInt32": | ||
case "Int8": | ||
case "Int16": | ||
case "Int32": | ||
case "Float32": | ||
case "Float64": | ||
return parseFloatValue(value, isNullable); | ||
case "UInt64": | ||
if (fieldName === "t") { | ||
return parseTimestampValue(value, isNullable); | ||
} | ||
return parseUInt64Value(value, isNullable); | ||
case "Int64": | ||
if (fieldName === "t") { | ||
return parseTimestampValue(value, isNullable); | ||
} | ||
return parseInt64Value(value, isNullable); | ||
default: | ||
if (fieldType.startsWith("Decimal")) { | ||
return parseFloatValue(value, isNullable); | ||
} else if (fieldType.startsWith("FixedString") || fieldType.startsWith("Enum")) { | ||
return parseStringValue(value, isNullable); | ||
} else if (fieldType.startsWith(dateTime64Prefix) && fieldType.includes("3")) { | ||
return parseDateTimeValue(value, dateTime64Layout3, tz, isNullable); | ||
} else if (fieldType.startsWith(dateTime64Prefix) && fieldType.includes("6")) { | ||
return parseDateTimeValue(value, dateTime64Layout6, tz, isNullable); | ||
} else if (fieldType.startsWith(dateTimePrefix)) { | ||
return parseDateTimeValue(value, dateTimeLayout, tz, isNullable); | ||
} else if (fieldType.startsWith(datePrefix)) { | ||
return parseDateTimeValue(value, dateLayout, tz, isNullable); | ||
} else { | ||
console.warn(`Value [${value}] has compound type [${fieldType}] and will be returned as string`); | ||
|
||
try { | ||
const byteValue = JSON.stringify(value); | ||
return parseStringValue(byteValue, isNullable); | ||
} catch (err) { | ||
console.warn(`Unable to append value of unknown type ${typeof value} because of JSON encoding problem: ${err}`); | ||
return null; | ||
} | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,23 +4,27 @@ import { CHDataSourceOptions } from "../../types/types"; | |
import {logger} from '@grafana/ts-backend'; | ||
|
||
export const getRequestSettings = (pluginContext: any): any => { | ||
logger.info("getRequestSettings pluginContext", pluginContext); | ||
logger.info("getRequestSettings pluginContext", JSON.stringify( pluginContext?.datasourceinstancesettings)); | ||
const jsonData: CHDataSourceOptions = pluginContext?.datasourceinstancesettings?.json | ||
|
||
const decryptedSecureJsonData = pluginContext?. | ||
datasourceinstancesettings?.decryptedsecurejsondataMap.reduce((acc: any, [key, value]: [string, string]) => { | ||
acc[key] = value; | ||
return acc; | ||
},{}); | ||
return { | ||
Instance: { | ||
URL: pluginContext.datasourceinstancesettings.url, | ||
BasicAuthEnabled: pluginContext.datasourceinstancesettings.basicAuthEnabled, | ||
DecryptedSecureJSONData: pluginContext.datasourceinstancesettings.decryptedSecureJsonData, | ||
DecryptedSecureJSONData: decryptedSecureJsonData, | ||
BasicAuthUser: pluginContext.datasourceinstancesettings.basicAuthUser, | ||
}, | ||
UsePost: jsonData.usePOST || false, | ||
UseCompression: jsonData.useCompression || false, | ||
CompressionType: jsonData.compressionType || 'gzip', | ||
UseYandexCloudAuthorization: jsonData.useYandexCloudAuthorization || false, | ||
XHeaderUser: jsonData.xHeaderUser || '', | ||
XHeaderKey: '', // Optional, set as needed | ||
TLSSkipVerify: false, // Set as needed | ||
XHeaderKey: decryptedSecureJsonData.xHeaderKey, // Optional, set as needed | ||
TLSSkipVerify: true, // Set as needed | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. wrong default behavior rollback it |
||
}; | ||
}; | ||
export const createQuery = (options: any, target: any, request: any) => { | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
how to install pkg in system?