Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updating key dependency packages - applicationinsights and @kubernetes/client-node #1353

Open
wants to merge 10 commits into
base: ai_prod
Choose a base branch
from
4 changes: 2 additions & 2 deletions .pipelines/azure_pipeline_mergedbranches_appmonitoring.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -173,8 +173,8 @@ jobs:
sudo apt-get update && sudo apt-get -y install qemu binfmt-support qemu-user-static
docker run --rm --privileged multiarch/qemu-user-static --reset -p yes

docker buildx create --name testbuilder
docker buildx use testbuilder
# docker buildx create --name testbuilder
# docker buildx use testbuilder

az --version
az account show
Expand Down
18 changes: 9 additions & 9 deletions appmonitoring/ts/src/.trivyignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@
CVE-2023-26136
CVE-2024-28863

# import-in-the-middle -> @opentelemetry/instrumentation -> @azure/opentelemetry-instrumentation-azure-sdk -> applicationinsights
CVE-2023-38704
# @opentelemetry/instrumentation -> @azure/opentelemetry-instrumentation-azure-sdk -> applicationinsights
GHSA-f8pq-3926-8gx5

# ws -> kubernetes/client-node
CVE-2024-37890

# temporarily ignore until the next PR is merged that fixes vulnerabilities by updating packages
# need the build to pass to get through the PR gate
CVE-2024-21538
CVE-2024-21534

# @kubernetes/[email protected]
# │ └─┬ [email protected]
# │ └─┬ [email protected]
# │ └─┬ [email protected]
# │ └─┬ [email protected]
# │ └─┬ [email protected]
# │ └── [email protected] deduped
CVE-2024-21538
37 changes: 17 additions & 20 deletions appmonitoring/ts/src/CertificateManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,17 +137,20 @@ export class CertificateManager {
public async PatchSecretStore(operationId: string, kubeConfig: k8s.KubeConfig, certificate: WebhookCertData) {
try {
const secretsApi = kubeConfig.makeApiClient(k8s.CoreV1Api);
const secretStore = await secretsApi.readNamespacedSecret(CertificateStoreName, KubeSystemNamespaceName);
const secretsObj: k8s.V1Secret = secretStore.body;
const secretsObj: k8s.V1Secret = await secretsApi.readNamespacedSecret({ name: CertificateStoreName, namespace: KubeSystemNamespaceName });

secretsObj.data['ca.cert'] = Buffer.from(certificate.caCert, 'utf-8').toString('base64');
secretsObj.data['ca.key'] = Buffer.from(certificate.caKey, 'utf-8').toString('base64');
secretsObj.data['tls.cert'] = Buffer.from(certificate.tlsCert, 'utf-8').toString('base64');
secretsObj.data['tls.key'] = Buffer.from(certificate.tlsKey, 'utf-8').toString('base64');

await secretsApi.patchNamespacedSecret(CertificateStoreName, KubeSystemNamespaceName, secretsObj, undefined, undefined, undefined, undefined, undefined, {
headers: { 'Content-Type' : 'application/strategic-merge-patch+json' }
});
const request: k8s.CoreV1ApiPatchNamespacedSecretRequest = {
name: CertificateStoreName,
namespace: KubeSystemNamespaceName,
body: secretsObj
};

await secretsApi.patchNamespacedSecret(request);
logger.addHeartbeatMetric(HeartbeatMetrics.SecretStoreUpdatedCount, 1);
} catch (error) {
logger.error('Failed to patch Secret Store!', operationId, this.requestMetadata);
Expand All @@ -160,8 +163,7 @@ export class CertificateManager {
public async GetSecretDetails(operationId: string, kubeConfig: k8s.KubeConfig): Promise<WebhookCertData> {
try {
const k8sApi = kubeConfig.makeApiClient(k8s.CoreV1Api);
const secretStore = await k8sApi.readNamespacedSecret(CertificateStoreName, KubeSystemNamespaceName)
const secretsObj = secretStore.body;
const secretsObj: k8s.V1Secret = await k8sApi.readNamespacedSecret({ name: CertificateStoreName, namespace: KubeSystemNamespaceName });
if (secretsObj.data) {
const certificate: WebhookCertData = {
caCert: Buffer.from(secretsObj.data['ca.cert'], 'base64').toString('utf-8'),
Expand All @@ -181,8 +183,7 @@ export class CertificateManager {
public async GetMutatingWebhookCABundle(operationId: string, kubeConfig: k8s.KubeConfig): Promise<string> {
try {
const webhookApi: k8s.AdmissionregistrationV1Api = kubeConfig.makeApiClient(k8s.AdmissionregistrationV1Api);
const mutatingWebhook = await webhookApi.readMutatingWebhookConfiguration(WebhookName);
const mutatingWebhookObject: k8s.V1MutatingWebhookConfiguration = mutatingWebhook.body;
const mutatingWebhookObject: k8s.V1MutatingWebhookConfiguration = await webhookApi.readMutatingWebhookConfiguration({ name: WebhookName });
if (!mutatingWebhookObject
|| !mutatingWebhookObject.webhooks
|| mutatingWebhookObject.webhooks.length !== 1 || !mutatingWebhookObject.webhooks[0].clientConfig)
Expand All @@ -200,18 +201,15 @@ export class CertificateManager {
public async PatchMutatingWebhook(operationId: string, kubeConfig: k8s.KubeConfig, certificate: WebhookCertData) {
try {
const webhookApi: k8s.AdmissionregistrationV1Api = kubeConfig.makeApiClient(k8s.AdmissionregistrationV1Api);
const mutatingWebhook = await webhookApi.readMutatingWebhookConfiguration(WebhookName);
const mutatingWebhookObject: k8s.V1MutatingWebhookConfiguration = mutatingWebhook.body;
const mutatingWebhookObject: k8s.V1MutatingWebhookConfiguration = await webhookApi.readMutatingWebhookConfiguration({ name: WebhookName });
if (!mutatingWebhookObject
|| !mutatingWebhookObject.webhooks
|| mutatingWebhookObject.webhooks.length !== 1 || !mutatingWebhookObject.webhooks[0].clientConfig)
{
throw new Error("MutatingWebhookConfiguration not found or is malformed!");
}
mutatingWebhookObject.webhooks[0].clientConfig.caBundle = Buffer.from(certificate.caCert, 'utf-8').toString('base64');
await webhookApi.patchMutatingWebhookConfiguration(WebhookName, mutatingWebhookObject, undefined, undefined, undefined, undefined, undefined, {
headers: { 'Content-Type' : 'application/strategic-merge-patch+json' }
});
await webhookApi.patchMutatingWebhookConfiguration({ name: WebhookName, body: mutatingWebhookObject });
logger.addHeartbeatMetric(HeartbeatMetrics.MutatingWebhookConfigurationUpdatedCount, 1);
} catch (error) {
logger.error('Failed to patch MutatingWebhookConfiguration!', operationId, this.requestMetadata);
Expand Down Expand Up @@ -265,11 +263,10 @@ export class CertificateManager {
const namespace = KubeSystemNamespaceName;

try {
const res = await k8sApi.readNamespacedJobStatus(jobName, namespace);
const jobStatus = res.body.status;
const jobStatus: k8s.V1Job = await k8sApi.readNamespacedJobStatus({ name: jobName, namespace: namespace });

if (jobStatus.conditions) {
for (const condition of jobStatus.conditions) {
if (jobStatus.status?.conditions) {
for (const condition of jobStatus.status.conditions) {
if (condition.type === 'Complete' && condition.status === 'True') {
logger.info(`Job ${jobName} has completed.`, operationId, requestMetadata);
logger.SendEvent("CertificateJobCompleted", operationId, null, clusterArmId, clusterArmRegion);
Expand Down Expand Up @@ -475,7 +472,7 @@ export class CertificateManager {
try {
const k8sApi = kc.makeApiClient(k8s.AppsV1Api);
const selector = "app-monitoring-webhook"
const deployments: k8s.V1DeploymentList = (await k8sApi.listNamespacedDeployment(KubeSystemNamespaceName)).body;
const deployments: k8s.V1DeploymentList = (await k8sApi.listNamespacedDeployment({ namespace: KubeSystemNamespaceName }));

if (!deployments)
{
Expand All @@ -496,7 +493,7 @@ export class CertificateManager {

logger.info(`Restarting deployment ${name}...`, operationId, this.requestMetadata);
logger.SendEvent("DeploymentRestarting", operationId, null, clusterArmId, clusterArmRegion);
await k8sApi.replaceNamespacedDeployment(name, KubeSystemNamespaceName, deployment);
await k8sApi.replaceNamespacedDeployment({ name: name, namespace: KubeSystemNamespaceName, body: deployment });
console.log(`Successfully restarted Deployment ${name}`);
logger.SendEvent("DeploymentRestarted", operationId, null, clusterArmId, clusterArmRegion);
} catch (err) {
Expand Down
18 changes: 7 additions & 11 deletions appmonitoring/ts/src/K8sWatcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,17 +44,13 @@ export class K8sWatcher {

logger.info(`Listing CRs, resourceVersion=${latestResourceVersion}...`, operationId, requestMetadata);

const crsResult: ListResponse = <ListResponse>await k8sApi.listClusterCustomObject(
K8sWatcher.crdApiGroup,
K8sWatcher.crdApiVersion,
K8sWatcher.crdNamePlural,
undefined,
undefined,
undefined,
undefined, // `metadata.name=${K8sWatcher.crName}`
undefined,
undefined,
latestResourceVersion);
const crsResult: ListResponse = <ListResponse>await k8sApi.listClusterCustomObject({
group: K8sWatcher.crdApiGroup,
version: K8sWatcher.crdApiVersion,
plural: K8sWatcher.crdNamePlural,
// fieldSelector: `metadata.name=${K8sWatcher.crName}`
resourceVersion: latestResourceVersion
});

logger.info(`CRs listed, resourceVersion=${crsResult.body.metadata.resourceVersion}`, operationId, requestMetadata);

Expand Down
9 changes: 4 additions & 5 deletions appmonitoring/ts/src/LoggerWrapper.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import * as applicationInsights from "applicationinsights";
import { EventTelemetry, MetricTelemetry, TraceTelemetry } from "applicationinsights/out/Declarations/Contracts";
import { PodInfo } from "./RequestDefinition.js";

import log4js from "log4js";
Expand Down Expand Up @@ -237,11 +236,11 @@ class LocalLogger {
}

for(const metricName in this.heartbeatAccumulator.metrics) {
const telemetryItem: MetricTelemetry = {
const telemetryItem: applicationInsights.Contracts.MetricTelemetry & applicationInsights.Contracts.MetricPointTelemetry = {
name: HeartbeatMetrics[metricName],
time: new Date(),
value: Number(this.heartbeatAccumulator.metrics[metricName]),
count: 1,
time: new Date(),
properties: {
clusterMetadata: this.clusterMetadata
}
Expand Down Expand Up @@ -270,7 +269,7 @@ class LocalLogger {
break;
}

const telemetryItem: TraceTelemetry = {
const telemetryItem: applicationInsights.Contracts.TraceTelemetry = {
message: logArray[j].message,
time: new Date(),
properties: {
Expand All @@ -288,7 +287,7 @@ class LocalLogger {

public SendEvent(eventName: string, operationId: string, uid: string, clusterArmId: string, clusterArmRegion: string, flush = false, ...args: unknown[]) {
try {
const event: EventTelemetry = {
const event: applicationInsights.Contracts.EventTelemetry = {
name: eventName,
properties: {
time: Date.now(),
Expand Down
1 change: 1 addition & 0 deletions appmonitoring/ts/src/jest.config.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
}
]
},
"transformIgnorePatterns": [],
"testEnvironment": "node",
"testRegex": "/tests/.*\\.spec\\.(ts|tsx)$",
"moduleFileExtensions": [
Expand Down
Loading