Skip to content

Commit

Permalink
Merge pull request #8 from baoduy/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
baoduy authored Mar 16, 2024
2 parents e6c6910 + d00b1f8 commit 019deab
Show file tree
Hide file tree
Showing 9 changed files with 531 additions and 4 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/build-publish-drunk.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,9 @@ jobs:
- run: npm ci

#Fix node_modules/openpgp/openpgp.d.ts:10:46 - error
- name: Replace text in file
run: |
sed -i 's/NodeStream as GenericNodeStream/NodeWebStream as GenericNodeStream/g' node_modules/openpgp/openpgp.d.ts
# - name: Replace text in file
# run: |
# sed -i 's/NodeStream as GenericNodeStream/NodeWebStream as GenericNodeStream/g' node_modules/openpgp/openpgp.d.ts

# - name: Test
# continue-on-error: true
Expand Down
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Logs
logs
#logs
*.log
npm-debug.log*
yarn-debug.log*
Expand Down
86 changes: 86 additions & 0 deletions src/Logs/AppInsight.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import * as native from '@pulumi/azure-native';

import {
AppInsightInfo,
BasicResourceArgs,
KeyVaultInfo,
ResourceInfo,
} from '../types';
import { getSecret } from '../KeyVault/Helper';
import { getAppInsightName } from '../Common/Naming';
import { addCustomSecret } from '../KeyVault/CustomHelper';
import { Input } from '@pulumi/pulumi';

interface Props extends BasicResourceArgs {
dailyCapGb?: number;
vaultInfo?: KeyVaultInfo;
immediatePurgeDataOn30Days?: boolean;
ingestionMode?: native.insights.IngestionMode;
workspaceResourceId?: Input<string>;
}

export default ({
group,
name,
dailyCapGb = 0.023,
immediatePurgeDataOn30Days = true,
ingestionMode = native.insights.IngestionMode.ApplicationInsights,
workspaceResourceId,
vaultInfo,
}: Props) => {
name = getAppInsightName(name);

const appInsight = new native.insights.Component(name, {
resourceName: name,
...group,

kind: 'web',
disableIpMasking: true,
applicationType: 'web',
flowType: 'Bluefield',

//samplingPercentage: isPrd ? 100 : 50,
retentionInDays: 30,

immediatePurgeDataOn30Days,
ingestionMode,

disableLocalAuth: true,
workspaceResourceId,
});

new native.insights.ComponentCurrentBillingFeature(
`${name}-CurrentBillingFeature`,
{
currentBillingFeatures: ['Basic'], // ['Basic', 'Application Insights Enterprise'],
dataVolumeCap: {
cap: dailyCapGb,
stopSendNotificationWhenHitCap: true,
},
resourceGroupName: group.resourceGroupName,
resourceName: appInsight.name,
}
);

if (vaultInfo) {
addCustomSecret({
name,
value: appInsight.instrumentationKey,
vaultInfo,
contentType: 'AppInsight',
});
}

return appInsight;
};

export const getAppInsightKey = async ({
resourceInfo,
vaultInfo,
}: {
resourceInfo: ResourceInfo;
vaultInfo: KeyVaultInfo;
}): Promise<AppInsightInfo> => {
const key = await getSecret({ name: resourceInfo.resourceName, vaultInfo });
return { ...resourceInfo, instrumentationKey: key?.value || '' };
};
151 changes: 151 additions & 0 deletions src/Logs/Helpers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
import * as native from '@pulumi/azure-native';
import { Input, interpolate } from '@pulumi/pulumi';

import { getResourceInfoFromId, subscriptionId } from '../Common/AzureEnv';
import { logGroupInfo } from '../Common/GlobalEnv';
import { getKeyName, getLogWpName, getStorageName } from '../Common/Naming';
import { getSecret } from '../KeyVault/Helper';
import { getStorageSecrets } from '../Storage/Helper';
import { DiagnosticProps, KeyVaultInfo } from '../types';

export const createDiagnostic = ({
name,
targetResourceId,
logWpId,
logStorageId,
metricsCategories = ['AllMetrics'],
logsCategories,
dependsOn,
}: DiagnosticProps) => {
//Ensure logWpId or logStorageId is provided
if (!logWpId && !logStorageId) {
console.error(
`Diagnostic for "${name}" must have either a "logWpId" or "logStorageId".`
);
return undefined;
}

//Ensure targetResourceId is valid
if (!targetResourceId) {
console.error(`Target resource of "${name}" must beprovided .`);
return undefined;
}

const n = `${name}-diag`;
return new native.insights.DiagnosticSetting(
n,
{
name: n,
resourceUri: targetResourceId,
logAnalyticsDestinationType: 'AzureDiagnostics',

workspaceId: logWpId,
storageAccountId: logWpId ? undefined : logStorageId,

//Metric
metrics: metricsCategories
? metricsCategories.map((c) => ({
category: c,
retentionPolicy: { enabled: false, days: 7 },
enabled: true,
}))
: undefined,
//Logs
logs: logsCategories
? logsCategories.map((c) => ({
category: c,
retentionPolicy: { enabled: false, days: 7 },
enabled: true,
}))
: undefined,
},
{ dependsOn }
);
};

interface ThreatProtectionProps {
name: string;
targetResourceId: Input<string>;
}

export const createThreatProtection = ({
name,
targetResourceId,
}: ThreatProtectionProps) =>
new native.security.AdvancedThreatProtection(name, {
isEnabled: true,
resourceId: targetResourceId,
});

export const getLogWpSecrets = async ({
fullName,
//group,
vaultInfo,
}: {
fullName: string;
//group: ResourceGroupInfo;
vaultInfo: KeyVaultInfo;
}) => {
const workspaceIdKeyName = `${fullName}-Id`;
const primaryKeyName = getKeyName(fullName, 'primary');
const secondaryKeyName = getKeyName(fullName, 'secondary');

const [wpId, primaryKey, secondaryKey] = await Promise.all([
getSecret({ name: workspaceIdKeyName, vaultInfo }),
getSecret({ name: primaryKeyName, nameFormatted: true, vaultInfo }),
getSecret({ name: secondaryKeyName, nameFormatted: true, vaultInfo }),
]);

return { wpId, primaryKey, secondaryKey };
};

export const getLogWpSecretsById = async ({
logWpId,
vaultInfo,
}: {
logWpId: string;
vaultInfo: KeyVaultInfo;
}) => {
const info = getResourceInfoFromId(logWpId);
const secrets = info
? await getLogWpSecrets({ fullName: info.name, vaultInfo })
: undefined;

return secrets ? { info, secrets } : undefined;
};

export const getLogWpInfo = async ({
logWpName,
vaultInfo,
}: {
logWpName: string;
vaultInfo?: KeyVaultInfo;
}) => {
const name = getLogWpName(logWpName);
const group = logGroupInfo;
const id = interpolate`/subscriptions/${subscriptionId}/resourcegroups/${group.resourceGroupName}/providers/microsoft.operationalinsights/workspaces/${name}`;

const secrets = vaultInfo
? await getLogWpSecrets({ fullName: name, vaultInfo })
: undefined;

return { name, group, id, secrets };
};

export const getLogStorageInfo = async ({
storageName,
vaultInfo,
}: {
storageName: string;
vaultInfo?: KeyVaultInfo;
}) => {
const name = getStorageName(storageName);
const group = logGroupInfo;
const id = interpolate`/subscriptions/${subscriptionId}/resourcegroups/${group.resourceGroupName}/providers/Microsoft.Storage/storageAccounts/${name}`;

const secrets = vaultInfo
? await getStorageSecrets({ name, vaultInfo })
: undefined;

return { name, group, id, secrets };
};
77 changes: 77 additions & 0 deletions src/Logs/LogAnalytics.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import * as operationalinsights from '@pulumi/azure-native/operationalinsights';
import { defaultTags } from '../Common/AzureEnv';
import { KeyVaultInfo, ResourceGroupInfo } from '../types';
import { getKeyName, getLogWpName } from '../Common/Naming';
import { addCustomSecret } from '../KeyVault/CustomHelper';

interface Props {
name: string;
group: ResourceGroupInfo;
sku?: operationalinsights.WorkspaceSkuNameEnum;
dailyQuotaGb?: number;
vaultInfo?: KeyVaultInfo;
}

export default ({
name,
group,
sku = operationalinsights.WorkspaceSkuNameEnum.Free,
dailyQuotaGb = 0.023,
vaultInfo,
}: Props) => {
name = getLogWpName(name);
const workspaceIdKeyName = `${name}-Id`;
const primaryKeyName = getKeyName(name, 'primary');
const secondaryKeyName = getKeyName(name, 'secondary');

const log = new operationalinsights.Workspace(name, {
workspaceName: name,
...group,

workspaceCapping:
sku === operationalinsights.WorkspaceSkuNameEnum.Free
? undefined
: { dailyQuotaGb }, //Fee is 2.99 USD/GB - Carefully

retentionInDays:
sku === operationalinsights.WorkspaceSkuNameEnum.Free ? 7 : 30, //DO NOT changes this
sku: { name: sku },
tags: defaultTags,
});

if (vaultInfo) {
log.customerId.apply(async (id) => {
if (!id) return;

const keys = await operationalinsights.getSharedKeys({
workspaceName: name,
resourceGroupName: group.resourceGroupName,
});

addCustomSecret({
name: workspaceIdKeyName,
value: id,
contentType: 'Log Analytics',
vaultInfo,
});

addCustomSecret({
name: primaryKeyName,
formattedName: true,
value: keys.primarySharedKey!,
contentType: 'Log Analytics',
vaultInfo,
});

addCustomSecret({
name: secondaryKeyName,
formattedName: true,
value: keys.secondarySharedKey!,
contentType: 'Log Analytics',
vaultInfo,
});
});
}

return { log, vaultNames: { primaryKeyName, secondaryKeyName } };
};
Loading

0 comments on commit 019deab

Please sign in to comment.