feat: render IPv6 links (#9853)
* feat: render IPv6 links Signed-off-by: mtfoley <mtfoley.mae@gmail.com>
This commit is contained in:
parent
d677aa4b29
commit
8e9b8d499d
|
@ -1,6 +1,6 @@
|
|||
import React from 'react';
|
||||
import { shallow, mount } from 'enzyme';
|
||||
import { Badge, Alert } from 'reactstrap';
|
||||
import { Badge } from 'reactstrap';
|
||||
import EndpointLink from './EndpointLink';
|
||||
|
||||
describe('EndpointLink', () => {
|
||||
|
@ -29,11 +29,24 @@ describe('EndpointLink', () => {
|
|||
const targetLabel = badges.filterWhere((badge) => badge.children().text() === 'target="http://some-service"');
|
||||
expect(targetLabel.length).toEqual(1);
|
||||
});
|
||||
|
||||
it('renders an alert if url is invalid', () => {
|
||||
const endpointLink = shallow(<EndpointLink endpoint={'afdsacas'} globalUrl={'afdsacas'} />);
|
||||
const err = endpointLink.find(Alert);
|
||||
expect(err.render().text()).toEqual('Error: Invalid URL: afdsacas');
|
||||
// In cases of IPv6 addresses with a Zone ID, URL may not be parseable.
|
||||
// See https://github.com/prometheus/prometheus/issues/9760
|
||||
it('renders an anchor for IPv6 link with zone ID including labels for query params', () => {
|
||||
const endpoint =
|
||||
'http://[fe80::f1ee:adeb:371d:983%eth1]:9100/stats/prometheus?module=http_2xx&target=http://some-service';
|
||||
const globalURL =
|
||||
'http://[fe80::f1ee:adeb:371d:983%eth1]:9100/stats/prometheus?module=http_2xx&target=http://some-service';
|
||||
const endpointLink = shallow(<EndpointLink endpoint={endpoint} globalUrl={globalURL} />);
|
||||
const anchor = endpointLink.find('a');
|
||||
const badges = endpointLink.find(Badge);
|
||||
expect(anchor.prop('href')).toEqual(globalURL);
|
||||
expect(anchor.children().text()).toEqual('http://[fe80::f1ee:adeb:371d:983%eth1]:9100/stats/prometheus');
|
||||
expect(endpointLink.find('br')).toHaveLength(1);
|
||||
expect(badges).toHaveLength(2);
|
||||
const moduleLabel = badges.filterWhere((badge) => badge.children().text() === 'module="http_2xx"');
|
||||
expect(moduleLabel.length).toEqual(1);
|
||||
const targetLabel = badges.filterWhere((badge) => badge.children().text() === 'target="http://some-service"');
|
||||
expect(targetLabel.length).toEqual(1);
|
||||
});
|
||||
|
||||
it('handles params with multiple values correctly', () => {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import React, { FC } from 'react';
|
||||
import { Badge, Alert } from 'reactstrap';
|
||||
import { Badge } from 'reactstrap';
|
||||
|
||||
export interface EndpointLinkProps {
|
||||
endpoint: string;
|
||||
|
@ -8,23 +8,28 @@ export interface EndpointLinkProps {
|
|||
|
||||
const EndpointLink: FC<EndpointLinkProps> = ({ endpoint, globalUrl }) => {
|
||||
let url: URL;
|
||||
let search = '';
|
||||
let invalidURL = false;
|
||||
try {
|
||||
url = new URL(endpoint);
|
||||
} catch (err: unknown) {
|
||||
const error = err as Error;
|
||||
return (
|
||||
<Alert color="danger">
|
||||
<strong>Error:</strong> {error.message}
|
||||
</Alert>
|
||||
);
|
||||
// In cases of IPv6 addresses with a Zone ID, URL may not be parseable.
|
||||
// See https://github.com/prometheus/prometheus/issues/9760
|
||||
// In this case, we attempt to prepare a synthetic URL with the
|
||||
// same query parameters, for rendering purposes.
|
||||
invalidURL = true;
|
||||
if (endpoint.indexOf('?') > -1) {
|
||||
search = endpoint.substring(endpoint.indexOf('?'));
|
||||
}
|
||||
url = new URL('http://0.0.0.0' + search);
|
||||
}
|
||||
|
||||
const { host, pathname, protocol, searchParams }: URL = url;
|
||||
const params = Array.from(searchParams.entries());
|
||||
|
||||
const displayLink = invalidURL ? endpoint.replace(search, '') : `${protocol}//${host}${pathname}`;
|
||||
return (
|
||||
<>
|
||||
<a href={globalUrl}>{`${protocol}//${host}${pathname}`}</a>
|
||||
<a href={globalUrl}>{displayLink}</a>
|
||||
{params.length > 0 ? <br /> : null}
|
||||
{params.map(([labelName, labelValue]: [string, string]) => {
|
||||
return (
|
||||
|
|
Loading…
Reference in New Issue