mirror of https://github.com/hashicorp/consul
209 lines
5.2 KiB
JavaScript
209 lines
5.2 KiB
JavaScript
/**
|
|
* Copyright (c) HashiCorp, Inc.
|
|
* SPDX-License-Identifier: BUSL-1.1
|
|
*/
|
|
|
|
import RepositoryService from 'consul-ui/services/repository';
|
|
import dataSource from 'consul-ui/decorators/data-source';
|
|
import { inject as service } from '@ember/service';
|
|
|
|
function normalizePeerPayload(peerPayload, dc, partition) {
|
|
const {
|
|
StreamStatus: { LastHeartbeat, LastReceive, LastSend, ImportedServices, ExportedServices },
|
|
} = peerPayload;
|
|
|
|
return {
|
|
...peerPayload,
|
|
LastHeartbeat,
|
|
LastReceive,
|
|
LastSend,
|
|
ImportedServices,
|
|
ExportedServices,
|
|
Datacenter: dc,
|
|
Partition: partition,
|
|
};
|
|
}
|
|
export default class PeerService extends RepositoryService {
|
|
@service store;
|
|
|
|
getModelName() {
|
|
return 'peer';
|
|
}
|
|
|
|
@dataSource('/:partition/:ns/:ds/exported-services/:name')
|
|
async fetchExportedServices({ dc, ns, partition, name }, configuration, request) {
|
|
return (
|
|
await request`
|
|
GET /v1/internal/ui/exported-services
|
|
|
|
${{
|
|
peer: name,
|
|
}}
|
|
`
|
|
)((headers, body, cache) => {
|
|
const serviceSerializer = this.store.serializerFor('service');
|
|
|
|
return this.store.push(
|
|
serviceSerializer.createJSONApiDocumentFromServicesPayload(headers, body, dc)
|
|
);
|
|
});
|
|
}
|
|
|
|
@dataSource('/:partition/:ns/:dc/peering/token-for/:name/:externalAddresses')
|
|
async fetchToken({ dc, ns, partition, name, externalAddresses }, configuration, request) {
|
|
const ServerExternalAddresses =
|
|
externalAddresses?.length > 0 ? externalAddresses.split(',') : [];
|
|
|
|
return (
|
|
await request`
|
|
POST /v1/peering/token
|
|
|
|
${{
|
|
PeerName: name,
|
|
Partition: partition || undefined,
|
|
ServerExternalAddresses,
|
|
}}
|
|
`
|
|
)((headers, body, cache) => body);
|
|
}
|
|
|
|
@dataSource('/:partition/:ns/:dc/peers')
|
|
async fetchAll({ dc, ns, partition }, { uri }, request) {
|
|
return (
|
|
await request`
|
|
GET /v1/peerings
|
|
|
|
${{
|
|
partition,
|
|
}}
|
|
`
|
|
)((headers, body, cache) => {
|
|
return {
|
|
meta: {
|
|
version: 2,
|
|
interval: 10000,
|
|
uri: uri,
|
|
},
|
|
body: body.map((item) => {
|
|
return cache(
|
|
normalizePeerPayload(item, dc, partition),
|
|
(uri) => uri`peer:///${partition}/${ns}/${dc}/peer/${item.Name}`
|
|
);
|
|
}),
|
|
};
|
|
});
|
|
}
|
|
|
|
@dataSource('/:partition/:ns/:dc/peer-generate/')
|
|
@dataSource('/:partition/:ns/:dc/peer-initiate/')
|
|
@dataSource('/:partition/:ns/:dc/peer/:name')
|
|
async fetchOne({ partition, ns, dc, name }, { uri }, request) {
|
|
if (typeof name === 'undefined' || name === '') {
|
|
const item = this.create({
|
|
Datacenter: dc,
|
|
Namespace: '',
|
|
Partition: partition,
|
|
});
|
|
item.meta = { cacheControl: 'no-store' };
|
|
return item;
|
|
}
|
|
return (
|
|
await request`
|
|
GET /v1/peering/${name}
|
|
|
|
${{
|
|
partition,
|
|
}}
|
|
`
|
|
)((headers, body, cache) => {
|
|
// we can't easily use fragments as we are working around the serializer
|
|
// layer
|
|
const { StreamStatus } = body;
|
|
|
|
if (StreamStatus) {
|
|
if (StreamStatus.LastHeartbeat) {
|
|
StreamStatus.LastHeartbeat = new Date(StreamStatus.LastHeartbeat);
|
|
}
|
|
if (StreamStatus.LastReceive) {
|
|
StreamStatus.LastReceive = new Date(StreamStatus.LastReceive);
|
|
}
|
|
if (StreamStatus.LastSend) {
|
|
StreamStatus.LastSend = new Date(StreamStatus.LastSend);
|
|
}
|
|
}
|
|
|
|
return {
|
|
meta: {
|
|
version: 2,
|
|
interval: 10000,
|
|
uri: uri,
|
|
},
|
|
body: cache(
|
|
normalizePeerPayload(body, dc, partition),
|
|
(uri) => uri`peer:///${partition}/${ns}/${dc}/peer/${body.Name}`
|
|
),
|
|
};
|
|
});
|
|
}
|
|
|
|
async persist(item, request) {
|
|
// mark it as ESTABLISHING ourselves as the request is successful
|
|
// and we don't have blocking queries here to get immediate updates
|
|
return (
|
|
await request`
|
|
POST /v1/peering/establish
|
|
|
|
${{
|
|
PeerName: item.Name,
|
|
PeeringToken: item.PeeringToken,
|
|
Partition: item.Partition || undefined,
|
|
}}
|
|
`
|
|
)((headers, body, cache) => {
|
|
const partition = item.Partition;
|
|
const ns = item.Namespace;
|
|
const dc = item.Datacenter;
|
|
return {
|
|
meta: {
|
|
version: 2,
|
|
},
|
|
body: cache(
|
|
{
|
|
...item,
|
|
State: 'ESTABLISHING',
|
|
},
|
|
(uri) => uri`peer:///${partition}/${ns}/${dc}/peer/${item.Name}`
|
|
),
|
|
};
|
|
});
|
|
}
|
|
|
|
async remove(item, request) {
|
|
// soft delete
|
|
// we just return the item we want to delete
|
|
// but mark it as DELETING ourselves as the request is successful
|
|
// and we don't have blocking queries here to get immediate updates
|
|
return (
|
|
await request`
|
|
DELETE /v1/peering/${item.Name}
|
|
`
|
|
)((headers, body, cache) => {
|
|
const partition = item.Partition;
|
|
const ns = item.Namespace;
|
|
const dc = item.Datacenter;
|
|
return {
|
|
meta: {
|
|
version: 2,
|
|
},
|
|
body: cache(
|
|
{
|
|
...item,
|
|
State: 'DELETING',
|
|
},
|
|
(uri) => uri`peer:///${partition}/${ns}/${dc}/peer/${item.Name}`
|
|
),
|
|
};
|
|
});
|
|
}
|
|
}
|