Skip to content

Commit

Permalink
add gateway products to report
Browse files Browse the repository at this point in the history
  • Loading branch information
ikethecoder committed Nov 13, 2024
1 parent fc6edff commit c84a94a
Show file tree
Hide file tree
Showing 13 changed files with 245 additions and 64 deletions.
1 change: 1 addition & 0 deletions src/services/keystone/access-request.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export async function getAccessRequestsByNamespace(
requestor {
name
username
providerUsername
}
application {
name
Expand Down
9 changes: 9 additions & 0 deletions src/services/keystone/product-environment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -180,11 +180,20 @@ export async function lookupEnvironmentsByNS(
appId
name
flow
active
additionalDetailsToRequest
approval
services {
name
}
product {
id
name
dataset {
name
title
isInCatalog
}
}
legal {
reference
Expand Down
4 changes: 2 additions & 2 deletions src/services/report/data/consumer-requests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { ReportOfNamespaces } from './namespaces';
import { ReportOfGatewayMetrics } from './gateway-metrics';
import { getAccessRequestsByNamespace } from '../../keystone';

interface ReportOfConsumerRequest {
export interface ReportOfConsumerRequest {
namespace: string;
displayName?: string;
prod_name: string;
Expand Down Expand Up @@ -44,7 +44,7 @@ export async function getConsumerRequests(
prod_env_flow: req.productEnvironment?.flow,
app_name: req.application.name,
app_id: req.application.appId,
requestor: req.requestor.name,
requestor: req.requestor.name ?? req.requestor.providerUsername,
req_created: req.createdAt,
req_reviewer: '',
req_result: req.isComplete
Expand Down
12 changes: 10 additions & 2 deletions src/services/report/data/features/api_directory.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
import { GatewayService } from '../../../../services/keystone/types';
import { ReportOfNamespaces } from '../namespaces';
import { ReportOfProducts } from '../products';

export function has_feature_api_directory(
export function has_feature_api_directory_for_product(
ns: ReportOfNamespaces,
product: ReportOfProducts
): Boolean {
return product.prod_env_active === 'Y';
}

export function has_feature_api_directory_for_service(
ns: ReportOfNamespaces,
service: GatewayService,
routeName: string
): Boolean {
return Boolean(service?.environment?.active);
return Boolean(service.environment?.active);
}
11 changes: 5 additions & 6 deletions src/services/report/data/features/consumer_mgmt.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
import { GatewayService } from '../../../keystone/types';
import { ReportOfNamespaces } from '../namespaces';
import { ReportOfProducts } from '../products';

export function has_feature_consumer_mgmt(
ns: ReportOfNamespaces,
service: GatewayService,
routeName: string
product: ReportOfProducts
): Boolean {
return (
['client-credentials', 'kong-api-key-acl'].indexOf(
service.environment?.flow
) >= 0
return Boolean(
['client-credentials', 'kong-api-key-acl'].indexOf(product.prod_env_flow) >=
0 && product.prod_env_active === 'Y'
);
}
10 changes: 10 additions & 0 deletions src/services/report/data/features/dataset_in_catalog.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { GatewayService } from '../../../keystone/types';
import { ReportOfNamespaces } from '../namespaces';
import { ReportOfProducts } from '../products';

export function has_feature_dataset_in_catalog(
ns: ReportOfNamespaces,
product: ReportOfProducts
): Boolean {
return product.dataset_in_catalog;
}
12 changes: 12 additions & 0 deletions src/services/report/data/features/has_gateway_mgmt.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { GatewayService } from '../../../keystone/types';
import { ReportOfNamespaces } from '../namespaces';

// If there is a Route, then can consider gateway
// management being used
export function has_gateway_mgmt(
ns: ReportOfNamespaces,
service: GatewayService,
routeName: string
): Boolean {
return Boolean(true);
}
24 changes: 20 additions & 4 deletions src/services/report/data/features/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,36 @@ import {
GatewayService,
} from '../../../../services/keystone/types';
import { ReportOfNamespaces } from '../namespaces';
import { has_feature_api_directory } from './api_directory';
import {
has_feature_api_directory_for_product,
has_feature_api_directory_for_service,
} from './api_directory';
import { has_feature_consumer_mgmt } from './consumer_mgmt';
import { has_feature_dataset_in_catalog } from './dataset_in_catalog';
import { has_gateway_mgmt } from './has_gateway_mgmt';
import { is_production } from './production';
import { has_feature_protected } from './protected';
import { has_feature_protected_externally } from './protected_exterrnally';
import { has_feature_shared_idp } from './shared_idp';
import { has_feature_two_tiered_access } from './two_tiered_access';

export const ProductFeatureList: { [key: string]: Function } = {
consumer_mgmt: has_feature_consumer_mgmt,
protected_externally: has_feature_protected_externally,
dataset_in_catalog: has_feature_dataset_in_catalog,
api_directory: has_feature_api_directory_for_product,
};

export const FeatureList: { [key: string]: Function } = {
api_directory: has_feature_api_directory,
api_directory: has_feature_api_directory_for_service, // evaluated at a Gateway level
shared_idp: has_feature_shared_idp,
consumer_mgmt: has_feature_consumer_mgmt,
gateway_mgmt: has_gateway_mgmt,
consumer_mgmt: undefined, // evaluated at a Gateway level
protected: has_feature_protected,
two_tiered_access: has_feature_two_tiered_access,
production: is_production,
protected_externally: undefined, // evaluated at a Gateway level
dataset_in_catalog: undefined, // evaluated at a Gateway level
};

export function getFeatures(
Expand All @@ -27,7 +43,7 @@ export function getFeatures(
const service = findService(services, routeName);
const features: string[] = [];
Object.entries(FeatureList).forEach((func) => {
if (func[1](ns, service, routeName)) {
if (func[1] && func[1](ns, service, routeName)) {
features.push(func[0]);
}
});
Expand Down
25 changes: 20 additions & 5 deletions src/services/report/data/namespaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import {
import { GWAService } from '../../gwaapi';
import { ReportOfGatewayMetrics } from './gateway-metrics';
import { ReportOfProducts } from './products';
import { ReportOfConsumerRequest } from './consumer-requests';
import { lookupUsersByNamespace } from '@/services/keystone';

export interface ReportOfNamespaces {
resource_id: string;
Expand All @@ -23,7 +25,9 @@ export interface ReportOfNamespaces {
org?: string;
orgUnit?: string;
decommissioned?: string;
features?: string[];
consumers?: number;
day_30_total?: number;
features?: { [feature: string]: string };
}

/*
Expand Down Expand Up @@ -87,18 +91,29 @@ export function rollupFeatures(
products: ReportOfProducts[]
) {
namespaces.forEach((ns) => {
ns.features = [];
ns.features = {};
ns.day_30_total = 0;
gatewayMetrics
.filter((gw) => gw.namespace == ns.name)
.forEach((gw) => {
ns.features.push.apply(ns.features, gw.features);
gw.features.forEach((feat) => (ns.features[feat] = 'Y'));
ns.day_30_total = ns.day_30_total + gw.day_30_total;
});
products
.filter((gw) => gw.namespace == ns.name)
.forEach((gw) => {
ns.features.push.apply(ns.features, gw.features);
gw.features.forEach((feat) => (ns.features[feat] = 'Y'));
});
});
}

ns.features = dedup(ns.features).sort();
export function rollupConsumers(
namespaces: ReportOfNamespaces[],
requests: ReportOfConsumerRequest[]
) {
namespaces.forEach((ns) => {
ns.consumers = requests.filter(
(req) => req.namespace === ns.name && req.req_result === 'Approved'
).length;
});
}
27 changes: 18 additions & 9 deletions src/services/report/data/products.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,25 @@ import { Keystone } from '@keystonejs/keystone';
import { ReportOfNamespaces } from './namespaces';
import { getServiceMetrics, calculateStats } from '../../keystone';
import { dateRange } from '../../utils';
import { getFeatures, getPlugins } from './features';
import { getFeatures, getPlugins, ProductFeatureList } from './features';
import { lookupEnvironmentsByNS } from '../../../services/keystone/product-environment';
import { Environment } from '../../../services/keystone/types';
import { has_feature_protected_externally } from './features/protected_exterrnally';
import { has_feature_dataset_in_catalog } from './features/dataset_in_catalog';

export interface ReportOfProducts {
namespace: string;
display_name?: string;
prod_name?: string;
prod_env_active: string;
prod_env_active: 'Y' | 'N';
prod_env_approval: 'Y' | 'N';
prod_env_name?: string;
prod_env_flow?: string;
prod_env_app_id?: string;
dataset_name?: string;
dataset_title?: string;
dataset_in_catalog: boolean;
service_names?: string[];
features: string[];
}

Expand All @@ -35,16 +41,19 @@ export async function getProducts(
prod_env_app_id: env.appId,
prod_env_flow: env.flow,
prod_env_active: env.active ? 'Y' : 'N',
prod_env_approval: env.approval ? 'Y' : 'N',
dataset_name: env.product?.dataset?.name,
dataset_title: env.product?.dataset?.title,
dataset_in_catalog: env.product?.dataset?.isInCatalog,
service_names: env.services.map((s) => s.name),
features: [],
} as ReportOfProducts;

const featureProtectedExternally = has_feature_protected_externally(
ns,
product
);
if (featureProtectedExternally) {
product.features.push('protected_externally');
}
Object.entries(ProductFeatureList).forEach((func) => {
if (func[1] && func[1](ns, product)) {
product.features.push(func[0]);
}
});
return product;
});
}
Expand Down
Loading

0 comments on commit c84a94a

Please sign in to comment.