diff --git a/locales/en/messages.po b/locales/en/messages.po
index cfa796b938..86024661b6 100644
--- a/locales/en/messages.po
+++ b/locales/en/messages.po
@@ -2407,8 +2407,8 @@ msgid "This field is required"
msgstr "This field is required"
#: src/renderer/components/input/input.validators.ts:39
-msgid "This field must contain only lowercase latin characters, numbers and dash."
-msgstr "This field must contain only lowercase latin characters, numbers and dash."
+msgid "A System Name must be lowercase DNS labels separated by dots. DNS labels are alphanumerics and dashes enclosed by alphanumerics."
+msgstr "A System Name must be lowercase DNS labels separated by dots. DNS labels are alphanumerics and dashes enclosed by alphanumerics."
#: src/renderer/components/cluster-manager/clusters-menu.tsx:84
msgid "This is the quick launch menu."
diff --git a/locales/fi/messages.po b/locales/fi/messages.po
index 0aa7bb5ca8..5aa3ed6695 100644
--- a/locales/fi/messages.po
+++ b/locales/fi/messages.po
@@ -2390,7 +2390,7 @@ msgid "This field is required"
msgstr ""
#: src/renderer/components/input/input.validators.ts:39
-msgid "This field must contain only lowercase latin characters, numbers and dash."
+msgid "A System Name must be lowercase DNS labels separated by dots. DNS labels are alphanumerics and dashes enclosed by alphanumerics."
msgstr ""
#: src/renderer/components/cluster-manager/clusters-menu.tsx:84
diff --git a/locales/ru/messages.po b/locales/ru/messages.po
index c32d565891..d125111613 100644
--- a/locales/ru/messages.po
+++ b/locales/ru/messages.po
@@ -2408,7 +2408,7 @@ msgid "This field is required"
msgstr "Это обязательное поле"
#: src/renderer/components/input/input.validators.ts:39
-msgid "This field must contain only lowercase latin characters, numbers and dash."
+msgid "A System Name must be lowercase DNS labels separated by dots. DNS labels are alphanumerics and dashes enclosed by alphanumerics."
msgstr "Это поле может содержать только латинские буквы в нижнем регистре, номера и дефис."
#: src/renderer/components/cluster-manager/clusters-menu.tsx:84
diff --git a/src/main/router.ts b/src/main/router.ts
index 7c5d48e1d6..1b50ec2c2e 100644
--- a/src/main/router.ts
+++ b/src/main/router.ts
@@ -121,7 +121,7 @@ export class Router {
this.router.add({ method: "post", path: `${apiPrefix}/metrics` }, metricsRoute.routeMetrics.bind(metricsRoute))
// Port-forward API
- this.router.add({ method: "post", path: `${apiPrefix}/services/{namespace}/{service}/port-forward/{port}` }, portForwardRoute.routeServicePortForward.bind(portForwardRoute))
+ this.router.add({ method: "post", path: `${apiPrefix}/pods/{namespace}/{resourceType}/{resourceName}/port-forward/{port}` }, portForwardRoute.routePortForward.bind(portForwardRoute))
// Helm API
this.router.add({ method: "get", path: `${apiPrefix}/v2/charts` }, helmRoute.listCharts.bind(helmRoute))
diff --git a/src/main/routes/port-forward-route.ts b/src/main/routes/port-forward-route.ts
index a5fe683cc2..86cf4f0917 100644
--- a/src/main/routes/port-forward-route.ts
+++ b/src/main/routes/port-forward-route.ts
@@ -14,7 +14,7 @@ class PortForward {
return PortForward.portForwards.find((pf) => {
return (
pf.clusterId == forward.clusterId &&
- pf.kind == "service" &&
+ pf.kind == forward.kind &&
pf.name == forward.name &&
pf.namespace == forward.namespace &&
pf.port == forward.port
@@ -42,7 +42,7 @@ class PortForward {
"--kubeconfig", this.kubeConfig,
"port-forward",
"-n", this.namespace,
- `service/${this.name}`,
+ `${this.kind}/${this.name}`,
`${this.localPort}:${this.port}`
]
@@ -72,21 +72,22 @@ class PortForward {
class PortForwardRoute extends LensApi {
- public async routeServicePortForward(request: LensApiRequest) {
+ public async routePortForward(request: LensApiRequest) {
const { params, response, cluster} = request
+ const { namespace, port, resourceType, resourceName } = params
let portForward = PortForward.getPortforward({
- clusterId: cluster.id, kind: "service", name: params.service,
- namespace: params.namespace, port: params.port
+ clusterId: cluster.id, kind: resourceType, name: resourceName,
+ namespace: namespace, port: port
})
if (!portForward) {
- logger.info(`Creating a new port-forward ${params.namespace}/${params.service}:${params.port}`)
+ logger.info(`Creating a new port-forward ${namespace}/${resourceType}/${resourceName}:${port}`)
portForward = new PortForward({
clusterId: cluster.id,
- kind: "service",
- namespace: params.namespace,
- name: params.service,
- port: params.port,
+ kind: resourceType,
+ namespace: namespace,
+ name: resourceName,
+ port: port,
kubeConfig: cluster.getProxyKubeconfigPath()
})
const started = await portForward.start()
diff --git a/src/renderer/api/kube-api-parse.ts b/src/renderer/api/kube-api-parse.ts
index df75eea2c4..d5e61c2305 100644
--- a/src/renderer/api/kube-api-parse.ts
+++ b/src/renderer/api/kube-api-parse.ts
@@ -50,6 +50,9 @@ export function parseKubeApi(path: string): IKubeApiParsed {
apiGroup = left.join("/");
} else {
switch (left.length) {
+ case 4:
+ [apiGroup, apiVersion, resource, name] = left
+ break;
case 2:
resource = left.pop();
// fallthrough
@@ -66,7 +69,7 @@ export function parseKubeApi(path: string): IKubeApiParsed {
* - `GROUP` is /^D(\.D)*$/ where D is `DNS_LABEL` and length <= 253
*
* There is no well defined selection from an array of items that were
- * seperated by '/'
+ * separated by '/'
*
* Solution is to create a huristic. Namely:
* 1. if '.' in left[0] then apiGroup <- left[0]
diff --git a/src/renderer/api/kube-api-parse_test.ts b/src/renderer/api/kube-api-parse_test.ts
index b33c833bfa..dee3bf031d 100644
--- a/src/renderer/api/kube-api-parse_test.ts
+++ b/src/renderer/api/kube-api-parse_test.ts
@@ -6,6 +6,19 @@ interface KubeApi_Parse_Test {
}
const tests: KubeApi_Parse_Test[] = [
+ {
+ url: "/apis/apiextensions.k8s.io/v1beta1/customresourcedefinitions/prometheuses.monitoring.coreos.com",
+ expected: {
+ apiBase: "/apis/apiextensions.k8s.io/v1beta1/customresourcedefinitions",
+ apiPrefix: "/apis",
+ apiGroup: "apiextensions.k8s.io",
+ apiVersion: "v1beta1",
+ apiVersionWithGroup: "apiextensions.k8s.io/v1beta1",
+ namespace: undefined,
+ resource: "customresourcedefinitions",
+ name: "prometheuses.monitoring.coreos.com"
+ },
+ },
{
url: "/api/v1/namespaces/kube-system/pods/coredns-6955765f44-v8p27",
expected: {
diff --git a/src/renderer/browser-check.tsx b/src/renderer/browser-check.tsx
deleted file mode 100644
index ce6c9ecad6..0000000000
--- a/src/renderer/browser-check.tsx
+++ /dev/null
@@ -1,20 +0,0 @@
-import React from "react";
-import { Notifications } from "./components/notifications";
-import { Trans } from "@lingui/macro";
-
-export function browserCheck() {
- const ua = window.navigator.userAgent
- const msie = ua.indexOf('MSIE ') // IE < 11
- const trident = ua.indexOf('Trident/') // IE 11
- const edge = ua.indexOf('Edge') // Edge
- if (msie > 0 || trident > 0 || edge > 0) {
- Notifications.info(
-
-
- Your browser does not support all Lens features. {" "}
- Please consider using another browser.
-
-
- )
- }
-}
\ No newline at end of file
diff --git a/src/renderer/components/+cluster-settings/cluster-settings.scss b/src/renderer/components/+cluster-settings/cluster-settings.scss
index e02a4da5f8..acb59ea0ac 100644
--- a/src/renderer/components/+cluster-settings/cluster-settings.scss
+++ b/src/renderer/components/+cluster-settings/cluster-settings.scss
@@ -57,6 +57,10 @@
font-size: smaller;
opacity: 0.8;
}
+
+ p + p, .hint + p {
+ padding-top: $padding;
+ }
}
.status-table {
@@ -79,7 +83,13 @@
}
}
- .Input,.Select {
+ .Input, .Select {
margin-top: 10px;
}
+
+ .Select {
+ &__control {
+ box-shadow: 0 0 0 1px $borderFaintColor;
+ }
+ }
}
\ No newline at end of file
diff --git a/src/renderer/components/+cluster-settings/components/cluster-prometheus-setting.tsx b/src/renderer/components/+cluster-settings/components/cluster-prometheus-setting.tsx
index e4f81bb18a..729090629d 100644
--- a/src/renderer/components/+cluster-settings/components/cluster-prometheus-setting.tsx
+++ b/src/renderer/components/+cluster-settings/components/cluster-prometheus-setting.tsx
@@ -1,10 +1,11 @@
import React from "react";
-import merge from "lodash/merge";
import { observer } from "mobx-react";
import { prometheusProviders } from "../../../../common/prometheus-providers";
import { Cluster } from "../../../../main/cluster";
import { SubTitle } from "../../layout/sub-title";
import { Select, SelectOption } from "../../select";
+import { Input } from "../../input";
+import { observable, computed } from "mobx";
const options: SelectOption[] = [
{ value: "", label: "Auto detect" },
@@ -17,6 +18,52 @@ interface Props {
@observer
export class ClusterPrometheusSetting extends React.Component {
+ @observable path = "";
+ @observable provider = "";
+
+ @computed get canEditPrometheusPath() {
+ if (this.provider === "" || this.provider === "lens") return false;
+ return true;
+ }
+
+ componentDidMount() {
+ const { prometheus, prometheusProvider } = this.props.cluster.preferences;
+ if (prometheus) {
+ const prefix = prometheus.prefix || "";
+ this.path = `${prometheus.namespace}/${prometheus.service}:${prometheus.port}${prefix}`;
+ }
+ if (prometheusProvider) {
+ this.provider = prometheusProvider.type;
+ }
+ }
+
+ parsePrometheusPath = () => {
+ if (!this.provider || !this.path) {
+ return null;
+ }
+ const parsed = this.path.split(/\/|:/, 3);
+ const apiPrefix = this.path.substring(parsed.join("/").length);
+ if (!parsed[0] || !parsed[1] || !parsed[2]) {
+ return null;
+ }
+ return {
+ namespace: parsed[0],
+ service: parsed[1],
+ port: parseInt(parsed[2]),
+ prefix: apiPrefix
+ }
+ }
+
+ onSaveProvider = () => {
+ this.props.cluster.preferences.prometheusProvider = this.provider ?
+ { type: this.provider } :
+ null;
+ }
+
+ onSavePath = () => {
+ this.props.cluster.preferences.prometheus = this.parsePrometheusPath();
+ };
+
render() {
return (
<>
@@ -26,18 +73,32 @@ export class ClusterPrometheusSetting extends React.Component {
guide{" "}
for possible configuration changes.
+ Prometheus installation method.