diff --git a/api/chalicelib/core/events/events_ch.py b/api/chalicelib/core/events/events_ch.py index f1f28a9e7..384a31d3d 100644 --- a/api/chalicelib/core/events/events_ch.py +++ b/api/chalicelib/core/events/events_ch.py @@ -1,18 +1,13 @@ from chalicelib.utils import ch_client from .events_pg import * - - -def __explode_properties(rows): - for i in range(len(rows)): - rows[i] = {**rows[i], **rows[i]["$properties"]} - rows[i].pop("$properties") - return rows +from chalicelib.utils.exp_ch_helper import explode_dproperties, add_timestamp def get_customs_by_session_id(session_id, project_id): with ch_client.ClickHouseClient() as cur: rows = cur.execute(""" \ SELECT `$properties`, + properties, created_at, 'CUSTOM' AS type FROM product_analytics.events @@ -21,8 +16,10 @@ def get_customs_by_session_id(session_id, project_id): AND `$event_name`!='INCIDENT' ORDER BY created_at;""", {"project_id": project_id, "session_id": session_id}) - rows = __explode_properties(rows) - return helper.list_to_camel_case(rows) + rows = helper.list_to_camel_case(rows, ignore_keys=["properties"]) + rows = explode_dproperties(rows) + rows = add_timestamp(rows) + return rows def __merge_cells(rows, start, count, replacement): @@ -69,12 +66,13 @@ def get_by_session_id(session_id, project_id, group_clickrage=False, event_type: parameters={"project_id": project_id, "session_id": session_id, "select_events": select_events}) rows = cur.execute(query) - rows = __explode_properties(rows) + rows = explode_dproperties(rows) if group_clickrage and 'CLICK' in select_events: rows = __get_grouped_clickrage(rows=rows, session_id=session_id, project_id=project_id) rows = helper.list_to_camel_case(rows) rows = sorted(rows, key=lambda k: k["createdAt"]) + rows = add_timestamp(rows) return rows @@ -91,7 +89,7 @@ def get_incidents_by_session_id(session_id, project_id): ORDER BY created_at;""", parameters={"project_id": project_id, "session_id": session_id}) rows = cur.execute(query) - rows = __explode_properties(rows) + rows = explode_dproperties(rows) rows = helper.list_to_camel_case(rows) rows = sorted(rows, key=lambda k: k["createdAt"]) return rows diff --git a/api/chalicelib/core/issues/issues_ch.py b/api/chalicelib/core/issues/issues_ch.py index b6297f598..3b0421747 100644 --- a/api/chalicelib/core/issues/issues_ch.py +++ b/api/chalicelib/core/issues/issues_ch.py @@ -1,6 +1,6 @@ from chalicelib.utils import ch_client, helper import datetime -from .issues_pg import get_all_types +from chalicelib.utils.exp_ch_helper import explode_dproperties, add_timestamp def get(project_id, issue_id): @@ -21,7 +21,7 @@ def get(project_id, issue_id): def get_by_session_id(session_id, project_id, issue_type=None): with ch_client.ClickHouseClient() as cur: query = cur.format(query=f"""\ - SELECT * + SELECT created_at, `$properties` FROM product_analytics.events WHERE session_id = %(session_id)s AND project_id= %(project_id)s @@ -29,8 +29,11 @@ def get_by_session_id(session_id, project_id, issue_type=None): {"AND issue_type = %(type)s" if issue_type is not None else ""} ORDER BY created_at;""", parameters={"session_id": session_id, "project_id": project_id, "type": issue_type}) - data = cur.execute(query) - return helper.list_to_camel_case(data) + rows = cur.execute(query) + rows = explode_dproperties(rows) + rows = helper.list_to_camel_case(rows) + rows = add_timestamp(rows) + return rows # To reduce the number of issues in the replay; diff --git a/api/chalicelib/utils/exp_ch_helper.py b/api/chalicelib/utils/exp_ch_helper.py index a0d02a524..f1231ec09 100644 --- a/api/chalicelib/utils/exp_ch_helper.py +++ b/api/chalicelib/utils/exp_ch_helper.py @@ -1,13 +1,14 @@ import logging +import math import re +import struct +from decimal import Decimal from typing import Union, Any import schemas from chalicelib.utils import sql_helper as sh +from chalicelib.utils.TimeUTC import TimeUTC from schemas import SearchEventOperator -import math -import struct -from decimal import Decimal logger = logging.getLogger(__name__) @@ -233,3 +234,16 @@ def best_clickhouse_type(value): return "Float64" raise TypeError(f"Unsupported type: {type(value).__name__}") + + +def explode_dproperties(rows): + for i in range(len(rows)): + rows[i] = {**rows[i], **rows[i]["$properties"]} + rows[i].pop("$properties") + return rows + + +def add_timestamp(rows): + for row in rows: + row["timestamp"] = TimeUTC.datetime_to_timestamp(row["createdAt"]) + return rows diff --git a/api/chalicelib/utils/helper.py b/api/chalicelib/utils/helper.py index 0c128d4a1..3d10ddcf3 100644 --- a/api/chalicelib/utils/helper.py +++ b/api/chalicelib/utils/helper.py @@ -15,11 +15,11 @@ def random_string(length=36): return "".join(random.choices(string.hexdigits, k=length)) -def list_to_camel_case(items: list[dict], flatten: bool = False) -> list[dict]: +def list_to_camel_case(items: list[dict], flatten: bool = False, ignore_keys=[]) -> list[dict]: for i in range(len(items)): if flatten: items[i] = flatten_nested_dicts(items[i]) - items[i] = dict_to_camel_case(items[i]) + items[i] = dict_to_camel_case(items[i], ignore_keys=[]) return items diff --git a/backend/pkg/db/clickhouse/connector.go b/backend/pkg/db/clickhouse/connector.go index b5aefc28f..8f723712a 100644 --- a/backend/pkg/db/clickhouse/connector.go +++ b/backend/pkg/db/clickhouse/connector.go @@ -733,8 +733,8 @@ func (c *connectorImpl) InsertCustom(session *sessions.Session, msg *messages.Cu if err != nil { return fmt.Errorf("can't marshal custom event: %s", err) } - var customPayload interface{} - if err := json.Unmarshal([]byte(msg.Payload), customPayload); err != nil { + customPayload := make(map[string]interface{}) + if err := json.Unmarshal([]byte(msg.Payload), &customPayload); err != nil { log.Printf("can't unmarshal custom event payload into object: %s", err) customPayload = map[string]interface{}{ "payload": msg.Payload, diff --git a/frontend/app/components/Kai/KaiChat.tsx b/frontend/app/components/Kai/KaiChat.tsx index 35fb8f257..4d3d13586 100644 --- a/frontend/app/components/Kai/KaiChat.tsx +++ b/frontend/app/components/Kai/KaiChat.tsx @@ -18,7 +18,7 @@ function KaiChat() { const chatTitle = kaiStore.chatTitle; const setTitle = kaiStore.setTitle; const userId = userStore.account.id; - const userLetter = userStore.account.name[0].toUpperCase(); + const userName = userStore.account.name; const { activeSiteId } = projectsStore; const [section, setSection] = React.useState<'intro' | 'chat'>('intro'); const [threadId, setThreadId] = React.useState(null); @@ -44,7 +44,11 @@ function KaiChat() { hideModal(); }} />, - { right: true, width: 300 }, + { + right: true, + width: 320, + className: 'bg-none flex items-center h-screen', + }, ); }; @@ -93,44 +97,70 @@ function KaiChat() { const newThread = await kaiService.createKaiChat(activeSiteId); if (newThread) { setThreadId(newThread.toString()); + kaiStore.setTitle(null); setSection('chat'); } else { toast.error("Something wen't wrong. Please try again later."); } }; + + const onCancel = () => { + if (!threadId) return; + void kaiStore.cancelGeneration({ + projectId: activeSiteId, + threadId, + }); + }; + return ( -
+
-
- {section === 'intro' ? ( - - ) : ( - - )} -
+ {section === 'intro' ? ( + <> +
+ +
+
+ OpenReplay AI can make mistakes. Verify its outputs. +
+ + ) : ( + + )}
); diff --git a/frontend/app/components/Kai/KaiService.ts b/frontend/app/components/Kai/KaiService.ts index 447ce1779..22cade0f8 100644 --- a/frontend/app/components/Kai/KaiService.ts +++ b/frontend/app/components/Kai/KaiService.ts @@ -36,6 +36,7 @@ export default class KaiService extends AiService { supports_visualization: boolean; chart: string; chart_data: string; + sessions?: Record[]; }[]; title: string; }> => { @@ -123,4 +124,19 @@ export default class KaiService extends AiService { const data = await r.json(); return data; }; + + getPromptSuggestions = async ( + projectId: string, + threadId?: string | null, + ): Promise => { + const endpoint = threadId + ? `/kai/${projectId}/chats/${threadId}/prompt-suggestions` + : `/kai/${projectId}/prompt-suggestions`; + const r = await this.client.get(endpoint); + if (!r.ok) { + throw new Error('Failed to fetch prompt suggestions'); + } + const data = await r.json(); + return data; + }; } diff --git a/frontend/app/components/Kai/KaiStore.ts b/frontend/app/components/Kai/KaiStore.ts index 7369b25b9..e7f496176 100644 --- a/frontend/app/components/Kai/KaiStore.ts +++ b/frontend/app/components/Kai/KaiStore.ts @@ -3,6 +3,7 @@ import { BotChunk, ChatManager } from './SocketManager'; import { kaiService as aiService, kaiService } from 'App/services'; import { toast } from 'react-toastify'; import Widget from 'App/mstore/types/widget'; +import Session, { ISession } from '@/types/session/session'; export interface Message { text: string; @@ -15,6 +16,7 @@ export interface Message { supports_visualization: boolean; feedback: boolean | null; duration: number; + sessions?: Session[]; } export interface SentMessage extends Omit< @@ -161,6 +163,9 @@ class KaiStore { chart: m.chart, supports_visualization: m.supports_visualization, chart_data: m.chart_data, + sessions: m.sessions + ? m.sessions.map((s) => new Session(s)) + : undefined, }; }), ); @@ -220,6 +225,9 @@ class KaiStore { chart: '', supports_visualization: msg.supports_visualization, chart_data: '', + sessions: msg.sessions + ? msg.sessions.map((s) => new Session(s)) + : undefined, }; this.bumpUsage(); this.addMessage(msgObj); @@ -268,7 +276,7 @@ class KaiStore { deleting.push(this.lastKaiMessage.index); } this.deleteAtIndex(deleting); - this.setReplacing(false); + this.setReplacing(null); } this.addMessage({ text: message, @@ -309,7 +317,6 @@ class KaiStore { cancelGeneration = async (settings: { projectId: string; - userId: string; threadId: string; }) => { try { diff --git a/frontend/app/components/Kai/SocketManager.ts b/frontend/app/components/Kai/SocketManager.ts index 7fcda3171..5906890c3 100644 --- a/frontend/app/components/Kai/SocketManager.ts +++ b/frontend/app/components/Kai/SocketManager.ts @@ -1,5 +1,6 @@ import io from 'socket.io-client'; import { toast } from 'react-toastify'; +import { ISession } from '@/types/session/session'; export class ChatManager { socket: ReturnType; @@ -77,9 +78,7 @@ export class ChatManager { msgCallback, titleCallback, }: { - msgCallback: ( - msg: StateEvent | BotChunk, - ) => void; + msgCallback: (msg: StateEvent | BotChunk) => void; titleCallback: (title: string) => void; }) => { this.socket.on('chunk', (msg: BotChunk) => { @@ -111,7 +110,8 @@ export interface BotChunk { messageId: string; duration: number; supports_visualization: boolean; - type: 'chunk' + sessions?: ISession[]; + type: 'chunk'; } interface StateEvent { diff --git a/frontend/app/components/Kai/components/ChatHeader.tsx b/frontend/app/components/Kai/components/ChatHeader.tsx index ae3cb4068..29aaa4365 100644 --- a/frontend/app/components/Kai/components/ChatHeader.tsx +++ b/frontend/app/components/Kai/components/ChatHeader.tsx @@ -1,56 +1,68 @@ import React from 'react'; import { Icon } from 'UI'; -import { MessagesSquare, ArrowLeft } from 'lucide-react'; +import { MessagesSquare, ArrowLeft, SquarePen } from 'lucide-react'; import { useTranslation } from 'react-i18next'; function ChatHeader({ openChats = () => {}, goBack, chatTitle, + onCreate, }: { goBack?: () => void; openChats?: () => void; chatTitle: string | null; + onCreate: () => void; }) { const { t } = useTranslation(); + //absolute top-0 left-0 right-0 z-10 return ( -
-
- {goBack ? ( +
+
+
+ {goBack ? ( +
+ +
{t('Back')}
+
+ ) : ( +
+ +
Kai
+
+ )} +
+
+ {chatTitle ? ( +
+ {chatTitle} +
+ ) : null} +
+
+ {goBack ? ( +
+ +
{t('New Chat')}
+
+ ) : null}
- -
{t('Back')}
+ +
{t('Chats')}
- ) : null} -
-
- {chatTitle ? ( -
- {chatTitle} -
- ) : ( - <> - -
Kai
- - )} -
-
-
- -
{t('Chats')}
diff --git a/frontend/app/components/Kai/components/ChatInput.tsx b/frontend/app/components/Kai/components/ChatInput.tsx index 237b79d6c..b860c4c32 100644 --- a/frontend/app/components/Kai/components/ChatInput.tsx +++ b/frontend/app/components/Kai/components/ChatInput.tsx @@ -1,6 +1,6 @@ import React from 'react'; import { Button, Input, Tooltip } from 'antd'; -import { SendHorizonal, OctagonX } from 'lucide-react'; +import { X, ArrowUp } from 'lucide-react'; import { kaiStore } from '../KaiStore'; import { observer } from 'mobx-react-lite'; import Usage from './Usage'; @@ -8,11 +8,13 @@ import Usage from './Usage'; function ChatInput({ isLoading, onSubmit, - threadId, + isArea, + onCancel, }: { isLoading?: boolean; onSubmit: (str: string) => void; - threadId: string; + onCancel: () => void; + isArea?: boolean; }) { const inputRef = React.useRef(null); const usage = kaiStore.usage; @@ -28,8 +30,7 @@ function ChatInput({ return; } if (isProcessing) { - const settings = { projectId: '2325', userId: '0', threadId }; - void kaiStore.cancelGeneration(settings); + onCancel(); } else { if (inputValue.length > 0) { onSubmit(inputValue); @@ -50,7 +51,34 @@ function ChatInput({ }, [inputValue]); const isReplacing = kaiStore.replacing !== null; - + const placeholder = limited + ? `You've reached the daily limit for queries, come again tomorrow!` + : 'Ask anything about your product and users...'; + if (isArea) { + return ( +
+ setInputValue(e.target.value)} + /> +
+ +
+
+ ); + } return (
setInputValue(e.target.value)} @@ -76,31 +101,19 @@ function ChatInput({ + + ); +} + export default observer(ChatInput); diff --git a/frontend/app/components/Kai/components/ChatLog.tsx b/frontend/app/components/Kai/components/ChatLog.tsx index ecb4405b4..d06e9df4b 100644 --- a/frontend/app/components/Kai/components/ChatLog.tsx +++ b/frontend/app/components/Kai/components/ChatLog.tsx @@ -1,6 +1,7 @@ import React from 'react'; import ChatInput from './ChatInput'; import ChatMsg, { ChatNotice } from './ChatMsg'; +import Ideas from './Ideas'; import { Loader } from 'UI'; import { kaiStore } from '../KaiStore'; import { observer } from 'mobx-react-lite'; @@ -8,17 +9,17 @@ import { observer } from 'mobx-react-lite'; function ChatLog({ projectId, threadId, - userLetter, initialMsg, chatTitle, setInitialMsg, + onCancel, }: { projectId: string; threadId: any; - userLetter: string; initialMsg: string | null; setInitialMsg: (msg: string | null) => void; chatTitle: string | null; + onCancel: () => void; }) { const messages = kaiStore.messages; const loading = kaiStore.loadingChat; @@ -50,11 +51,15 @@ function ChatLog({ }); }, [messages.length, processingStage]); - const lastHumanMsgInd: null | number = kaiStore.lastHumanMessage.index; + const lastKaiMessageInd: null | number = kaiStore.lastKaiMessage.index; + const lastHumanMsgInd: number | null = kaiStore.lastHumanMessage.index; + const showIdeas = + !processingStage && lastKaiMessageInd === messages.length - 1; return (
( ) : null} + {showIdeas ? ( + onSubmit(query)} + projectId={projectId} + threadId={threadId} + /> + ) : null}
-
- +
+
diff --git a/frontend/app/components/Kai/components/ChatMsg.tsx b/frontend/app/components/Kai/components/ChatMsg.tsx index d335952ae..5239f9745 100644 --- a/frontend/app/components/Kai/components/ChatMsg.tsx +++ b/frontend/app/components/Kai/components/ChatMsg.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { Icon, CopyButton } from 'UI'; +import { CopyButton } from 'UI'; import { observer } from 'mobx-react-lite'; import cn from 'classnames'; import Markdown from 'react-markdown'; @@ -8,7 +8,7 @@ import { Loader, ThumbsUp, ThumbsDown, - ListRestart, + SquarePen, FileDown, Clock, ChartLine, @@ -20,6 +20,7 @@ import { durationFormatted } from 'App/date'; import WidgetChart from '@/components/Dashboard/components/WidgetChart'; import Widget from 'App/mstore/types/widget'; import { useTranslation } from 'react-i18next'; +import SessionItem from 'Shared/SessionItem'; function ChatMsg({ userName, @@ -168,28 +169,12 @@ function ChatMsg({ }, [metricData, chart_data]); return (
- {isUser ? ( -
- {userName} -
- ) : ( -
- -
- )} -
+
) : null} + {message.sessions ? ( +
+ {message.sessions.map((session) => ( +
+ +
+ ))} +
+ ) : null} {isUser ? ( - <> -
- -
{t('Edit')}
-
+
+ +
+ +
+
{t('Cancel')}
- +
) : (
{duration ? : null} diff --git a/frontend/app/components/Kai/components/ChatsModal.tsx b/frontend/app/components/Kai/components/ChatsModal.tsx index 16f374d15..8fb279aea 100644 --- a/frontend/app/components/Kai/components/ChatsModal.tsx +++ b/frontend/app/components/Kai/components/ChatsModal.tsx @@ -44,10 +44,13 @@ function ChatsModal({ refetch(); }; return ( -
+
- {t('Chats')} + {t('Previous Chats')}
{usage.percent > 80 ? (
diff --git a/frontend/app/components/Kai/components/Ideas.tsx b/frontend/app/components/Kai/components/Ideas.tsx index 1cd2f86e2..bade87acb 100644 --- a/frontend/app/components/Kai/components/Ideas.tsx +++ b/frontend/app/components/Kai/components/Ideas.tsx @@ -1,30 +1,72 @@ import React from 'react'; import { Lightbulb, MoveRight } from 'lucide-react'; +import { useQuery } from '@tanstack/react-query'; +import { kaiService } from 'App/services'; +import { useTranslation } from 'react-i18next'; -function Ideas({ onClick }: { onClick: (query: string) => void }) { +function Ideas({ + onClick, + projectId, + threadId = null, +}: { + onClick: (query: string) => void; + projectId: string; + threadId?: string | null; +}) { + const { t } = useTranslation(); + const { data: suggestedPromptIdeas = [], isPending } = useQuery({ + queryKey: ['kai', projectId, 'chats', threadId, 'prompt-suggestions'], + queryFn: () => kaiService.getPromptSuggestions(projectId, threadId), + staleTime: 1000 * 60, + }); + const ideas = React.useMemo(() => { + const defaultPromptIdeas = [ + 'Top user journeys', + 'Where do users drop off', + 'Failed network requests today', + ]; + const result = suggestedPromptIdeas; + const targetSize = 3; + while (result.length < targetSize && defaultPromptIdeas.length) { + result.push(defaultPromptIdeas.pop()); + } + return result; + }, [suggestedPromptIdeas.length]); return ( - <> +
- - Ideas: + Suggested Ideas:
- - - - + {isPending ? ( +
+ {t('Generating ideas')}... +
+ ) : ( +
+ {ideas.map((title) => ( + + ))} +
+ )} +
); } -function IdeaItem({ title, onClick }: { title: string, onClick: (query: string) => void }) { +function IdeaItem({ + title, + onClick, +}: { + title: string; + onClick: (query: string) => void; +}) { return (
onClick(title)} className={ - 'flex items-center gap-2 cursor-pointer text-gray-dark hover:text-black' + 'cursor-pointer text-gray-dark hover:text-black rounded-full px-4 py-2 shadow border' } > - - {title} + {title}
); } diff --git a/frontend/app/components/Kai/components/IntroSection.tsx b/frontend/app/components/Kai/components/IntroSection.tsx index 71a69b99c..dd28f667a 100644 --- a/frontend/app/components/Kai/components/IntroSection.tsx +++ b/frontend/app/components/Kai/components/IntroSection.tsx @@ -2,23 +2,33 @@ import React from 'react'; import ChatInput from './ChatInput'; import Ideas from './Ideas'; -function IntroSection({ onAsk }: { onAsk: (query: string) => void }) { +function IntroSection({ + onAsk, + onCancel, + userName, + projectId, +}: { + onAsk: (query: string) => void; + projectId: string; + onCancel: () => void; + userName: string; +}) { const isLoading = false; return ( <> -
- Kai is your AI assistant, delivering smart insights in response to your - queries. -
-
- {/* null} />*/} - -
- onAsk(query)} /> +
+
+ Hey {userName}, how can I help you? +
+ +
+ onAsk(query)} projectId={projectId} />
-
-
- OpenReplay AI can make mistakes. Verify its outputs.
); diff --git a/frontend/app/components/Modal/index.tsx b/frontend/app/components/Modal/index.tsx index 3b84beeb8..22a531656 100644 --- a/frontend/app/components/Modal/index.tsx +++ b/frontend/app/components/Modal/index.tsx @@ -1,6 +1,7 @@ // @ts-nocheck import React, { Component, createContext } from 'react'; import Modal from './Modal'; +import { className } from '@medv/finder'; const ModalContext = createContext({ component: null, @@ -29,6 +30,7 @@ export class ModalProvider extends Component { this.setState({ component, props, + className: props.className || undefined, }); document.addEventListener('keydown', this.handleKeyDown); document.querySelector('body').style.overflow = 'hidden'; diff --git a/frontend/app/components/shared/SessionItem/SessionItem.tsx b/frontend/app/components/shared/SessionItem/SessionItem.tsx index af42caf1d..23128a84f 100644 --- a/frontend/app/components/shared/SessionItem/SessionItem.tsx +++ b/frontend/app/components/shared/SessionItem/SessionItem.tsx @@ -71,6 +71,7 @@ interface Props { bookmarked?: boolean; toggleFavorite?: (sessionId: string) => void; query?: string; + slim?: boolean; } const PREFETCH_STATE = { @@ -99,6 +100,7 @@ function SessionItem(props: RouteComponentProps & Props) { isDisabled, live: propsLive, isAdd, + slim, } = props; const { @@ -261,7 +263,7 @@ function SessionItem(props: RouteComponentProps & Props) { } >
e.stopPropagation()} onMouseEnter={handleHover} @@ -343,7 +345,7 @@ function SessionItem(props: RouteComponentProps & Props) { : 'Event'}
- + )}
@@ -373,7 +375,7 @@ function SessionItem(props: RouteComponentProps & Props) { )} {userOs && userBrowser && ( - + )} {userOs && ( )} {userOs && ( - + )} + ); +} + +export default Kai_mono; diff --git a/frontend/app/components/ui/SVG.tsx b/frontend/app/components/ui/SVG.tsx index e3d70baff..a7ee85dca 100644 --- a/frontend/app/components/ui/SVG.tsx +++ b/frontend/app/components/ui/SVG.tsx @@ -356,6 +356,7 @@ import { Integrations_vuejs, Integrations_zustand, Journal_code, + Kai_mono, Kai, Kai_colored, Key, @@ -1565,6 +1566,9 @@ const SVG = (props: Props) => { // case 'journal-code': case 'journal-code': return ; + // case 'kai-mono': + case 'kai-mono': return ; + case 'kai': return ; diff --git a/frontend/app/svg/icons/kai-mono.svg b/frontend/app/svg/icons/kai-mono.svg new file mode 100644 index 000000000..97738455d --- /dev/null +++ b/frontend/app/svg/icons/kai-mono.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/scripts/helmcharts/databases/charts/clickhouse/templates/configmap.yaml b/scripts/helmcharts/databases/charts/clickhouse/templates/configmap.yaml index 709e0929e..4fdd5709d 100644 --- a/scripts/helmcharts/databases/charts/clickhouse/templates/configmap.yaml +++ b/scripts/helmcharts/databases/charts/clickhouse/templates/configmap.yaml @@ -1,3 +1,4 @@ +{{- if .Values.configOverride.serverConfig }} --- apiVersion: v1 kind: ConfigMap @@ -8,6 +9,7 @@ data: {{ $filename }}: |- {{ $content | indent 4 }} {{- end }} +{{- end }} --- apiVersion: v1 kind: ConfigMap diff --git a/scripts/helmcharts/databases/charts/clickhouse/values.yaml b/scripts/helmcharts/databases/charts/clickhouse/values.yaml index 641d80bab..68a42f494 100644 --- a/scripts/helmcharts/databases/charts/clickhouse/values.yaml +++ b/scripts/helmcharts/databases/charts/clickhouse/values.yaml @@ -87,27 +87,26 @@ storageSize: 100Gi configOverride: serverConfig: zz-server-override.xml: |- - # - # - # information - # true - # - # - # - # 0.0.0.0 - # 100 - # 64 - # 2 - # fair_round_robin - # 102400000000 - # 10000 - # 0.8 - # - # 26214 - # + + + information + true + + + + 0.0.0.0 + 100 + # another-config.xml: |- # - # value + # 64 + # 2 + # fair_round_robin + # 102400000000 + # 10000 + # 0.8 + # + # 26214 # userConfig: zz-user-override.xml: |- diff --git a/scripts/helmcharts/openreplay/Chart.yaml b/scripts/helmcharts/openreplay/Chart.yaml index 71f89e366..664a32226 100644 --- a/scripts/helmcharts/openreplay/Chart.yaml +++ b/scripts/helmcharts/openreplay/Chart.yaml @@ -37,3 +37,7 @@ dependencies: repository: file://charts/connector version: 0.1.1 condition: connector.enabled + - name: assist-api + repository: file://charts/assist-api + version: 0.1.1 + condition: assist-api.enabled diff --git a/scripts/helmcharts/openreplay/charts/assist-api/.helmignore b/scripts/helmcharts/openreplay/charts/assist-api/.helmignore new file mode 100644 index 000000000..0e8a0eb36 --- /dev/null +++ b/scripts/helmcharts/openreplay/charts/assist-api/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/scripts/helmcharts/openreplay/charts/assist-api/Chart.yaml b/scripts/helmcharts/openreplay/charts/assist-api/Chart.yaml new file mode 100644 index 000000000..498f81dd6 --- /dev/null +++ b/scripts/helmcharts/openreplay/charts/assist-api/Chart.yaml @@ -0,0 +1,24 @@ +apiVersion: v2 +name: assist-api +description: A Helm chart for Kubernetes + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rassist-apiing +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +# Versions are expected to follow Semantic Versioning (https://semver.org/) +version: 0.1.1 + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. Versions are not expected to +# follow Semantic Versioning. They should reflect the version the application is using. +# It is recommended to use it with quotes. +AppVersion: "v1.22.0" diff --git a/scripts/helmcharts/openreplay/charts/assist-api/templates/NOTES.txt b/scripts/helmcharts/openreplay/charts/assist-api/templates/NOTES.txt new file mode 100644 index 000000000..f5106914d --- /dev/null +++ b/scripts/helmcharts/openreplay/charts/assist-api/templates/NOTES.txt @@ -0,0 +1,22 @@ +1. Get the application URL by running these commands: +{{- if .Values.ingress.enabled }} +{{- range $host := .Values.ingress.hosts }} + {{- range .paths }} + http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ .path }} + {{- end }} +{{- end }} +{{- else if contains "NodePort" .Values.service.type }} + export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "assist-api.fullname" . }}) + export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") + echo http://$NODE_IP:$NODE_PORT +{{- else if contains "LoadBalancer" .Values.service.type }} + NOTE: It may take a few minutes for the LoadBalancer IP to be available. + You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "assist-api.fullname" . }}' + export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "assist-api.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}") + echo http://$SERVICE_IP:{{ .Values.service.port }} +{{- else if contains "ClusterIP" .Values.service.type }} + export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "assist-api.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") + export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}") + echo "Visit http://127.0.0.1:8080 to use your application" + kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:$CONTAINER_PORT +{{- end }} diff --git a/scripts/helmcharts/openreplay/charts/assist-api/templates/_helpers.tpl b/scripts/helmcharts/openreplay/charts/assist-api/templates/_helpers.tpl new file mode 100644 index 000000000..568007bc7 --- /dev/null +++ b/scripts/helmcharts/openreplay/charts/assist-api/templates/_helpers.tpl @@ -0,0 +1,65 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "assist-api.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "assist-api.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "assist-api.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "assist-api.labels" -}} +helm.sh/chart: {{ include "assist-api.chart" . }} +{{ include "assist-api.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- if .Values.global.appLabels }} +{{- .Values.global.appLabels | toYaml | nindent 0}} +{{- end}} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "assist-api.selectorLabels" -}} +app.kubernetes.io/name: {{ include "assist-api.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "assist-api.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "assist-api.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} diff --git a/scripts/helmcharts/openreplay/charts/assist-api/templates/deployment.yaml b/scripts/helmcharts/openreplay/charts/assist-api/templates/deployment.yaml new file mode 100644 index 000000000..232b9528f --- /dev/null +++ b/scripts/helmcharts/openreplay/charts/assist-api/templates/deployment.yaml @@ -0,0 +1,101 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "assist-api.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "assist-api.labels" . | nindent 4 }} +spec: + {{- if not .Values.autoscaling.enabled }} + replicas: {{ .Values.replicaCount }} + {{- end }} + selector: + matchLabels: + {{- include "assist-api.selectorLabels" . | nindent 6 }} + template: + metadata: + {{- with .Values.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "assist-api.selectorLabels" . | nindent 8 }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "assist-api.serviceAccountName" . }} + securityContext: + {{- toYaml .Values.podSecurityContext | nindent 8 }} + shareProcessNamespace: true + containers: + - name: {{ .Chart.Name }} + securityContext: + {{- toYaml .Values.securityContext | nindent 12 }} + {{- if .Values.global.enterpriseEditionLicense }} + image: "{{ tpl .Values.image.repository . }}:{{ .Values.image.tag | default .Chart.AppVersion }}-ee" + {{- else }} + image: "{{ tpl .Values.image.repository . }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + {{- end }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + {{- if .Values.healthCheck}} + {{- .Values.healthCheck | toYaml | nindent 10}} + {{- end}} + env: + - name: LICENSE_KEY + value: '{{ .Values.global.enterpriseEditionLicense }}' + - name: ASSIST_KEY + value: {{ .Values.global.assistKey }} + - name: pg_password + {{- if .Values.global.postgresql.existingSecret }} + valueFrom: + secretKeyRef: + name: {{ .Values.global.postgresql.existingSecret }} + key: postgresql-postgres-password + {{- else }} + value: '{{ .Values.global.postgresql.postgresqlPassword }}' + {{- end}} + - name: POSTGRES_STRING + value: 'postgres://{{ .Values.global.postgresql.postgresqlUser }}:$(pg_password)@{{ .Values.global.postgresql.postgresqlHost }}:{{ .Values.global.postgresql.postgresqlPort }}/{{ .Values.global.postgresql.postgresqlDatabase }}' + - name: REDIS_CACHE_ENABLED + value: {{ if .Values.global.enterpriseEditionLicense }}"true"{{ else }}"false"{{ end }} + {{- include "openreplay.env.redis_string" .Values.global.redis | nindent 12 }} + {{- range $key, $val := .Values.global.env }} + - name: {{ $key }} + value: '{{ $val }}' + {{- end }} + {{- range $key, $val := .Values.env }} + - name: {{ $key }} + value: '{{ $val }}' + {{- end}} + ports: + {{- range $key, $val := .Values.service.ports }} + - name: {{ $key }} + containerPort: {{ $val }} + protocol: TCP + {{- end }} + volumeMounts: + {{- include "openreplay.volume.redis_ca_certificate.mount" .Values.global.redis | nindent 12 }} + {{- with .Values.persistence.mounts }} + {{- toYaml . | nindent 12 }} + {{- end }} + resources: + {{- toYaml .Values.resources | nindent 12 }} + volumes: + {{- with .Values.persistence.volumes }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- include "openreplay.volume.redis_ca_certificate" .Values.global.redis | nindent 8 }} + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} diff --git a/scripts/helmcharts/openreplay/charts/assist-api/templates/hpa.yaml b/scripts/helmcharts/openreplay/charts/assist-api/templates/hpa.yaml new file mode 100644 index 000000000..04f9e7961 --- /dev/null +++ b/scripts/helmcharts/openreplay/charts/assist-api/templates/hpa.yaml @@ -0,0 +1,33 @@ +{{- if .Values.autoscaling.enabled }} +apiVersion: autoscaling/v2 +kind: HorizontalPodAutoscaler +metadata: + name: {{ include "assist-api.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "assist-api.labels" . | nindent 4 }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: {{ include "assist-api.fullname" . }} + minReplicas: {{ .Values.autoscaling.minReplicas }} + maxReplicas: {{ .Values.autoscaling.maxReplicas }} + metrics: + {{- if .Values.autoscaling.targetCPUUtilizationPercentage }} + - type: Resource + resource: + name: cpu + target: + type: Utilization + averageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }} + {{- end }} + {{- if .Values.autoscaling.targetMemoryUtilizationPercentage }} + - type: Resource + resource: + name: memory + target: + type: Utilization + averageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }} + {{- end }} +{{- end }} diff --git a/scripts/helmcharts/openreplay/charts/assist-api/templates/service.yaml b/scripts/helmcharts/openreplay/charts/assist-api/templates/service.yaml new file mode 100644 index 000000000..6838d1702 --- /dev/null +++ b/scripts/helmcharts/openreplay/charts/assist-api/templates/service.yaml @@ -0,0 +1,18 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "assist-api.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "assist-api.labels" . | nindent 4 }} +spec: + type: {{ .Values.service.type }} + ports: + {{- range $key, $val := .Values.service.ports }} + - port: {{ $val }} + targetPort: {{ $key }} + protocol: TCP + name: {{ $key }} + {{- end}} + selector: + {{- include "assist-api.selectorLabels" . | nindent 4 }} diff --git a/scripts/helmcharts/openreplay/charts/assist-api/templates/serviceMonitor.yaml b/scripts/helmcharts/openreplay/charts/assist-api/templates/serviceMonitor.yaml new file mode 100644 index 000000000..c57c21606 --- /dev/null +++ b/scripts/helmcharts/openreplay/charts/assist-api/templates/serviceMonitor.yaml @@ -0,0 +1,18 @@ +{{- if and ( .Capabilities.APIVersions.Has "monitoring.coreos.com/v1" ) ( .Values.serviceMonitor.enabled ) }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ include "assist-api.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "assist-api.labels" . | nindent 4 }} + {{- if .Values.serviceMonitor.additionalLabels }} + {{- toYaml .Values.serviceMonitor.additionalLabels | nindent 4 }} + {{- end }} +spec: + endpoints: + {{- .Values.serviceMonitor.scrapeConfigs | toYaml | nindent 4 }} + selector: + matchLabels: + {{- include "assist-api.selectorLabels" . | nindent 6 }} +{{- end }} diff --git a/scripts/helmcharts/openreplay/charts/assist-api/templates/serviceaccount.yaml b/scripts/helmcharts/openreplay/charts/assist-api/templates/serviceaccount.yaml new file mode 100644 index 000000000..06db808ac --- /dev/null +++ b/scripts/helmcharts/openreplay/charts/assist-api/templates/serviceaccount.yaml @@ -0,0 +1,13 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "assist-api.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "assist-api.labels" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/scripts/helmcharts/openreplay/charts/assist-api/templates/tests/test-connection.yaml b/scripts/helmcharts/openreplay/charts/assist-api/templates/tests/test-connection.yaml new file mode 100644 index 000000000..57e38f294 --- /dev/null +++ b/scripts/helmcharts/openreplay/charts/assist-api/templates/tests/test-connection.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Pod +metadata: + name: "{{ include "assist-api.fullname" . }}-test-connection" + labels: + {{- include "assist-api.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": test +spec: + containers: + - name: wget + image: busybox + command: ['wget'] + args: ['{{ include "assist-api.fullname" . }}:{{ .Values.service.port }}'] + restartPolicy: Never diff --git a/scripts/helmcharts/openreplay/charts/assist-api/values.yaml b/scripts/helmcharts/openreplay/charts/assist-api/values.yaml new file mode 100644 index 000000000..f5bf928e0 --- /dev/null +++ b/scripts/helmcharts/openreplay/charts/assist-api/values.yaml @@ -0,0 +1,119 @@ +# Default values for openreplay. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +replicaCount: 1 + +image: + repository: "{{ .Values.global.openReplayContainerRegistry }}/assist-api" + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: "" + +imagePullSecrets: [] +nameOverride: "assist-api" +fullnameOverride: "assist-api-openreplay" + +serviceAccount: + # Specifies whether a service account should be created + create: true + # Annotations to add to the service account + annotations: {} + # The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template + name: "" + +podAnnotations: {} + +securityContext: + runAsUser: 1001 + runAsGroup: 1001 +podSecurityContext: + runAsUser: 1001 + runAsGroup: 1001 + fsGroup: 1001 + fsGroupChangePolicy: "OnRootMismatch" + # podSecurityContext: {} + # fsGroup: 2000 + + # securityContext: {} + # capabilities: + # drop: + # - ALL + # readOnlyRootFilesystem: true + # runAsNonRoot: true + # runAsUser: 1000 + +#service: +# type: ClusterIP +# port: 9000 + +serviceMonitor: + enabled: false + additionalLabels: + release: observability + scrapeConfigs: + - port: metrics + honorLabels: true + interval: 15s + path: /metrics + scheme: http + scrapeTimeout: 10s + +service: + type: ClusterIP + ports: + http: 8080 + metrics: 8888 + +ingress: + enabled: false + className: "{{ .Values.global.ingress.controller.ingressClassResource.name }}" + annotations: + nginx.ingress.kubernetes.io/proxy-read-timeout: "3600" + nginx.ingress.kubernetes.io/proxy-send-timeout: "3600" + # kubernetes.io/ingress.class: nginx + # kubernetes.io/tls-acme: "true" + tls: + secretName: openreplay-ssl + +resources: {} + # We usually recommend not to specify default resources and to leave this as a conscious + # choice for the user. This also increases chances charts run on environments with little + # resources, such as Minikube. If you do want to specify resources, uncomment the following + # lines, adjust them as necessary, and remove the curly braces after 'resources:'. + # limits: + # cpu: 100m + # memory: 128Mi + # requests: + # cpu: 100m +# memory: 128Mi + +autoscaling: + enabled: false + minReplicas: 1 + maxReplicas: 5 + targetCPUUtilizationPercentage: 80 + # targetMemoryUtilizationPercentage: 80 + +env: + CLEAR_SOCKET_TIME: 720 + + +nodeSelector: {} + +tolerations: [] + +affinity: {} + + +persistence: {} + # # Spec of spec.template.spec.containers[*].volumeMounts + # mounts: + # - name: kafka-ssl + # mountPath: /opt/kafka/ssl + # # Spec of spec.template.spec.volumes + # volumes: + # - name: kafka-ssl + # secret: +# secretName: kafka-ssl diff --git a/scripts/helmcharts/openreplay/charts/assist/templates/deployment.yaml b/scripts/helmcharts/openreplay/charts/assist/templates/deployment.yaml index a4af9a9f8..d12498255 100644 --- a/scripts/helmcharts/openreplay/charts/assist/templates/deployment.yaml +++ b/scripts/helmcharts/openreplay/charts/assist/templates/deployment.yaml @@ -49,32 +49,18 @@ spec: value: {{ .Values.global.assistKey }} - name: AWS_DEFAULT_REGION value: "{{ .Values.global.s3.region }}" - - name: S3_HOST - {{- if contains "minio" .Values.global.s3.endpoint }} - value: '{{ ternary "https" "http" .Values.global.ORSecureAccess}}://{{ .Values.global.domainName }}:{{ ternary .Values.global.ingress.controller.service.ports.https .Values.global.ingress.controller.service.ports.http .Values.global.ORSecureAccess }}' - {{- else}} - value: '{{ .Values.global.s3.endpoint }}' - {{- end}} - - name: S3_KEY - {{- if .Values.global.s3.existingSecret }} - valueFrom: - secretKeyRef: - name: {{ .Values.global.s3.existingSecret }} - key: access-key - {{- else }} - value: {{ .Values.global.s3.accessKey }} - {{- end }} - - name: S3_SECRET - {{- if .Values.global.s3.existingSecret }} - valueFrom: - secretKeyRef: - name: {{ .Values.global.s3.existingSecret }} - key: secret-key - {{- else }} - value: {{ .Values.global.s3.secretKey }} - {{- end }} - name: REDIS_URL - value: {{ .Values.global.redis.redisHost }} + value: {{ default .Values.global.redis.redisHost .Values.redisHost }} + {{- if .Values.global.enterpriseEditionLicense }} + - name: COMPRESSION + value: "true" + - name: port + value: "9000" + - name: CACHE_REFRESH_INTERVAL_SECONDS + value: '5' + - name: debug + value: '0' + {{- end}} {{- range $key, $val := .Values.global.env }} - name: {{ $key }} value: '{{ $val }}' diff --git a/scripts/helmcharts/openreplay/charts/assist/templates/ingress.yaml b/scripts/helmcharts/openreplay/charts/assist/templates/ingress.yaml index 41436c679..df355cefe 100644 --- a/scripts/helmcharts/openreplay/charts/assist/templates/ingress.yaml +++ b/scripts/helmcharts/openreplay/charts/assist/templates/ingress.yaml @@ -10,25 +10,6 @@ metadata: {{- include "assist.labels" . | nindent 4 }} annotations: nginx.ingress.kubernetes.io/rewrite-target: /$1 - nginx.ingress.kubernetes.io/configuration-snippet: | - #set $sticky_used "no"; - #if ($sessionid != "") { - # set $sticky_used "yes"; - #} - - #add_header X-Debug-Session-ID $sessionid; - #add_header X-Debug-Session-Type "wss"; - #add_header X-Sticky-Session-Used $sticky_used; - #add_header X-Upstream-Server $upstream_addr; - - proxy_hide_header access-control-allow-headers; - proxy_hide_header Access-Control-Allow-Origin; - add_header 'Access-Control-Allow-Origin' $http_origin always; - add_header 'Access-Control-Allow-Methods' 'GET, OPTIONS' always; - add_header 'Access-Control-Allow-Headers' 'sessionid, Content-Type, Authorization' always; - add_header 'Access-Control-Max-Age' 1728000; - add_header 'Content-Type' 'text/plain charset=UTF-8'; - nginx.ingress.kubernetes.io/upstream-hash-by: $sessionid {{- with .Values.ingress.annotations }} diff --git a/scripts/helmcharts/openreplay/charts/chalice/templates/deployment.yaml b/scripts/helmcharts/openreplay/charts/chalice/templates/deployment.yaml index 3d86796a7..a18256e30 100644 --- a/scripts/helmcharts/openreplay/charts/chalice/templates/deployment.yaml +++ b/scripts/helmcharts/openreplay/charts/chalice/templates/deployment.yaml @@ -59,7 +59,7 @@ spec: - name: sourcemaps_reader value: "http://sourcemapreader-openreplay.{{.Release.Namespace}}.{{.Values.global.clusterDomain}}:9000/%s/sourcemaps" - name: ASSIST_URL - value: "http://assist-openreplay.{{.Release.Namespace}}.{{.Values.global.clusterDomain}}:9001/assist/%s" + value: {{ include "openreplay.assist_url" . }} - name: ASSIST_JWT_SECRET value: {{ .Values.global.assistJWTSecret }} - name: JWT_SECRET diff --git a/scripts/helmcharts/openreplay/templates/_helpers.tpl b/scripts/helmcharts/openreplay/templates/_helpers.tpl index e239d2f8f..82419631f 100644 --- a/scripts/helmcharts/openreplay/templates/_helpers.tpl +++ b/scripts/helmcharts/openreplay/templates/_helpers.tpl @@ -161,3 +161,11 @@ Create the volume mount config for redis TLS certificates {{- printf "postgres://%s:$(pg_password)@%s:%s/%s" .Values.global.postgresql.postgresqlUser .Values.global.postgresql.postgresqlHost .Values.global.postgresql.postgresqlPort .Values.global.postgresql.postgresqlDatabase -}} {{- end -}} {{- end}} + +{{- define "openreplay.assist_url"}} +{{- if .Values.global.enterpriseEditionLicense }} +{{- printf "http://assist-api-openreplay.%s.%s:9001/assist/%%s" .Release.Namespace .Values.global.clusterDomain }} +{{- else}} +{{- printf "http://assist-openreplay.%s.%s:9001/assist/%%s" .Release.Namespace .Values.global.clusterDomain }} +{{- end}} +{{- end}} diff --git a/scripts/helmcharts/openreplay/values.yaml b/scripts/helmcharts/openreplay/values.yaml index 8be97a2dc..627db73c6 100644 --- a/scripts/helmcharts/openreplay/values.yaml +++ b/scripts/helmcharts/openreplay/values.yaml @@ -47,6 +47,8 @@ vault: &vault {{- with secret "database/creds/db-app" -}} POSTGRES_STRING=postgres://{{.Data.username}}:{{.Data.password}}@postgresql.db.svc.cluster.local:5432/postgres {{- end -}} +assist-api: + enabled: false minio: # Force initialize minio, even if the instance is not provisioned by OR