Skip to content

Commit

Permalink
add new mutations and queries to support synce topology from topology…
Browse files Browse the repository at this point in the history
… discovery (#389)
  • Loading branch information
MarcoMruz authored Jan 11, 2024
1 parent 15a5c52 commit 528f340
Show file tree
Hide file tree
Showing 6 changed files with 538 additions and 9 deletions.
236 changes: 230 additions & 6 deletions src/__generated__/topology-discovery.graphql.ts

Large diffs are not rendered by default.

83 changes: 83 additions & 0 deletions src/external-api/topology-discovery-graphql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {
TopologyType,
UpdateCoordinatesMutation,
UpdateCoordinatesMutationVariables,
SynceTopologyQuery,
} from '../__generated__/topology-discovery.graphql';
import {
HasAndInterfacesOutput,
Expand Down Expand Up @@ -276,6 +277,81 @@ const PTP_PATH = gql`
}
`;

const SYNCE_TOPOLOGY = gql`
fragment SynceDeviceParts on SynceDevice {
id
name
coordinates {
x
y
}
details {
selected_for_use
}
status
labels
synceInterfaces {
edges {
cursor
node {
...SynceInterfaceParts
}
}
}
}
fragment SynceInterfaceDeviceParts on SynceDevice {
id
name
coordinates {
x
y
}
synceInterfaces {
edges {
node {
id
idLink
name
synceLink {
id
idLink
name
}
}
}
}
}
fragment SynceInterfaceParts on SynceInterface {
id
idLink
name
status
synceDevice {
...SynceInterfaceDeviceParts
}
synceLink {
id
idLink
synceDevice {
...SynceInterfaceDeviceParts
}
}
}
query SynceTopology {
synceDevices {
edges {
cursor
node {
...SynceDeviceParts
}
}
}
}
`;

function getTopologyDiscoveryApi() {
if (!config.topologyEnabled) {
return undefined;
Expand Down Expand Up @@ -381,6 +457,12 @@ function getTopologyDiscoveryApi() {
return response.ptpPathToGmClock.nodes;
}

async function getSynceTopology(): Promise<SynceTopologyQuery> {
const response = await client.request<SynceTopologyQuery>(SYNCE_TOPOLOGY);

return response;
}

return {
getTopologyDevices,
getNetTopologyDevices,
Expand All @@ -393,6 +475,7 @@ function getTopologyDiscoveryApi() {
getPtpTopology,
getPtpPathToGrandMaster,
updateCoordinates,
getSynceTopology,
};
}

Expand Down
94 changes: 93 additions & 1 deletion src/helpers/topology.helpers.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import { device as PrismaDevice } from '@prisma/client';
import { NetTopologyQuery, PtpTopologyQuery, TopologyDevicesQuery } from '../__generated__/topology-discovery.graphql';
import {
NetTopologyQuery,
PtpTopologyQuery,
SynceTopologyQuery,
TopologyDevicesQuery,
} from '../__generated__/topology-discovery.graphql';
import {
ArangoDevice,
ArangoEdge,
Expand Down Expand Up @@ -28,6 +33,10 @@ type PtpDeviceDetails = {
gmClockId: string;
};

type SynceDeviceDetails = {
selectedForUse: string | null;
};

function getLabelsQuery(labelIds: string[]): Record<string, unknown> | undefined {
return labelIds.length ? { some: { labelId: { in: labelIds } } } : undefined;
}
Expand Down Expand Up @@ -410,3 +419,86 @@ export function makePtpTopologyEdges(ptpDevices?: PtpTopologyQuery) {
.filter(omitNullValue) ?? []
);
}

export function makeSynceDeviceDetails(
device: NonNullable<NonNullable<NonNullable<SynceTopologyQuery['synceDevices']['edges']>[0]>['node']>,
): SynceDeviceDetails {
return {
selectedForUse: device.details.selected_for_use,
};
}

export function makeSynceTopologyNodes(synceDevices?: SynceTopologyQuery) {
return (
synceDevices?.synceDevices.edges
?.map((e) => {
const node = e?.node;
if (!node) {
return null;
}
return {
id: toGraphId('GraphNode', node.id),
nodeId: node.id,
name: node.name,
synceDeviceDetails: makeSynceDeviceDetails(node),
status: getStatus(node.status),
labels: node.labels?.map((l) => l) ?? [],
interfaces:
node.synceInterfaces.edges
?.map((i) => {
const interfaceNode = i?.node;
if (!interfaceNode) {
return null;
}
return {
id: interfaceNode.id,
name: interfaceNode.name,
status: getStatus(interfaceNode.status),
};
})
.filter(omitNullValue) ?? [],
coordinates: node.coordinates ?? { x: 0, y: 0 },
};
})
.filter(omitNullValue) ?? []
);
}

export function makeSynceTopologyEdges(synceDevices?: SynceTopologyQuery) {
return (
synceDevices?.synceDevices.edges
?.flatMap((e) => {
const device = e?.node ?? null;
if (!device) {
return [];
}

return device.synceInterfaces.edges
?.map((i) => {
const deviceInterface = i?.node;
if (
!deviceInterface ||
!deviceInterface.synceLink ||
!deviceInterface.synceLink.synceDevice ||
!deviceInterface.synceDevice
) {
return null;
}

return {
id: `${deviceInterface.id}-${deviceInterface.synceLink.id}`,
source: {
interface: deviceInterface.id,
nodeId: deviceInterface.synceDevice.name,
},
target: {
interface: deviceInterface.synceLink.id,
nodeId: deviceInterface.synceLink.synceDevice.name,
},
};
})
.filter(omitNullValue);
})
.filter(omitNullValue) ?? []
);
}
22 changes: 22 additions & 0 deletions src/schema/api.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -511,6 +511,7 @@ type Query {
ptpPathToGrandMaster(deviceFrom: String!): [String!]
ptpTopology: PtpTopology
shortestPath(from: String!, to: String!): [NetRoutingPathNode!]!
synceTopology: SynceTopology
topology(filter: FilterTopologyInput): Topology
topologyCommonNodes(nodes: [String!]!): TopologyCommonNodes
topologyVersionData(version: String!): TopologyVersionData!
Expand Down Expand Up @@ -552,6 +553,26 @@ type SyncFromNetworkPayload {
dataStore: DataStore
}

type SynceDeviceDetails {
selectedForUse: String
}

type SynceGraphNode {
coordinates: GraphNodeCoordinates!
id: ID!
interfaces: [GraphNodeInterface!]!
labels: [String!]
name: String!
nodeId: String!
status: GraphEdgeStatus!
synceDeviceDetails: SynceDeviceDetails!
}

type SynceTopology {
edges: [GraphEdge!]!
nodes: [SynceGraphNode!]!
}

type Topology {
edges: [GraphEdge!]!
nodes: [GraphNode!]!
Expand All @@ -562,6 +583,7 @@ type TopologyCommonNodes {
}

enum TopologyLayer {
EthTopology
PhysicalTopology
PtpTopology
}
Expand Down
64 changes: 63 additions & 1 deletion src/schema/nexus-typegen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ export interface NexusGenEnums {
GraphEdgeStatus: 'ok' | 'unknown';
SortDeviceBy: 'createdAt' | 'name' | 'serviceState';
SortDirection: 'ASC' | 'DESC';
TopologyLayer: 'PhysicalTopology' | 'PtpTopology';
TopologyLayer: 'EthTopology' | 'PhysicalTopology' | 'PtpTopology';
}

export interface NexusGenScalars {
Expand Down Expand Up @@ -481,6 +481,26 @@ export interface NexusGenObjects {
// root type
dataStore?: NexusGenRootTypes['DataStore'] | null; // DataStore
};
SynceDeviceDetails: {
// root type
selectedForUse?: string | null; // String
};
SynceGraphNode: {
// root type
coordinates: NexusGenRootTypes['GraphNodeCoordinates']; // GraphNodeCoordinates!
id: string; // ID!
interfaces: NexusGenRootTypes['GraphNodeInterface'][]; // [GraphNodeInterface!]!
labels?: string[] | null; // [String!]
name: string; // String!
nodeId: string; // String!
status: NexusGenEnums['GraphEdgeStatus']; // GraphEdgeStatus!
synceDeviceDetails: NexusGenRootTypes['SynceDeviceDetails']; // SynceDeviceDetails!
};
SynceTopology: {
// root type
edges: NexusGenRootTypes['GraphEdge'][]; // [GraphEdge!]!
nodes: NexusGenRootTypes['SynceGraphNode'][]; // [SynceGraphNode!]!
};
Topology: {
// root type
edges: NexusGenRootTypes['GraphEdge'][]; // [GraphEdge!]!
Expand Down Expand Up @@ -939,6 +959,7 @@ export interface NexusGenFieldTypes {
ptpPathToGrandMaster: string[] | null; // [String!]
ptpTopology: NexusGenRootTypes['PtpTopology'] | null; // PtpTopology
shortestPath: NexusGenRootTypes['NetRoutingPathNode'][]; // [NetRoutingPathNode!]!
synceTopology: NexusGenRootTypes['SynceTopology'] | null; // SynceTopology
topology: NexusGenRootTypes['Topology'] | null; // Topology
topologyCommonNodes: NexusGenRootTypes['TopologyCommonNodes'] | null; // TopologyCommonNodes
topologyVersionData: NexusGenRootTypes['TopologyVersionData']; // TopologyVersionData!
Expand Down Expand Up @@ -968,6 +989,26 @@ export interface NexusGenFieldTypes {
// field return type
dataStore: NexusGenRootTypes['DataStore'] | null; // DataStore
};
SynceDeviceDetails: {
// field return type
selectedForUse: string | null; // String
};
SynceGraphNode: {
// field return type
coordinates: NexusGenRootTypes['GraphNodeCoordinates']; // GraphNodeCoordinates!
id: string; // ID!
interfaces: NexusGenRootTypes['GraphNodeInterface'][]; // [GraphNodeInterface!]!
labels: string[] | null; // [String!]
name: string; // String!
nodeId: string; // String!
status: NexusGenEnums['GraphEdgeStatus']; // GraphEdgeStatus!
synceDeviceDetails: NexusGenRootTypes['SynceDeviceDetails']; // SynceDeviceDetails!
};
SynceTopology: {
// field return type
edges: NexusGenRootTypes['GraphEdge'][]; // [GraphEdge!]!
nodes: NexusGenRootTypes['SynceGraphNode'][]; // [SynceGraphNode!]!
};
Topology: {
// field return type
edges: NexusGenRootTypes['GraphEdge'][]; // [GraphEdge!]!
Expand Down Expand Up @@ -1427,6 +1468,7 @@ export interface NexusGenFieldTypeNames {
ptpPathToGrandMaster: 'String';
ptpTopology: 'PtpTopology';
shortestPath: 'NetRoutingPathNode';
synceTopology: 'SynceTopology';
topology: 'Topology';
topologyCommonNodes: 'TopologyCommonNodes';
topologyVersionData: 'TopologyVersionData';
Expand Down Expand Up @@ -1456,6 +1498,26 @@ export interface NexusGenFieldTypeNames {
// field return type name
dataStore: 'DataStore';
};
SynceDeviceDetails: {
// field return type name
selectedForUse: 'String';
};
SynceGraphNode: {
// field return type name
coordinates: 'GraphNodeCoordinates';
id: 'ID';
interfaces: 'GraphNodeInterface';
labels: 'String';
name: 'String';
nodeId: 'String';
status: 'GraphEdgeStatus';
synceDeviceDetails: 'SynceDeviceDetails';
};
SynceTopology: {
// field return type name
edges: 'GraphEdge';
nodes: 'SynceGraphNode';
};
Topology: {
// field return type name
edges: 'GraphEdge';
Expand Down
Loading

0 comments on commit 528f340

Please sign in to comment.