consul/ui/packages/consul-ui/app/services/repository/peer.js

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}`
),
};
});
}
}