Skip to content

Commit

Permalink
feat: add card collection listing & help (#144)
Browse files Browse the repository at this point in the history
* feat: init collection listing

* feat: add sort

* feat: update manage history

* feat: collection and recommendation updates

* feat: update btn type
  • Loading branch information
Kav91 committed Nov 11, 2022
1 parent ffa6be8 commit 6e87c01
Show file tree
Hide file tree
Showing 26 changed files with 3,114 additions and 1,416 deletions.
176 changes: 95 additions & 81 deletions backend/processor/entities/AWSALB.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,14 @@ const { batchEntityQuery, fetchPricing, BASE_URL } = require('./utils');

const LoadBalancerQuery = `FROM LoadBalancerSample SELECT latest(awsRegion), latest(provider.ruleEvaluations.Sum), latest(provider.processedBytes.Maximum), latest(provider.newConnectionCount.Sum), latest(procider.activeConnectionCount.Sum) LIMIT 1`;

exports.run = (entities, key, config, timeNrql, totalPeriodMs) => {
exports.run = (
entities,
key,
config,
timeNrql,
totalPeriodMs,
nerdGraphUrl
) => {
// milliseconds to hours - divide the time value by 3.6e+6
const operatingHours = totalPeriodMs / 3.6e6;

Expand All @@ -28,88 +35,95 @@ exports.run = (entities, key, config, timeNrql, totalPeriodMs) => {
}
}`;

batchEntityQuery(key, query, entities, config).then(async entityData => {
// get cloud pricing
const cloudPricing = await fetchPricing(
`${BASE_URL}/amazon/elb/pricing.json`
);
const priceData = cloudPricing?.priceData;

if (priceData) {
entityData.forEach(e => {
// move samples top level
const LoadBalancerSample = e?.LoadBalancerSample?.results?.[0] || {};

// clean up keys
Object.keys(LoadBalancerSample).forEach(key => {
if (!LoadBalancerSample[key]) {
delete LoadBalancerSample[key];
} else if (key.startsWith('latest.')) {
const newKey = key.replace('latest.', '');
LoadBalancerSample[newKey] = LoadBalancerSample[key];
delete LoadBalancerSample[key];
batchEntityQuery(key, query, entities, config, nerdGraphUrl).then(
async entityData => {
// get cloud pricing
const cloudPricing = await fetchPricing(
`${BASE_URL}/amazon/elb/pricing.json`
);
const priceData = cloudPricing?.priceData;

if (priceData) {
entityData.forEach(e => {
// move samples top level
const LoadBalancerSample =
e?.LoadBalancerSample?.results?.[0] || {};

// clean up keys
Object.keys(LoadBalancerSample).forEach(key => {
if (!LoadBalancerSample[key]) {
delete LoadBalancerSample[key];
} else if (key.startsWith('latest.')) {
const newKey = key.replace('latest.', '');
LoadBalancerSample[newKey] = LoadBalancerSample[key];
delete LoadBalancerSample[key];
}
});
e.LoadBalancerSample = LoadBalancerSample;

const region = priceData?.mapping?.[e.tags?.['aws.awsRegion']?.[0]];
const pricing = priceData?.regions?.[region];

// https://aws.amazon.com/elasticloadbalancing/pricing/

if (pricing) {
// LCU Cost
// You are charged only on the dimension with the highest usage. An LCU contains:
// 25 new connections per second.
// 3,000 active connections per minute.
// 1 GB per hour for EC2 instances, containers and IP addresses as targets and 0.4 GB per hour for Lambda functions as targets

// work on 1 connection per second
const newConnLCUs = LoadBalancerSample[
'provider.newConnectionCount.Sum'
]
? 1 / LoadBalancerSample['provider.newConnectionCount.Sum']
: 0;

// work on 1 new connection per second, each lasting 2 minutes
const activeConnLCUs = LoadBalancerSample[
'provider.activeConnectionCount.Sum'
]
? 120 / LoadBalancerSample['provider.activeConnectionCount.Sum']
: 0;

const processedGbLCUs = LoadBalancerSample[
'provider.processedBytes.Sum'
]
? LoadBalancerSample['provider.processedBytes.Sum'] / 1e9 / 1
: 0;

// Rule Evaluations (per second): For simplicity, assume that all configured rules are processed for a request.
// Each LCU provides 1,000 rule evaluations per second (averaged over the hour).
// Since your application receives 5 requests/sec, 60 processed rules for each request results
// in a maximum 250 rule evaluations per second (60 processed rules – 10 free rules) * 5 or 0.25 LCU (250 rule evaluations per second / 1,000 rule evaluations per second)
const rulesSum =
LoadBalancerSample['provider.ruleEvaluations.Sum'];
const rulesEvalLCUs = rulesSum > 10 ? (rulesSum - 10) * 5 : 0;

e.lcuPricePerHour = parseFloat(
pricing['Application Load Balancer LCU Hours'].price
);

e.lcuCostPerHour =
e.lcuPricePerHour *
(newConnLCUs +
activeConnLCUs +
processedGbLCUs +
rulesEvalLCUs);
e.pricePerHour = parseFloat(
pricing['Application Load Balancer Hours'].price
);

e.periodCost =
operatingHours * e.pricePerHour +
operatingHours * e.lcuCostPerHour;
}
});
e.LoadBalancerSample = LoadBalancerSample;

const region = priceData?.mapping?.[e.tags?.['aws.awsRegion']?.[0]];
const pricing = priceData?.regions?.[region];

// https://aws.amazon.com/elasticloadbalancing/pricing/

if (pricing) {
// LCU Cost
// You are charged only on the dimension with the highest usage. An LCU contains:
// 25 new connections per second.
// 3,000 active connections per minute.
// 1 GB per hour for EC2 instances, containers and IP addresses as targets and 0.4 GB per hour for Lambda functions as targets

// work on 1 connection per second
const newConnLCUs = LoadBalancerSample[
'provider.newConnectionCount.Sum'
]
? 1 / LoadBalancerSample['provider.newConnectionCount.Sum']
: 0;

// work on 1 new connection per second, each lasting 2 minutes
const activeConnLCUs = LoadBalancerSample[
'provider.activeConnectionCount.Sum'
]
? 120 / LoadBalancerSample['provider.activeConnectionCount.Sum']
: 0;

const processedGbLCUs = LoadBalancerSample[
'provider.processedBytes.Sum'
]
? LoadBalancerSample['provider.processedBytes.Sum'] / 1e9 / 1
: 0;

// Rule Evaluations (per second): For simplicity, assume that all configured rules are processed for a request.
// Each LCU provides 1,000 rule evaluations per second (averaged over the hour).
// Since your application receives 5 requests/sec, 60 processed rules for each request results
// in a maximum 250 rule evaluations per second (60 processed rules – 10 free rules) * 5 or 0.25 LCU (250 rule evaluations per second / 1,000 rule evaluations per second)
const rulesSum = LoadBalancerSample['provider.ruleEvaluations.Sum'];
const rulesEvalLCUs = rulesSum > 10 ? (rulesSum - 10) * 5 : 0;

e.lcuPricePerHour = parseFloat(
pricing['Application Load Balancer LCU Hours'].price
);

e.lcuCostPerHour =
e.lcuPricePerHour *
(newConnLCUs + activeConnLCUs + processedGbLCUs + rulesEvalLCUs);
e.pricePerHour = parseFloat(
pricing['Application Load Balancer Hours'].price
);

e.periodCost =
operatingHours * e.pricePerHour +
operatingHours * e.lcuCostPerHour;
}
});
}
}

resolve(entityData);
});
resolve(entityData);
}
);
});
};
84 changes: 47 additions & 37 deletions backend/processor/entities/AWSAPIGATEWAYAPI.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,14 @@ const { batchEntityQuery, fetchPricing, BASE_URL } = require('./utils');

const GatewaySampleQuery = `SELECT sum(provider.count.SampleCount) as 'requests' FROM ApiGatewaySample WHERE provider='ApiGatewayApi' LIMIT 1`;

exports.run = (entities, key, config, timeNrql) => {
exports.run = (
entities,
key,
config,
timeNrql,
totalPeriodMs,
nerdGraphUrl
) => {
return new Promise(resolve => {
const query = `query Query($guids: [EntityGuid]!) {
actor {
Expand All @@ -25,48 +32,51 @@ exports.run = (entities, key, config, timeNrql) => {
}
}`;

batchEntityQuery(key, query, entities, config).then(async entityData => {
// get cloud pricing
const cloudPricing = await fetchPricing(
`${BASE_URL}/amazon/apigateway/pricing.json`
);
const priceData = cloudPricing?.priceData;
batchEntityQuery(key, query, entities, config, nerdGraphUrl).then(
async entityData => {
// get cloud pricing
const cloudPricing = await fetchPricing(
`${BASE_URL}/amazon/apigateway/pricing.json`
);
const priceData = cloudPricing?.priceData;

if (priceData) {
// massage entity data
entityData.forEach(e => {
// move samples top level
const ApiGatewaySample = e?.ApiGatewaySample?.results?.[0] || {};
if (priceData) {
// massage entity data
entityData.forEach(e => {
// move samples top level
const ApiGatewaySample = e?.ApiGatewaySample?.results?.[0] || {};

// clean up keys
Object.keys(ApiGatewaySample).forEach(key => {
if (!ApiGatewaySample[key]) {
delete ApiGatewaySample[key];
} else if (key.startsWith('latest.')) {
const newKey = key.replace('latest.', '');
ApiGatewaySample[newKey] = ApiGatewaySample[key];
delete ApiGatewaySample[key];
}
});
e.ApiGatewaySample = ApiGatewaySample;
// clean up keys
Object.keys(ApiGatewaySample).forEach(key => {
if (!ApiGatewaySample[key]) {
delete ApiGatewaySample[key];
} else if (key.startsWith('latest.')) {
const newKey = key.replace('latest.', '');
ApiGatewaySample[newKey] = ApiGatewaySample[key];
delete ApiGatewaySample[key];
}
});
e.ApiGatewaySample = ApiGatewaySample;

const region = priceData?.mapping?.[e.tags?.['aws.awsRegion']?.[0]];
const pricing = priceData?.regions?.[region.replace('Europe', 'EU')];
const region = priceData?.mapping?.[e.tags?.['aws.awsRegion']?.[0]];
const pricing =
priceData?.regions?.[region.replace('Europe', 'EU')];

if (pricing) {
const requests = ApiGatewaySample.requests || 0;
const apiCallPrice =
pricing?.['API Calls Number of up to 333 million']?.price;
if (pricing) {
const requests = ApiGatewaySample.requests || 0;
const apiCallPrice =
pricing?.['API Calls Number of up to 333 million']?.price;

if (apiCallPrice) {
e.requestCost = apiCallPrice * requests;
e.apiCallPrice = apiCallPrice;
if (apiCallPrice) {
e.requestCost = apiCallPrice * requests;
e.apiCallPrice = apiCallPrice;
}
}
}
});
}
});
}

resolve(entityData);
});
resolve(entityData);
}
);
});
};

0 comments on commit 6e87c01

Please sign in to comment.