From 823da4a2ec1e0cf6f3f40a0358b138c2888a9fda Mon Sep 17 00:00:00 2001 From: Vincent De Smet Date: Sat, 2 Sep 2023 19:22:19 +0700 Subject: [PATCH 1/3] chore: Bump datadog-dashboard (rename) --- ...{datadog-dashboard-1.0.0.json => datadog-dashboard-2.1.0.json} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename cf-schema/{datadog-dashboard-1.0.0.json => datadog-dashboard-2.1.0.json} (100%) diff --git a/cf-schema/datadog-dashboard-1.0.0.json b/cf-schema/datadog-dashboard-2.1.0.json similarity index 100% rename from cf-schema/datadog-dashboard-1.0.0.json rename to cf-schema/datadog-dashboard-2.1.0.json From 6e4c35ee85938fe5d4ba83b6580acb0656020f00 Mon Sep 17 00:00:00 2001 From: Vincent De Smet Date: Mon, 4 Sep 2023 15:04:05 +0700 Subject: [PATCH 2/3] chore: Refactor json schema generators - Use Projen FileBase objects to manage autogenerated files - Add Dashboard - Add SLO --- .gitattributes | 3 + .gitignore | 3 + .projen/deps.json | 27 +- .projen/files.json | 3 + .projen/tasks.json | 8 - .projenrc.ts | 156 +- .vscode/settings.json | 19 + README.md | 25 +- cf-schema/README.md | 5 + cf-schema/datadog-dashboard-2.1.0.json | 37 +- cf-schema/datadog-slo-1.1.0.json | 210 ++ package.json | 10 +- projenrc/datadog-dashboard-generator.ts | 30 + projenrc/datadog-monitor-generator.ts | 44 + projenrc/datadog-slo-generator.ts | 35 + projenrc/index.ts | 4 + projenrc/json-schema-base.ts | 110 + scripts/README.md | 5 - scripts/create-types.js | 41 - scripts/package.json | 9 - scripts/yarn.lock | 356 --- .../datadog-api-dashboard.generated.ts | 1993 +++++++++++++++++ .../datadog-dashboard-schema.generated.ts | 19 + src/dashboards/datadog-dashboard.ts | 37 + src/dashboards/index.ts | 3 + src/index.ts | 6 +- ...ts => datadog-monitor-schema.generated.ts} | 64 +- src/monitors/datadog-monitor.ts | 5 +- src/monitors/index.ts | 3 + src/slos/datadog-slo-schema.generated.ts | 96 + src/slos/datadog-slo.ts | 20 + src/slos/index.ts | 3 + src/slos/properties.ts | 16 + .../datadog-dashboard.test.ts.snap | 48 + .../datadog-monitor.test.ts.snap | 0 test/__snapshots__/datadog-slo.test.ts.snap | 71 + test/datadog-dashboard.test.ts | 63 + test/{monitors => }/datadog-monitor.test.ts | 2 +- test/datadog-slo.test.ts | 29 + tsconfig.dev.json | 2 +- yarn.lock | 338 ++- 41 files changed, 3310 insertions(+), 648 deletions(-) create mode 100644 .vscode/settings.json create mode 100644 cf-schema/README.md create mode 100644 cf-schema/datadog-slo-1.1.0.json create mode 100644 projenrc/datadog-dashboard-generator.ts create mode 100644 projenrc/datadog-monitor-generator.ts create mode 100644 projenrc/datadog-slo-generator.ts create mode 100644 projenrc/index.ts create mode 100644 projenrc/json-schema-base.ts delete mode 100644 scripts/README.md delete mode 100644 scripts/create-types.js delete mode 100644 scripts/package.json delete mode 100644 scripts/yarn.lock create mode 100644 src/dashboards/datadog-api-dashboard.generated.ts create mode 100644 src/dashboards/datadog-dashboard-schema.generated.ts create mode 100644 src/dashboards/datadog-dashboard.ts create mode 100644 src/dashboards/index.ts rename src/monitors/{datadog-monitor-schema.ts => datadog-monitor-schema.generated.ts} (90%) create mode 100644 src/monitors/index.ts create mode 100644 src/slos/datadog-slo-schema.generated.ts create mode 100644 src/slos/datadog-slo.ts create mode 100644 src/slos/index.ts create mode 100644 src/slos/properties.ts create mode 100644 test/__snapshots__/datadog-dashboard.test.ts.snap rename test/{monitors => }/__snapshots__/datadog-monitor.test.ts.snap (100%) create mode 100644 test/__snapshots__/datadog-slo.test.ts.snap create mode 100644 test/datadog-dashboard.test.ts rename test/{monitors => }/datadog-monitor.test.ts (90%) create mode 100644 test/datadog-slo.test.ts diff --git a/.gitattributes b/.gitattributes index a8417da..e4a73cf 100644 --- a/.gitattributes +++ b/.gitattributes @@ -19,5 +19,8 @@ /API.md linguist-generated /LICENSE linguist-generated /package.json linguist-generated +/src/dashboards/datadog-dashboard-schema.generated.ts linguist-generated +/src/monitors/datadog-monitor-schema.generated.ts linguist-generated +/src/slos/datadog-slo-schema.generated.ts linguist-generated /tsconfig.dev.json linguist-generated /yarn.lock linguist-generated \ No newline at end of file diff --git a/.gitignore b/.gitignore index 9c0d41c..2602080 100644 --- a/.gitignore +++ b/.gitignore @@ -52,3 +52,6 @@ junit.xml .jsii tsconfig.json !/API.md +!/src/monitors/datadog-monitor-schema.generated.ts +!/src/dashboards/datadog-dashboard-schema.generated.ts +!/src/slos/datadog-slo-schema.generated.ts diff --git a/.projen/deps.json b/.projen/deps.json index 8090b11..867e474 100644 --- a/.projen/deps.json +++ b/.projen/deps.json @@ -2,7 +2,6 @@ "dependencies": [ { "name": "@types/jest", - "version": "^27", "type": "build" }, { @@ -53,13 +52,12 @@ "type": "build" }, { - "name": "jest-junit", - "version": "^15", + "name": "jest", "type": "build" }, { - "name": "jest", - "version": "^27", + "name": "jest-junit", + "version": "^15", "type": "build" }, { @@ -76,12 +74,16 @@ }, { "name": "jsii-rosetta", - "version": "1.x", + "version": "~5.0.0", "type": "build" }, { "name": "jsii", - "version": "1.x", + "version": "~5.0.0", + "type": "build" + }, + { + "name": "json-schema-to-typescript", "type": "build" }, { @@ -104,7 +106,6 @@ }, { "name": "ts-jest", - "version": "^27", "type": "build" }, { @@ -119,16 +120,6 @@ "name": "camelcase-keys", "type": "bundled" }, - { - "name": "@types/babel__traverse", - "version": "7.18.2", - "type": "override" - }, - { - "name": "@types/prettier", - "version": "2.6.0", - "type": "override" - }, { "name": "aws-cdk-lib", "version": "^2.92.0", diff --git a/.projen/files.json b/.projen/files.json index bcba8f7..8baca03 100644 --- a/.projen/files.json +++ b/.projen/files.json @@ -14,6 +14,9 @@ ".projen/files.json", ".projen/tasks.json", "LICENSE", + "src/dashboards/datadog-dashboard-schema.generated.ts", + "src/monitors/datadog-monitor-schema.generated.ts", + "src/slos/datadog-slo-schema.generated.ts", "tsconfig.dev.json" ], "//": "~~ Generated by projen. To modify, edit .projenrc.ts and run \"npx projen\"." diff --git a/.projen/tasks.json b/.projen/tasks.json index 6312a34..30673f1 100644 --- a/.projen/tasks.json +++ b/.projen/tasks.json @@ -91,14 +91,6 @@ } ] }, - "create-typescript-types": { - "name": "create-typescript-types", - "steps": [ - { - "exec": "yarn --cwd scripts node create-types.js" - } - ] - }, "default": { "name": "default", "description": "Synthesize project files", diff --git a/.projenrc.ts b/.projenrc.ts index e303baf..2e1c87e 100644 --- a/.projenrc.ts +++ b/.projenrc.ts @@ -1,125 +1,73 @@ -import { javascript } from 'projen'; +import * as path from 'path'; +import { javascript, JsonPatch } from 'projen'; import { AwsCdkConstructLibrary } from 'projen/lib/awscdk'; - -const ORGANIZATION = 'goodnotes-oss'; -const PROJECT_NAME = 'cdk-datadog-resources'; +import { + DataDogMonitorSchemaGenerator, + DataDogDashboardSchemaGenerator, + DataDogSLOSchemaGenerator, + PATCHERS, +} from './projenrc'; const project = new AwsCdkConstructLibrary({ author: 'Gabriel Fürstenheim', authorAddress: 'gabriel.f@goodnotes.com', cdkVersion: '2.92.0', defaultReleaseBranch: 'master', - name: `@${ORGANIZATION}/${PROJECT_NAME}`, + name: '@goodnotes-oss/cdk-datadog-resources', repositoryUrl: 'https://github.com/GoodNotes/cdk-datadog-resources.git', projenrcTs: true, /* AwsCdkConstructLibraryOptions */ constructsVersion: '10.2.69', - // cdkDependenciesAsDeps: true, /* If this is enabled (default), all modules declared in `cdkDependencies` will be also added as normal `dependencies` (as well as `peerDependencies`). */ - // cdkTestDependencies: undefined, /* AWS CDK modules required for testing. */ - // cdkVersionPinning: false, /* Use pinned version instead of caret version for CDK. */ - - /* ConstructLibraryOptions */ - // catalog: undefined, /* Libraries will be picked up by the construct catalog when they are published to npm as jsii modules and will be published under:. */ - - /* JsiiProjectOptions */ - // compat: false, /* Automatically run API compatibility test against the latest version published to npm after compilation. */ - // compatIgnore: '.compatignore', /* Name of the ignore file for API compatibility tests. */ - // docgen: true, /* Automatically generate API.md from jsii. */ - // eslint: true, /* Install eslint. */ - // eslintOptions: undefined, /* Eslint options. */ - // excludeTypescript: undefined, /* Accepts a list of glob patterns. */ - // publishToGo: undefined, /* Publish Go bindings to a git repository. */ - // publishToMaven: undefined, - // publishToNuget: undefined, /* Publish to NuGet. */ - // publishToPypi: undefined, - // rootdir: '.', /* undefined */ - // sampleCode: true, /* Generate one-time sample in `src/` and `test/` if there are no files there. */ - - /* NodePackageOptions */ - // allowLibraryDependencies: true, /* Allow the project to include `peerDependencies` and `bundledDependencies`. */ - // authorEmail: undefined, /* Author's e-mail. */ - // authorName: undefined, /* Author's name. */ - // authorOrganization: undefined, /* Author's Organization. */ - // authorUrl: undefined, /* Author's URL / Website. */ - // autoDetectBin: true, /* Automatically add all executables under the `bin` directory to your `package.json` file under the `bin` section. */ - // bin: undefined, /* Binary programs vended with your module. */ + jsiiVersion: '~5.0.0', + peerDeps: ['aws-cdk-lib@2.92.0'], bundledDeps: ['camelcase-keys'], - // deps: [], /* Runtime dependencies of this module. */ - // description: undefined, /* The description is just a string that helps people understand the purpose of the package. */ - devDeps: ['prettier', 'aws-cdk@2.93.0', 'aws-cdk-lib@2.92.0'], - // entrypoint: 'lib/index.js', /* Module entrypoint (`main` in `package.json`). */ - // homepage: undefined, /* Package's Homepage / Website. */ - // keywords: undefined, /* Keywords to include in `package.json`. */ - // license: 'Apache-2.0', /* License's SPDX identifier. */ - // licensed: true, /* Indicates if a license should be added. */ - // maxNodeVersion: undefined, /* Minimum node.js version to require via `engines` (inclusive). */ - // minNodeVersion: undefined, /* Minimum Node.js version to require via package.json `engines` (inclusive). */ - npmAccess: javascript.NpmAccess.PUBLIC, - // npmDistTag: 'latest', /* Tags can be used to provide an alias instead of version numbers. */ - // npmRegistryUrl: 'https://registry.npmjs.org', /* The base URL of the npm package registry. */ - // npmTaskExecution: NpmTaskExecution.PROJEN, /* Determines how tasks are executed when invoked as npm scripts (yarn/npm run xyz). */ - // packageManager: NodePackageManager.YARN, /* The Node Package Manager used to execute scripts. */ - // packageName: undefined, /* The "name" in package.json. */ - // peerDependencyOptions: undefined, /* Options for `peerDeps`. */ - peerDeps: ['aws-cdk-lib@2.92.0'] /* Peer dependencies for this module. */, - // projenCommand: 'npx projen', /* The shell command to use in order to run the projen CLI. */ - // repository: undefined, /* The repository is the location where the actual code for your package lives. */ - // repositoryDirectory: undefined, /* If the package.json for your package is not in the root directory (for example if it is part of a monorepo), you can specify the directory in which it lives. */ - // scripts: {}, /* npm scripts to include. */ - // stability: undefined, /* Package's Stability. */ + devDeps: ['prettier', 'aws-cdk@2.93.0', 'aws-cdk-lib@2.92.0', 'json-schema-to-typescript'], - /* NodeProjectOptions */ - // antitamper: true, /* Checks that after build there are no modified files on git. */ - // artifactsDirectory: 'dist', /* A directory which will contain artifacts to be published to npm. */ - // buildWorkflow: undefined, /* Define a GitHub workflow for building PRs. */ - // codeCov: false, /* Define a GitHub workflow step for sending code coverage metrics to https://codecov.io/ Uses codecov/codecov-action@v1 A secret is required for private repos. Configured with @codeCovTokenSecret. */ - // codeCovTokenSecret: undefined, /* Define the secret name for a specified https://codecov.io/ token A secret is required to send coverage for private repositories. */ - // copyrightOwner: undefined, /* License copyright owner. */ - // copyrightPeriod: undefined, /* The copyright years to put in the LICENSE file. */ - // dependabot: true, /* Include dependabot configuration. */ - // dependabotOptions: undefined, /* Options for dependabot. */ + npmAccess: javascript.NpmAccess.PUBLIC, gitignore: ['cdk.out/'], - // jest: true, /* Setup jest unit tests. */ - // jestOptions: undefined, /* Jest options. */ - // jsiiReleaseVersion: 'latest', /* Version requirement of `jsii-release` which is used to publish modules to npm. */ - // mergify: true, /* Adds mergify configuration. */ - // mergifyAutoMergeLabel: 'auto-merge', /* Automatically merge PRs that build successfully and have this label. */ - // mergifyOptions: undefined, /* Options for mergify. */ - // mutableBuild: true, /* Automatically update files modified during builds to pull-request branches. */ - // npmignore: undefined, /* Additional entries to .npmignore. */ - // npmignoreEnabled: true, /* Defines an .npmignore file. Normally this is only needed for libraries that are packaged as tarballs. */ - // projenDevDependency: true, /* Indicates of "projen" should be installed as a devDependency. */ - // projenDuringBuild: true, /* Execute `projen` as the first step of the `build` task to synthesize project files. */ - // projenUpgradeAutoMerge: undefined, /* Automatically merge projen upgrade PRs when build passes. */ - // projenUpgradeSchedule: [ '0 6 * * *' ], /* Customize the projenUpgrade schedule in cron expression. */ - // projenUpgradeSecret: undefined, /* Periodically submits a pull request for projen upgrades (executes `yarn projen:upgrade`). */ - // projenVersion: undefined, /* Version of projen to install. */ - // pullRequestTemplate: true, /* Include a GitHub pull request template. */ - // pullRequestTemplateContents: undefined, /* The contents of the pull request template. */ - // releaseBranches: [ 'main' ], /* Branches which trigger a release. */ - // releaseEveryCommit: true, /* Automatically release new versions every commit to one of branches in `releaseBranches`. */ - // releaseSchedule: undefined, /* CRON schedule to trigger new releases. */ - // releaseToNpm: false, /* Automatically release to npm when new versions are introduced. */ - // releaseWorkflow: undefined, /* Define a GitHub workflow for releasing from "main" when new versions are bumped. */ - // workflowBootstrapSteps: 'yarn install --frozen-lockfile && yarn projen', /* Workflow steps to use in order to bootstrap this repo. */ - // workflowContainerImage: undefined, /* Container image to use for GitHub workflows. */ - // workflowNodeVersion: undefined, /* The node version to use in GitHub workflows. */ - - /* ProjectOptions */ - // clobber: true, /* Add a `clobber` task which resets the repo to origin. */ - // devContainer: false, /* Add a VSCode development environment (used for GitHub Codespaces). */ - // gitpod: false, /* Add a Gitpod development environment. */ - // logging: {}, /* Configure logging options such as verbosity. */ - // outdir: '.', /* The root directory of the project. */ - // parent: undefined, /* The parent project, if this project is part of a bigger project. */ - // projectType: ProjectType.UNKNOWN, /* Which type of project this is (library/app). */ - // readme: undefined, /* The README setup. */ }); + +// JSII sets this to `false` so we need to be compatible +const tsConfigDev = project.tryFindObjectFile('tsconfig.dev.json'); +tsConfigDev?.patch(JsonPatch.replace('/compilerOptions/esModuleInterop', false)); + // docgen is currently the only task of post-compile and it fails for aws-cdk-lib in jsii // https://github.com/cdklabs/jsii-docgen/issues/1122 const docgen = project.tasks.tryFind('docgen'); if (docgen) docgen.reset(); -project.tasks.addTask('create-typescript-types', { exec: 'yarn --cwd scripts node create-types.js' }); -project.synth(); +const schemaDir = 'cf-schema'; + +const monitorProps = new DataDogMonitorSchemaGenerator( + project, + path.join(project.srcdir, 'monitors', 'datadog-monitor-schema.generated.ts'), + { + filePath: path.join(schemaDir, 'datadog-monitor-4.6.0.json'), + }, +); + +const dashboardProps = new DataDogDashboardSchemaGenerator( + project, + path.join(project.srcdir, 'dashboards', 'datadog-dashboard-schema.generated.ts'), + { + filePath: path.join(schemaDir, 'datadog-dashboard-2.1.0.json'), + }, +); + +const sloProps = new DataDogSLOSchemaGenerator( + project, + path.join(project.srcdir, 'slos', 'datadog-slo-schema.generated.ts'), + { + filePath: path.join(schemaDir, 'datadog-slo-1.1.0.json'), + }, +); + +// call all Json Schema generators async, then synth +void Promise.all([ + monitorProps.generate('DatadogMonitorProps', PATCHERS.readonlyFields), + dashboardProps.generate('DatadogDashboardProps', PATCHERS.readonlyFields), + sloProps.generate('DatadogSLOProps', PATCHERS.readonlyFields), +]).then(() => { + project.synth(); +}); diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..e70c51e --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,19 @@ +{ + "cSpell.words": [ + "awscdk", + "camelcase", + "docgen", + "Fürstenheim", + "httpservice", + "jsii", + "NINETYDAYS", + "projenrc", + "SEVENDAYS", + "slos", + "srcdir", + "THIRTYDAYS", + "Timeframe", + "xaxis", + "yaxis" + ] +} diff --git a/README.md b/README.md index 793687e..ca64ea6 100644 --- a/README.md +++ b/README.md @@ -18,11 +18,18 @@ You need to register the correct version listed in `Supported Resources`. ## Supported Resources -| Supported? | Resource | Datadog CF Resource Name | Description | Datadog CF Version | -| :--------: | ----------------------- | -------------------------------- | -------------------------------------------------------- |--------------------| -| ✅ | Monitors | `Datadog::Monitors::Monitor` | [Create, update, and delete Datadog monitors.][3] | [4.6.0][6] | - -[6]: https://github.com/DataDog/datadog-cloudformation-resources/blob/master/datadog-monitors-monitor-handler/CHANGELOG.md#300--2021-02-16 +| Supported? | Resource | Datadog CF Resource Name | Description | Datadog CF Version | +| :--------: | ---------- | -------------------------------- | --------------------------------------------------- | ------------------ | +| ✅ | Dashboards | `Datadog::Dashboards::Dashboard` | [Create, update, and delete Datadog dashboards.][1] | [2.1.0][2] | +| ✅ | Monitors | `Datadog::Monitors::Monitor` | [Create, update, and delete Datadog monitors.][3] | [4.6.0][4] | +| ✅ | SLOs | `Datadog::SLOs::SLO` | [Create, update, and delete Datadog SLOs.][5] | [1.1.0][6] | + +[1]: https://github.com/DataDog/datadog-cloudformation-resources/tree/master/datadog-dashboards-dashboard-handler +[2]: https://github.com/DataDog/datadog-cloudformation-resources/blob/master/datadog-dashboards-dashboard-handler/CHANGELOG.md#210--2023-04-10 +[3]: https://github.com/DataDog/datadog-cloudformation-resources/tree/master/datadog-monitors-monitor-handler +[4]: https://github.com/DataDog/datadog-cloudformation-resources/blob/master/datadog-monitors-monitor-handler/CHANGELOG.md#300--2021-02-16 +[5]: https://github.com/DataDog/datadog-cloudformation-resources/tree/master/datadog-slos-slo-handler +[6]: https://github.com/DataDog/datadog-cloudformation-resources/blob/master/datadog-slos-slo-handler/CHANGELOG.md#110--2023-04-10 ## Installation @@ -57,6 +64,10 @@ new DatadogMonitor(yourStack, 'TestMonitor', { }); ``` - ## Fork -This is a fork of https://github.com/NomadBlacky/cdk-datadog-resources, which is currently unmaintained. \ No newline at end of file + +This is a fork of https://github.com/NomadBlacky/cdk-datadog-resources, which is currently unmaintained. + +## Notes + +- The DataDog [Dashboard TypeScript Interface](src/dashboards/datadog-api-dashboard.generated.ts) was generated from the [DataDog/datadog-api-client-typescript](https://github.com/DataDog/datadog-api-client-typescript) package through [GoodNotes/ts-interface-generator](https://github.com/GoodNotes/ts-interface-generator). It is currently inlined while this setup is PoC. diff --git a/cf-schema/README.md b/cf-schema/README.md new file mode 100644 index 0000000..a22c727 --- /dev/null +++ b/cf-schema/README.md @@ -0,0 +1,5 @@ +# JSON Schemas from respective CFN Resource handlers + +- [Dashboards Handler](https://github.com/DataDog/datadog-cloudformation-resources/blob/datadog-dashboards-dashboard-2.1.0/datadog-dashboards-dashboard-handler/datadog-dashboards-dashboard.json) +- [Monitors Handler](https://github.com/DataDog/datadog-cloudformation-resources/tree/datadog-monitors-monitor-4.6.0/datadog-monitors-monitor-handler) +- [SLOs Handler](https://github.com/DataDog/datadog-cloudformation-resources/tree/datadog-slos-slo-1.1.0/datadog-slos-slo-handler) diff --git a/cf-schema/datadog-dashboard-2.1.0.json b/cf-schema/datadog-dashboard-2.1.0.json index a85dda6..12f04ab 100644 --- a/cf-schema/datadog-dashboard-2.1.0.json +++ b/cf-schema/datadog-dashboard-2.1.0.json @@ -1,9 +1,15 @@ { "typeName": "Datadog::Dashboards::Dashboard", - "description": "Datadog Dashboard 1.0.0", - "definitions": { + "description": "Datadog Dashboard 2.1.0", + "typeConfiguration": { + "properties": { + "DatadogCredentials": { + "$ref": "#/definitions/DatadogCredentials" + } + }, + "additionalProperties": false }, - "properties": { + "definitions": { "DatadogCredentials": { "description": "Credentials for the Datadog API", "properties": { @@ -24,12 +30,19 @@ "ApiKey", "ApplicationKey" ], - "type": "object" - }, + "type": "object", + "additionalProperties": false + } + }, + "properties": { "Id": { "description": "ID of the dashboard", "type": "string" }, + "Url": { + "description": "Url of the dashboard", + "type": "string" + }, "DashboardDefinition": { "description": "JSON string of the dashboard definition", "type": "string" @@ -37,14 +50,11 @@ }, "additionalProperties": false, "required": [ - "DatadogCredentials", "DashboardDefinition" ], - "writeOnlyProperties": [ - "/properties/DatadogCredentials" - ], "readOnlyProperties": [ - "/properties/Id" + "/properties/Id", + "/properties/Url" ], "primaryIdentifier": [ "/properties/Id" @@ -69,11 +79,6 @@ "permissions": [ "" ] - }, - "list": { - "permissions": [ - "" - ] } } -} \ No newline at end of file +} diff --git a/cf-schema/datadog-slo-1.1.0.json b/cf-schema/datadog-slo-1.1.0.json new file mode 100644 index 0000000..28046fc --- /dev/null +++ b/cf-schema/datadog-slo-1.1.0.json @@ -0,0 +1,210 @@ +{ + "typeName": "Datadog::SLOs::SLO", + "description": "Datadog SLO 1.1.0", + "typeConfiguration": { + "properties": { + "DatadogCredentials": { + "$ref": "#/definitions/DatadogCredentials" + } + }, + "additionalProperties": false + }, + "definitions": { + "Creator": { + "type": "object", + "additionalProperties": false, + "properties": { + "Name": { + "description": "Name of the creator of the slo", + "type": "string" + }, + "Handle": { + "description": "Handle of the creator of the slo", + "type": "string" + }, + "Email": { + "description": "Email of the creator of the slo", + "type": "string" + } + } + }, + "Threshold": { + "type": "object", + "additionalProperties": false, + "properties": { + "Target": { + "description": "The target value for the service level indicator within the corresponding timeframe.", + "type": "number" + }, + "TargetDisplay": { + "description": "A string representation of the target that indicates its precision.(e.g. 98.00)", + "type": "string" + }, + "Timeframe": { + "description": "The SLO time window options. Allowed enum values: 7d,30d,90d", + "type": "string", + "enum": [ + "7d", + "30d", + "90d" + ] + }, + "Warning": { + "description": "The warning value for the service level objective.", + "type": "number" + }, + "WarningDisplay": { + "description": "A string representation of the warning target.(e.g. 98.00)", + "type": "string" + } + } + }, + "Query": { + "type": "object", + "additionalProperties": false, + "properties": { + "Numerator": { + "description": "A Datadog metric query for total (valid) events.", + "type": "string" + }, + "Denominator": { + "description": "A Datadog metric query for good events.", + "type": "string" + } + } + }, + "DatadogCredentials": { + "description": "Credentials for the Datadog API", + "properties": { + "ApiKey": { + "description": "Datadog API key", + "type": "string" + }, + "ApplicationKey": { + "description": "Datadog application key", + "type": "string" + }, + "ApiURL": { + "description": "Datadog API URL (defaults to https://api.datadoghq.com) Use https://api.datadoghq.eu for EU accounts.", + "type": "string" + } + }, + "required": [ + "ApiKey", + "ApplicationKey" + ], + "type": "object", + "additionalProperties": false + } + }, + "properties": { + "Creator": { + "$ref": "#/definitions/Creator" + }, + "Description": { + "description": "Description of the slo", + "type": "string" + }, + "Groups": { + "description": "A list of (up to 20) monitor groups that narrow the scope of a monitor service level objective.", + "type": "array", + "items": { + "type": "string" + } + }, + "Id": { + "description": "ID of the slo", + "type": "string" + }, + "MonitorIds": { + "description": "A list of monitor ids that defines the scope of a monitor service level objective. Required if type is monitor.", + "type": "array", + "items": { + "type": "integer" + } + }, + "Name": { + "description": "Name of the slo", + "type": "string" + }, + "Query": { + "$ref": "#/definitions/Query" + }, + "Tags": { + "description": "Tags associated with the slo", + "type": "array", + "items": { + "type": "string" + } + }, + "Thresholds": { + "type": "array", + "items": { + "$ref": "#/definitions/Threshold" + } + }, + "Type": { + "type": "string", + "description": "The type of the slo", + "enum": [ + "monitor", + "metric" + ] + }, + "Created": { + "description": "Date of creation of the slo", + "type": "string", + "format": "date-time" + }, + "Deleted": { + "description": "Date of deletion of the slo", + "type": "string", + "format": "date-time" + }, + "Modified": { + "description": "Date of modification of the slo", + "type": "string", + "format": "date-time" + } + }, + "required": [ + "Name", + "Thresholds", + "Type" + ], + "primaryIdentifier": [ + "/properties/Id" + ], + "readOnlyProperties": [ + "/properties/Modified", + "/properties/Id", + "/properties/Deleted", + "/properties/State", + "/properties/OverallState", + "/properties/Creator", + "/properties/Created" + ], + "additionalProperties": false, + "handlers": { + "create": { + "permissions": [ + "" + ] + }, + "read": { + "permissions": [ + "" + ] + }, + "update": { + "permissions": [ + "" + ] + }, + "delete": { + "permissions": [ + "" + ] + } + } +} diff --git a/package.json b/package.json index 6190cfd..09918dd 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,6 @@ "clobber": "npx projen clobber", "compat": "npx projen compat", "compile": "npx projen compile", - "create-typescript-types": "npx projen create-typescript-types", "default": "npx projen default", "docgen": "npx projen docgen", "eject": "npx projen eject", @@ -48,11 +47,12 @@ "eslint-plugin-import": "^2.25.2", "jest": "^27", "jest-junit": "^15", - "jsii": "1.x", + "jsii": "~5.0.0", "jsii-diff": "1", "jsii-docgen": "1.8.110", "jsii-pacmak": "^1.42.0", - "jsii-rosetta": "1.x", + "jsii-rosetta": "~5.0.0", + "json-schema-to-typescript": "^13.1.1", "npm-check-updates": "^16", "prettier": "^2.4.1", "projen": "0.71.128", @@ -71,10 +71,6 @@ "bundledDependencies": [ "camelcase-keys" ], - "resolutions": { - "@types/babel__traverse": "7.18.2", - "@types/prettier": "2.6.0" - }, "keywords": [ "cdk" ], diff --git a/projenrc/datadog-dashboard-generator.ts b/projenrc/datadog-dashboard-generator.ts new file mode 100644 index 0000000..a0d0ead --- /dev/null +++ b/projenrc/datadog-dashboard-generator.ts @@ -0,0 +1,30 @@ +import * as camelcaseKeys from 'camelcase-keys'; +import { Project } from 'projen'; +import { JsonSchemaBase, JsonSchemaBaseOptions } from './json-schema-base'; + +export class DataDogDashboardSchemaGenerator extends JsonSchemaBase { + /** + * Creates a DataDog Dashboard Typescript Interface from a json schema file. + * + * @param project The project + * @param filePath File path from project root + * @param options Options + */ + constructor(project: Project, filePath: string, options: JsonSchemaBaseOptions) { + super(project, filePath, options); + // JSII requires all properties to be camelCase + const convertedSchema = camelcaseKeys(this.schema, { + deep: true, + pascalCase: false, + }); + + if (convertedSchema.definitions) { + // JSII requires all definitions (types) to be PascalCase + convertedSchema.definitions = camelcaseKeys(convertedSchema.definitions, { + deep: false, + pascalCase: true, + }); + } + this.schema = convertedSchema; + } +} diff --git a/projenrc/datadog-monitor-generator.ts b/projenrc/datadog-monitor-generator.ts new file mode 100644 index 0000000..7e8c668 --- /dev/null +++ b/projenrc/datadog-monitor-generator.ts @@ -0,0 +1,44 @@ +import * as camelcaseKeys from 'camelcase-keys'; +import { Project } from 'projen'; +import { JsonSchemaBase, JsonSchemaBaseOptions } from './json-schema-base'; + +export class DataDogMonitorSchemaGenerator extends JsonSchemaBase { + /** + * Creates a DataDog Monitor Typescript Interface from a json schema file. + * + * @param project The project + * @param filePath File path from project root + * @param options Options + */ + constructor(project: Project, filePath: string, options: JsonSchemaBaseOptions) { + super(project, filePath, options); + this.moveDeclarationToType(this.schema, 'MonitorFormulaAndFunctionEventQueryGroupBy', 'Sort'); + this.moveDeclarationToType(this.schema, 'MonitorFormulaAndFunctionEventQueryDefinition', 'Search'); + this.moveDeclarationToType(this.schema, 'MonitorFormulaAndFunctionEventQueryDefinition', 'Compute'); + + // JSII requires all properties to be camelCase + const convertedSchema = camelcaseKeys(this.schema, { + deep: true, + pascalCase: false, + }); + + if (convertedSchema.definitions) { + // JSII requires all definitions (types) to be PascalCase + convertedSchema.definitions = camelcaseKeys(convertedSchema.definitions, { + deep: false, + pascalCase: true, + }); + + // fix MonitorThresholds.ok -> MonitorThresholds.oK + if (convertedSchema.definitions.MonitorThresholds?.properties?.ok) { + // camelCase converted OK -> ok, + // reverse (PascalCase) ok -> Ok, is incorrect + // reverse (PascalCase) oK --> OK, is correct + convertedSchema.definitions.MonitorThresholds.properties.oK = + convertedSchema.definitions.MonitorThresholds.properties.ok; + delete convertedSchema.definitions.MonitorThresholds.properties.ok; + } + } + this.schema = convertedSchema; + } +} diff --git a/projenrc/datadog-slo-generator.ts b/projenrc/datadog-slo-generator.ts new file mode 100644 index 0000000..ea04829 --- /dev/null +++ b/projenrc/datadog-slo-generator.ts @@ -0,0 +1,35 @@ +import * as camelcaseKeys from 'camelcase-keys'; +import { Project } from 'projen'; +import { JsonSchemaBase, JsonSchemaBaseOptions } from './json-schema-base'; + +export class DataDogSLOSchemaGenerator extends JsonSchemaBase { + /** + * Creates a DataDog Monitor Typescript Interface from a json schema file. + * + * @param project The project + * @param filePath File path from project root + * @param options Options + */ + constructor(project: Project, filePath: string, options: JsonSchemaBaseOptions) { + super(project, filePath, options); + + // Avoid conflict with Monitor.Creator + ///TODO: It's the same type... find a better way to handle this? + this.renameDeclaration(this.schema, 'Creator', 'Creator', 'SloCreator'); + + // JSII requires all properties to be camelCase + const convertedSchema = camelcaseKeys(this.schema, { + deep: true, + pascalCase: false, + }); + + if (convertedSchema.definitions) { + // JSII requires all definitions (types) to be PascalCase + convertedSchema.definitions = camelcaseKeys(convertedSchema.definitions, { + deep: false, + pascalCase: true, + }); + } + this.schema = convertedSchema; + } +} diff --git a/projenrc/index.ts b/projenrc/index.ts new file mode 100644 index 0000000..d3a8f50 --- /dev/null +++ b/projenrc/index.ts @@ -0,0 +1,4 @@ +export * from './json-schema-base'; +export * from './datadog-monitor-generator'; +export * from './datadog-dashboard-generator'; +export * from './datadog-slo-generator'; diff --git a/projenrc/json-schema-base.ts b/projenrc/json-schema-base.ts new file mode 100644 index 0000000..9e8136e --- /dev/null +++ b/projenrc/json-schema-base.ts @@ -0,0 +1,110 @@ +import * as fs from 'fs'; +import { compile, JSONSchema } from 'json-schema-to-typescript'; +import { Project, FileBase, FileBaseOptions, IResolver } from 'projen'; + +export interface JsonSchemaBaseOptions extends FileBaseOptions { + /** + * File Path from project root to json schema file + */ + filePath: string; +} + +/** + * Utility patches to apply to generated TypeScript interfaces + * not supported by json-schema-to-typescript + */ +export const PATCHERS = { + /** + * Make all properties readonly + * + * jsii will complain if properties aren't readonly + */ + readonlyFields: (ts: string | undefined): string | undefined => { + if (!ts) return ts; + // regex to set all fields that start with a lowercase letter to readonly + return ts.replace(/^( +)([a-z])/gm, '$1readonly $2'); + }, +}; + +export class JsonSchemaBase extends FileBase { + protected schema: JSONSchema; + private contents?: string; + + /** + * Creates a new TypeScript interface from a json schema file. + * + * @param project The project + * @param outFile File path from project root + * @param options Options + */ + constructor(project: Project, outFile: string, options: JsonSchemaBaseOptions) { + super(project, outFile, options); + this.schema = JSON.parse(fs.readFileSync(options.filePath).toString()) as JSONSchema; + } + + /** + * Generate TypeScript interface from JSON Schema + * and apply patches to the generated interface + * + * @param name Name of the Interface to generate + * @param patches Patches to apply to the generated interface + */ + async generate(name: string, ...patches: ((schema: string | undefined) => string | undefined)[]) { + this.contents = await compile(this.schema, name, { + bannerComment: `// ${this.marker}`, + }); + + for (const patch of patches) { + this.contents = patch(this.contents); + } + } + + /** + * Returns the generated TypeScript Interface if it was compiled + * else throws an error + */ + protected synthesizeContent(_: IResolver): string | undefined { + if (!this.contents) { + throw new Error('contents not compiled'); + } + return this.contents; + } + + /** + * Move a nested declaration to top level schema definitions + * and update nested property to a reference instead. + * + * @param schema JSON Schema to modify + * @param parentClass Name of the Parent Class containing the nested class definition as a property + * @param className Name of the nested class to move to top level definitions + */ + protected moveDeclarationToType(schema: JSONSchema, parentClass: string, className: string) { + if (schema.definitions) { + const parentDefinition = schema.definitions[parentClass]; + if (parentDefinition.properties && parentDefinition.properties[className]) { + const newName = parentClass + className; + schema.definitions[newName] = parentDefinition.properties[className]; + parentDefinition.properties[className] = { $ref: `#/definitions/${newName}` }; + } + } + } + + /** + * Rename top level schema definition + * and update property to new reference. + * + * @param schema JSON Schema to modify + * @param propertyName Property name to update to new reference + * @param oldName Old name of the definition + * @param newName New name of the definition + */ + protected renameDeclaration(schema: JSONSchema, propertyName: string, oldName: string, newName: string) { + if (schema.definitions && schema.properties && schema.properties[propertyName]) { + schema.definitions[newName] = schema.definitions[oldName]; + schema.properties[propertyName] = { + $ref: `#/definitions/${newName}`, + }; + delete schema.definitions[oldName]; + } + } +} diff --git a/scripts/README.md b/scripts/README.md deleted file mode 100644 index b53b64c..0000000 --- a/scripts/README.md +++ /dev/null @@ -1,5 +0,0 @@ -## Scripts - -These scripts are moved to a subproject to workaround jsii problems with @lodash/types :/ - - diff --git a/scripts/create-types.js b/scripts/create-types.js deleted file mode 100644 index 750204c..0000000 --- a/scripts/create-types.js +++ /dev/null @@ -1,41 +0,0 @@ -const js = require('json-schema-to-typescript') -const camelcaseKeys = require('camelcase-keys') -const fs = require('fs') -const schema = JSON.parse(fs.readFileSync('../cf-schema/datadog-monitor-4.6.0.json').toString()) - -moveDeclarationToType(schema, 'MonitorFormulaAndFunctionEventQueryGroupBy', 'Sort') -moveDeclarationToType(schema, 'MonitorFormulaAndFunctionEventQueryDefinition', 'Search') -moveDeclarationToType(schema, 'MonitorFormulaAndFunctionEventQueryDefinition', 'Compute') - - -const convertedSchema = camelcaseKeys(schema, { - deep: true, - pascalCase: false, -}) - -// Definitions in the json schema type are types -convertedSchema.definitions = camelcaseKeys(convertedSchema.definitions, { - deep: false, - pascalCase: true -}) - -// when converting to camel case OK -> ok, but ok -> oK !== OK -convertedSchema.definitions.MonitorThresholds.properties.oK = convertedSchema.definitions.MonitorThresholds.properties.ok -delete convertedSchema.definitions.MonitorThresholds.properties.ok - -js.compile(convertedSchema, 'DatadogMonitorProps', {bannerComment: '// This file was autogenerated by `yarn create-typescript-types`. DO NOT MODIFY\n'}) - .then((ts) => { - // jsii will complain about not read only properties - // But the library json-schema-to-typescript does not support readonly properties - const readonlyTs = ts.replaceAll(/^( +)([a-z])/mg, '$1readonly $2') - fs.writeFileSync('../src/monitors/datadog-monitor-schema.ts', readonlyTs) - }) - - -function moveDeclarationToType (schema, parentClass, className) { - const newName = parentClass + className - const definition = schema.definitions[parentClass].properties[className] - schema.definitions[newName] = definition - schema.definitions[parentClass].properties[className] = {"$ref": `#/definitions/${newName}`} - -} \ No newline at end of file diff --git a/scripts/package.json b/scripts/package.json deleted file mode 100644 index 0967ea8..0000000 --- a/scripts/package.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "name": "scripts", - "version": "1.0.0", - "main": "index.js", - "license": "MIT", - "dependencies": { - "json-schema-to-typescript": "^13.1.1" - } -} diff --git a/scripts/yarn.lock b/scripts/yarn.lock deleted file mode 100644 index 31860e2..0000000 --- a/scripts/yarn.lock +++ /dev/null @@ -1,356 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -"@bcherny/json-schema-ref-parser@10.0.5-fork": - version "10.0.5-fork" - resolved "https://registry.yarnpkg.com/@bcherny/json-schema-ref-parser/-/json-schema-ref-parser-10.0.5-fork.tgz#9b5e1e7e07964ea61840174098e634edbe8197bc" - integrity sha512-E/jKbPoca1tfUPj3iSbitDZTGnq6FUFjkH6L8U2oDwSuwK1WhnnVtCG7oFOTg/DDnyoXbQYUiUiGOibHqaGVnw== - dependencies: - "@jsdevtools/ono" "^7.1.3" - "@types/json-schema" "^7.0.6" - call-me-maybe "^1.0.1" - js-yaml "^4.1.0" - -"@jsdevtools/ono@^7.1.3": - version "7.1.3" - resolved "https://registry.yarnpkg.com/@jsdevtools/ono/-/ono-7.1.3.tgz#9df03bbd7c696a5c58885c34aa06da41c8543796" - integrity sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg== - -"@types/glob@^7.1.3": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.2.0.tgz#bc1b5bf3aa92f25bd5dd39f35c57361bdce5b2eb" - integrity sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA== - dependencies: - "@types/minimatch" "*" - "@types/node" "*" - -"@types/json-schema@^7.0.11", "@types/json-schema@^7.0.6": - version "7.0.12" - resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.12.tgz#d70faba7039d5fca54c83c7dbab41051d2b6f6cb" - integrity sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA== - -"@types/lodash@^4.14.182": - version "4.14.197" - resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.197.tgz#e95c5ddcc814ec3e84c891910a01e0c8a378c54b" - integrity sha512-BMVOiWs0uNxHVlHBgzTIqJYmj+PgCo4euloGF+5m4okL3rEYzM2EEv78mw8zWSMM57dM7kVIgJ2QDvwHSoCI5g== - -"@types/minimatch@*": - version "5.1.2" - resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-5.1.2.tgz#07508b45797cb81ec3f273011b054cd0755eddca" - integrity sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA== - -"@types/node@*": - version "20.5.7" - resolved "https://registry.yarnpkg.com/@types/node/-/node-20.5.7.tgz#4b8ecac87fbefbc92f431d09c30e176fc0a7c377" - integrity sha512-dP7f3LdZIysZnmvP3ANJYTSwg+wLLl8p7RqniVlV7j+oXSXAbt9h0WIBFmJy5inWZoX9wZN6eXx+YXd9Rh3RBA== - -"@types/prettier@^2.6.1": - version "2.7.3" - resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.7.3.tgz#3e51a17e291d01d17d3fc61422015a933af7a08f" - integrity sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA== - -any-promise@^1.0.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f" - integrity sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A== - -argparse@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" - integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== - -balanced-match@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" - integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== - -brace-expansion@^1.1.7: - version "1.1.11" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" - integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== - dependencies: - balanced-match "^1.0.0" - concat-map "0.0.1" - -call-me-maybe@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/call-me-maybe/-/call-me-maybe-1.0.2.tgz#03f964f19522ba643b1b0693acb9152fe2074baa" - integrity sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ== - -cli-color@^2.0.2: - version "2.0.3" - resolved "https://registry.yarnpkg.com/cli-color/-/cli-color-2.0.3.tgz#73769ba969080629670f3f2ef69a4bf4e7cc1879" - integrity sha512-OkoZnxyC4ERN3zLzZaY9Emb7f/MhBOIpePv0Ycok0fJYT+Ouo00UBEIwsVsr0yoow++n5YWlSUgST9GKhNHiRQ== - dependencies: - d "^1.0.1" - es5-ext "^0.10.61" - es6-iterator "^2.0.3" - memoizee "^0.4.15" - timers-ext "^0.1.7" - -concat-map@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" - integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== - -d@1, d@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/d/-/d-1.0.1.tgz#8698095372d58dbee346ffd0c7093f99f8f9eb5a" - integrity sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA== - dependencies: - es5-ext "^0.10.50" - type "^1.0.1" - -es5-ext@^0.10.35, es5-ext@^0.10.46, es5-ext@^0.10.50, es5-ext@^0.10.53, es5-ext@^0.10.61, es5-ext@~0.10.14, es5-ext@~0.10.2, es5-ext@~0.10.46: - version "0.10.62" - resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.62.tgz#5e6adc19a6da524bf3d1e02bbc8960e5eb49a9a5" - integrity sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA== - dependencies: - es6-iterator "^2.0.3" - es6-symbol "^3.1.3" - next-tick "^1.1.0" - -es6-iterator@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7" - integrity sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g== - dependencies: - d "1" - es5-ext "^0.10.35" - es6-symbol "^3.1.1" - -es6-symbol@^3.1.1, es6-symbol@^3.1.3: - version "3.1.3" - resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.3.tgz#bad5d3c1bcdac28269f4cb331e431c78ac705d18" - integrity sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA== - dependencies: - d "^1.0.1" - ext "^1.1.2" - -es6-weak-map@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/es6-weak-map/-/es6-weak-map-2.0.3.tgz#b6da1f16cc2cc0d9be43e6bdbfc5e7dfcdf31d53" - integrity sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA== - dependencies: - d "1" - es5-ext "^0.10.46" - es6-iterator "^2.0.3" - es6-symbol "^3.1.1" - -event-emitter@^0.3.5: - version "0.3.5" - resolved "https://registry.yarnpkg.com/event-emitter/-/event-emitter-0.3.5.tgz#df8c69eef1647923c7157b9ce83840610b02cc39" - integrity sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA== - dependencies: - d "1" - es5-ext "~0.10.14" - -ext@^1.1.2: - version "1.7.0" - resolved "https://registry.yarnpkg.com/ext/-/ext-1.7.0.tgz#0ea4383c0103d60e70be99e9a7f11027a33c4f5f" - integrity sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw== - dependencies: - type "^2.7.2" - -fs.realpath@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" - integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== - -get-stdin@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-8.0.0.tgz#cbad6a73feb75f6eeb22ba9e01f89aa28aa97a53" - integrity sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg== - -glob-promise@^4.2.2: - version "4.2.2" - resolved "https://registry.yarnpkg.com/glob-promise/-/glob-promise-4.2.2.tgz#15f44bcba0e14219cd93af36da6bb905ff007877" - integrity sha512-xcUzJ8NWN5bktoTIX7eOclO1Npxd/dyVqUJxlLIDasT4C7KZyqlPIwkdJ0Ypiy3p2ZKahTjK4M9uC3sNSfNMzw== - dependencies: - "@types/glob" "^7.1.3" - -glob@^7.1.6: - version "7.2.3" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" - integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.1.1" - once "^1.3.0" - path-is-absolute "^1.0.0" - -inflight@^1.0.4: - version "1.0.6" - resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" - integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== - dependencies: - once "^1.3.0" - wrappy "1" - -inherits@2: - version "2.0.4" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" - integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== - -is-extglob@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" - integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== - -is-glob@^4.0.3: - version "4.0.3" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" - integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== - dependencies: - is-extglob "^2.1.1" - -is-promise@^2.2.2: - version "2.2.2" - resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.2.2.tgz#39ab959ccbf9a774cf079f7b40c7a26f763135f1" - integrity sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ== - -js-yaml@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" - integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== - dependencies: - argparse "^2.0.1" - -json-schema-to-typescript@^13.1.1: - version "13.1.1" - resolved "https://registry.yarnpkg.com/json-schema-to-typescript/-/json-schema-to-typescript-13.1.1.tgz#8d1b28f93530d3b57730ee7272eec8e4400238e9" - integrity sha512-F3CYhtA7F3yPbb8vF7sFchk/2dnr1/yTKf8RcvoNpjnh67ZS/ZMH1ElLt5KHAtf2/bymiejLQQszszPWEeTdSw== - dependencies: - "@bcherny/json-schema-ref-parser" "10.0.5-fork" - "@types/json-schema" "^7.0.11" - "@types/lodash" "^4.14.182" - "@types/prettier" "^2.6.1" - cli-color "^2.0.2" - get-stdin "^8.0.0" - glob "^7.1.6" - glob-promise "^4.2.2" - is-glob "^4.0.3" - lodash "^4.17.21" - minimist "^1.2.6" - mkdirp "^1.0.4" - mz "^2.7.0" - prettier "^2.6.2" - -lodash@^4.17.21: - version "4.17.21" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" - integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== - -lru-queue@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/lru-queue/-/lru-queue-0.1.0.tgz#2738bd9f0d3cf4f84490c5736c48699ac632cda3" - integrity sha512-BpdYkt9EvGl8OfWHDQPISVpcl5xZthb+XPsbELj5AQXxIC8IriDZIQYjBJPEm5rS420sjZ0TLEzRcq5KdBhYrQ== - dependencies: - es5-ext "~0.10.2" - -memoizee@^0.4.15: - version "0.4.15" - resolved "https://registry.yarnpkg.com/memoizee/-/memoizee-0.4.15.tgz#e6f3d2da863f318d02225391829a6c5956555b72" - integrity sha512-UBWmJpLZd5STPm7PMUlOw/TSy972M+z8gcyQ5veOnSDRREz/0bmpyTfKt3/51DhEBqCZQn1udM/5flcSPYhkdQ== - dependencies: - d "^1.0.1" - es5-ext "^0.10.53" - es6-weak-map "^2.0.3" - event-emitter "^0.3.5" - is-promise "^2.2.2" - lru-queue "^0.1.0" - next-tick "^1.1.0" - timers-ext "^0.1.7" - -minimatch@^3.1.1: - version "3.1.2" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" - integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== - dependencies: - brace-expansion "^1.1.7" - -minimist@^1.2.6: - version "1.2.8" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" - integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== - -mkdirp@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" - integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== - -mz@^2.7.0: - version "2.7.0" - resolved "https://registry.yarnpkg.com/mz/-/mz-2.7.0.tgz#95008057a56cafadc2bc63dde7f9ff6955948e32" - integrity sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q== - dependencies: - any-promise "^1.0.0" - object-assign "^4.0.1" - thenify-all "^1.0.0" - -next-tick@1, next-tick@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.1.0.tgz#1836ee30ad56d67ef281b22bd199f709449b35eb" - integrity sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ== - -object-assign@^4.0.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" - integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== - -once@^1.3.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== - dependencies: - wrappy "1" - -path-is-absolute@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" - integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== - -prettier@^2.6.2: - version "2.8.8" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.8.tgz#e8c5d7e98a4305ffe3de2e1fc4aca1a71c28b1da" - integrity sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q== - -thenify-all@^1.0.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/thenify-all/-/thenify-all-1.6.0.tgz#1a1918d402d8fc3f98fbf234db0bcc8cc10e9726" - integrity sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA== - dependencies: - thenify ">= 3.1.0 < 4" - -"thenify@>= 3.1.0 < 4": - version "3.3.1" - resolved "https://registry.yarnpkg.com/thenify/-/thenify-3.3.1.tgz#8932e686a4066038a016dd9e2ca46add9838a95f" - integrity sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw== - dependencies: - any-promise "^1.0.0" - -timers-ext@^0.1.7: - version "0.1.7" - resolved "https://registry.yarnpkg.com/timers-ext/-/timers-ext-0.1.7.tgz#6f57ad8578e07a3fb9f91d9387d65647555e25c6" - integrity sha512-b85NUNzTSdodShTIbky6ZF02e8STtVVfD+fu4aXXShEELpozH+bCpJLYMPZbsABN2wDH7fJpqIoXxJpzbf0NqQ== - dependencies: - es5-ext "~0.10.46" - next-tick "1" - -type@^1.0.1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/type/-/type-1.2.0.tgz#848dd7698dafa3e54a6c479e759c4bc3f18847a0" - integrity sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg== - -type@^2.7.2: - version "2.7.2" - resolved "https://registry.yarnpkg.com/type/-/type-2.7.2.tgz#2376a15a3a28b1efa0f5350dcf72d24df6ef98d0" - integrity sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw== - -wrappy@1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" - integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== diff --git a/src/dashboards/datadog-api-dashboard.generated.ts b/src/dashboards/datadog-api-dashboard.generated.ts new file mode 100644 index 0000000..79ab20e --- /dev/null +++ b/src/dashboards/datadog-api-dashboard.generated.ts @@ -0,0 +1,1993 @@ +// curl -Lo datadog-api-dashboard.generated.ts https://raw.githubusercontent.com/GoodNotes/ts-interface-generator/3e1d9a740ffe4d10f7279b636ca3e01a34dbc0dd/src/Dashboard.generated.ts +export interface Dashboard { + /** Identifier of the dashboard author. */ + readonly authorHandle?: string; + /** Name of the dashboard author. */ + readonly authorName?: string; + /** Creation date of the dashboard. */ + readonly createdAt?: Date; + /** Description of the dashboard. */ + readonly description?: string; + /** ID of the dashboard. */ + readonly id?: string; + /** Whether this dashboard is read-only. If True, only the author and admins can make changes to it. Prefer using `restricted_roles` to manage write authorization. */ + readonly isReadOnly?: boolean; + /** Layout type of the dashboard. */ + readonly layoutType: 'ordered' | 'free' | UnparsedObject; + /** Modification date of the dashboard. */ + readonly modifiedAt?: Date; + /** List of handles of users to notify when changes are made to this dashboard. */ + readonly notifyList?: string[]; + /** + * Reflow type for a **new dashboard layout** dashboard. Set this only when layout type is 'ordered'. + * If set to 'fixed', the dashboard expects all widgets to have a layout, and if it's set to 'auto', + * widgets should not have layouts. + */ + readonly reflowType?: 'auto' | 'fixed' | UnparsedObject; + /** A list of role identifiers. Only the author and users associated with at least one of these roles can edit this dashboard. */ + readonly restrictedRoles?: string[]; + /** List of team names representing ownership of a dashboard. */ + readonly tags?: string[]; + /** Array of template variables saved views. */ + readonly templateVariablePresets?: Array; + /** List of template variables for this dashboard. */ + readonly templateVariables?: Array; + /** Title of the dashboard. */ + readonly title: string; + /** The URL of the dashboard. */ + readonly url?: string; + /** List of widgets to display on the dashboard. */ + readonly widgets: Array; +} + +export interface UnparsedObject { + /** @internal */ + readonly _data: any; +} + +export interface DashboardTemplateVariablePreset { + /** The name of the variable. */ + readonly name?: string; + /** List of variables. */ + readonly templateVariables?: Array; +} + +export interface DashboardTemplateVariablePresetValue { + /** The name of the variable. */ + readonly name?: string; + /** (deprecated) The value of the template variable within the saved view. Cannot be used in conjunction with `values`. */ + readonly value?: string; + /** One or many template variable values within the saved view, which will be unioned together using `OR` if more than one is specified. Cannot be used in conjunction with `value`. */ + readonly values?: string[]; +} + +export interface DashboardTemplateVariable { + /** The list of values that the template variable drop-down is limited to. */ + readonly availableValues?: string[]; + /** One or many default values for template variables on load. If more than one default is specified, they will be unioned together with `OR`. Cannot be used in conjunction with `default`. */ + readonly defaults?: string[]; + /** The name of the variable. */ + readonly name: string; + /** The tag prefix associated with the variable. Only tags with this prefix appear in the variable drop-down. */ + readonly prefix?: string; +} + +export interface Widget { + /** [Definition of the widget](https://docs.datadoghq.com/dashboards/widgets/). */ + readonly definition: + | AlertGraphWidgetDefinition + | AlertValueWidgetDefinition + | ChangeWidgetDefinition + | CheckStatusWidgetDefinition + | DistributionWidgetDefinition + | EventStreamWidgetDefinition + | EventTimelineWidgetDefinition + | FreeTextWidgetDefinition + | GeomapWidgetDefinition + | GroupWidgetDefinition + | HeatMapWidgetDefinition + | HostMapWidgetDefinition + | IFrameWidgetDefinition + | ImageWidgetDefinition + | LogStreamWidgetDefinition + | MonitorSummaryWidgetDefinition + | NoteWidgetDefinition + | QueryValueWidgetDefinition + | RunWorkflowWidgetDefinition + | ScatterPlotWidgetDefinition + | SLOWidgetDefinition + | SLOListWidgetDefinition + | ServiceMapWidgetDefinition + | ServiceSummaryWidgetDefinition + | SunburstWidgetDefinition + | TableWidgetDefinition + | TimeseriesWidgetDefinition + | ToplistWidgetDefinition + | TreeMapWidgetDefinition + | ListStreamWidgetDefinition + | FunnelWidgetDefinition + | TopologyMapWidgetDefinition + | UnparsedObject; + /** ID of the widget. */ + readonly id?: number; + /** The layout for a widget on a `free` or **new dashboard layout** dashboard. */ + readonly layout?: WidgetLayout; +} + +export interface AlertGraphWidgetDefinition { + /** ID of the alert to use in the widget. */ + readonly alertId: string; + /** Time setting for the widget. */ + readonly time?: WidgetTime; + /** The title of the widget. */ + readonly title?: string; + /** How to align the text on the widget. */ + readonly titleAlign?: 'center' | 'left' | 'right' | UnparsedObject; + /** Size of the title. */ + readonly titleSize?: string; + /** Type of the alert graph widget. */ + readonly type: 'alert_graph' | UnparsedObject; + /** Whether to display the Alert Graph as a timeseries or a top list. */ + readonly vizType: 'timeseries' | 'toplist' | UnparsedObject; +} + +export interface WidgetTime { + /** The available timeframes depend on the widget you are using. */ + readonly liveSpan?: + | '1m' + | '5m' + | '10m' + | '15m' + | '30m' + | '1h' + | '4h' + | '1d' + | '2d' + | '1w' + | '1mo' + | '3mo' + | '6mo' + | '1y' + | 'alert' + | UnparsedObject; +} + +export interface AlertValueWidgetDefinition { + /** ID of the alert to use in the widget. */ + readonly alertId: string; + /** Number of decimal to show. If not defined, will use the raw value. */ + readonly precision?: number; + /** How to align the text on the widget. */ + readonly textAlign?: 'center' | 'left' | 'right' | UnparsedObject; + /** Title of the widget. */ + readonly title?: string; + /** How to align the text on the widget. */ + readonly titleAlign?: 'center' | 'left' | 'right' | UnparsedObject; + /** Size of value in the widget. */ + readonly titleSize?: string; + /** Type of the alert value widget. */ + readonly type: 'alert_value' | UnparsedObject; + /** Unit to display with the value. */ + readonly unit?: string; +} + +export interface ChangeWidgetDefinition { + /** List of custom links. */ + readonly customLinks?: Array; + /** + * Array of one request object to display in the widget. + * + * See the dedicated [Request JSON schema documentation](https://docs.datadoghq.com/dashboards/graphing_json/request_json) + * to learn how to build the `REQUEST_SCHEMA`. + */ + readonly requests: Array; + /** Time setting for the widget. */ + readonly time?: WidgetTime; + /** Title of the widget. */ + readonly title?: string; + /** How to align the text on the widget. */ + readonly titleAlign?: 'center' | 'left' | 'right' | UnparsedObject; + /** Size of the title. */ + readonly titleSize?: string; + /** Type of the change widget. */ + readonly type: 'change' | UnparsedObject; +} + +export interface WidgetCustomLink { + /** The flag for toggling context menu link visibility. */ + readonly isHidden?: boolean; + /** The label for the custom link URL. Keep the label short and descriptive. Use metrics and tags as variables. */ + readonly label?: string; + /** The URL of the custom link. URL must include `http` or `https`. A relative URL must start with `/`. */ + readonly link?: string; + /** The label ID that refers to a context menu link. Can be `logs`, `hosts`, `traces`, `profiles`, `processes`, `containers`, or `rum`. */ + readonly overrideLabel?: string; +} + +export interface ChangeWidgetRequest { + /** The log query. */ + readonly apmQuery?: LogQueryDefinition; + /** Show the absolute or the relative change. */ + readonly changeType?: 'absolute' | 'relative' | UnparsedObject; + /** Timeframe used for the change comparison. */ + readonly compareTo?: 'hour_before' | 'day_before' | 'week_before' | 'month_before' | UnparsedObject; + /** The log query. */ + readonly eventQuery?: LogQueryDefinition; + /** List of formulas that operate on queries. */ + readonly formulas?: Array; + /** Whether to show increase as good. */ + readonly increaseGood?: boolean; + /** The log query. */ + readonly logQuery?: LogQueryDefinition; + /** The log query. */ + readonly networkQuery?: LogQueryDefinition; + /** What to order by. */ + readonly orderBy?: 'change' | 'name' | 'present' | 'past' | UnparsedObject; + /** Widget sorting methods. */ + readonly orderDir?: 'asc' | 'desc' | UnparsedObject; + /** The process query to use in the widget. */ + readonly processQuery?: ProcessQueryDefinition; + /** The log query. */ + readonly profileMetricsQuery?: LogQueryDefinition; + /** Query definition. */ + readonly q?: string; + /** List of queries that can be returned directly or used in formulas. */ + readonly queries?: Array< + | FormulaAndFunctionMetricQueryDefinition + | FormulaAndFunctionEventQueryDefinition + | FormulaAndFunctionProcessQueryDefinition + | FormulaAndFunctionApmDependencyStatsQueryDefinition + | FormulaAndFunctionApmResourceStatsQueryDefinition + | FormulaAndFunctionSLOQueryDefinition + | FormulaAndFunctionCloudCostQueryDefinition + | UnparsedObject + >; + /** Timeseries, scalar, or event list response. Event list response formats are supported by Geomap widgets. */ + readonly responseFormat?: 'timeseries' | 'scalar' | 'event_list' | UnparsedObject; + /** The log query. */ + readonly rumQuery?: LogQueryDefinition; + /** The log query. */ + readonly securityQuery?: LogQueryDefinition; + /** Whether to show the present value. */ + readonly showPresent?: boolean; +} + +export interface LogQueryDefinition { + /** Define computation for a log query. */ + readonly compute?: LogsQueryCompute; + /** List of tag prefixes to group by in the case of a cluster check. */ + readonly groupBy?: Array; + /** A coma separated-list of index names. Use "*" query all indexes at once. [Multiple Indexes](https://docs.datadoghq.com/logs/indexes/#multiple-indexes) */ + readonly index?: string; + /** This field is mutually exclusive with `compute`. */ + readonly multiCompute?: Array; + /** The query being made on the logs. */ + readonly search?: LogQueryDefinitionSearch; +} + +export interface LogsQueryCompute { + /** The aggregation method. */ + readonly aggregation: string; + /** Facet name. */ + readonly facet?: string; + /** Define a time interval in seconds. */ + readonly interval?: number; +} + +export interface LogQueryDefinitionGroupBy { + /** Facet name. */ + readonly facet: string; + /** Maximum number of items in the group. */ + readonly limit?: number; + /** Define a sorting method. */ + readonly sort?: LogQueryDefinitionGroupBySort; +} + +export interface LogQueryDefinitionGroupBySort { + /** The aggregation method. */ + readonly aggregation: string; + /** Facet name. */ + readonly facet?: string; + /** Widget sorting methods. */ + readonly order: 'asc' | 'desc' | UnparsedObject; +} + +export interface LogQueryDefinitionSearch { + /** Search value to apply. */ + readonly query: string; +} + +export interface WidgetFormula { + /** Expression alias. */ + readonly alias?: string; + /** Define a display mode for the table cell. */ + readonly cellDisplayMode?: 'number' | 'bar' | UnparsedObject; + /** List of conditional formats. */ + readonly conditionalFormats?: Array; + /** String expression built from queries, formulas, and functions. */ + readonly formula: string; + /** Options for limiting results returned. */ + readonly limit?: WidgetFormulaLimit; + /** Styling options for widget formulas. */ + readonly style?: WidgetFormulaStyle; +} + +export interface WidgetConditionalFormat { + /** Comparator to apply. */ + readonly comparator: '=' | '>' | '>=' | '<' | '<=' | UnparsedObject; + /** Color palette to apply to the background, same values available as palette. */ + readonly customBgColor?: string; + /** Color palette to apply to the foreground, same values available as palette. */ + readonly customFgColor?: string; + /** True hides values. */ + readonly hideValue?: boolean; + /** Displays an image as the background. */ + readonly imageUrl?: string; + /** Metric from the request to correlate this conditional format with. */ + readonly metric?: string; + /** Color palette to apply. */ + readonly palette: + | 'blue' + | 'custom_bg' + | 'custom_image' + | 'custom_text' + | 'gray_on_white' + | 'grey' + | 'green' + | 'orange' + | 'red' + | 'red_on_white' + | 'white_on_gray' + | 'white_on_green' + | 'green_on_white' + | 'white_on_red' + | 'white_on_yellow' + | 'yellow_on_white' + | 'black_on_light_yellow' + | 'black_on_light_green' + | 'black_on_light_red' + | UnparsedObject; + /** Defines the displayed timeframe. */ + readonly timeframe?: string; + /** Value for the comparator. */ + readonly value: number; +} + +export interface WidgetFormulaLimit { + /** Number of results to return. */ + readonly count?: number; + /** Direction of sort. */ + readonly order?: 'asc' | 'desc' | UnparsedObject; +} + +export interface WidgetFormulaStyle { + /** The color palette used to display the formula. A guide to the available color palettes can be found at https://docs.datadoghq.com/dashboards/guide/widget_colors */ + readonly palette?: string; + /** Index specifying which color to use within the palette. */ + readonly paletteIndex?: number; +} + +export interface ProcessQueryDefinition { + /** List of processes. */ + readonly filterBy?: string[]; + /** Max number of items in the filter list. */ + readonly limit?: number; + /** Your chosen metric. */ + readonly metric: string; + /** Your chosen search term. */ + readonly searchBy?: string; +} + +export interface FormulaAndFunctionMetricQueryDefinition { + /** The aggregation methods available for metrics queries. */ + readonly aggregator?: 'avg' | 'min' | 'max' | 'sum' | 'last' | 'area' | 'l2norm' | 'percentile' | UnparsedObject; + /** Data source for metrics queries. */ + readonly dataSource: 'metrics' | UnparsedObject; + /** Name of the query for use in formulas. */ + readonly name: string; + /** Metrics query definition. */ + readonly query: string; +} + +export interface FormulaAndFunctionEventQueryDefinition { + /** Compute options. */ + readonly compute: FormulaAndFunctionEventQueryDefinitionCompute; + /** Data source for event platform-based queries. */ + readonly dataSource: + | 'logs' + | 'spans' + | 'network' + | 'rum' + | 'security_signals' + | 'profiles' + | 'audit' + | 'events' + | 'ci_tests' + | 'ci_pipelines' + | UnparsedObject; + /** Group by options. */ + readonly groupBy?: Array; + /** An array of index names to query in the stream. Omit or use `[]` to query all indexes at once. */ + readonly indexes?: string[]; + /** Name of the query for use in formulas. */ + readonly name: string; + /** Search options. */ + readonly search?: FormulaAndFunctionEventQueryDefinitionSearch; + /** Option for storage location. Feature in Private Beta. */ + readonly storage?: string; +} + +export interface FormulaAndFunctionEventQueryDefinitionCompute { + /** Aggregation methods for event platform queries. */ + readonly aggregation: + | 'count' + | 'cardinality' + | 'median' + | 'pc75' + | 'pc90' + | 'pc95' + | 'pc98' + | 'pc99' + | 'sum' + | 'min' + | 'max' + | 'avg' + | UnparsedObject; + /** A time interval in milliseconds. */ + readonly interval?: number; + /** Measurable attribute to compute. */ + readonly metric?: string; +} + +export interface FormulaAndFunctionEventQueryGroupBy { + /** Event facet. */ + readonly facet: string; + /** Number of groups to return. */ + readonly limit?: number; + /** Options for sorting group by results. */ + readonly sort?: FormulaAndFunctionEventQueryGroupBySort; +} + +export interface FormulaAndFunctionEventQueryGroupBySort { + /** Aggregation methods for event platform queries. */ + readonly aggregation: + | 'count' + | 'cardinality' + | 'median' + | 'pc75' + | 'pc90' + | 'pc95' + | 'pc98' + | 'pc99' + | 'sum' + | 'min' + | 'max' + | 'avg' + | UnparsedObject; + /** Metric used for sorting group by results. */ + readonly metric?: string; + /** Direction of sort. */ + readonly order?: 'asc' | 'desc' | UnparsedObject; +} + +export interface FormulaAndFunctionEventQueryDefinitionSearch { + /** Events search string. */ + readonly query: string; +} + +export interface FormulaAndFunctionProcessQueryDefinition { + /** The aggregation methods available for metrics queries. */ + readonly aggregator?: 'avg' | 'min' | 'max' | 'sum' | 'last' | 'area' | 'l2norm' | 'percentile' | UnparsedObject; + /** Data sources that rely on the process backend. */ + readonly dataSource: 'process' | 'container' | UnparsedObject; + /** Whether to normalize the CPU percentages. */ + readonly isNormalizedCpu?: boolean; + /** Number of hits to return. */ + readonly limit?: number; + /** Process metric name. */ + readonly metric: string; + /** Name of query for use in formulas. */ + readonly name: string; + /** Direction of sort. */ + readonly sort?: 'asc' | 'desc' | UnparsedObject; + /** An array of tags to filter by. */ + readonly tagFilters?: string[]; + /** Text to use as filter. */ + readonly textFilter?: string; +} + +export interface FormulaAndFunctionApmDependencyStatsQueryDefinition { + /** Data source for APM dependency stats queries. */ + readonly dataSource: 'apm_dependency_stats' | UnparsedObject; + /** APM environment. */ + readonly env: string; + /** Determines whether stats for upstream or downstream dependencies should be queried. */ + readonly isUpstream?: boolean; + /** Name of query to use in formulas. */ + readonly name: string; + /** Name of operation on service. */ + readonly operationName: string; + /** The name of the second primary tag used within APM; required when `primary_tag_value` is specified. See https://docs.datadoghq.com/tracing/guide/setting_primary_tags_to_scope/#add-a-second-primary-tag-in-datadog. */ + readonly primaryTagName?: string; + /** Filter APM data by the second primary tag. `primary_tag_name` must also be specified. */ + readonly primaryTagValue?: string; + /** APM resource. */ + readonly resourceName: string; + /** APM service. */ + readonly service: string; + /** APM statistic. */ + readonly stat: + | 'avg_duration' + | 'avg_root_duration' + | 'avg_spans_per_trace' + | 'error_rate' + | 'pct_exec_time' + | 'pct_of_traces' + | 'total_traces_count' + | UnparsedObject; +} + +export interface FormulaAndFunctionApmResourceStatsQueryDefinition { + /** Data source for APM resource stats queries. */ + readonly dataSource: 'apm_resource_stats' | UnparsedObject; + /** APM environment. */ + readonly env: string; + /** Array of fields to group results by. */ + readonly groupBy?: string[]; + /** Name of this query to use in formulas. */ + readonly name: string; + /** Name of operation on service. */ + readonly operationName?: string; + /** Name of the second primary tag used within APM. Required when `primary_tag_value` is specified. See https://docs.datadoghq.com/tracing/guide/setting_primary_tags_to_scope/#add-a-second-primary-tag-in-datadog */ + readonly primaryTagName?: string; + /** Value of the second primary tag by which to filter APM data. `primary_tag_name` must also be specified. */ + readonly primaryTagValue?: string; + /** APM resource name. */ + readonly resourceName?: string; + /** APM service name. */ + readonly service: string; + /** APM resource stat name. */ + readonly stat: + | 'errors' + | 'error_rate' + | 'hits' + | 'latency_avg' + | 'latency_distribution' + | 'latency_max' + | 'latency_p50' + | 'latency_p75' + | 'latency_p90' + | 'latency_p95' + | 'latency_p99' + | UnparsedObject; +} + +export interface FormulaAndFunctionSLOQueryDefinition { + /** Additional filters applied to the SLO query. */ + readonly additionalQueryFilters?: string; + /** Data source for SLO measures queries. */ + readonly dataSource: 'slo' | UnparsedObject; + /** Group mode to query measures. */ + readonly groupMode?: 'overall' | 'components' | UnparsedObject; + /** SLO measures queries. */ + readonly measure: + | 'good_events' + | 'bad_events' + | 'slo_status' + | 'error_budget_remaining' + | 'burn_rate' + | 'error_budget_burndown' + | UnparsedObject; + /** Name of the query for use in formulas. */ + readonly name?: string; + /** ID of an SLO to query measures. */ + readonly sloId: string; + /** Name of the query for use in formulas. */ + readonly sloQueryType?: 'metric' | UnparsedObject; +} + +export interface FormulaAndFunctionCloudCostQueryDefinition { + /** Aggregator used for the request. */ + readonly aggregator?: 'avg' | 'last' | 'max' | 'min' | 'sum' | 'percentile' | UnparsedObject; + /** Data source for Cloud Cost queries. */ + readonly dataSource: 'cloud_cost' | UnparsedObject; + /** Name of the query for use in formulas. */ + readonly name: string; + /** Query for Cloud Cost data. */ + readonly query: string; +} + +export interface CheckStatusWidgetDefinition { + /** Name of the check to use in the widget. */ + readonly check: string; + /** Group reporting a single check. */ + readonly group?: string; + /** List of tag prefixes to group by in the case of a cluster check. */ + readonly groupBy?: string[]; + /** The kind of grouping to use. */ + readonly grouping: 'check' | 'cluster' | UnparsedObject; + /** List of tags used to filter the groups reporting a cluster check. */ + readonly tags?: string[]; + /** Time setting for the widget. */ + readonly time?: WidgetTime; + /** Title of the widget. */ + readonly title?: string; + /** How to align the text on the widget. */ + readonly titleAlign?: 'center' | 'left' | 'right' | UnparsedObject; + /** Size of the title. */ + readonly titleSize?: string; + /** Type of the check status widget. */ + readonly type: 'check_status' | UnparsedObject; +} + +export interface DistributionWidgetDefinition { + /** A list of custom links. */ + readonly customLinks?: Array; + /** (Deprecated) The widget legend was replaced by a tooltip and sidebar. */ + readonly legendSize?: string; + /** List of markers. */ + readonly markers?: Array; + /** + * Array of one request object to display in the widget. + * + * See the dedicated [Request JSON schema documentation](https://docs.datadoghq.com/dashboards/graphing_json/request_json) + * to learn how to build the `REQUEST_SCHEMA`. + */ + readonly requests: Array; + /** (Deprecated) The widget legend was replaced by a tooltip and sidebar. */ + readonly showLegend?: boolean; + /** Time setting for the widget. */ + readonly time?: WidgetTime; + /** Title of the widget. */ + readonly title?: string; + /** How to align the text on the widget. */ + readonly titleAlign?: 'center' | 'left' | 'right' | UnparsedObject; + /** Size of the title. */ + readonly titleSize?: string; + /** Type of the distribution widget. */ + readonly type: 'distribution' | UnparsedObject; + /** X Axis controls for the distribution widget. */ + readonly xaxis?: DistributionWidgetXAxis; + /** Y Axis controls for the distribution widget. */ + readonly yaxis?: DistributionWidgetYAxis; +} + +export interface WidgetMarker { + /** + * Combination of: + * - A severity error, warning, ok, or info + * - A line type: dashed, solid, or bold + * In this case of a Distribution widget, this can be set to be `x_axis_percentile`. + */ + readonly displayType?: string; + /** Label to display over the marker. */ + readonly label?: string; + /** Timestamp for the widget. */ + readonly time?: string; + /** Value to apply. Can be a single value y = 15 or a range of values 0 < y < 10. */ + readonly value: string; +} + +export interface DistributionWidgetRequest { + /** The log query. */ + readonly apmQuery?: LogQueryDefinition; + /** The APM stats query for table and distributions widgets. */ + readonly apmStatsQuery?: ApmStatsQueryDefinition; + /** The log query. */ + readonly eventQuery?: LogQueryDefinition; + /** The log query. */ + readonly logQuery?: LogQueryDefinition; + /** The log query. */ + readonly networkQuery?: LogQueryDefinition; + /** The process query to use in the widget. */ + readonly processQuery?: ProcessQueryDefinition; + /** The log query. */ + readonly profileMetricsQuery?: LogQueryDefinition; + /** Widget query. */ + readonly q?: string; + /** Query definition for Distribution Widget Histogram Request */ + readonly query?: + | FormulaAndFunctionMetricQueryDefinition + | FormulaAndFunctionEventQueryDefinition + | FormulaAndFunctionApmResourceStatsQueryDefinition + | UnparsedObject; + /** Request type for the histogram request. */ + readonly requestType?: 'histogram' | UnparsedObject; + /** The log query. */ + readonly rumQuery?: LogQueryDefinition; + /** The log query. */ + readonly securityQuery?: LogQueryDefinition; + /** Widget style definition. */ + readonly style?: WidgetStyle; +} + +export interface ApmStatsQueryDefinition { + /** Column properties used by the front end for display. */ + readonly columns?: Array; + /** Environment name. */ + readonly env: string; + /** Operation name associated with service. */ + readonly name: string; + /** The organization's host group name and value. */ + readonly primaryTag: string; + /** Resource name. */ + readonly resource?: string; + /** The level of detail for the request. */ + readonly rowType: 'service' | 'resource' | 'span' | UnparsedObject; + /** Service name. */ + readonly service: string; +} + +export interface ApmStatsQueryColumnType { + /** A user-assigned alias for the column. */ + readonly alias?: string; + /** Define a display mode for the table cell. */ + readonly cellDisplayMode?: 'number' | 'bar' | UnparsedObject; + /** Column name. */ + readonly name: string; + /** Widget sorting methods. */ + readonly order?: 'asc' | 'desc' | UnparsedObject; +} + +export interface WidgetStyle { + /** Color palette to apply to the widget. */ + readonly palette?: string; +} + +export interface DistributionWidgetXAxis { + /** True includes zero. */ + readonly includeZero?: boolean; + /** Specifies maximum value to show on the x-axis. It takes a number, percentile (p90 === 90th percentile), or auto for default behavior. */ + readonly max?: string; + /** Specifies minimum value to show on the x-axis. It takes a number, percentile (p90 === 90th percentile), or auto for default behavior. */ + readonly min?: string; + /** Specifies the scale type. Possible values are `linear`. */ + readonly scale?: string; +} + +export interface DistributionWidgetYAxis { + /** True includes zero. */ + readonly includeZero?: boolean; + /** The label of the axis to display on the graph. */ + readonly label?: string; + /** Specifies the maximum value to show on the y-axis. It takes a number, or auto for default behavior. */ + readonly max?: string; + /** Specifies minimum value to show on the y-axis. It takes a number, or auto for default behavior. */ + readonly min?: string; + /** Specifies the scale type. Possible values are `linear` or `log`. */ + readonly scale?: string; +} + +export interface EventStreamWidgetDefinition { + /** Size to use to display an event. */ + readonly eventSize?: 's' | 'l' | UnparsedObject; + /** Query to filter the event stream with. */ + readonly query: string; + /** The execution method for multi-value filters. Can be either and or or. */ + readonly tagsExecution?: string; + /** Time setting for the widget. */ + readonly time?: WidgetTime; + /** Title of the widget. */ + readonly title?: string; + /** How to align the text on the widget. */ + readonly titleAlign?: 'center' | 'left' | 'right' | UnparsedObject; + /** Size of the title. */ + readonly titleSize?: string; + /** Type of the event stream widget. */ + readonly type: 'event_stream' | UnparsedObject; +} + +export interface EventTimelineWidgetDefinition { + /** Query to filter the event timeline with. */ + readonly query: string; + /** The execution method for multi-value filters. Can be either and or or. */ + readonly tagsExecution?: string; + /** Time setting for the widget. */ + readonly time?: WidgetTime; + /** Title of the widget. */ + readonly title?: string; + /** How to align the text on the widget. */ + readonly titleAlign?: 'center' | 'left' | 'right' | UnparsedObject; + /** Size of the title. */ + readonly titleSize?: string; + /** Type of the event timeline widget. */ + readonly type: 'event_timeline' | UnparsedObject; +} + +export interface FreeTextWidgetDefinition { + /** Color of the text. */ + readonly color?: string; + /** Size of the text. */ + readonly fontSize?: string; + /** Text to display. */ + readonly text: string; + /** How to align the text on the widget. */ + readonly textAlign?: 'center' | 'left' | 'right' | UnparsedObject; + /** Type of the free text widget. */ + readonly type: 'free_text' | UnparsedObject; +} + +export interface GeomapWidgetDefinition { + /** A list of custom links. */ + readonly customLinks?: Array; + /** + * Array of one request object to display in the widget. The request must contain a `group-by` tag whose value is a country ISO code. + * + * See the [Request JSON schema documentation](https://docs.datadoghq.com/dashboards/graphing_json/request_json) + * for information about building the `REQUEST_SCHEMA`. + */ + readonly requests: Array; + /** The style to apply to the widget. */ + readonly style: GeomapWidgetDefinitionStyle; + /** Time setting for the widget. */ + readonly time?: WidgetTime; + /** The title of your widget. */ + readonly title?: string; + /** How to align the text on the widget. */ + readonly titleAlign?: 'center' | 'left' | 'right' | UnparsedObject; + /** The size of the title. */ + readonly titleSize?: string; + /** Type of the geomap widget. */ + readonly type: 'geomap' | UnparsedObject; + /** The view of the world that the map should render. */ + readonly view: GeomapWidgetDefinitionView; +} + +export interface GeomapWidgetRequest { + /** Widget columns. */ + readonly columns?: Array; + /** List of formulas that operate on queries. */ + readonly formulas?: Array; + /** The log query. */ + readonly logQuery?: LogQueryDefinition; + /** The widget metrics query. */ + readonly q?: string; + /** List of queries that can be returned directly or used in formulas. */ + readonly queries?: Array< + | FormulaAndFunctionMetricQueryDefinition + | FormulaAndFunctionEventQueryDefinition + | FormulaAndFunctionProcessQueryDefinition + | FormulaAndFunctionApmDependencyStatsQueryDefinition + | FormulaAndFunctionApmResourceStatsQueryDefinition + | FormulaAndFunctionSLOQueryDefinition + | FormulaAndFunctionCloudCostQueryDefinition + | UnparsedObject + >; + /** Updated list stream widget. */ + readonly query?: ListStreamQuery; + /** Timeseries, scalar, or event list response. Event list response formats are supported by Geomap widgets. */ + readonly responseFormat?: 'timeseries' | 'scalar' | 'event_list' | UnparsedObject; + /** The log query. */ + readonly rumQuery?: LogQueryDefinition; + /** The log query. */ + readonly securityQuery?: LogQueryDefinition; +} + +export interface ListStreamColumn { + /** Widget column field. */ + readonly field: string; + /** Widget column width. */ + readonly width: 'auto' | 'compact' | 'full' | UnparsedObject; +} + +export interface ListStreamQuery { + /** Compute configuration for the List Stream Widget. Compute can be used only with the logs_transaction_stream (from 1 to 5 items) list stream source. */ + readonly compute?: Array; + /** Source from which to query items to display in the stream. */ + readonly dataSource: + | 'logs_stream' + | 'audit_stream' + | 'ci_pipeline_stream' + | 'ci_test_stream' + | 'rum_issue_stream' + | 'apm_issue_stream' + | 'logs_issue_stream' + | 'logs_pattern_stream' + | 'logs_transaction_stream' + | 'event_stream' + | UnparsedObject; + /** Size to use to display an event. */ + readonly eventSize?: 's' | 'l' | UnparsedObject; + /** Group by configuration for the List Stream Widget. Group by can be used only with logs_pattern_stream (up to 3 items) or logs_transaction_stream (one group by item is required) list stream source. */ + readonly groupBy?: Array; + /** List of indexes. */ + readonly indexes?: string[]; + /** Widget query. */ + readonly queryString: string; + /** Which column and order to sort by */ + readonly sort?: WidgetFieldSort; + /** Option for storage location. Feature in Private Beta. */ + readonly storage?: string; +} + +export interface ListStreamComputeItems { + /** Aggregation value. */ + readonly aggregation: + | 'count' + | 'cardinality' + | 'median' + | 'pc75' + | 'pc90' + | 'pc95' + | 'pc98' + | 'pc99' + | 'sum' + | 'min' + | 'max' + | 'avg' + | 'earliest' + | 'latest' + | 'most_frequent' + | UnparsedObject; + /** Facet name. */ + readonly facet?: string; +} + +export interface ListStreamGroupByItems { + /** Facet name. */ + readonly facet: string; +} + +export interface WidgetFieldSort { + /** Facet path for the column */ + readonly column: string; + /** Widget sorting methods. */ + readonly order: 'asc' | 'desc' | UnparsedObject; +} + +export interface GeomapWidgetDefinitionStyle { + /** The color palette to apply to the widget. */ + readonly palette: string; + /** Whether to flip the palette tones. */ + readonly paletteFlip: boolean; +} + +export interface GeomapWidgetDefinitionView { + /** The 2-letter ISO code of a country to focus the map on. Or `WORLD`. */ + readonly focus: string; +} + +export interface GroupWidgetDefinition { + /** Background color of the group title. */ + readonly backgroundColor?: string; + /** URL of image to display as a banner for the group. */ + readonly bannerImg?: string; + /** Layout type of the group. */ + readonly layoutType: 'ordered' | UnparsedObject; + /** Whether to show the title or not. */ + readonly showTitle?: boolean; + /** Title of the widget. */ + readonly title?: string; + /** How to align the text on the widget. */ + readonly titleAlign?: 'center' | 'left' | 'right' | UnparsedObject; + /** Type of the group widget. */ + readonly type: 'group' | UnparsedObject; + /** List of widget groups. */ + readonly widgets: Array; +} + +export interface HeatMapWidgetDefinition { + /** List of custom links. */ + readonly customLinks?: Array; + /** List of widget events. */ + readonly events?: Array; + /** Available legend sizes for a widget. Should be one of "0", "2", "4", "8", "16", or "auto". */ + readonly legendSize?: string; + /** List of widget types. */ + readonly requests: Array; + /** Whether or not to display the legend on this widget. */ + readonly showLegend?: boolean; + /** Time setting for the widget. */ + readonly time?: WidgetTime; + /** Title of the widget. */ + readonly title?: string; + /** How to align the text on the widget. */ + readonly titleAlign?: 'center' | 'left' | 'right' | UnparsedObject; + /** Size of the title. */ + readonly titleSize?: string; + /** Type of the heat map widget. */ + readonly type: 'heatmap' | UnparsedObject; + /** Axis controls for the widget. */ + readonly yaxis?: WidgetAxis; +} + +export interface WidgetEvent { + /** Query definition. */ + readonly q: string; + /** The execution method for multi-value filters. */ + readonly tagsExecution?: string; +} + +export interface HeatMapWidgetRequest { + /** The log query. */ + readonly apmQuery?: LogQueryDefinition; + /** The event query. */ + readonly eventQuery?: EventQueryDefinition; + /** The log query. */ + readonly logQuery?: LogQueryDefinition; + /** The log query. */ + readonly networkQuery?: LogQueryDefinition; + /** The process query to use in the widget. */ + readonly processQuery?: ProcessQueryDefinition; + /** The log query. */ + readonly profileMetricsQuery?: LogQueryDefinition; + /** Widget query. */ + readonly q?: string; + /** The log query. */ + readonly rumQuery?: LogQueryDefinition; + /** The log query. */ + readonly securityQuery?: LogQueryDefinition; + /** Widget style definition. */ + readonly style?: WidgetStyle; +} + +export interface EventQueryDefinition { + /** The query being made on the event. */ + readonly search: string; + /** The execution method for multi-value filters. Can be either and or or. */ + readonly tagsExecution: string; +} + +export interface WidgetAxis { + /** Set to `true` to include zero. */ + readonly includeZero?: boolean; + /** The label of the axis to display on the graph. Only usable on Scatterplot Widgets. */ + readonly label?: string; + /** Specifies maximum numeric value to show on the axis. Defaults to `auto`. */ + readonly max?: string; + /** Specifies minimum numeric value to show on the axis. Defaults to `auto`. */ + readonly min?: string; + /** Specifies the scale type. Possible values are `linear`, `log`, `sqrt`, and `pow##` (for example `pow2` or `pow0.5`). */ + readonly scale?: string; +} + +export interface HostMapWidgetDefinition { + /** List of custom links. */ + readonly customLinks?: Array; + /** List of tag prefixes to group by. */ + readonly group?: string[]; + /** Whether to show the hosts that don’t fit in a group. */ + readonly noGroupHosts?: boolean; + /** Whether to show the hosts with no metrics. */ + readonly noMetricHosts?: boolean; + /** Which type of node to use in the map. */ + readonly nodeType?: 'host' | 'container' | UnparsedObject; + /** Notes on the title. */ + readonly notes?: string; + /** List of definitions. */ + readonly requests: HostMapWidgetDefinitionRequests; + /** List of tags used to filter the map. */ + readonly scope?: string[]; + /** The style to apply to the widget. */ + readonly style?: HostMapWidgetDefinitionStyle; + /** Title of the widget. */ + readonly title?: string; + /** How to align the text on the widget. */ + readonly titleAlign?: 'center' | 'left' | 'right' | UnparsedObject; + /** Size of the title. */ + readonly titleSize?: string; + /** Type of the host map widget. */ + readonly type: 'hostmap' | UnparsedObject; +} + +export interface HostMapWidgetDefinitionRequests { + /** Updated host map. */ + readonly fill?: HostMapRequest; + /** Updated host map. */ + readonly size?: HostMapRequest; +} + +export interface HostMapRequest { + /** The log query. */ + readonly apmQuery?: LogQueryDefinition; + /** The log query. */ + readonly eventQuery?: LogQueryDefinition; + /** The log query. */ + readonly logQuery?: LogQueryDefinition; + /** The log query. */ + readonly networkQuery?: LogQueryDefinition; + /** The process query to use in the widget. */ + readonly processQuery?: ProcessQueryDefinition; + /** The log query. */ + readonly profileMetricsQuery?: LogQueryDefinition; + /** Query definition. */ + readonly q?: string; + /** The log query. */ + readonly rumQuery?: LogQueryDefinition; + /** The log query. */ + readonly securityQuery?: LogQueryDefinition; +} + +export interface HostMapWidgetDefinitionStyle { + /** Max value to use to color the map. */ + readonly fillMax?: string; + /** Min value to use to color the map. */ + readonly fillMin?: string; + /** Color palette to apply to the widget. */ + readonly palette?: string; + /** Whether to flip the palette tones. */ + readonly paletteFlip?: boolean; +} + +export interface IFrameWidgetDefinition { + /** Type of the iframe widget. */ + readonly type: 'iframe' | UnparsedObject; + /** URL of the iframe. */ + readonly url: string; +} + +export interface ImageWidgetDefinition { + /** Whether to display a background or not. */ + readonly hasBackground?: boolean; + /** Whether to display a border or not. */ + readonly hasBorder?: boolean; + /** Horizontal alignment. */ + readonly horizontalAlign?: 'center' | 'left' | 'right' | UnparsedObject; + /** + * Size of the margins around the image. + * **Note**: `small` and `large` values are deprecated. + */ + readonly margin?: 'sm' | 'md' | 'lg' | 'small' | 'large' | UnparsedObject; + /** + * How to size the image on the widget. The values are based on the image `object-fit` CSS properties. + * **Note**: `zoom`, `fit` and `center` values are deprecated. + */ + readonly sizing?: 'fill' | 'contain' | 'cover' | 'none' | 'scale-down' | 'zoom' | 'fit' | 'center' | UnparsedObject; + /** Type of the image widget. */ + readonly type: 'image' | UnparsedObject; + /** URL of the image. */ + readonly url: string; + /** URL of the image in dark mode. */ + readonly urlDarkTheme?: string; + /** Vertical alignment. */ + readonly verticalAlign?: 'center' | 'top' | 'bottom' | UnparsedObject; +} + +export interface LogStreamWidgetDefinition { + /** Which columns to display on the widget. */ + readonly columns?: string[]; + /** An array of index names to query in the stream. Use [] to query all indexes at once. */ + readonly indexes?: string[]; + /** ID of the log set to use. */ + readonly logset?: string; + /** Amount of log lines to display */ + readonly messageDisplay?: 'inline' | 'expanded-md' | 'expanded-lg' | UnparsedObject; + /** Query to filter the log stream with. */ + readonly query?: string; + /** Whether to show the date column or not */ + readonly showDateColumn?: boolean; + /** Whether to show the message column or not */ + readonly showMessageColumn?: boolean; + /** Which column and order to sort by */ + readonly sort?: WidgetFieldSort; + /** Time setting for the widget. */ + readonly time?: WidgetTime; + /** Title of the widget. */ + readonly title?: string; + /** How to align the text on the widget. */ + readonly titleAlign?: 'center' | 'left' | 'right' | UnparsedObject; + /** Size of the title. */ + readonly titleSize?: string; + /** Type of the log stream widget. */ + readonly type: 'log_stream' | UnparsedObject; +} + +export interface MonitorSummaryWidgetDefinition { + /** Which color to use on the widget. */ + readonly colorPreference?: 'background' | 'text' | UnparsedObject; + /** The number of monitors to display. */ + readonly count?: number; + /** What to display on the widget. */ + readonly displayFormat?: 'counts' | 'countsAndList' | 'list' | UnparsedObject; + /** Whether to show counts of 0 or not. */ + readonly hideZeroCounts?: boolean; + /** Query to filter the monitors with. */ + readonly query: string; + /** Whether to show the time that has elapsed since the monitor/group triggered. */ + readonly showLastTriggered?: boolean; + /** Whether to show the priorities column. */ + readonly showPriority?: boolean; + /** Widget sorting methods. */ + readonly sort?: + | 'name' + | 'group' + | 'status' + | 'tags' + | 'triggered' + | 'group,asc' + | 'group,desc' + | 'name,asc' + | 'name,desc' + | 'status,asc' + | 'status,desc' + | 'tags,asc' + | 'tags,desc' + | 'triggered,asc' + | 'triggered,desc' + | 'priority,asc' + | 'priority,desc' + | UnparsedObject; + /** The start of the list. Typically 0. */ + readonly start?: number; + /** Which summary type should be used. */ + readonly summaryType?: 'monitors' | 'groups' | 'combined' | UnparsedObject; + /** Title of the widget. */ + readonly title?: string; + /** How to align the text on the widget. */ + readonly titleAlign?: 'center' | 'left' | 'right' | UnparsedObject; + /** Size of the title. */ + readonly titleSize?: string; + /** Type of the monitor summary widget. */ + readonly type: 'manage_status' | UnparsedObject; +} + +export interface NoteWidgetDefinition { + /** Background color of the note. */ + readonly backgroundColor?: string; + /** Content of the note. */ + readonly content: string; + /** Size of the text. */ + readonly fontSize?: string; + /** Whether to add padding or not. */ + readonly hasPadding?: boolean; + /** Whether to show a tick or not. */ + readonly showTick?: boolean; + /** How to align the text on the widget. */ + readonly textAlign?: 'center' | 'left' | 'right' | UnparsedObject; + /** Define how you want to align the text on the widget. */ + readonly tickEdge?: 'bottom' | 'left' | 'right' | 'top' | UnparsedObject; + /** Where to position the tick on an edge. */ + readonly tickPos?: string; + /** Type of the note widget. */ + readonly type: 'note' | UnparsedObject; + /** Vertical alignment. */ + readonly verticalAlign?: 'center' | 'top' | 'bottom' | UnparsedObject; +} + +export interface QueryValueWidgetDefinition { + /** Whether to use auto-scaling or not. */ + readonly autoscale?: boolean; + /** List of custom links. */ + readonly customLinks?: Array; + /** Display a unit of your choice on the widget. */ + readonly customUnit?: string; + /** Number of decimals to show. If not defined, the widget uses the raw value. */ + readonly precision?: number; + /** Widget definition. */ + readonly requests: Array; + /** How to align the text on the widget. */ + readonly textAlign?: 'center' | 'left' | 'right' | UnparsedObject; + /** Time setting for the widget. */ + readonly time?: WidgetTime; + /** Set a timeseries on the widget background. */ + readonly timeseriesBackground?: TimeseriesBackground; + /** Title of your widget. */ + readonly title?: string; + /** How to align the text on the widget. */ + readonly titleAlign?: 'center' | 'left' | 'right' | UnparsedObject; + /** Size of the title. */ + readonly titleSize?: string; + /** Type of the query value widget. */ + readonly type: 'query_value' | UnparsedObject; +} + +export interface QueryValueWidgetRequest { + /** Aggregator used for the request. */ + readonly aggregator?: 'avg' | 'last' | 'max' | 'min' | 'sum' | 'percentile' | UnparsedObject; + /** The log query. */ + readonly apmQuery?: LogQueryDefinition; + /** The log query. */ + readonly auditQuery?: LogQueryDefinition; + /** List of conditional formats. */ + readonly conditionalFormats?: Array; + /** The log query. */ + readonly eventQuery?: LogQueryDefinition; + /** List of formulas that operate on queries. */ + readonly formulas?: Array; + /** The log query. */ + readonly logQuery?: LogQueryDefinition; + /** The log query. */ + readonly networkQuery?: LogQueryDefinition; + /** The process query to use in the widget. */ + readonly processQuery?: ProcessQueryDefinition; + /** The log query. */ + readonly profileMetricsQuery?: LogQueryDefinition; + /** TODO. */ + readonly q?: string; + /** List of queries that can be returned directly or used in formulas. */ + readonly queries?: Array< + | FormulaAndFunctionMetricQueryDefinition + | FormulaAndFunctionEventQueryDefinition + | FormulaAndFunctionProcessQueryDefinition + | FormulaAndFunctionApmDependencyStatsQueryDefinition + | FormulaAndFunctionApmResourceStatsQueryDefinition + | FormulaAndFunctionSLOQueryDefinition + | FormulaAndFunctionCloudCostQueryDefinition + | UnparsedObject + >; + /** Timeseries, scalar, or event list response. Event list response formats are supported by Geomap widgets. */ + readonly responseFormat?: 'timeseries' | 'scalar' | 'event_list' | UnparsedObject; + /** The log query. */ + readonly rumQuery?: LogQueryDefinition; + /** The log query. */ + readonly securityQuery?: LogQueryDefinition; +} + +export interface TimeseriesBackground { + /** Timeseries is made using an area or bars. */ + readonly type: 'bars' | 'area' | UnparsedObject; + /** Axis controls for the widget. */ + readonly yaxis?: WidgetAxis; +} + +export interface RunWorkflowWidgetDefinition { + /** List of custom links. */ + readonly customLinks?: Array; + /** Array of workflow inputs to map to dashboard template variables. */ + readonly inputs?: Array; + /** Time setting for the widget. */ + readonly time?: WidgetTime; + /** Title of your widget. */ + readonly title?: string; + /** How to align the text on the widget. */ + readonly titleAlign?: 'center' | 'left' | 'right' | UnparsedObject; + /** Size of the title. */ + readonly titleSize?: string; + /** Type of the run workflow widget. */ + readonly type: 'run_workflow' | UnparsedObject; + /** Workflow id. */ + readonly workflowId: string; +} + +export interface RunWorkflowWidgetInput { + /** Name of the workflow input. */ + readonly name: string; + /** Dashboard template variable. Can be suffixed with '.value' or '.key'. */ + readonly value: string; +} + +export interface ScatterPlotWidgetDefinition { + /** List of groups used for colors. */ + readonly colorByGroups?: string[]; + /** List of custom links. */ + readonly customLinks?: Array; + /** Widget definition. */ + readonly requests: ScatterPlotWidgetDefinitionRequests; + /** Time setting for the widget. */ + readonly time?: WidgetTime; + /** Title of your widget. */ + readonly title?: string; + /** How to align the text on the widget. */ + readonly titleAlign?: 'center' | 'left' | 'right' | UnparsedObject; + /** Size of the title. */ + readonly titleSize?: string; + /** Type of the scatter plot widget. */ + readonly type: 'scatterplot' | UnparsedObject; + /** Axis controls for the widget. */ + readonly xaxis?: WidgetAxis; + /** Axis controls for the widget. */ + readonly yaxis?: WidgetAxis; +} + +export interface ScatterPlotWidgetDefinitionRequests { + /** Scatterplot request containing formulas and functions. */ + readonly table?: ScatterplotTableRequest; + /** Updated scatter plot. */ + readonly x?: ScatterPlotRequest; + /** Updated scatter plot. */ + readonly y?: ScatterPlotRequest; +} + +export interface ScatterplotTableRequest { + /** List of Scatterplot formulas that operate on queries. */ + readonly formulas?: Array; + /** List of queries that can be returned directly or used in formulas. */ + readonly queries?: Array< + | FormulaAndFunctionMetricQueryDefinition + | FormulaAndFunctionEventQueryDefinition + | FormulaAndFunctionProcessQueryDefinition + | FormulaAndFunctionApmDependencyStatsQueryDefinition + | FormulaAndFunctionApmResourceStatsQueryDefinition + | FormulaAndFunctionSLOQueryDefinition + | FormulaAndFunctionCloudCostQueryDefinition + | UnparsedObject + >; + /** Timeseries, scalar, or event list response. Event list response formats are supported by Geomap widgets. */ + readonly responseFormat?: 'timeseries' | 'scalar' | 'event_list' | UnparsedObject; +} + +export interface ScatterplotWidgetFormula { + /** Expression alias. */ + readonly alias?: string; + /** Dimension of the Scatterplot. */ + readonly dimension: 'x' | 'y' | 'radius' | 'color' | UnparsedObject; + /** String expression built from queries, formulas, and functions. */ + readonly formula: string; +} + +export interface ScatterPlotRequest { + /** Aggregator used for the request. */ + readonly aggregator?: 'avg' | 'last' | 'max' | 'min' | 'sum' | UnparsedObject; + /** The log query. */ + readonly apmQuery?: LogQueryDefinition; + /** The log query. */ + readonly eventQuery?: LogQueryDefinition; + /** The log query. */ + readonly logQuery?: LogQueryDefinition; + /** The log query. */ + readonly networkQuery?: LogQueryDefinition; + /** The process query to use in the widget. */ + readonly processQuery?: ProcessQueryDefinition; + /** The log query. */ + readonly profileMetricsQuery?: LogQueryDefinition; + /** Query definition. */ + readonly q?: string; + /** The log query. */ + readonly rumQuery?: LogQueryDefinition; + /** The log query. */ + readonly securityQuery?: LogQueryDefinition; +} + +export interface SLOWidgetDefinition { + /** Additional filters applied to the SLO query. */ + readonly additionalQueryFilters?: string; + /** Defined global time target. */ + readonly globalTimeTarget?: string; + /** Defined error budget. */ + readonly showErrorBudget?: boolean; + /** ID of the SLO displayed. */ + readonly sloId?: string; + /** Times being monitored. */ + readonly timeWindows?: Array< + | '7d' + | '30d' + | '90d' + | 'week_to_date' + | 'previous_week' + | 'month_to_date' + | 'previous_month' + | 'global_time' + | UnparsedObject + >; + /** Title of the widget. */ + readonly title?: string; + /** How to align the text on the widget. */ + readonly titleAlign?: 'center' | 'left' | 'right' | UnparsedObject; + /** Size of the title. */ + readonly titleSize?: string; + /** Type of the SLO widget. */ + readonly type: 'slo' | UnparsedObject; + /** Define how you want the SLO to be displayed. */ + readonly viewMode?: 'overall' | 'component' | 'both' | UnparsedObject; + /** Type of view displayed by the widget. */ + readonly viewType: string; +} + +export interface SLOListWidgetDefinition { + /** Array of one request object to display in the widget. */ + readonly requests: Array; + /** Title of the widget. */ + readonly title?: string; + /** How to align the text on the widget. */ + readonly titleAlign?: 'center' | 'left' | 'right' | UnparsedObject; + /** Size of the title. */ + readonly titleSize?: string; + /** Type of the SLO List widget. */ + readonly type: 'slo_list' | UnparsedObject; +} + +export interface SLOListWidgetRequest { + /** Updated SLO List widget. */ + readonly query: SLOListWidgetQuery; + /** Widget request type. */ + readonly requestType: 'slo_list' | UnparsedObject; +} + +export interface SLOListWidgetQuery { + /** Maximum number of results to display in the table. */ + readonly limit?: number; + /** Widget query. */ + readonly queryString: string; + /** Options for sorting results. */ + readonly sort?: Array; +} + +export interface ServiceMapWidgetDefinition { + /** List of custom links. */ + readonly customLinks?: Array; + /** Your environment and primary tag (or * if enabled for your account). */ + readonly filters: string[]; + /** The ID of the service you want to map. */ + readonly service: string; + /** The title of your widget. */ + readonly title?: string; + /** How to align the text on the widget. */ + readonly titleAlign?: 'center' | 'left' | 'right' | UnparsedObject; + /** Size of the title. */ + readonly titleSize?: string; + /** Type of the service map widget. */ + readonly type: 'servicemap' | UnparsedObject; +} + +export interface ServiceSummaryWidgetDefinition { + /** Number of columns to display. */ + readonly displayFormat?: 'one_column' | 'two_column' | 'three_column' | UnparsedObject; + /** APM environment. */ + readonly env: string; + /** APM service. */ + readonly service: string; + /** Whether to show the latency breakdown or not. */ + readonly showBreakdown?: boolean; + /** Whether to show the latency distribution or not. */ + readonly showDistribution?: boolean; + /** Whether to show the error metrics or not. */ + readonly showErrors?: boolean; + /** Whether to show the hits metrics or not. */ + readonly showHits?: boolean; + /** Whether to show the latency metrics or not. */ + readonly showLatency?: boolean; + /** Whether to show the resource list or not. */ + readonly showResourceList?: boolean; + /** Size of the widget. */ + readonly sizeFormat?: 'small' | 'medium' | 'large' | UnparsedObject; + /** APM span name. */ + readonly spanName: string; + /** Time setting for the widget. */ + readonly time?: WidgetTime; + /** Title of the widget. */ + readonly title?: string; + /** How to align the text on the widget. */ + readonly titleAlign?: 'center' | 'left' | 'right' | UnparsedObject; + /** Size of the title. */ + readonly titleSize?: string; + /** Type of the service summary widget. */ + readonly type: 'trace_service' | UnparsedObject; +} + +export interface SunburstWidgetDefinition { + /** List of custom links. */ + readonly customLinks?: Array; + /** Show the total value in this widget. */ + readonly hideTotal?: boolean; + /** Configuration of the legend. */ + readonly legend?: SunburstWidgetLegendTable | SunburstWidgetLegendInlineAutomatic | UnparsedObject; + /** List of sunburst widget requests. */ + readonly requests: Array; + /** Time setting for the widget. */ + readonly time?: WidgetTime; + /** Title of your widget. */ + readonly title?: string; + /** How to align the text on the widget. */ + readonly titleAlign?: 'center' | 'left' | 'right' | UnparsedObject; + /** Size of the title. */ + readonly titleSize?: string; + /** Type of the Sunburst widget. */ + readonly type: 'sunburst' | UnparsedObject; +} + +export interface SunburstWidgetLegendTable { + /** Whether or not to show a table legend. */ + readonly type: 'table' | 'none' | UnparsedObject; +} + +export interface SunburstWidgetLegendInlineAutomatic { + /** Whether to hide the percentages of the groups. */ + readonly hidePercent?: boolean; + /** Whether to hide the values of the groups. */ + readonly hideValue?: boolean; + /** Whether to show the legend inline or let it be automatically generated. */ + readonly type: 'inline' | 'automatic' | UnparsedObject; +} + +export interface SunburstWidgetRequest { + /** The log query. */ + readonly apmQuery?: LogQueryDefinition; + /** The log query. */ + readonly auditQuery?: LogQueryDefinition; + /** The log query. */ + readonly eventQuery?: LogQueryDefinition; + /** List of formulas that operate on queries. */ + readonly formulas?: Array; + /** The log query. */ + readonly logQuery?: LogQueryDefinition; + /** The log query. */ + readonly networkQuery?: LogQueryDefinition; + /** The process query to use in the widget. */ + readonly processQuery?: ProcessQueryDefinition; + /** The log query. */ + readonly profileMetricsQuery?: LogQueryDefinition; + /** Widget query. */ + readonly q?: string; + /** List of queries that can be returned directly or used in formulas. */ + readonly queries?: Array< + | FormulaAndFunctionMetricQueryDefinition + | FormulaAndFunctionEventQueryDefinition + | FormulaAndFunctionProcessQueryDefinition + | FormulaAndFunctionApmDependencyStatsQueryDefinition + | FormulaAndFunctionApmResourceStatsQueryDefinition + | FormulaAndFunctionSLOQueryDefinition + | FormulaAndFunctionCloudCostQueryDefinition + | UnparsedObject + >; + /** Timeseries, scalar, or event list response. Event list response formats are supported by Geomap widgets. */ + readonly responseFormat?: 'timeseries' | 'scalar' | 'event_list' | UnparsedObject; + /** The log query. */ + readonly rumQuery?: LogQueryDefinition; + /** The log query. */ + readonly securityQuery?: LogQueryDefinition; +} + +export interface TableWidgetDefinition { + /** List of custom links. */ + readonly customLinks?: Array; + /** Controls the display of the search bar. */ + readonly hasSearchBar?: 'always' | 'never' | 'auto' | UnparsedObject; + /** Widget definition. */ + readonly requests: Array; + /** Time setting for the widget. */ + readonly time?: WidgetTime; + /** Title of your widget. */ + readonly title?: string; + /** How to align the text on the widget. */ + readonly titleAlign?: 'center' | 'left' | 'right' | UnparsedObject; + /** Size of the title. */ + readonly titleSize?: string; + /** Type of the table widget. */ + readonly type: 'query_table' | UnparsedObject; +} + +export interface TableWidgetRequest { + /** Aggregator used for the request. */ + readonly aggregator?: 'avg' | 'last' | 'max' | 'min' | 'sum' | 'percentile' | UnparsedObject; + /** The column name (defaults to the metric name). */ + readonly alias?: string; + /** The log query. */ + readonly apmQuery?: LogQueryDefinition; + /** The APM stats query for table and distributions widgets. */ + readonly apmStatsQuery?: ApmStatsQueryDefinition; + /** A list of display modes for each table cell. */ + readonly cellDisplayMode?: Array<'number' | 'bar' | UnparsedObject>; + /** List of conditional formats. */ + readonly conditionalFormats?: Array; + /** The log query. */ + readonly eventQuery?: LogQueryDefinition; + /** List of formulas that operate on queries. */ + readonly formulas?: Array; + /** For metric queries, the number of lines to show in the table. Only one request should have this property. */ + readonly limit?: number; + /** The log query. */ + readonly logQuery?: LogQueryDefinition; + /** The log query. */ + readonly networkQuery?: LogQueryDefinition; + /** Widget sorting methods. */ + readonly order?: 'asc' | 'desc' | UnparsedObject; + /** The process query to use in the widget. */ + readonly processQuery?: ProcessQueryDefinition; + /** The log query. */ + readonly profileMetricsQuery?: LogQueryDefinition; + /** Query definition. */ + readonly q?: string; + /** List of queries that can be returned directly or used in formulas. */ + readonly queries?: Array< + | FormulaAndFunctionMetricQueryDefinition + | FormulaAndFunctionEventQueryDefinition + | FormulaAndFunctionProcessQueryDefinition + | FormulaAndFunctionApmDependencyStatsQueryDefinition + | FormulaAndFunctionApmResourceStatsQueryDefinition + | FormulaAndFunctionSLOQueryDefinition + | FormulaAndFunctionCloudCostQueryDefinition + | UnparsedObject + >; + /** Timeseries, scalar, or event list response. Event list response formats are supported by Geomap widgets. */ + readonly responseFormat?: 'timeseries' | 'scalar' | 'event_list' | UnparsedObject; + /** The log query. */ + readonly rumQuery?: LogQueryDefinition; + /** The log query. */ + readonly securityQuery?: LogQueryDefinition; +} + +export interface TimeseriesWidgetDefinition { + /** List of custom links. */ + readonly customLinks?: Array; + /** List of widget events. */ + readonly events?: Array; + /** Columns displayed in the legend. */ + readonly legendColumns?: Array<'value' | 'avg' | 'sum' | 'min' | 'max' | UnparsedObject>; + /** Layout of the legend. */ + readonly legendLayout?: 'auto' | 'horizontal' | 'vertical' | UnparsedObject; + /** Available legend sizes for a widget. Should be one of "0", "2", "4", "8", "16", or "auto". */ + readonly legendSize?: string; + /** List of markers. */ + readonly markers?: Array; + /** List of timeseries widget requests. */ + readonly requests: Array; + /** Axis controls for the widget. */ + readonly rightYaxis?: WidgetAxis; + /** (screenboard only) Show the legend for this widget. */ + readonly showLegend?: boolean; + /** Time setting for the widget. */ + readonly time?: WidgetTime; + /** Title of your widget. */ + readonly title?: string; + /** How to align the text on the widget. */ + readonly titleAlign?: 'center' | 'left' | 'right' | UnparsedObject; + /** Size of the title. */ + readonly titleSize?: string; + /** Type of the timeseries widget. */ + readonly type: 'timeseries' | UnparsedObject; + /** Axis controls for the widget. */ + readonly yaxis?: WidgetAxis; +} + +export interface TimeseriesWidgetRequest { + /** The log query. */ + readonly apmQuery?: LogQueryDefinition; + /** The log query. */ + readonly auditQuery?: LogQueryDefinition; + /** Type of display to use for the request. */ + readonly displayType?: 'area' | 'bars' | 'line' | 'overlay' | UnparsedObject; + /** The log query. */ + readonly eventQuery?: LogQueryDefinition; + /** List of formulas that operate on queries. */ + readonly formulas?: Array; + /** The log query. */ + readonly logQuery?: LogQueryDefinition; + /** Used to define expression aliases. */ + readonly metadata?: Array; + /** The log query. */ + readonly networkQuery?: LogQueryDefinition; + /** Whether or not to display a second y-axis on the right. */ + readonly onRightYaxis?: boolean; + /** The process query to use in the widget. */ + readonly processQuery?: ProcessQueryDefinition; + /** The log query. */ + readonly profileMetricsQuery?: LogQueryDefinition; + /** Widget query. */ + readonly q?: string; + /** List of queries that can be returned directly or used in formulas. */ + readonly queries?: Array< + | FormulaAndFunctionMetricQueryDefinition + | FormulaAndFunctionEventQueryDefinition + | FormulaAndFunctionProcessQueryDefinition + | FormulaAndFunctionApmDependencyStatsQueryDefinition + | FormulaAndFunctionApmResourceStatsQueryDefinition + | FormulaAndFunctionSLOQueryDefinition + | FormulaAndFunctionCloudCostQueryDefinition + | UnparsedObject + >; + /** Timeseries, scalar, or event list response. Event list response formats are supported by Geomap widgets. */ + readonly responseFormat?: 'timeseries' | 'scalar' | 'event_list' | UnparsedObject; + /** The log query. */ + readonly rumQuery?: LogQueryDefinition; + /** The log query. */ + readonly securityQuery?: LogQueryDefinition; + /** Define request widget style. */ + readonly style?: WidgetRequestStyle; +} + +export interface TimeseriesWidgetExpressionAlias { + /** Expression alias. */ + readonly aliasName?: string; + /** Expression name. */ + readonly expression: string; +} + +export interface WidgetRequestStyle { + /** Type of lines displayed. */ + readonly lineType?: 'dashed' | 'dotted' | 'solid' | UnparsedObject; + /** Width of line displayed. */ + readonly lineWidth?: 'normal' | 'thick' | 'thin' | UnparsedObject; + /** Color palette to apply to the widget. */ + readonly palette?: string; +} + +export interface ToplistWidgetDefinition { + /** List of custom links. */ + readonly customLinks?: Array; + /** List of top list widget requests. */ + readonly requests: Array; + /** Time setting for the widget. */ + readonly time?: WidgetTime; + /** Title of your widget. */ + readonly title?: string; + /** How to align the text on the widget. */ + readonly titleAlign?: 'center' | 'left' | 'right' | UnparsedObject; + /** Size of the title. */ + readonly titleSize?: string; + /** Type of the top list widget. */ + readonly type: 'toplist' | UnparsedObject; +} + +export interface ToplistWidgetRequest { + /** The log query. */ + readonly apmQuery?: LogQueryDefinition; + /** The log query. */ + readonly auditQuery?: LogQueryDefinition; + /** List of conditional formats. */ + readonly conditionalFormats?: Array; + /** The log query. */ + readonly eventQuery?: LogQueryDefinition; + /** List of formulas that operate on queries. */ + readonly formulas?: Array; + /** The log query. */ + readonly logQuery?: LogQueryDefinition; + /** The log query. */ + readonly networkQuery?: LogQueryDefinition; + /** The process query to use in the widget. */ + readonly processQuery?: ProcessQueryDefinition; + /** The log query. */ + readonly profileMetricsQuery?: LogQueryDefinition; + /** Widget query. */ + readonly q?: string; + /** List of queries that can be returned directly or used in formulas. */ + readonly queries?: Array< + | FormulaAndFunctionMetricQueryDefinition + | FormulaAndFunctionEventQueryDefinition + | FormulaAndFunctionProcessQueryDefinition + | FormulaAndFunctionApmDependencyStatsQueryDefinition + | FormulaAndFunctionApmResourceStatsQueryDefinition + | FormulaAndFunctionSLOQueryDefinition + | FormulaAndFunctionCloudCostQueryDefinition + | UnparsedObject + >; + /** Timeseries, scalar, or event list response. Event list response formats are supported by Geomap widgets. */ + readonly responseFormat?: 'timeseries' | 'scalar' | 'event_list' | UnparsedObject; + /** The log query. */ + readonly rumQuery?: LogQueryDefinition; + /** The log query. */ + readonly securityQuery?: LogQueryDefinition; + /** Define request widget style. */ + readonly style?: WidgetRequestStyle; +} + +export interface TreeMapWidgetDefinition { + /** (deprecated) The attribute formerly used to determine color in the widget. */ + readonly colorBy?: 'user' | UnparsedObject; + /** List of custom links. */ + readonly customLinks?: Array; + /** (deprecated) The attribute formerly used to group elements in the widget. */ + readonly groupBy?: 'user' | 'family' | 'process' | UnparsedObject; + /** List of treemap widget requests. */ + readonly requests: Array; + /** (deprecated) The attribute formerly used to determine size in the widget. */ + readonly sizeBy?: 'pct_cpu' | 'pct_mem' | UnparsedObject; + /** Time setting for the widget. */ + readonly time?: WidgetTime; + /** Title of your widget. */ + readonly title?: string; + /** Type of the treemap widget. */ + readonly type: 'treemap' | UnparsedObject; +} + +export interface TreeMapWidgetRequest { + /** List of formulas that operate on queries. */ + readonly formulas?: Array; + /** The widget metrics query. */ + readonly q?: string; + /** List of queries that can be returned directly or used in formulas. */ + readonly queries?: Array< + | FormulaAndFunctionMetricQueryDefinition + | FormulaAndFunctionEventQueryDefinition + | FormulaAndFunctionProcessQueryDefinition + | FormulaAndFunctionApmDependencyStatsQueryDefinition + | FormulaAndFunctionApmResourceStatsQueryDefinition + | FormulaAndFunctionSLOQueryDefinition + | FormulaAndFunctionCloudCostQueryDefinition + | UnparsedObject + >; + /** Timeseries, scalar, or event list response. Event list response formats are supported by Geomap widgets. */ + readonly responseFormat?: 'timeseries' | 'scalar' | 'event_list' | UnparsedObject; +} + +export interface ListStreamWidgetDefinition { + /** Available legend sizes for a widget. Should be one of "0", "2", "4", "8", "16", or "auto". */ + readonly legendSize?: string; + /** Request payload used to query items. */ + readonly requests: Array; + /** Whether or not to display the legend on this widget. */ + readonly showLegend?: boolean; + /** Time setting for the widget. */ + readonly time?: WidgetTime; + /** Title of the widget. */ + readonly title?: string; + /** How to align the text on the widget. */ + readonly titleAlign?: 'center' | 'left' | 'right' | UnparsedObject; + /** Size of the title. */ + readonly titleSize?: string; + /** Type of the list stream widget. */ + readonly type: 'list_stream' | UnparsedObject; +} + +export interface ListStreamWidgetRequest { + /** Widget columns. */ + readonly columns: Array; + /** Updated list stream widget. */ + readonly query: ListStreamQuery; + /** Widget response format. */ + readonly responseFormat: 'event_list' | UnparsedObject; +} + +export interface FunnelWidgetDefinition { + /** Request payload used to query items. */ + readonly requests: Array; + /** Time setting for the widget. */ + readonly time?: WidgetTime; + /** The title of the widget. */ + readonly title?: string; + /** How to align the text on the widget. */ + readonly titleAlign?: 'center' | 'left' | 'right' | UnparsedObject; + /** The size of the title. */ + readonly titleSize?: string; + /** Type of funnel widget. */ + readonly type: 'funnel' | UnparsedObject; +} + +export interface FunnelWidgetRequest { + /** Updated funnel widget. */ + readonly query: FunnelQuery; + /** Widget request type. */ + readonly requestType: 'funnel' | UnparsedObject; +} + +export interface FunnelQuery { + /** Source from which to query items to display in the funnel. */ + readonly dataSource: 'rum' | UnparsedObject; + /** The widget query. */ + readonly queryString: string; + /** List of funnel steps. */ + readonly steps: Array; +} + +export interface FunnelStep { + /** The facet of the step. */ + readonly facet: string; + /** The value of the step. */ + readonly value: string; +} + +export interface TopologyMapWidgetDefinition { + /** List of custom links. */ + readonly customLinks?: Array; + /** One or more Topology requests. */ + readonly requests: Array; + /** Title of your widget. */ + readonly title?: string; + /** How to align the text on the widget. */ + readonly titleAlign?: 'center' | 'left' | 'right' | UnparsedObject; + /** Size of the title. */ + readonly titleSize?: string; + /** Type of the topology map widget. */ + readonly type: 'topology_map' | UnparsedObject; +} + +export interface TopologyRequest { + /** Query to service-based topology data sources like the service map or data streams. */ + readonly query?: TopologyQuery; + /** Widget request type. */ + readonly requestType?: 'topology' | UnparsedObject; +} + +export interface TopologyQuery { + /** Name of the data source */ + readonly dataSource?: 'data_streams' | 'service_map' | UnparsedObject; + /** Your environment and primary tag (or * if enabled for your account). */ + readonly filters?: string[]; + /** Name of the service */ + readonly service?: string; +} + +export interface WidgetLayout { + /** The height of the widget. Should be a non-negative integer. */ + readonly height: number; + /** + * Whether the widget should be the first one on the second column in high density or not. + * **Note**: Only for the **new dashboard layout** and only one widget in the dashboard should have this property set to `true`. + */ + readonly isColumnBreak?: boolean; + /** The width of the widget. Should be a non-negative integer. */ + readonly width: number; + /** The position of the widget on the x (horizontal) axis. Should be a non-negative integer. */ + readonly x: number; + /** The position of the widget on the y (vertical) axis. Should be a non-negative integer. */ + readonly y: number; +} diff --git a/src/dashboards/datadog-dashboard-schema.generated.ts b/src/dashboards/datadog-dashboard-schema.generated.ts new file mode 100644 index 0000000..a775247 --- /dev/null +++ b/src/dashboards/datadog-dashboard-schema.generated.ts @@ -0,0 +1,19 @@ +// ~~ Generated by projen. To modify, edit .projenrc.ts and run "npx projen". + +/** + * Datadog Dashboard 2.1.0 + */ +export interface DatadogDashboardProps { + /** + * ID of the dashboard + */ + readonly id?: string; + /** + * Url of the dashboard + */ + readonly url?: string; + /** + * JSON string of the dashboard definition + */ + readonly dashboardDefinition?: string; +} diff --git a/src/dashboards/datadog-dashboard.ts b/src/dashboards/datadog-dashboard.ts new file mode 100644 index 0000000..4aa3c74 --- /dev/null +++ b/src/dashboards/datadog-dashboard.ts @@ -0,0 +1,37 @@ +import { CfnResource } from 'aws-cdk-lib'; +import * as camelcaseKeys from 'camelcase-keys'; +import { Construct } from 'constructs'; +import { Dashboard } from './datadog-api-dashboard.generated'; +import { DatadogDashboardProps } from './datadog-dashboard-schema.generated'; + +/** + * Wrapper for generated Schema with typed dashboard property + */ +export interface DataDogDashboardCfnOptions extends DatadogDashboardProps { + /** Typed Dashboard instance */ + readonly dashboard?: Dashboard; +} + +/** + * Datadog Dashboard 2.1.0 + */ +export class DatadogDashboard { + constructor(scope: Construct, id: string, props: DataDogDashboardCfnOptions) { + let propsCopy = { ...props }; + if (props.dashboard) { + propsCopy = { + ...props, + dashboardDefinition: JSON.stringify(props.dashboard), + }; + delete propsCopy.dashboard; + } + const cfnProperties = camelcaseKeys(propsCopy, { + deep: true, + pascalCase: true, + }); + new CfnResource(scope, id, { + type: 'Datadog::Dashboards::Dashboard', + properties: { ...cfnProperties }, + }); + } +} diff --git a/src/dashboards/index.ts b/src/dashboards/index.ts new file mode 100644 index 0000000..4dca07c --- /dev/null +++ b/src/dashboards/index.ts @@ -0,0 +1,3 @@ +export * from './datadog-dashboard-schema.generated'; +export * from './datadog-api-dashboard.generated'; +export * from './datadog-dashboard'; diff --git a/src/index.ts b/src/index.ts index 6f5788a..6f1ee64 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,3 +1,3 @@ -export * from './monitors/datadog-monitor'; -export * from './monitors/properties'; -export * from './monitors/datadog-monitor-schema'; +export * from './monitors'; +export * from './dashboards'; +export * from './slos'; diff --git a/src/monitors/datadog-monitor-schema.ts b/src/monitors/datadog-monitor-schema.generated.ts similarity index 90% rename from src/monitors/datadog-monitor-schema.ts rename to src/monitors/datadog-monitor-schema.generated.ts index 7a3285b..88c8b5b 100644 --- a/src/monitors/datadog-monitor-schema.ts +++ b/src/monitors/datadog-monitor-schema.generated.ts @@ -1,21 +1,21 @@ -// This file was autogenerated by `yarn create-typescript-types`. DO NOT MODIFY +// ~~ Generated by projen. To modify, edit .projenrc.ts and run "npx projen". /** * Data source for event platform-based queries. */ export type MonitorFormulaAndFunctionEventAggregation = - | 'count' - | 'cardinality' - | 'median' - | 'pc75' - | 'pc90' - | 'pc95' - | 'pc98' - | 'pc99' - | 'sum' - | 'min' - | 'max' - | 'avg'; + | "count" + | "cardinality" + | "median" + | "pc75" + | "pc90" + | "pc95" + | "pc98" + | "pc99" + | "sum" + | "min" + | "max" + | "avg"; /** * Datadog Monitor 4.6.0 @@ -51,22 +51,22 @@ export interface DatadogMonitorProps { * The type of the monitor */ readonly type?: - | 'audit alert' - | 'composite' - | 'event alert' - | 'event-v2 alert' - | 'log alert' - | 'metric alert' - | 'process alert' - | 'query alert' - | 'service check' - | 'synthetics alert' - | 'trace-analytics alert' - | 'slo alert' - | 'rum alert' - | 'ci-pipelines alert' - | 'error-tracking alert' - | 'ci-tests alert'; + | "audit alert" + | "composite" + | "event alert" + | "event-v2 alert" + | "log alert" + | "metric alert" + | "process alert" + | "query alert" + | "service check" + | "synthetics alert" + | "trace-analytics alert" + | "slo alert" + | "rum alert" + | "ci-pipelines alert" + | "error-tracking alert" + | "ci-tests alert"; /** * Whether or not the monitor is multi alert */ @@ -171,7 +171,7 @@ export interface MonitorOptions { /** * The types of monitor statuses for which re-notification messages are sent. */ - readonly renotifyStatuses?: ('alert' | 'no data' | 'warn')[]; + readonly renotifyStatuses?: ("alert" | "no data" | "warn")[]; /** * How long the test should be in failure before alerting (integer, number of seconds, max 7200). */ @@ -230,7 +230,7 @@ export interface MonitorFormulaAndFunctionEventQueryDefinition { /** * Threshold value for triggering an alert. */ - readonly dataSource?: 'rum' | 'ci_pipelines' | 'ci_tests' | 'audit' | 'events' | 'logs' | 'spans'; + readonly dataSource?: "rum" | "ci_pipelines" | "ci_tests" | "audit" | "events" | "logs" | "spans"; readonly search?: MonitorFormulaAndFunctionEventQueryDefinitionSearch; /** * An array of index names to query in the stream. Omit or use `[]` to query all indexes at once. @@ -295,5 +295,5 @@ export interface MonitorFormulaAndFunctionEventQueryGroupBySort { /** * Direction of sort. */ - readonly order?: 'asc' | 'desc'; + readonly order?: "asc" | "desc"; } diff --git a/src/monitors/datadog-monitor.ts b/src/monitors/datadog-monitor.ts index 2d1e1ac..e9d4b2a 100644 --- a/src/monitors/datadog-monitor.ts +++ b/src/monitors/datadog-monitor.ts @@ -1,8 +1,7 @@ import { CfnResource } from 'aws-cdk-lib'; -// eslint-disable-next-line @typescript-eslint/no-require-imports -import camelcaseKeys = require('camelcase-keys'); +import * as camelcaseKeys from 'camelcase-keys'; import { Construct } from 'constructs'; -import { DatadogMonitorProps } from './datadog-monitor-schema'; +import { DatadogMonitorProps } from './datadog-monitor-schema.generated'; /** * Datadog Monitor 4.6.0 diff --git a/src/monitors/index.ts b/src/monitors/index.ts new file mode 100644 index 0000000..e703861 --- /dev/null +++ b/src/monitors/index.ts @@ -0,0 +1,3 @@ +export * from './datadog-monitor-schema.generated'; +export * from './datadog-monitor'; +export * from './properties'; diff --git a/src/slos/datadog-slo-schema.generated.ts b/src/slos/datadog-slo-schema.generated.ts new file mode 100644 index 0000000..70ca616 --- /dev/null +++ b/src/slos/datadog-slo-schema.generated.ts @@ -0,0 +1,96 @@ +// ~~ Generated by projen. To modify, edit .projenrc.ts and run "npx projen". + +/** + * Datadog SLO 1.1.0 + */ +export interface DatadogSLOProps { + readonly creator?: SloCreator; + /** + * Description of the slo + */ + readonly description?: string; + /** + * A list of (up to 20) monitor groups that narrow the scope of a monitor service level objective. + */ + readonly groups?: string[]; + /** + * ID of the slo + */ + readonly id?: string; + /** + * A list of monitor ids that defines the scope of a monitor service level objective. Required if type is monitor. + */ + readonly monitorIds?: number[]; + /** + * Name of the slo + */ + readonly name?: string; + readonly query?: Query; + /** + * Tags associated with the slo + */ + readonly tags?: string[]; + readonly thresholds?: Threshold[]; + /** + * The type of the slo + */ + readonly type?: "monitor" | "metric"; + /** + * Date of creation of the slo + */ + readonly created?: string; + /** + * Date of deletion of the slo + */ + readonly deleted?: string; + /** + * Date of modification of the slo + */ + readonly modified?: string; +} +export interface SloCreator { + /** + * Name of the creator of the slo + */ + readonly name?: string; + /** + * Handle of the creator of the slo + */ + readonly handle?: string; + /** + * Email of the creator of the slo + */ + readonly email?: string; +} +export interface Query { + /** + * A Datadog metric query for total (valid) events. + */ + readonly numerator?: string; + /** + * A Datadog metric query for good events. + */ + readonly denominator?: string; +} +export interface Threshold { + /** + * The target value for the service level indicator within the corresponding timeframe. + */ + readonly target?: number; + /** + * A string representation of the target that indicates its precision.(e.g. 98.00) + */ + readonly targetDisplay?: string; + /** + * The SLO time window options. Allowed enum values: 7d,30d,90d + */ + readonly timeframe?: "7d" | "30d" | "90d"; + /** + * The warning value for the service level objective. + */ + readonly warning?: number; + /** + * A string representation of the warning target.(e.g. 98.00) + */ + readonly warningDisplay?: string; +} diff --git a/src/slos/datadog-slo.ts b/src/slos/datadog-slo.ts new file mode 100644 index 0000000..3436c27 --- /dev/null +++ b/src/slos/datadog-slo.ts @@ -0,0 +1,20 @@ +import { CfnResource } from 'aws-cdk-lib'; +import * as camelcaseKeys from 'camelcase-keys'; +import { Construct } from 'constructs'; +import { DatadogSLOProps } from './datadog-slo-schema.generated'; + +/** + * Datadog SLO 1.1.0 + */ +export class DatadogSLO { + constructor(scope: Construct, id: string, props: DatadogSLOProps) { + const cfnProperties = camelcaseKeys(props, { + deep: true, + pascalCase: true, + }); + new CfnResource(scope, id, { + type: 'Datadog::SLOs::SLO', + properties: { ...cfnProperties }, + }); + } +} diff --git a/src/slos/index.ts b/src/slos/index.ts new file mode 100644 index 0000000..06a24f6 --- /dev/null +++ b/src/slos/index.ts @@ -0,0 +1,3 @@ +export * from './datadog-slo-schema.generated'; +export * from './datadog-slo'; +export * from './properties'; diff --git a/src/slos/properties.ts b/src/slos/properties.ts new file mode 100644 index 0000000..4b10616 --- /dev/null +++ b/src/slos/properties.ts @@ -0,0 +1,16 @@ +/** + * The type of the SLO + */ +export enum SLOType { + METRIC = 'metric', + MONITOR = 'monitor', +} + +/** + * The type of the Timeframe + */ +export enum TimeframeType { + SEVENDAYS = '7d', + THIRTYDAYS = '30d', + NINETYDAYS = '90d', +} diff --git a/test/__snapshots__/datadog-dashboard.test.ts.snap b/test/__snapshots__/datadog-dashboard.test.ts.snap new file mode 100644 index 0000000..0e2c004 --- /dev/null +++ b/test/__snapshots__/datadog-dashboard.test.ts.snap @@ -0,0 +1,48 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Snapshot test 1`] = ` +Object { + "Parameters": Object { + "BootstrapVersion": Object { + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]", + "Type": "AWS::SSM::Parameter::Value", + }, + }, + "Resources": Object { + "TestDashboard": Object { + "Properties": Object { + "DashboardDefinition": "{\\"title\\":\\"Example-Dashboard\\",\\"widgets\\":[{\\"definition\\":{\\"title\\":\\"Metrics HOP\\",\\"titleSize\\":\\"16\\",\\"titleAlign\\":\\"left\\",\\"showLegend\\":false,\\"type\\":\\"distribution\\",\\"customLinks\\":[{\\"label\\":\\"Example\\",\\"link\\":\\"https://example.org/\\"}],\\"xaxis\\":{\\"max\\":\\"auto\\",\\"includeZero\\":true,\\"scale\\":\\"linear\\",\\"min\\":\\"auto\\"},\\"yaxis\\":{\\"max\\":\\"auto\\",\\"includeZero\\":true,\\"scale\\":\\"linear\\",\\"min\\":\\"auto\\"},\\"requests\\":[{\\"query\\":{\\"query\\":\\"histogram:trace.Load{*}\\",\\"dataSource\\":\\"metrics\\",\\"name\\":\\"query1\\"},\\"requestType\\":\\"histogram\\",\\"style\\":{\\"palette\\":\\"dog_classic\\"}}]},\\"layout\\":{\\"x\\":0,\\"y\\":0,\\"width\\":4,\\"height\\":2}}],\\"layoutType\\":\\"ordered\\"}", + }, + "Type": "Datadog::Dashboards::Dashboard", + }, + }, + "Rules": Object { + "CheckBootstrapVersion": Object { + "Assertions": Array [ + Object { + "Assert": Object { + "Fn::Not": Array [ + Object { + "Fn::Contains": Array [ + Array [ + "1", + "2", + "3", + "4", + "5", + ], + Object { + "Ref": "BootstrapVersion", + }, + ], + }, + ], + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI.", + }, + ], + }, + }, +} +`; diff --git a/test/monitors/__snapshots__/datadog-monitor.test.ts.snap b/test/__snapshots__/datadog-monitor.test.ts.snap similarity index 100% rename from test/monitors/__snapshots__/datadog-monitor.test.ts.snap rename to test/__snapshots__/datadog-monitor.test.ts.snap diff --git a/test/__snapshots__/datadog-slo.test.ts.snap b/test/__snapshots__/datadog-slo.test.ts.snap new file mode 100644 index 0000000..566c43e --- /dev/null +++ b/test/__snapshots__/datadog-slo.test.ts.snap @@ -0,0 +1,71 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Snapshot test 1`] = ` +Object { + "Parameters": Object { + "BootstrapVersion": Object { + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]", + "Type": "AWS::SSM::Parameter::Value", + }, + }, + "Resources": Object { + "TestSLO": Object { + "Properties": Object { + "Description": "Example SLO", + "Groups": Array [ + "env:test", + "role:mysql", + ], + "Name": "Example-Service-Level-Objective", + "Query": Object { + "Denominator": "sum:httpservice.hits{!code:3xx}.as_count()", + "Numerator": "sum:httpservice.hits{code:2xx}.as_count()", + }, + "Tags": Array [ + "env:prod", + "app:core", + ], + "Thresholds": Array [ + Object { + "Target": 97, + "TargetDisplay": "97.0", + "Timeframe": "7d", + "Warning": 98, + "WarningDisplay": "98.0", + }, + ], + "Type": "metric", + }, + "Type": "Datadog::SLOs::SLO", + }, + }, + "Rules": Object { + "CheckBootstrapVersion": Object { + "Assertions": Array [ + Object { + "Assert": Object { + "Fn::Not": Array [ + Object { + "Fn::Contains": Array [ + Array [ + "1", + "2", + "3", + "4", + "5", + ], + Object { + "Ref": "BootstrapVersion", + }, + ], + }, + ], + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI.", + }, + ], + }, + }, +} +`; diff --git a/test/datadog-dashboard.test.ts b/test/datadog-dashboard.test.ts new file mode 100644 index 0000000..328509b --- /dev/null +++ b/test/datadog-dashboard.test.ts @@ -0,0 +1,63 @@ +import { Stack } from 'aws-cdk-lib'; +import { Template } from 'aws-cdk-lib/assertions'; +import { DatadogDashboard } from '../src'; + +test('Snapshot test', () => { + const stack = new Stack(); + + new DatadogDashboard(stack, 'TestDashboard', { + dashboard: { + title: 'Example-Dashboard', + widgets: [ + { + definition: { + title: 'Metrics HOP', + titleSize: '16', + titleAlign: 'left', + showLegend: false, + type: 'distribution', + customLinks: [ + { + label: 'Example', + link: 'https://example.org/', + }, + ], + xaxis: { + max: 'auto', + includeZero: true, + scale: 'linear', + min: 'auto', + }, + yaxis: { + max: 'auto', + includeZero: true, + scale: 'linear', + min: 'auto', + }, + requests: [ + { + query: { + query: 'histogram:trace.Load{*}', + dataSource: 'metrics', + name: 'query1', + }, + requestType: 'histogram', + style: { + palette: 'dog_classic', + }, + }, + ], + }, + layout: { + x: 0, + y: 0, + width: 4, + height: 2, + }, + }, + ], + layoutType: 'ordered', + }, + }); + expect(Template.fromStack(stack)).toMatchSnapshot(); +}); diff --git a/test/monitors/datadog-monitor.test.ts b/test/datadog-monitor.test.ts similarity index 90% rename from test/monitors/datadog-monitor.test.ts rename to test/datadog-monitor.test.ts index 30afd4e..b546bec 100644 --- a/test/monitors/datadog-monitor.test.ts +++ b/test/datadog-monitor.test.ts @@ -1,6 +1,6 @@ import { Stack } from 'aws-cdk-lib'; import { Template } from 'aws-cdk-lib/assertions'; -import { DatadogMonitor, MonitorType } from '../../src'; +import { DatadogMonitor, MonitorType } from '../src'; test('Snapshot test', () => { const stack = new Stack(); diff --git a/test/datadog-slo.test.ts b/test/datadog-slo.test.ts new file mode 100644 index 0000000..fa09f8e --- /dev/null +++ b/test/datadog-slo.test.ts @@ -0,0 +1,29 @@ +import { Stack } from 'aws-cdk-lib'; +import { Template } from 'aws-cdk-lib/assertions'; +import { DatadogSLO, SLOType, TimeframeType } from '../src'; + +test('Snapshot test', () => { + const stack = new Stack(); + + new DatadogSLO(stack, 'TestSLO', { + name: 'Example-Service-Level-Objective', + description: 'Example SLO', + groups: ['env:test', 'role:mysql'], + tags: ['env:prod', 'app:core'], + type: SLOType.METRIC, + query: { + denominator: 'sum:httpservice.hits{!code:3xx}.as_count()', + numerator: 'sum:httpservice.hits{code:2xx}.as_count()', + }, + thresholds: [ + { + target: 97.0, + targetDisplay: '97.0', + timeframe: TimeframeType.SEVENDAYS, + warning: 98, + warningDisplay: '98.0', + }, + ], + }); + expect(Template.fromStack(stack)).toMatchSnapshot(); +}); diff --git a/tsconfig.dev.json b/tsconfig.dev.json index 88cc2f2..a6467da 100644 --- a/tsconfig.dev.json +++ b/tsconfig.dev.json @@ -3,7 +3,7 @@ "compilerOptions": { "alwaysStrict": true, "declaration": true, - "esModuleInterop": true, + "esModuleInterop": false, "experimentalDecorators": true, "inlineSourceMap": true, "inlineSources": true, diff --git a/yarn.lock b/yarn.lock index 02af2a8..770eaaf 100644 --- a/yarn.lock +++ b/yarn.lock @@ -514,6 +514,16 @@ resolved "https://registry.yarnpkg.com/@balena/dockerignore/-/dockerignore-1.0.2.tgz#9ffe4726915251e8eb69f44ef3547e0da2c03e0d" integrity sha512-wMue2Sy4GAVTk6Ic4tJVcnfdau+gx2EnG7S+uAEe+TWJFqE4YoWN4/H8MSLj4eYJKxGg26lZwboEniNiNwZQ6Q== +"@bcherny/json-schema-ref-parser@10.0.5-fork": + version "10.0.5-fork" + resolved "https://registry.yarnpkg.com/@bcherny/json-schema-ref-parser/-/json-schema-ref-parser-10.0.5-fork.tgz#9b5e1e7e07964ea61840174098e634edbe8197bc" + integrity sha512-E/jKbPoca1tfUPj3iSbitDZTGnq6FUFjkH6L8U2oDwSuwK1WhnnVtCG7oFOTg/DDnyoXbQYUiUiGOibHqaGVnw== + dependencies: + "@jsdevtools/ono" "^7.1.3" + "@types/json-schema" "^7.0.6" + call-me-maybe "^1.0.1" + js-yaml "^4.1.0" + "@bcoe/v8-coverage@^0.2.3": version "0.2.3" resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" @@ -829,6 +839,11 @@ "@jridgewell/resolve-uri" "^3.1.0" "@jridgewell/sourcemap-codec" "^1.4.14" +"@jsdevtools/ono@^7.1.3": + version "7.1.3" + resolved "https://registry.yarnpkg.com/@jsdevtools/ono/-/ono-7.1.3.tgz#9df03bbd7c696a5c58885c34aa06da41c8543796" + integrity sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg== + "@jsii/check-node@1.42.0": version "1.42.0" resolved "https://registry.yarnpkg.com/@jsii/check-node/-/check-node-1.42.0.tgz#10dd84fbefa020344c9574079361c1a18754872a" @@ -845,13 +860,6 @@ chalk "^4.1.2" semver "^7.5.4" -"@jsii/spec@1.88.0", "@jsii/spec@^1.88.0": - version "1.88.0" - resolved "https://registry.yarnpkg.com/@jsii/spec/-/spec-1.88.0.tgz#46216d3ca93872b4d878bb81f0cc7b28dc621c28" - integrity sha512-Q6xirxPM06TRW0GcsHa+tzPZLwe9I+mFYx5BaNMimcv21u6bQnxfynZMgNhHqvLYCmP37HWg0SboUYTa5JROzw== - dependencies: - ajv "^8.12.0" - "@jsii/spec@^1.30.0", "@jsii/spec@^1.42.0": version "1.42.0" resolved "https://registry.yarnpkg.com/@jsii/spec/-/spec-1.42.0.tgz#39e787e5ac2ddc96256b73421603bc734c56f7d8" @@ -859,6 +867,13 @@ dependencies: jsonschema "^1.4.0" +"@jsii/spec@^1.88.0": + version "1.88.0" + resolved "https://registry.yarnpkg.com/@jsii/spec/-/spec-1.88.0.tgz#46216d3ca93872b4d878bb81f0cc7b28dc621c28" + integrity sha512-Q6xirxPM06TRW0GcsHa+tzPZLwe9I+mFYx5BaNMimcv21u6bQnxfynZMgNhHqvLYCmP37HWg0SboUYTa5JROzw== + dependencies: + ajv "^8.12.0" + "@nodelib/fs.scandir@2.1.5": version "2.1.5" resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" @@ -1122,13 +1137,21 @@ "@babel/parser" "^7.1.0" "@babel/types" "^7.0.0" -"@types/babel__traverse@*", "@types/babel__traverse@7.18.2", "@types/babel__traverse@^7.0.4", "@types/babel__traverse@^7.0.6": +"@types/babel__traverse@*", "@types/babel__traverse@^7.0.4", "@types/babel__traverse@^7.0.6": version "7.18.2" resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.18.2.tgz#235bf339d17185bdec25e024ca19cce257cc7309" integrity sha512-FcFaxOr2V5KZCviw1TnutEMVUVsGt4D2hP1TAfXZAMKuHYW3xQhe3jTxNPWutgCJ3/X1c5yX8ZoGVEItxKbwBg== dependencies: "@babel/types" "^7.3.0" +"@types/glob@^7.1.3": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.2.0.tgz#bc1b5bf3aa92f25bd5dd39f35c57361bdce5b2eb" + integrity sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA== + dependencies: + "@types/minimatch" "*" + "@types/node" "*" + "@types/graceful-fs@^4.1.2": version "4.1.5" resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.5.tgz#21ffba0d98da4350db64891f92a9e5db3cdb4e15" @@ -1168,7 +1191,7 @@ jest-matcher-utils "^27.0.0" pretty-format "^27.0.0" -"@types/json-schema@^7.0.9": +"@types/json-schema@^7.0.11", "@types/json-schema@^7.0.6", "@types/json-schema@^7.0.9": version "7.0.12" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.12.tgz#d70faba7039d5fca54c83c7dbab41051d2b6f6cb" integrity sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA== @@ -1178,6 +1201,16 @@ resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4= +"@types/lodash@^4.14.182": + version "4.14.197" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.197.tgz#e95c5ddcc814ec3e84c891910a01e0c8a378c54b" + integrity sha512-BMVOiWs0uNxHVlHBgzTIqJYmj+PgCo4euloGF+5m4okL3rEYzM2EEv78mw8zWSMM57dM7kVIgJ2QDvwHSoCI5g== + +"@types/minimatch@*": + version "5.1.2" + resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-5.1.2.tgz#07508b45797cb81ec3f273011b054cd0755eddca" + integrity sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA== + "@types/minimist@^1.2.0": version "1.2.2" resolved "https://registry.yarnpkg.com/@types/minimist/-/minimist-1.2.2.tgz#ee771e2ba4b3dc5b372935d549fd9617bf345b8c" @@ -1198,11 +1231,16 @@ resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz#d3357479a0fdfdd5907fe67e17e0a85c906e1301" integrity sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw== -"@types/prettier@2.6.0", "@types/prettier@^2.1.5": +"@types/prettier@^2.1.5": version "2.6.0" resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.6.0.tgz#efcbd41937f9ae7434c714ab698604822d890759" integrity sha512-G/AdOadiZhnJp0jXCaBQU449W2h716OW/EoXeYkCytxKL06X1WCXB4DZpp8TpZ8eyIJVS1cw4lrlkkSYU21cDw== +"@types/prettier@^2.6.1": + version "2.7.3" + resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.7.3.tgz#3e51a17e291d01d17d3fc61422015a933af7a08f" + integrity sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA== + "@types/semver@^7.3.12": version "7.5.1" resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.1.tgz#0480eeb7221eb9bc398ad7432c9d7e14b1a5a367" @@ -1480,6 +1518,11 @@ ansi-styles@^6.1.0: resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.1.tgz#0e62320cf99c21afff3b3012192546aacbfb05c5" integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug== +any-promise@^1.0.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f" + integrity sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A== + anymatch@^3.0.3: version "3.1.2" resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" @@ -1797,6 +1840,11 @@ call-bind@^1.0.0, call-bind@^1.0.2: function-bind "^1.1.1" get-intrinsic "^1.0.2" +call-me-maybe@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/call-me-maybe/-/call-me-maybe-1.0.2.tgz#03f964f19522ba643b1b0693acb9152fe2074baa" + integrity sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ== + callsites@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" @@ -1893,6 +1941,17 @@ cli-boxes@^3.0.0: resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-3.0.0.tgz#71a10c716feeba005e4504f36329ef0b17cf3145" integrity sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g== +cli-color@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/cli-color/-/cli-color-2.0.3.tgz#73769ba969080629670f3f2ef69a4bf4e7cc1879" + integrity sha512-OkoZnxyC4ERN3zLzZaY9Emb7f/MhBOIpePv0Ycok0fJYT+Ouo00UBEIwsVsr0yoow++n5YWlSUgST9GKhNHiRQ== + dependencies: + d "^1.0.1" + es5-ext "^0.10.61" + es6-iterator "^2.0.3" + memoizee "^0.4.15" + timers-ext "^0.1.7" + cli-table3@^0.6.3: version "0.6.3" resolved "https://registry.yarnpkg.com/cli-table3/-/cli-table3-0.6.3.tgz#61ab765aac156b52f222954ffc607a6f01dbeeb2" @@ -2276,6 +2335,14 @@ cssstyle@^2.3.0: dependencies: cssom "~0.3.6" +d@1, d@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/d/-/d-1.0.1.tgz#8698095372d58dbee346ffd0c7093f99f8f9eb5a" + integrity sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA== + dependencies: + es5-ext "^0.10.50" + type "^1.0.1" + dargs@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/dargs/-/dargs-7.0.0.tgz#04015c41de0bcb69ec84050f3d9be0caf8d6d5cc" @@ -2480,6 +2547,15 @@ dotgitignore@^2.1.0: find-up "^3.0.0" minimatch "^3.0.4" +downlevel-dts@^0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/downlevel-dts/-/downlevel-dts-0.11.0.tgz#514a2d723009c5845730c1db6c994484c596ed9c" + integrity sha512-vo835pntK7kzYStk7xUHDifiYJvXxVhUapt85uk2AI94gUUAQX9HNRtrcMHNSc3YHJUEHGbYIGsM99uIbgAtxw== + dependencies: + semver "^7.3.2" + shelljs "^0.8.3" + typescript next + eastasianwidth@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" @@ -2574,6 +2650,42 @@ es-to-primitive@^1.2.1: is-date-object "^1.0.1" is-symbol "^1.0.2" +es5-ext@^0.10.35, es5-ext@^0.10.46, es5-ext@^0.10.50, es5-ext@^0.10.53, es5-ext@^0.10.61, es5-ext@~0.10.14, es5-ext@~0.10.2, es5-ext@~0.10.46: + version "0.10.62" + resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.62.tgz#5e6adc19a6da524bf3d1e02bbc8960e5eb49a9a5" + integrity sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA== + dependencies: + es6-iterator "^2.0.3" + es6-symbol "^3.1.3" + next-tick "^1.1.0" + +es6-iterator@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7" + integrity sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g== + dependencies: + d "1" + es5-ext "^0.10.35" + es6-symbol "^3.1.1" + +es6-symbol@^3.1.1, es6-symbol@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.3.tgz#bad5d3c1bcdac28269f4cb331e431c78ac705d18" + integrity sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA== + dependencies: + d "^1.0.1" + ext "^1.1.2" + +es6-weak-map@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/es6-weak-map/-/es6-weak-map-2.0.3.tgz#b6da1f16cc2cc0d9be43e6bdbfc5e7dfcdf31d53" + integrity sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA== + dependencies: + d "1" + es5-ext "^0.10.46" + es6-iterator "^2.0.3" + es6-symbol "^3.1.1" + escalade@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" @@ -2765,6 +2877,14 @@ esutils@^2.0.2: resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== +event-emitter@^0.3.5: + version "0.3.5" + resolved "https://registry.yarnpkg.com/event-emitter/-/event-emitter-0.3.5.tgz#df8c69eef1647923c7157b9ce83840610b02cc39" + integrity sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA== + dependencies: + d "1" + es5-ext "~0.10.14" + execa@^5.0.0: version "5.1.1" resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" @@ -2800,6 +2920,13 @@ exponential-backoff@^3.1.1: resolved "https://registry.yarnpkg.com/exponential-backoff/-/exponential-backoff-3.1.1.tgz#64ac7526fe341ab18a39016cd22c787d01e00bf6" integrity sha512-dX7e/LHVJ6W3DE1MHWi9S1EYzDESENfLrYohG2G++ovZrYOkm4Knwa0mc1cn84xJOR4KEU0WSchhLbd0UklbHw== +ext@^1.1.2: + version "1.7.0" + resolved "https://registry.yarnpkg.com/ext/-/ext-1.7.0.tgz#0ea4383c0103d60e70be99e9a7f11027a33c4f5f" + integrity sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw== + dependencies: + type "^2.7.2" + fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" @@ -3149,6 +3276,13 @@ glob-parent@^6.0.2: dependencies: is-glob "^4.0.3" +glob-promise@^4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/glob-promise/-/glob-promise-4.2.2.tgz#15f44bcba0e14219cd93af36da6bb905ff007877" + integrity sha512-xcUzJ8NWN5bktoTIX7eOclO1Npxd/dyVqUJxlLIDasT4C7KZyqlPIwkdJ0Ypiy3p2ZKahTjK4M9uC3sNSfNMzw== + dependencies: + "@types/glob" "^7.1.3" + glob@^10.2.2, glob@^10.2.5: version "10.3.3" resolved "https://registry.yarnpkg.com/glob/-/glob-10.3.3.tgz#8360a4ffdd6ed90df84aa8d52f21f452e86a123b" @@ -3172,6 +3306,18 @@ glob@^7.0.0, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.7: once "^1.3.0" path-is-absolute "^1.0.0" +glob@^7.1.6: + version "7.2.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" + integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.1.1" + once "^1.3.0" + path-is-absolute "^1.0.0" + glob@^8: version "8.1.0" resolved "https://registry.yarnpkg.com/glob/-/glob-8.1.0.tgz#d388f656593ef708ee3e34640fdfb99a9fd1c33e" @@ -3657,6 +3803,11 @@ is-potential-custom-element-name@^1.0.1: resolved "https://registry.yarnpkg.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz#171ed6f19e3ac554394edf78caa05784a45bebb5" integrity sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ== +is-promise@^2.2.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.2.2.tgz#39ab959ccbf9a774cf079f7b40c7a26f763135f1" + integrity sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ== + is-regex@^1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" @@ -4328,24 +4479,6 @@ jsii-reflect@^1.88.0: oo-ascii-tree "^1.88.0" yargs "^16.2.0" -jsii-rosetta@1.x: - version "1.88.0" - resolved "https://registry.yarnpkg.com/jsii-rosetta/-/jsii-rosetta-1.88.0.tgz#1189fb2aa538082d3099b104e2d51daf2cf485e7" - integrity sha512-6xRRkwWUKFqDTnjgCXkB6v9dxA51KUD4Cd7InLB4qirMBDuMtyYhYVNc1yJbHPYs9gkN5/ao0dFk+1CQxt7T7g== - dependencies: - "@jsii/check-node" "1.88.0" - "@jsii/spec" "1.88.0" - "@xmldom/xmldom" "^0.8.10" - commonmark "^0.30.0" - fast-glob "^3.3.1" - jsii "1.88.0" - semver "^7.5.4" - semver-intersect "^1.4.0" - stream-json "^1.8.0" - typescript "~3.9.10" - workerpool "^6.4.2" - yargs "^16.2.0" - jsii-rosetta@^1.42.0: version "1.42.0" resolved "https://registry.yarnpkg.com/jsii-rosetta/-/jsii-rosetta-1.42.0.tgz#84f80a91446b0a6e4ed8c981b1807eb7fce0b79e" @@ -4361,24 +4494,43 @@ jsii-rosetta@^1.42.0: workerpool "^6.1.5" yargs "^16.2.0" -jsii@1.88.0, jsii@1.x: - version "1.88.0" - resolved "https://registry.yarnpkg.com/jsii/-/jsii-1.88.0.tgz#f8b56420d47c6230dafb5d78a601bd5696e4f69c" - integrity sha512-WKfwHbcEI/j5OYDPexvkH8KKDcTZR7tIBFNTxu8h1Nh3G8xFT4hh3pObUUSMRCa6rsSF9EHGjS+AKC+TfpFGrQ== +jsii-rosetta@~5.0.0: + version "5.0.21" + resolved "https://registry.yarnpkg.com/jsii-rosetta/-/jsii-rosetta-5.0.21.tgz#22a3ef2163ef9b2b3946a9c164d2a6d6bfaddb44" + integrity sha512-R3WSE49/9/ReybESyqn9hAQPfZN+uPY4iNO5Kuk1b6z9El8R558MXlT3xvxu3huwJs+lUmQcNWVFXNqEcXL+vQ== + dependencies: + "@jsii/check-node" "1.88.0" + "@jsii/spec" "^1.88.0" + "@xmldom/xmldom" "^0.8.10" + chalk "^4" + commonmark "^0.30.0" + fast-glob "^3.3.1" + jsii "~5.0.5" + semver "^7.5.4" + semver-intersect "^1.4.0" + stream-json "^1.8.0" + typescript "~5.0.4" + workerpool "^6.4.2" + yargs "^17.7.2" + +jsii@~5.0.0, jsii@~5.0.5: + version "5.0.21" + resolved "https://registry.yarnpkg.com/jsii/-/jsii-5.0.21.tgz#442ba19cc72be9c7285802decca6f5fa1b3d8219" + integrity sha512-m5WEKKnER9veGrJNxr5OULu43D6DSe69RmKgQjTSHLEKSCS+taCf32sFmBT/b3nBcSh1gfch7QfjoHKoKpUz2w== dependencies: "@jsii/check-node" "1.88.0" "@jsii/spec" "^1.88.0" case "^1.6.3" chalk "^4" + downlevel-dts "^0.11.0" fast-deep-equal "^3.1.3" - fs-extra "^10.1.0" log4js "^6.9.1" semver "^7.5.4" semver-intersect "^1.4.0" sort-json "^2.0.1" spdx-license-list "^6.6.0" - typescript "~3.9.10" - yargs "^16.2.0" + typescript "~5.0.4" + yargs "^17.7.2" json-buffer@3.0.1: version "3.0.1" @@ -4407,6 +4559,26 @@ json-parse-helpfulerror@^1.0.3: dependencies: jju "^1.1.0" +json-schema-to-typescript@^13.1.1: + version "13.1.1" + resolved "https://registry.yarnpkg.com/json-schema-to-typescript/-/json-schema-to-typescript-13.1.1.tgz#8d1b28f93530d3b57730ee7272eec8e4400238e9" + integrity sha512-F3CYhtA7F3yPbb8vF7sFchk/2dnr1/yTKf8RcvoNpjnh67ZS/ZMH1ElLt5KHAtf2/bymiejLQQszszPWEeTdSw== + dependencies: + "@bcherny/json-schema-ref-parser" "10.0.5-fork" + "@types/json-schema" "^7.0.11" + "@types/lodash" "^4.14.182" + "@types/prettier" "^2.6.1" + cli-color "^2.0.2" + get-stdin "^8.0.0" + glob "^7.1.6" + glob-promise "^4.2.2" + is-glob "^4.0.3" + lodash "^4.17.21" + minimist "^1.2.6" + mkdirp "^1.0.4" + mz "^2.7.0" + prettier "^2.6.2" + json-schema-traverse@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" @@ -4642,6 +4814,13 @@ lru-cache@^7.4.4, lru-cache@^7.5.1, lru-cache@^7.7.1: resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.0.1.tgz#0a3be479df549cca0e5d693ac402ff19537a6b7a" integrity sha512-IJ4uwUTi2qCccrioU6g9g/5rvvVl13bsdczUUcqbciD9iLr095yj8DQKdObriEvuNSx325N1rV1O0sJFszx75g== +lru-queue@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/lru-queue/-/lru-queue-0.1.0.tgz#2738bd9f0d3cf4f84490c5736c48699ac632cda3" + integrity sha512-BpdYkt9EvGl8OfWHDQPISVpcl5xZthb+XPsbELj5AQXxIC8IriDZIQYjBJPEm5rS420sjZ0TLEzRcq5KdBhYrQ== + dependencies: + es5-ext "~0.10.2" + make-dir@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" @@ -4697,6 +4876,20 @@ mdurl@~1.0.1: resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e" integrity sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4= +memoizee@^0.4.15: + version "0.4.15" + resolved "https://registry.yarnpkg.com/memoizee/-/memoizee-0.4.15.tgz#e6f3d2da863f318d02225391829a6c5956555b72" + integrity sha512-UBWmJpLZd5STPm7PMUlOw/TSy972M+z8gcyQ5veOnSDRREz/0bmpyTfKt3/51DhEBqCZQn1udM/5flcSPYhkdQ== + dependencies: + d "^1.0.1" + es5-ext "^0.10.53" + es6-weak-map "^2.0.3" + event-emitter "^0.3.5" + is-promise "^2.2.2" + lru-queue "^0.1.0" + next-tick "^1.1.0" + timers-ext "^0.1.7" + meow@^8.0.0: version "8.1.2" resolved "https://registry.yarnpkg.com/meow/-/meow-8.1.2.tgz#bcbe45bda0ee1729d350c03cffc8395a36c4e897" @@ -4771,7 +4964,7 @@ minimatch@^3.0.4: dependencies: brace-expansion "^1.1.7" -minimatch@^3.0.5, minimatch@^3.1.2: +minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== @@ -4806,6 +4999,11 @@ minimist@>=1.2.2, minimist@^1.2.0, minimist@^1.2.3, minimist@^1.2.5: resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== +minimist@^1.2.6: + version "1.2.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" + integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== + minipass-collect@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/minipass-collect/-/minipass-collect-1.0.2.tgz#22b813bf745dc6edba2576b940022ad6edc8c617" @@ -4903,6 +5101,15 @@ ms@^2.0.0, ms@^2.1.1: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== +mz@^2.7.0: + version "2.7.0" + resolved "https://registry.yarnpkg.com/mz/-/mz-2.7.0.tgz#95008057a56cafadc2bc63dde7f9ff6955948e32" + integrity sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q== + dependencies: + any-promise "^1.0.0" + object-assign "^4.0.1" + thenify-all "^1.0.0" + natural-compare-lite@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz#17b09581988979fddafe0201e931ba933c96cbb4" @@ -4923,6 +5130,11 @@ neo-async@^2.6.0: resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== +next-tick@1, next-tick@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.1.0.tgz#1836ee30ad56d67ef281b22bd199f709449b35eb" + integrity sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ== + node-gyp@^9.0.0: version "9.4.0" resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-9.4.0.tgz#2a7a91c7cba4eccfd95e949369f27c9ba704f369" @@ -5125,6 +5337,11 @@ nwsapi@^2.2.0: resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.0.tgz#204879a9e3d068ff2a55139c2c772780681a38b7" integrity sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ== +object-assign@^4.0.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== + object-inspect@^1.11.0, object-inspect@^1.9.0: version "1.11.0" resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.11.0.tgz#9dceb146cedd4148a0d9e51ab88d34cf509922b1" @@ -5441,6 +5658,11 @@ prettier@^2.4.1: resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.4.1.tgz#671e11c89c14a4cfc876ce564106c4a6726c9f5c" integrity sha512-9fbDAXSBcc6Bs1mZrDYb3XKzDLm4EXXL9sC1LqKP5rZkT6KRr/rf9amVUcODVXgguK/isJz0d0hP72WeaKWsvA== +prettier@^2.6.2: + version "2.8.8" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.8.tgz#e8c5d7e98a4305ffe3de2e1fc4aca1a71c28b1da" + integrity sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q== + pretty-format@^27.0.0, pretty-format@^27.5.1: version "27.5.1" resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-27.5.1.tgz#2181879fdea51a7a5851fb39d920faa63f01d88e" @@ -5884,7 +6106,7 @@ shebang-regex@^3.0.0: resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== -shelljs@^0.8.5: +shelljs@^0.8.3, shelljs@^0.8.5: version "0.8.5" resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.8.5.tgz#de055408d8361bed66c669d2f000538ced8ee20c" integrity sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow== @@ -6345,6 +6567,20 @@ text-table@^0.2.0: resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= +thenify-all@^1.0.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/thenify-all/-/thenify-all-1.6.0.tgz#1a1918d402d8fc3f98fbf234db0bcc8cc10e9726" + integrity sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA== + dependencies: + thenify ">= 3.1.0 < 4" + +"thenify@>= 3.1.0 < 4": + version "3.3.1" + resolved "https://registry.yarnpkg.com/thenify/-/thenify-3.3.1.tgz#8932e686a4066038a016dd9e2ca46add9838a95f" + integrity sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw== + dependencies: + any-promise "^1.0.0" + throat@^6.0.1: version "6.0.2" resolved "https://registry.yarnpkg.com/throat/-/throat-6.0.2.tgz#51a3fbb5e11ae72e2cf74861ed5c8020f89f29fe" @@ -6370,6 +6606,14 @@ through@2, "through@>=2.2.7 <3": resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= +timers-ext@^0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/timers-ext/-/timers-ext-0.1.7.tgz#6f57ad8578e07a3fb9f91d9387d65647555e25c6" + integrity sha512-b85NUNzTSdodShTIbky6ZF02e8STtVVfD+fu4aXXShEELpozH+bCpJLYMPZbsABN2wDH7fJpqIoXxJpzbf0NqQ== + dependencies: + es5-ext "~0.10.46" + next-tick "1" + tmpl@1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.5.tgz#8683e0b902bb9c20c4f726e3c0b69f36518c07cc" @@ -6526,6 +6770,16 @@ type-fest@^2.13.0: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-2.19.0.tgz#88068015bb33036a598b952e55e9311a60fd3a9b" integrity sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA== +type@^1.0.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/type/-/type-1.2.0.tgz#848dd7698dafa3e54a6c479e759c4bc3f18847a0" + integrity sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg== + +type@^2.7.2: + version "2.7.2" + resolved "https://registry.yarnpkg.com/type/-/type-2.7.2.tgz#2376a15a3a28b1efa0f5350dcf72d24df6ef98d0" + integrity sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw== + typedarray-to-buffer@^3.1.5: version "3.1.5" resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" @@ -6543,11 +6797,21 @@ typescript@^4.4.4: resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.4.4.tgz#2cd01a1a1f160704d3101fd5a58ff0f9fcb8030c" integrity sha512-DqGhF5IKoBl8WNf8C1gu8q0xZSInh9j1kJJMqT3a94w1JzVaBU4EXOSMrz9yDqMT0xt3selp83fuFMQ0uzv6qA== +typescript@next: + version "5.3.0-dev.20230902" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.3.0-dev.20230902.tgz#c27fe5baf87059ce3aee6fa69c4e4295c4aa7bf2" + integrity sha512-Ip28siJUrn+uiMBdppvNJrsuVs7yVJY4t//Vtn91JTaGvtqgrqYP14pxyL93HHfnXsKlPHyQLG6hC8oYLDEN6g== + typescript@~3.9.10: version "3.9.10" resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.9.10.tgz#70f3910ac7a51ed6bef79da7800690b19bf778b8" integrity sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q== +typescript@~5.0.4: + version "5.0.4" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.0.4.tgz#b217fd20119bd61a94d4011274e0ab369058da3b" + integrity sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw== + uglify-js@^3.1.4: version "3.14.3" resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.14.3.tgz#c0f25dfea1e8e5323eccf59610be08b6043c15cf" From 4a2828afda119e44293726ec6cd0270b1fe3b1b8 Mon Sep 17 00:00:00 2001 From: Vincent De Smet Date: Wed, 6 Sep 2023 13:16:53 +0700 Subject: [PATCH 3/3] Fix prettier eslint integration existing prettier config was broken, removed manual prettier config in favor of projen managed config --- .eslintrc.json | 102 +- .gitattributes | 2 + .gitignore | 2 + .prettierignore | 8 +- .prettierrc | 5 - .prettierrc.json | 3 + .projen/deps.json | 12 + .projen/files.json | 2 + .projen/tasks.json | 10 + .projenrc.ts | 76 +- .vscode/settings.json | 46 +- package.json | 11 +- projenrc/datadog-dashboard-generator.ts | 12 +- projenrc/datadog-monitor-generator.ts | 30 +- projenrc/datadog-slo-generator.ts | 14 +- projenrc/index.ts | 8 +- projenrc/json-schema-base.ts | 53 +- projenrc/parse-json.ts | 43 + src/dashboards/datadog-dashboard.ts | 15 +- src/dashboards/index.ts | 6 +- src/index.ts | 6 +- src/monitors/datadog-monitor.ts | 10 +- src/monitors/index.ts | 6 +- src/monitors/properties.ts | 33 +- src/slos/datadog-slo.ts | 10 +- src/slos/index.ts | 6 +- src/slos/properties.ts | 10 +- src/util.ts | 20 + .../datadog-dashboard.test.ts.snap | 2 +- test/datadog-dashboard.test.ts | 2255 +++++++++++++++- test/datadog-monitor.test.ts | 14 +- test/datadog-slo.test.ts | 26 +- test/fixtures/.gitignore | 1 + test/fixtures/argocd-dashboard.json | 2380 +++++++++++++++++ version.json | 3 - yarn.lock | 215 +- 36 files changed, 5170 insertions(+), 287 deletions(-) delete mode 100644 .prettierrc create mode 100644 .prettierrc.json create mode 100644 projenrc/parse-json.ts create mode 100644 src/util.ts create mode 100644 test/fixtures/.gitignore create mode 100644 test/fixtures/argocd-dashboard.json delete mode 100644 version.json diff --git a/.eslintrc.json b/.eslintrc.json index d741455..fb2b2de 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -7,7 +7,8 @@ "root": true, "plugins": [ "@typescript-eslint", - "import" + "import", + "prettier" ], "parser": "@typescript-eslint/parser", "parserOptions": { @@ -16,7 +17,9 @@ "project": "./tsconfig.dev.json" }, "extends": [ - "plugin:import/typescript" + "plugin:import/typescript", + "prettier", + "plugin:prettier/recommended" ], "settings": { "import/parsers": { @@ -43,102 +46,9 @@ "!projenrc/**/*.ts" ], "rules": { - "indent": [ - "off" - ], - "@typescript-eslint/indent": [ - "error", - 2 - ], - "quotes": [ - "error", - "single", - { - "avoidEscape": true - } - ], - "comma-dangle": [ - "error", - "always-multiline" - ], - "comma-spacing": [ - "error", - { - "before": false, - "after": true - } - ], - "no-multi-spaces": [ - "error", - { - "ignoreEOLComments": false - } - ], - "array-bracket-spacing": [ - "error", - "never" - ], - "array-bracket-newline": [ - "error", - "consistent" - ], - "object-curly-spacing": [ - "error", - "always" - ], - "object-curly-newline": [ - "error", - { - "multiline": true, - "consistent": true - } - ], - "object-property-newline": [ - "error", - { - "allowAllPropertiesOnSameLine": true - } - ], - "keyword-spacing": [ - "error" - ], - "brace-style": [ - "error", - "1tbs", - { - "allowSingleLine": true - } - ], - "space-before-blocks": [ + "prettier/prettier": [ "error" ], - "curly": [ - "error", - "multi-line", - "consistent" - ], - "@typescript-eslint/member-delimiter-style": [ - "error" - ], - "semi": [ - "error", - "always" - ], - "max-len": [ - "error", - { - "code": 150, - "ignoreUrls": true, - "ignoreStrings": true, - "ignoreTemplateLiterals": true, - "ignoreComments": true, - "ignoreRegExpLiterals": true - } - ], - "quote-props": [ - "error", - "consistent-as-needed" - ], "@typescript-eslint/no-require-imports": [ "error" ], diff --git a/.gitattributes b/.gitattributes index e4a73cf..f9342b9 100644 --- a/.gitattributes +++ b/.gitattributes @@ -12,6 +12,8 @@ /.mergify.yml linguist-generated /.npmignore linguist-generated /.npmrc linguist-generated +/.prettierignore linguist-generated +/.prettierrc.json linguist-generated /.projen/** linguist-generated /.projen/deps.json linguist-generated /.projen/files.json linguist-generated diff --git a/.gitignore b/.gitignore index 2602080..09d6994 100644 --- a/.gitignore +++ b/.gitignore @@ -42,6 +42,8 @@ junit.xml !/.mergify.yml !/.github/workflows/upgrade-master.yml !/.github/pull_request_template.md +!/.prettierignore +!/.prettierrc.json !/.npmrc !/test/ !/tsconfig.dev.json diff --git a/.prettierignore b/.prettierignore index df02f8d..3385eb8 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,7 +1 @@ -.eslintrc.json -.github/pull_request_template.md -.projen/tasks.json -.versionrc.json -tsconfig.jest.json -.projenrc.js -package.json +# ~~ Generated by projen. To modify, edit .projenrc.ts and run "npx projen". diff --git a/.prettierrc b/.prettierrc deleted file mode 100644 index 5d40fd8..0000000 --- a/.prettierrc +++ /dev/null @@ -1,5 +0,0 @@ -{ - "printWidth": 120, - "tabWidth": 2, - "singleQuote": true -} diff --git a/.prettierrc.json b/.prettierrc.json new file mode 100644 index 0000000..84c85a3 --- /dev/null +++ b/.prettierrc.json @@ -0,0 +1,3 @@ +{ + "overrides": [] +} diff --git a/.projen/deps.json b/.projen/deps.json index 867e474..6a39e87 100644 --- a/.projen/deps.json +++ b/.projen/deps.json @@ -34,6 +34,10 @@ "version": "10.2.69", "type": "build" }, + { + "name": "eslint-config-prettier", + "type": "build" + }, { "name": "eslint-import-resolver-node", "type": "build" @@ -46,6 +50,10 @@ "name": "eslint-plugin-import", "type": "build" }, + { + "name": "eslint-plugin-prettier", + "type": "build" + }, { "name": "eslint", "version": "^8", @@ -120,6 +128,10 @@ "name": "camelcase-keys", "type": "bundled" }, + { + "name": "decamelize", + "type": "bundled" + }, { "name": "aws-cdk-lib", "version": "^2.92.0", diff --git a/.projen/files.json b/.projen/files.json index 8baca03..7b62162 100644 --- a/.projen/files.json +++ b/.projen/files.json @@ -10,6 +10,8 @@ ".gitignore", ".mergify.yml", ".npmrc", + ".prettierignore", + ".prettierrc.json", ".projen/deps.json", ".projen/files.json", ".projen/tasks.json", diff --git a/.projen/tasks.json b/.projen/tasks.json index 30673f1..402e45b 100644 --- a/.projen/tasks.json +++ b/.projen/tasks.json @@ -170,6 +170,16 @@ } ] }, + "parse-json": { + "name": "parse-json", + "description": "Parse a DataDog json file into DataDog Typescript compatible json", + "steps": [ + { + "exec": "ts-node projenrc/parse-json.ts", + "receiveArgs": true + } + ] + }, "post-compile": { "name": "post-compile", "description": "Runs after successful compilation", diff --git a/.projenrc.ts b/.projenrc.ts index 2e1c87e..514bcda 100644 --- a/.projenrc.ts +++ b/.projenrc.ts @@ -1,73 +1,91 @@ -import * as path from 'path'; -import { javascript, JsonPatch } from 'projen'; -import { AwsCdkConstructLibrary } from 'projen/lib/awscdk'; +import * as path from "path"; +import { javascript, JsonPatch } from "projen"; +import { AwsCdkConstructLibrary } from "projen/lib/awscdk"; import { DataDogMonitorSchemaGenerator, DataDogDashboardSchemaGenerator, DataDogSLOSchemaGenerator, PATCHERS, -} from './projenrc'; +} from "./projenrc"; const project = new AwsCdkConstructLibrary({ - author: 'Gabriel Fürstenheim', - authorAddress: 'gabriel.f@goodnotes.com', - cdkVersion: '2.92.0', - defaultReleaseBranch: 'master', - name: '@goodnotes-oss/cdk-datadog-resources', - repositoryUrl: 'https://github.com/GoodNotes/cdk-datadog-resources.git', + author: "Gabriel Fürstenheim", + authorAddress: "gabriel.f@goodnotes.com", + cdkVersion: "2.92.0", + defaultReleaseBranch: "master", + name: "@goodnotes-oss/cdk-datadog-resources", + repositoryUrl: "https://github.com/GoodNotes/cdk-datadog-resources.git", projenrcTs: true, /* AwsCdkConstructLibraryOptions */ - constructsVersion: '10.2.69', - jsiiVersion: '~5.0.0', - peerDeps: ['aws-cdk-lib@2.92.0'], - bundledDeps: ['camelcase-keys'], - devDeps: ['prettier', 'aws-cdk@2.93.0', 'aws-cdk-lib@2.92.0', 'json-schema-to-typescript'], + constructsVersion: "10.2.69", + jsiiVersion: "~5.0.0", + peerDeps: ["aws-cdk-lib@2.92.0"], + bundledDeps: ["camelcase-keys", "decamelize"], + devDeps: [ + "aws-cdk@2.93.0", + "aws-cdk-lib@2.92.0", + "json-schema-to-typescript", + ], npmAccess: javascript.NpmAccess.PUBLIC, - gitignore: ['cdk.out/'], + gitignore: ["cdk.out/"], + prettier: true, }); // JSII sets this to `false` so we need to be compatible -const tsConfigDev = project.tryFindObjectFile('tsconfig.dev.json'); -tsConfigDev?.patch(JsonPatch.replace('/compilerOptions/esModuleInterop', false)); +const tsConfigDev = project.tryFindObjectFile("tsconfig.dev.json"); +tsConfigDev?.patch( + JsonPatch.replace("/compilerOptions/esModuleInterop", false), +); // docgen is currently the only task of post-compile and it fails for aws-cdk-lib in jsii // https://github.com/cdklabs/jsii-docgen/issues/1122 -const docgen = project.tasks.tryFind('docgen'); +const docgen = project.tasks.tryFind("docgen"); if (docgen) docgen.reset(); -const schemaDir = 'cf-schema'; +const schemaDir = "cf-schema"; const monitorProps = new DataDogMonitorSchemaGenerator( project, - path.join(project.srcdir, 'monitors', 'datadog-monitor-schema.generated.ts'), + path.join(project.srcdir, "monitors", "datadog-monitor-schema.generated.ts"), { - filePath: path.join(schemaDir, 'datadog-monitor-4.6.0.json'), + filePath: path.join(schemaDir, "datadog-monitor-4.6.0.json"), }, ); const dashboardProps = new DataDogDashboardSchemaGenerator( project, - path.join(project.srcdir, 'dashboards', 'datadog-dashboard-schema.generated.ts'), + path.join( + project.srcdir, + "dashboards", + "datadog-dashboard-schema.generated.ts", + ), { - filePath: path.join(schemaDir, 'datadog-dashboard-2.1.0.json'), + filePath: path.join(schemaDir, "datadog-dashboard-2.1.0.json"), }, ); const sloProps = new DataDogSLOSchemaGenerator( project, - path.join(project.srcdir, 'slos', 'datadog-slo-schema.generated.ts'), + path.join(project.srcdir, "slos", "datadog-slo-schema.generated.ts"), { - filePath: path.join(schemaDir, 'datadog-slo-1.1.0.json'), + filePath: path.join(schemaDir, "datadog-slo-1.1.0.json"), }, ); +project.addTask("parse-json", { + exec: "ts-node projenrc/parse-json.ts", + description: + "Parse a DataDog json file into DataDog Typescript compatible json", + receiveArgs: true, +}); + // call all Json Schema generators async, then synth void Promise.all([ - monitorProps.generate('DatadogMonitorProps', PATCHERS.readonlyFields), - dashboardProps.generate('DatadogDashboardProps', PATCHERS.readonlyFields), - sloProps.generate('DatadogSLOProps', PATCHERS.readonlyFields), + monitorProps.generate("DatadogMonitorProps", PATCHERS.readonlyFields), + dashboardProps.generate("DatadogDashboardProps", PATCHERS.readonlyFields), + sloProps.generate("DatadogSLOProps", PATCHERS.readonlyFields), ]).then(() => { project.synth(); }); diff --git a/.vscode/settings.json b/.vscode/settings.json index e70c51e..f01df42 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,19 +1,63 @@ { "cSpell.words": [ + "accountservice", + "applicationservice", + "argocd", + "autoscale", "awscdk", + "Blogpost", + "burndown", "camelcase", + "clusterservice", + "cobertura", + "compat", + "decamelize", "docgen", "Fürstenheim", + "geomap", + "Geomap", + "goodnotes", + "goroutines", + "Goroutines", + "hostmap", "httpservice", "jsii", + "JSII", + "lcov", + "logset", + "memstats", "NINETYDAYS", + "outdir", + "pacmak", + "projen", "projenrc", + "repositoryservice", + "scatterplot", + "Scatterplot", + "screenboard", + "servicemap", + "sessionservice", + "settingsservice", "SEVENDAYS", "slos", "srcdir", "THIRTYDAYS", + "timeframe", "Timeframe", + "timeframes", + "timeseries", + "Timeseries", + "toplist", + "Toplist", + "treemap", + "tsbuildinfo", + "unbump", + "unioned", + "versionservice", + "workqueue", + "Workqueue", "xaxis", - "yaxis" + "yaxis", + "Yaxis", ] } diff --git a/package.json b/package.json index 09918dd..873a7a0 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,7 @@ "package": "npx projen package", "package-all": "npx projen package-all", "package:js": "npx projen package:js", + "parse-json": "npx projen parse-json", "post-compile": "npx projen post-compile", "post-upgrade": "npx projen post-upgrade", "pre-compile": "npx projen pre-compile", @@ -42,9 +43,11 @@ "aws-cdk-lib": "2.92.0", "constructs": "10.2.69", "eslint": "^8", + "eslint-config-prettier": "^9.0.0", "eslint-import-resolver-node": "^0.3.6", "eslint-import-resolver-typescript": "^2.5.0", "eslint-plugin-import": "^2.25.2", + "eslint-plugin-prettier": "^5.0.0", "jest": "^27", "jest-junit": "^15", "jsii": "~5.0.0", @@ -54,7 +57,7 @@ "jsii-rosetta": "~5.0.0", "json-schema-to-typescript": "^13.1.1", "npm-check-updates": "^16", - "prettier": "^2.4.1", + "prettier": "^3.0.0", "projen": "0.71.128", "standard-version": "^9", "ts-jest": "^27", @@ -66,10 +69,12 @@ "constructs": "^10.2.69" }, "dependencies": { - "camelcase-keys": "^6.2.2" + "camelcase-keys": "^6.2.2", + "decamelize": "^5.0.1" }, "bundledDependencies": [ - "camelcase-keys" + "camelcase-keys", + "decamelize" ], "keywords": [ "cdk" diff --git a/projenrc/datadog-dashboard-generator.ts b/projenrc/datadog-dashboard-generator.ts index a0d0ead..9f66854 100644 --- a/projenrc/datadog-dashboard-generator.ts +++ b/projenrc/datadog-dashboard-generator.ts @@ -1,6 +1,6 @@ -import * as camelcaseKeys from 'camelcase-keys'; -import { Project } from 'projen'; -import { JsonSchemaBase, JsonSchemaBaseOptions } from './json-schema-base'; +import * as camelcaseKeys from "camelcase-keys"; +import { Project } from "projen"; +import { JsonSchemaBase, JsonSchemaBaseOptions } from "./json-schema-base"; export class DataDogDashboardSchemaGenerator extends JsonSchemaBase { /** @@ -10,7 +10,11 @@ export class DataDogDashboardSchemaGenerator extends JsonSchemaBase { * @param filePath File path from project root * @param options Options */ - constructor(project: Project, filePath: string, options: JsonSchemaBaseOptions) { + constructor( + project: Project, + filePath: string, + options: JsonSchemaBaseOptions, + ) { super(project, filePath, options); // JSII requires all properties to be camelCase const convertedSchema = camelcaseKeys(this.schema, { diff --git a/projenrc/datadog-monitor-generator.ts b/projenrc/datadog-monitor-generator.ts index 7e8c668..49ddc5b 100644 --- a/projenrc/datadog-monitor-generator.ts +++ b/projenrc/datadog-monitor-generator.ts @@ -1,6 +1,6 @@ -import * as camelcaseKeys from 'camelcase-keys'; -import { Project } from 'projen'; -import { JsonSchemaBase, JsonSchemaBaseOptions } from './json-schema-base'; +import * as camelcaseKeys from "camelcase-keys"; +import { Project } from "projen"; +import { JsonSchemaBase, JsonSchemaBaseOptions } from "./json-schema-base"; export class DataDogMonitorSchemaGenerator extends JsonSchemaBase { /** @@ -10,11 +10,27 @@ export class DataDogMonitorSchemaGenerator extends JsonSchemaBase { * @param filePath File path from project root * @param options Options */ - constructor(project: Project, filePath: string, options: JsonSchemaBaseOptions) { + constructor( + project: Project, + filePath: string, + options: JsonSchemaBaseOptions, + ) { super(project, filePath, options); - this.moveDeclarationToType(this.schema, 'MonitorFormulaAndFunctionEventQueryGroupBy', 'Sort'); - this.moveDeclarationToType(this.schema, 'MonitorFormulaAndFunctionEventQueryDefinition', 'Search'); - this.moveDeclarationToType(this.schema, 'MonitorFormulaAndFunctionEventQueryDefinition', 'Compute'); + this.moveDeclarationToType( + this.schema, + "MonitorFormulaAndFunctionEventQueryGroupBy", + "Sort", + ); + this.moveDeclarationToType( + this.schema, + "MonitorFormulaAndFunctionEventQueryDefinition", + "Search", + ); + this.moveDeclarationToType( + this.schema, + "MonitorFormulaAndFunctionEventQueryDefinition", + "Compute", + ); // JSII requires all properties to be camelCase const convertedSchema = camelcaseKeys(this.schema, { diff --git a/projenrc/datadog-slo-generator.ts b/projenrc/datadog-slo-generator.ts index ea04829..ce46761 100644 --- a/projenrc/datadog-slo-generator.ts +++ b/projenrc/datadog-slo-generator.ts @@ -1,6 +1,6 @@ -import * as camelcaseKeys from 'camelcase-keys'; -import { Project } from 'projen'; -import { JsonSchemaBase, JsonSchemaBaseOptions } from './json-schema-base'; +import * as camelcaseKeys from "camelcase-keys"; +import { Project } from "projen"; +import { JsonSchemaBase, JsonSchemaBaseOptions } from "./json-schema-base"; export class DataDogSLOSchemaGenerator extends JsonSchemaBase { /** @@ -10,12 +10,16 @@ export class DataDogSLOSchemaGenerator extends JsonSchemaBase { * @param filePath File path from project root * @param options Options */ - constructor(project: Project, filePath: string, options: JsonSchemaBaseOptions) { + constructor( + project: Project, + filePath: string, + options: JsonSchemaBaseOptions, + ) { super(project, filePath, options); // Avoid conflict with Monitor.Creator ///TODO: It's the same type... find a better way to handle this? - this.renameDeclaration(this.schema, 'Creator', 'Creator', 'SloCreator'); + this.renameDeclaration(this.schema, "Creator", "Creator", "SloCreator"); // JSII requires all properties to be camelCase const convertedSchema = camelcaseKeys(this.schema, { diff --git a/projenrc/index.ts b/projenrc/index.ts index d3a8f50..54f4831 100644 --- a/projenrc/index.ts +++ b/projenrc/index.ts @@ -1,4 +1,4 @@ -export * from './json-schema-base'; -export * from './datadog-monitor-generator'; -export * from './datadog-dashboard-generator'; -export * from './datadog-slo-generator'; +export * from "./json-schema-base"; +export * from "./datadog-monitor-generator"; +export * from "./datadog-dashboard-generator"; +export * from "./datadog-slo-generator"; diff --git a/projenrc/json-schema-base.ts b/projenrc/json-schema-base.ts index 9e8136e..f0b6290 100644 --- a/projenrc/json-schema-base.ts +++ b/projenrc/json-schema-base.ts @@ -1,6 +1,6 @@ -import * as fs from 'fs'; -import { compile, JSONSchema } from 'json-schema-to-typescript'; -import { Project, FileBase, FileBaseOptions, IResolver } from 'projen'; +import * as fs from "fs"; +import { compile, JSONSchema } from "json-schema-to-typescript"; +import { Project, FileBase, FileBaseOptions, IResolver } from "projen"; export interface JsonSchemaBaseOptions extends FileBaseOptions { /** @@ -22,7 +22,7 @@ export const PATCHERS = { readonlyFields: (ts: string | undefined): string | undefined => { if (!ts) return ts; // regex to set all fields that start with a lowercase letter to readonly - return ts.replace(/^( +)([a-z])/gm, '$1readonly $2'); + return ts.replace(/^( +)([a-z])/gm, "$1readonly $2"); }, }; @@ -37,9 +37,15 @@ export class JsonSchemaBase extends FileBase { * @param outFile File path from project root * @param options Options */ - constructor(project: Project, outFile: string, options: JsonSchemaBaseOptions) { + constructor( + project: Project, + outFile: string, + options: JsonSchemaBaseOptions, + ) { super(project, outFile, options); - this.schema = JSON.parse(fs.readFileSync(options.filePath).toString()) as JSONSchema; + this.schema = JSON.parse( + fs.readFileSync(options.filePath).toString(), + ) as JSONSchema; } /** @@ -49,7 +55,10 @@ export class JsonSchemaBase extends FileBase { * @param name Name of the Interface to generate * @param patches Patches to apply to the generated interface */ - async generate(name: string, ...patches: ((schema: string | undefined) => string | undefined)[]) { + async generate( + name: string, + ...patches: ((schema: string | undefined) => string | undefined)[] + ) { this.contents = await compile(this.schema, name, { bannerComment: `// ${this.marker}`, }); @@ -65,7 +74,7 @@ export class JsonSchemaBase extends FileBase { */ protected synthesizeContent(_: IResolver): string | undefined { if (!this.contents) { - throw new Error('contents not compiled'); + throw new Error("contents not compiled"); } return this.contents; } @@ -78,13 +87,22 @@ export class JsonSchemaBase extends FileBase { * @param parentClass Name of the Parent Class containing the nested class definition as a property * @param className Name of the nested class to move to top level definitions */ - protected moveDeclarationToType(schema: JSONSchema, parentClass: string, className: string) { + protected moveDeclarationToType( + schema: JSONSchema, + parentClass: string, + className: string, + ) { if (schema.definitions) { const parentDefinition = schema.definitions[parentClass]; - if (parentDefinition.properties && parentDefinition.properties[className]) { + if ( + parentDefinition.properties && + parentDefinition.properties[className] + ) { const newName = parentClass + className; schema.definitions[newName] = parentDefinition.properties[className]; - parentDefinition.properties[className] = { $ref: `#/definitions/${newName}` }; + parentDefinition.properties[className] = { + $ref: `#/definitions/${newName}`, + }; } } } @@ -98,8 +116,17 @@ export class JsonSchemaBase extends FileBase { * @param oldName Old name of the definition * @param newName New name of the definition */ - protected renameDeclaration(schema: JSONSchema, propertyName: string, oldName: string, newName: string) { - if (schema.definitions && schema.properties && schema.properties[propertyName]) { + protected renameDeclaration( + schema: JSONSchema, + propertyName: string, + oldName: string, + newName: string, + ) { + if ( + schema.definitions && + schema.properties && + schema.properties[propertyName] + ) { schema.definitions[newName] = schema.definitions[oldName]; schema.properties[propertyName] = { $ref: `#/definitions/${newName}`, diff --git a/projenrc/parse-json.ts b/projenrc/parse-json.ts new file mode 100644 index 0000000..298e1d7 --- /dev/null +++ b/projenrc/parse-json.ts @@ -0,0 +1,43 @@ +import { readFileSync, writeFileSync } from "fs"; +import * as camelcaseKeys from "camelcase-keys"; +import { Dashboard } from "../src/dashboards/datadog-api-dashboard.generated"; +// convert a JSON string to a Dashboards API compatible JSON string + +function convertDashboard(dashboard: any): Dashboard { + return camelcaseKeys(dashboard, { + deep: true, + pascalCase: false, + }) as Dashboard; +} + +function readJsonFile(filePath: string): any { + return JSON.parse(readFileSync(filePath).toString()); +} + +function writeJsonFile(filename: string, data: any) { + writeFileSync(filename, JSON.stringify(data, null, 2), "utf8"); +} + +function convertDashboardFile(filePath: string): Dashboard { + return convertDashboard(readJsonFile(filePath)); +} + +const args = process.argv.slice(2); // Ignore node and filename path +// ensure args are passed in +if (args.length < 2) { + console.error("Usage: ts-node parse-json.js "); + console.error( + " type: dashboard - convert a datadog json file to a dashboards api compatible object", + ); + process.exit(1); +} +const [type, file] = args; +if (type !== "dashboard") { + console.error(`Unknown type: ${type}`); + process.exit(1); +} else { + const newFile = file.replace(".json", ".converted.json"); + const convertData = convertDashboardFile(file); + writeJsonFile(newFile, convertData); + console.log(`Converted to ${newFile}`); +} diff --git a/src/dashboards/datadog-dashboard.ts b/src/dashboards/datadog-dashboard.ts index 4aa3c74..f975ce4 100644 --- a/src/dashboards/datadog-dashboard.ts +++ b/src/dashboards/datadog-dashboard.ts @@ -1,8 +1,9 @@ -import { CfnResource } from 'aws-cdk-lib'; -import * as camelcaseKeys from 'camelcase-keys'; -import { Construct } from 'constructs'; -import { Dashboard } from './datadog-api-dashboard.generated'; -import { DatadogDashboardProps } from './datadog-dashboard-schema.generated'; +import { CfnResource } from "aws-cdk-lib"; +import * as camelcaseKeys from "camelcase-keys"; +import { Construct } from "constructs"; +import { snakeCaseKeys } from "../util"; +import { Dashboard } from "./datadog-api-dashboard.generated"; +import { DatadogDashboardProps } from "./datadog-dashboard-schema.generated"; /** * Wrapper for generated Schema with typed dashboard property @@ -21,7 +22,7 @@ export class DatadogDashboard { if (props.dashboard) { propsCopy = { ...props, - dashboardDefinition: JSON.stringify(props.dashboard), + dashboardDefinition: JSON.stringify(snakeCaseKeys(props.dashboard)), }; delete propsCopy.dashboard; } @@ -30,7 +31,7 @@ export class DatadogDashboard { pascalCase: true, }); new CfnResource(scope, id, { - type: 'Datadog::Dashboards::Dashboard', + type: "Datadog::Dashboards::Dashboard", properties: { ...cfnProperties }, }); } diff --git a/src/dashboards/index.ts b/src/dashboards/index.ts index 4dca07c..12d1dca 100644 --- a/src/dashboards/index.ts +++ b/src/dashboards/index.ts @@ -1,3 +1,3 @@ -export * from './datadog-dashboard-schema.generated'; -export * from './datadog-api-dashboard.generated'; -export * from './datadog-dashboard'; +export * from "./datadog-dashboard-schema.generated"; +export * from "./datadog-api-dashboard.generated"; +export * from "./datadog-dashboard"; diff --git a/src/index.ts b/src/index.ts index 6f1ee64..a71a46b 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,3 +1,3 @@ -export * from './monitors'; -export * from './dashboards'; -export * from './slos'; +export * from "./monitors"; +export * from "./dashboards"; +export * from "./slos"; diff --git a/src/monitors/datadog-monitor.ts b/src/monitors/datadog-monitor.ts index e9d4b2a..1cc354c 100644 --- a/src/monitors/datadog-monitor.ts +++ b/src/monitors/datadog-monitor.ts @@ -1,7 +1,7 @@ -import { CfnResource } from 'aws-cdk-lib'; -import * as camelcaseKeys from 'camelcase-keys'; -import { Construct } from 'constructs'; -import { DatadogMonitorProps } from './datadog-monitor-schema.generated'; +import { CfnResource } from "aws-cdk-lib"; +import * as camelcaseKeys from "camelcase-keys"; +import { Construct } from "constructs"; +import { DatadogMonitorProps } from "./datadog-monitor-schema.generated"; /** * Datadog Monitor 4.6.0 @@ -13,7 +13,7 @@ export class DatadogMonitor { pascalCase: true, }); new CfnResource(scope, id, { - type: 'Datadog::Monitors::Monitor', + type: "Datadog::Monitors::Monitor", properties: { ...cfnProperties }, }); } diff --git a/src/monitors/index.ts b/src/monitors/index.ts index e703861..30e19ba 100644 --- a/src/monitors/index.ts +++ b/src/monitors/index.ts @@ -1,3 +1,3 @@ -export * from './datadog-monitor-schema.generated'; -export * from './datadog-monitor'; -export * from './properties'; +export * from "./datadog-monitor-schema.generated"; +export * from "./datadog-monitor"; +export * from "./properties"; diff --git a/src/monitors/properties.ts b/src/monitors/properties.ts index bb880ea..1e76eb5 100644 --- a/src/monitors/properties.ts +++ b/src/monitors/properties.ts @@ -2,21 +2,20 @@ * The type of the monitor */ export enum MonitorType { - AUDIT_ALERT = 'audit alert', - COMPOSITE = 'composite', - EVENT_ALERT = 'event alert', - EVENT_V_2_ALERT = 'event-v2 alert', - LOG_ALERT = 'log alert', - METRIC_ALERT = 'metric alert', - PROCESS_ALERT = 'process alert', - QUERY_ALERT = 'query alert', - SERVICE_CHECK = 'service check', - SYNTHETICS_ALERT = 'synthetics alert', - TRACE_ANALYTICS_ALERT = 'trace-analytics alert', - SLO_ALERT = 'slo alert', - RUM_ALERT = 'rum alert', - CI_PIPELINES_ALERT = 'ci-pipelines alert', - ERROR_TRACKING_ALERT = 'error-tracking alert', - CI_TESTS_ALERT = 'ci-tests alert' + AUDIT_ALERT = "audit alert", + COMPOSITE = "composite", + EVENT_ALERT = "event alert", + EVENT_V_2_ALERT = "event-v2 alert", + LOG_ALERT = "log alert", + METRIC_ALERT = "metric alert", + PROCESS_ALERT = "process alert", + QUERY_ALERT = "query alert", + SERVICE_CHECK = "service check", + SYNTHETICS_ALERT = "synthetics alert", + TRACE_ANALYTICS_ALERT = "trace-analytics alert", + SLO_ALERT = "slo alert", + RUM_ALERT = "rum alert", + CI_PIPELINES_ALERT = "ci-pipelines alert", + ERROR_TRACKING_ALERT = "error-tracking alert", + CI_TESTS_ALERT = "ci-tests alert", } - diff --git a/src/slos/datadog-slo.ts b/src/slos/datadog-slo.ts index 3436c27..2cb720e 100644 --- a/src/slos/datadog-slo.ts +++ b/src/slos/datadog-slo.ts @@ -1,7 +1,7 @@ -import { CfnResource } from 'aws-cdk-lib'; -import * as camelcaseKeys from 'camelcase-keys'; -import { Construct } from 'constructs'; -import { DatadogSLOProps } from './datadog-slo-schema.generated'; +import { CfnResource } from "aws-cdk-lib"; +import * as camelcaseKeys from "camelcase-keys"; +import { Construct } from "constructs"; +import { DatadogSLOProps } from "./datadog-slo-schema.generated"; /** * Datadog SLO 1.1.0 @@ -13,7 +13,7 @@ export class DatadogSLO { pascalCase: true, }); new CfnResource(scope, id, { - type: 'Datadog::SLOs::SLO', + type: "Datadog::SLOs::SLO", properties: { ...cfnProperties }, }); } diff --git a/src/slos/index.ts b/src/slos/index.ts index 06a24f6..9067778 100644 --- a/src/slos/index.ts +++ b/src/slos/index.ts @@ -1,3 +1,3 @@ -export * from './datadog-slo-schema.generated'; -export * from './datadog-slo'; -export * from './properties'; +export * from "./datadog-slo-schema.generated"; +export * from "./datadog-slo"; +export * from "./properties"; diff --git a/src/slos/properties.ts b/src/slos/properties.ts index 4b10616..45e45fd 100644 --- a/src/slos/properties.ts +++ b/src/slos/properties.ts @@ -2,15 +2,15 @@ * The type of the SLO */ export enum SLOType { - METRIC = 'metric', - MONITOR = 'monitor', + METRIC = "metric", + MONITOR = "monitor", } /** * The type of the Timeframe */ export enum TimeframeType { - SEVENDAYS = '7d', - THIRTYDAYS = '30d', - NINETYDAYS = '90d', + SEVENDAYS = "7d", + THIRTYDAYS = "30d", + NINETYDAYS = "90d", } diff --git a/src/util.ts b/src/util.ts new file mode 100644 index 0000000..db78850 --- /dev/null +++ b/src/util.ts @@ -0,0 +1,20 @@ +import * as decamelize from "decamelize"; + +export function snakeCaseKeys(obj: T, sep = "_"): T { + if (typeof obj !== "object" || obj == null) { + return obj; + } + + if (Array.isArray(obj)) { + return obj.map((o) => snakeCaseKeys(o, sep)) as any; + } + + const result: Record = {}; + for (let [k, v] of Object.entries(obj)) { + if (typeof v === "object" && v != null) { + v = snakeCaseKeys(v); + } + result[decamelize(k, { separator: sep })] = v; + } + return result as any; +} diff --git a/test/__snapshots__/datadog-dashboard.test.ts.snap b/test/__snapshots__/datadog-dashboard.test.ts.snap index 0e2c004..6cbd105 100644 --- a/test/__snapshots__/datadog-dashboard.test.ts.snap +++ b/test/__snapshots__/datadog-dashboard.test.ts.snap @@ -12,7 +12,7 @@ Object { "Resources": Object { "TestDashboard": Object { "Properties": Object { - "DashboardDefinition": "{\\"title\\":\\"Example-Dashboard\\",\\"widgets\\":[{\\"definition\\":{\\"title\\":\\"Metrics HOP\\",\\"titleSize\\":\\"16\\",\\"titleAlign\\":\\"left\\",\\"showLegend\\":false,\\"type\\":\\"distribution\\",\\"customLinks\\":[{\\"label\\":\\"Example\\",\\"link\\":\\"https://example.org/\\"}],\\"xaxis\\":{\\"max\\":\\"auto\\",\\"includeZero\\":true,\\"scale\\":\\"linear\\",\\"min\\":\\"auto\\"},\\"yaxis\\":{\\"max\\":\\"auto\\",\\"includeZero\\":true,\\"scale\\":\\"linear\\",\\"min\\":\\"auto\\"},\\"requests\\":[{\\"query\\":{\\"query\\":\\"histogram:trace.Load{*}\\",\\"dataSource\\":\\"metrics\\",\\"name\\":\\"query1\\"},\\"requestType\\":\\"histogram\\",\\"style\\":{\\"palette\\":\\"dog_classic\\"}}]},\\"layout\\":{\\"x\\":0,\\"y\\":0,\\"width\\":4,\\"height\\":2}}],\\"layoutType\\":\\"ordered\\"}", + "DashboardDefinition": "{\\"title\\":\\"Example-Dashboard\\",\\"widgets\\":[{\\"definition\\":{\\"title\\":\\"Metrics HOP\\",\\"title_size\\":\\"16\\",\\"title_align\\":\\"left\\",\\"show_legend\\":false,\\"type\\":\\"distribution\\",\\"custom_links\\":[{\\"label\\":\\"Example\\",\\"link\\":\\"https://example.org/\\"}],\\"xaxis\\":{\\"max\\":\\"auto\\",\\"include_zero\\":true,\\"scale\\":\\"linear\\",\\"min\\":\\"auto\\"},\\"yaxis\\":{\\"max\\":\\"auto\\",\\"include_zero\\":true,\\"scale\\":\\"linear\\",\\"min\\":\\"auto\\"},\\"requests\\":[{\\"query\\":{\\"query\\":\\"histogram:trace.Load{*}\\",\\"data_source\\":\\"metrics\\",\\"name\\":\\"query1\\"},\\"request_type\\":\\"histogram\\",\\"style\\":{\\"palette\\":\\"dog_classic\\"}}]},\\"layout\\":{\\"x\\":0,\\"y\\":0,\\"width\\":4,\\"height\\":2}}],\\"layout_type\\":\\"ordered\\"}", }, "Type": "Datadog::Dashboards::Dashboard", }, diff --git a/test/datadog-dashboard.test.ts b/test/datadog-dashboard.test.ts index 328509b..df748f4 100644 --- a/test/datadog-dashboard.test.ts +++ b/test/datadog-dashboard.test.ts @@ -1,49 +1,51 @@ -import { Stack } from 'aws-cdk-lib'; -import { Template } from 'aws-cdk-lib/assertions'; -import { DatadogDashboard } from '../src'; +import { readFileSync } from "fs"; +import { join as pathJoin } from "path"; +import { Stack } from "aws-cdk-lib"; +import { Template } from "aws-cdk-lib/assertions"; +import { DatadogDashboard } from "../src"; -test('Snapshot test', () => { +test("Snapshot test", () => { const stack = new Stack(); - new DatadogDashboard(stack, 'TestDashboard', { + new DatadogDashboard(stack, "TestDashboard", { dashboard: { - title: 'Example-Dashboard', + title: "Example-Dashboard", widgets: [ { definition: { - title: 'Metrics HOP', - titleSize: '16', - titleAlign: 'left', + title: "Metrics HOP", + titleSize: "16", + titleAlign: "left", showLegend: false, - type: 'distribution', + type: "distribution", customLinks: [ { - label: 'Example', - link: 'https://example.org/', + label: "Example", + link: "https://example.org/", }, ], xaxis: { - max: 'auto', + max: "auto", includeZero: true, - scale: 'linear', - min: 'auto', + scale: "linear", + min: "auto", }, yaxis: { - max: 'auto', + max: "auto", includeZero: true, - scale: 'linear', - min: 'auto', + scale: "linear", + min: "auto", }, requests: [ { query: { - query: 'histogram:trace.Load{*}', - dataSource: 'metrics', - name: 'query1', + query: "histogram:trace.Load{*}", + dataSource: "metrics", + name: "query1", }, - requestType: 'histogram', + requestType: "histogram", style: { - palette: 'dog_classic', + palette: "dog_classic", }, }, ], @@ -56,8 +58,2213 @@ test('Snapshot test', () => { }, }, ], - layoutType: 'ordered', + layoutType: "ordered", }, }); expect(Template.fromStack(stack)).toMatchSnapshot(); }); + +test("ArgoCD Dashboard", () => { + const stack = new Stack(); + + new DatadogDashboard(stack, "TestDashboard", { + // This object was generated from DataDog -> Export Dashboard JSON + // pj parse-json dashboard test/fixtures/argocd-dashboard.json + // NOTE: the template_variables field `default: ""` had to be converted to `defaults: []` + dashboard: { + title: "[GNC] Argo CD Overview", + description: + "## Argo CD Overview\n\n### The Argo CD dashboard gives you broad visibility into your Argo CD Clusters\n\nThis dashboard provides a high-level overview of your Argo CD clusters so that you can monitor the deployments, performance, and overall health of a cluster.\n\n### Useful Links\n\n- [Datadog Argo CD Integration Documentation](https://docs.datadoghq.com/integrations/argocd/)\n- [Argo CD Official Documentation](https://argo-cd.readthedocs.io/en/latest/)\n- [Monitoring Argo CD Blogpost](https://www.datadoghq.com/blog/argo-cd-datadog/)\n\nClone this template dashboard to make changes and add your own graph widgets. (cloned)", + widgets: [ + { + id: 8741772350597652, + definition: { + title: "Overview", + bannerImg: "/static/images/logos/argocd_small.svg", + showTitle: false, + type: "group", + layoutType: "ordered", + widgets: [ + { + id: 5723783152443636, + definition: { + type: "note", + content: + "\n### Useful Links\n- [Datadog Argo CD Integration Documentation](https://docs.datadoghq.com/integrations/argocd/)\n- [Argo CD Official Documentation](https://argo-cd.readthedocs.io/en/latest/)\n- [Monitor Argo CD Blogpost](https://www.datadoghq.com/blog/argo-cd-datadog/)", + backgroundColor: "transparent", + fontSize: "14", + textAlign: "left", + verticalAlign: "top", + showTick: false, + tickPos: "50%", + tickEdge: "left", + hasPadding: true, + }, + layout: { + x: 0, + y: 0, + width: 4, + height: 2, + }, + }, + ], + }, + layout: { + x: 0, + y: 0, + width: 4, + height: 5, + }, + }, + { + id: 2293131439045202, + definition: { + title: "Overview", + backgroundColor: "vivid_blue", + showTitle: true, + type: "group", + layoutType: "ordered", + widgets: [ + { + id: 1107851890687136, + definition: { + title: "Number of Applications", + titleSize: "16", + titleAlign: "left", + showLegend: true, + legendLayout: "auto", + legendColumns: ["avg", "min", "max", "value", "sum"], + type: "timeseries", + requests: [ + { + formulas: [ + { + alias: "Number of Applications", + formula: "query1", + }, + ], + queries: [ + { + dataSource: "metrics", + name: "query1", + query: + "sum:argocd.app_controller.app.info{$host,$kube_cluster_name,$health_status,$kube_namespace,$repo} by {host}", + }, + ], + responseFormat: "timeseries", + style: { + palette: "blue", + lineType: "solid", + lineWidth: "normal", + }, + displayType: "line", + }, + ], + }, + layout: { + x: 0, + y: 0, + width: 4, + height: 3, + }, + }, + { + id: 148852812141642, + definition: { + title: "Containers in ArgoCD namespace by Host", + titleSize: "16", + titleAlign: "left", + type: "hostmap", + requests: { + fill: { + q: "avg:process.stat.container.cpu.user_pct{$kube_cluster_name,$kube_namespace} by {host}", + }, + size: { + q: "avg:process.stat.container.memory.rss{$kube_cluster_name,$kube_namespace} by {host}", + }, + }, + nodeType: "container", + noMetricHosts: true, + noGroupHosts: true, + group: ["host"], + scope: ["$kube_cluster_name", "$kube_namespace"], + style: { + palette: "green_to_orange", + paletteFlip: false, + }, + }, + layout: { + x: 4, + y: 0, + width: 4, + height: 3, + }, + }, + { + id: 8391951914104866, + definition: { + title: "App Controllers", + titleSize: "16", + titleAlign: "left", + type: "query_value", + requests: [ + { + formulas: [ + { + formula: "query1", + }, + ], + queries: [ + { + aggregator: "max", + dataSource: "metrics", + name: "query1", + query: + "count:argocd.app_controller.go.goroutines{$host,$kube_cluster_name,$kube_namespace}", + }, + ], + responseFormat: "scalar", + }, + ], + autoscale: true, + precision: 2, + }, + layout: { + x: 0, + y: 3, + width: 2, + height: 1, + }, + }, + { + id: 3088551287926924, + definition: { + title: "AppSet Controllers (pending)", + titleSize: "16", + titleAlign: "left", + type: "query_value", + requests: [ + { + formulas: [ + { + formula: "query1", + }, + ], + queries: [ + { + aggregator: "max", + dataSource: "metrics", + name: "query1", + query: + "count:argocd.app_controller.go.goroutines{$host,$kube_cluster_name,$kube_namespace}", + }, + ], + responseFormat: "scalar", + }, + ], + autoscale: true, + precision: 2, + }, + layout: { + x: 2, + y: 3, + width: 2, + height: 1, + }, + }, + { + id: 3083362413703058, + definition: { + title: "Repository Servers", + titleSize: "16", + titleAlign: "left", + type: "query_value", + requests: [ + { + formulas: [ + { + formula: "query1", + }, + ], + queries: [ + { + aggregator: "max", + dataSource: "metrics", + name: "query1", + query: + "count:argocd.repo_server.go.goroutines{$host,$kube_cluster_name,$kube_namespace}", + }, + ], + responseFormat: "scalar", + }, + ], + autoscale: true, + precision: 2, + }, + layout: { + x: 4, + y: 3, + width: 2, + height: 1, + }, + }, + { + id: 2764269609392968, + definition: { + title: "API Servers", + titleSize: "16", + titleAlign: "left", + type: "query_value", + requests: [ + { + formulas: [ + { + formula: "query1", + }, + ], + queries: [ + { + aggregator: "max", + dataSource: "metrics", + name: "query1", + query: + "count:argocd.api_server.go.goroutines{$host,$kube_cluster_name,$kube_namespace}", + }, + ], + responseFormat: "scalar", + }, + ], + autoscale: true, + precision: 2, + }, + layout: { + x: 6, + y: 3, + width: 2, + height: 1, + }, + }, + ], + }, + layout: { + x: 4, + y: 0, + width: 8, + height: 5, + }, + }, + { + id: 5039638453713644, + definition: { + title: "Logs", + backgroundColor: "vivid_blue", + showTitle: true, + type: "group", + layoutType: "ordered", + widgets: [ + { + id: 7799454257481500, + definition: { + title: "", + titleSize: "16", + titleAlign: "left", + requests: [ + { + responseFormat: "event_list", + query: { + dataSource: "logs_pattern_stream", + queryString: "status:error source:argocd", + indexes: [], + groupBy: [ + { + facet: "service", + }, + ], + }, + columns: [ + { + field: "status_line", + width: "auto", + }, + { + field: "matches", + width: "auto", + }, + { + field: "volume", + width: "auto", + }, + { + field: "service", + width: "auto", + }, + { + field: "message", + width: "auto", + }, + ], + }, + ], + type: "list_stream", + }, + layout: { + x: 0, + y: 0, + width: 12, + height: 3, + }, + }, + ], + }, + layout: { + x: 0, + y: 5, + width: 12, + height: 4, + }, + }, + { + id: 3103904444573384, + definition: { + title: "Application Status", + backgroundColor: "vivid_green", + showTitle: true, + type: "group", + layoutType: "ordered", + widgets: [ + { + id: 4761912700194790, + definition: { + title: "Applications by Repositories", + titleSize: "16", + titleAlign: "left", + requests: [ + { + formulas: [ + { + formula: "query1", + }, + ], + queries: [ + { + aggregator: "avg", + dataSource: "metrics", + name: "query1", + query: + "count:argocd.app_controller.app.info{$host,$kube_cluster_name,$health_status,$kube_namespace,$repo} by {repo,host,name}", + }, + ], + responseFormat: "scalar", + }, + ], + type: "sunburst", + hideTotal: false, + legend: { + type: "table", + }, + }, + layout: { + x: 0, + y: 0, + width: 12, + height: 4, + }, + }, + { + id: 7617765285986134, + definition: { + title: "Number of Applications", + titleSize: "16", + titleAlign: "left", + showLegend: true, + legendLayout: "horizontal", + legendColumns: ["avg", "min", "max", "value", "sum"], + type: "timeseries", + requests: [ + { + formulas: [ + { + alias: "Number of Applications", + formula: "query1", + }, + ], + queries: [ + { + dataSource: "metrics", + name: "query1", + query: + "sum:argocd.app_controller.app.info{$host,$kube_cluster_name,$health_status,$kube_namespace,$repo} by {sync_status}", + }, + ], + responseFormat: "timeseries", + style: { + palette: "dog_classic", + lineType: "solid", + lineWidth: "normal", + }, + displayType: "bars", + }, + ], + }, + layout: { + x: 0, + y: 4, + width: 6, + height: 3, + }, + }, + { + id: 8732078285048376, + definition: { + title: "Applications Not in Sync by Sync_Status & Host", + titleSize: "16", + titleAlign: "left", + showLegend: true, + legendLayout: "auto", + legendColumns: ["avg", "min", "max", "value", "sum"], + type: "timeseries", + requests: [ + { + formulas: [ + { + alias: "Application not Synced", + formula: "query1", + }, + ], + queries: [ + { + dataSource: "metrics", + name: "query1", + query: + "sum:argocd.app_controller.app.info{!sync_status:synced,$host,$kube_cluster_name,$health_status,$kube_namespace,$repo} by {sync_status,host,name}", + }, + ], + responseFormat: "timeseries", + style: { + palette: "dog_classic", + lineType: "solid", + lineWidth: "normal", + }, + displayType: "bars", + }, + ], + }, + layout: { + x: 6, + y: 4, + width: 6, + height: 3, + }, + }, + { + id: 4491005302659932, + definition: { + title: "Number of Application Syncs", + titleSize: "16", + titleAlign: "left", + showLegend: true, + legendLayout: "auto", + legendColumns: ["avg", "min", "max", "value", "sum"], + type: "timeseries", + requests: [ + { + formulas: [ + { + alias: "Application Syncs", + formula: "query1", + }, + ], + queries: [ + { + dataSource: "metrics", + name: "query1", + query: + "sum:argocd.app_controller.app.sync.count{$host,$kube_cluster_name,$health_status,$kube_namespace,$repo} by {host}.as_count()", + }, + ], + responseFormat: "timeseries", + style: { + palette: "blue", + lineType: "solid", + lineWidth: "normal", + }, + displayType: "bars", + }, + ], + }, + layout: { + x: 0, + y: 7, + width: 6, + height: 3, + }, + }, + { + id: 3479937394251732, + definition: { + title: "Number of Non Successful Application Syncs", + titleSize: "16", + titleAlign: "left", + showLegend: true, + legendLayout: "auto", + legendColumns: ["avg", "min", "max", "value", "sum"], + type: "timeseries", + requests: [ + { + formulas: [ + { + alias: "Unsuccessful Syncs", + formula: "query1", + }, + ], + queries: [ + { + dataSource: "metrics", + name: "query1", + query: + "sum:argocd.app_controller.app.sync.count{!phase:succeeded,$host,$kube_cluster_name,$health_status,$kube_namespace,$repo} by {phase,host}.as_count()", + }, + ], + responseFormat: "timeseries", + style: { + palette: "blue", + lineType: "solid", + lineWidth: "normal", + }, + displayType: "bars", + }, + ], + }, + layout: { + x: 6, + y: 7, + width: 6, + height: 3, + }, + }, + { + id: 2091528630387406, + definition: { + type: "note", + content: "Application Controller Telemetry", + backgroundColor: "green", + fontSize: "18", + textAlign: "center", + verticalAlign: "center", + showTick: false, + tickPos: "50%", + tickEdge: "left", + hasPadding: true, + }, + layout: { + x: 0, + y: 10, + width: 12, + height: 1, + }, + }, + { + id: 4927792811835832, + definition: { + title: "Application Controller Memory Usage by Cluster", + titleSize: "16", + titleAlign: "left", + showLegend: true, + legendLayout: "auto", + legendColumns: ["avg", "min", "max", "value", "sum"], + type: "timeseries", + requests: [ + { + formulas: [ + { + alias: "Memory Allocated", + formula: "query1", + }, + ], + queries: [ + { + dataSource: "metrics", + name: "query1", + query: + "avg:argocd.app_controller.go.memstats.heap.alloc_bytes{$host,$kube_cluster_name,$kube_namespace} by {cluster_name,host}", + }, + ], + responseFormat: "timeseries", + style: { + palette: "dog_classic", + lineType: "solid", + lineWidth: "normal", + }, + displayType: "line", + }, + ], + }, + layout: { + x: 0, + y: 11, + width: 4, + height: 3, + }, + }, + { + id: 6525343257017112, + definition: { + title: "Application Controller Goroutines Usage by Cluster", + titleSize: "16", + titleAlign: "left", + showLegend: true, + legendLayout: "auto", + legendColumns: ["avg", "min", "max", "value", "sum"], + type: "timeseries", + requests: [ + { + formulas: [ + { + alias: "Goroutines", + formula: "query1", + }, + ], + queries: [ + { + dataSource: "metrics", + name: "query1", + query: + "avg:argocd.app_controller.go.goroutines{$host,$kube_cluster_name,$kube_namespace} by {kube_namespace,host}", + }, + ], + responseFormat: "timeseries", + style: { + palette: "dog_classic", + lineType: "solid", + lineWidth: "normal", + }, + displayType: "line", + }, + ], + }, + layout: { + x: 4, + y: 11, + width: 4, + height: 3, + }, + }, + { + id: 3471621043457984, + definition: { + title: "Application Controller CPU Time by Cluster", + titleSize: "16", + titleAlign: "left", + showLegend: true, + legendLayout: "auto", + legendColumns: ["avg", "min", "max", "value", "sum"], + type: "timeseries", + requests: [ + { + formulas: [ + { + alias: "CPU Time", + formula: "query1", + }, + ], + queries: [ + { + dataSource: "metrics", + name: "query1", + query: + "sum:argocd.app_controller.process.cpu.seconds.count{$host,$kube_cluster_name,$kube_namespace} by {kube_namespace,host}.as_count()", + }, + ], + responseFormat: "timeseries", + style: { + palette: "dog_classic", + lineType: "solid", + lineWidth: "normal", + }, + displayType: "line", + }, + ], + }, + layout: { + x: 8, + y: 11, + width: 4, + height: 3, + }, + }, + ], + }, + layout: { + x: 0, + y: 9, + width: 12, + height: 1, + }, + }, + { + id: 8970831812548910, + definition: { + title: "Controller Stats", + backgroundColor: "vivid_orange", + showTitle: true, + type: "group", + layoutType: "ordered", + widgets: [ + { + id: 1683090577470882, + definition: { + title: "Count of Application Reconciliation", + titleSize: "16", + titleAlign: "left", + showLegend: true, + legendLayout: "auto", + legendColumns: ["avg", "min", "max", "value", "sum"], + type: "timeseries", + requests: [ + { + formulas: [ + { + alias: "Application Reconciliation", + formula: "query1", + }, + ], + queries: [ + { + dataSource: "metrics", + name: "query1", + query: + "sum:argocd.app_controller.app.reconcile.count{$host,$kube_cluster_name,$kube_namespace} by {namespace,host}.as_count()", + }, + ], + responseFormat: "timeseries", + style: { + palette: "orange", + lineType: "solid", + lineWidth: "normal", + }, + displayType: "bars", + }, + ], + }, + layout: { + x: 0, + y: 0, + width: 6, + height: 3, + }, + }, + { + id: 2882037992742898, + definition: { + title: + "Count of Application Reconciliation by Duration Bounds", + titleSize: "16", + titleAlign: "left", + showLegend: true, + legendLayout: "auto", + legendColumns: ["avg", "min", "max", "value", "sum"], + type: "timeseries", + requests: [ + { + formulas: [ + { + alias: "Reconciliation Duration", + formula: "query1", + }, + ], + queries: [ + { + dataSource: "metrics", + name: "query1", + query: + "sum:argocd.app_controller.app.reconcile.bucket{$host,$kube_cluster_name,$kube_namespace} by {upper_bound,host}.as_count()", + }, + ], + responseFormat: "timeseries", + style: { + palette: "orange", + lineType: "solid", + lineWidth: "normal", + }, + displayType: "bars", + }, + ], + }, + layout: { + x: 6, + y: 0, + width: 6, + height: 3, + }, + }, + { + id: 2092421836560578, + definition: { + title: "Depth of the Workqueue", + titleSize: "16", + titleAlign: "left", + showLegend: true, + legendLayout: "auto", + legendColumns: ["avg", "min", "max", "value", "sum"], + type: "timeseries", + requests: [ + { + formulas: [ + { + alias: "Workqueue depth", + formula: "query1", + }, + ], + queries: [ + { + dataSource: "metrics", + name: "query1", + query: + "sum:argocd.app_controller.workqueue.depth{$host,$kube_cluster_name,$kube_namespace} by {host,kube_cluster_name}", + }, + ], + responseFormat: "timeseries", + style: { + palette: "orange", + }, + displayType: "bars", + }, + ], + yaxis: { + includeZero: true, + scale: "linear", + min: "auto", + max: "auto", + }, + }, + layout: { + x: 0, + y: 3, + width: 6, + height: 3, + }, + }, + { + id: 4125569125075486, + definition: { + title: "Count of Kubernetes Requests Executed", + titleSize: "16", + titleAlign: "left", + showLegend: true, + legendLayout: "auto", + legendColumns: ["avg", "min", "max", "value", "sum"], + type: "timeseries", + requests: [ + { + formulas: [ + { + alias: "Kubectl Request Executed", + formula: "query1", + }, + ], + queries: [ + { + dataSource: "metrics", + name: "query1", + query: + "sum:argocd.app_controller.app.k8s.request.count{$host,$kube_cluster_name,$kube_namespace} by {host,kube_cluster_name}.as_count()", + }, + ], + responseFormat: "timeseries", + style: { + palette: "orange", + }, + displayType: "bars", + }, + ], + yaxis: { + includeZero: true, + scale: "linear", + min: "auto", + max: "auto", + }, + }, + layout: { + x: 6, + y: 3, + width: 6, + height: 3, + }, + }, + { + id: 6916335121689932, + definition: { + title: "Count of Kubectl Executions", + titleSize: "16", + titleAlign: "left", + showLegend: true, + legendLayout: "auto", + legendColumns: ["avg", "min", "max", "value", "sum"], + type: "timeseries", + requests: [ + { + formulas: [ + { + alias: "Kubectl Execution", + formula: "query1", + }, + ], + queries: [ + { + dataSource: "metrics", + name: "query1", + query: + "sum:argocd.app_controller.kubectl.exec.count{$host,$kube_cluster_name,$kube_namespace} by {host,kube_cluster_name}.as_count()", + }, + ], + responseFormat: "timeseries", + style: { + palette: "orange", + }, + displayType: "bars", + }, + ], + yaxis: { + includeZero: true, + scale: "linear", + min: "auto", + max: "auto", + }, + }, + layout: { + x: 0, + y: 6, + width: 6, + height: 3, + }, + }, + { + id: 1713544962494578, + definition: { + title: "Count of Pending Kubectl Executions", + titleSize: "16", + titleAlign: "left", + showLegend: true, + legendLayout: "auto", + legendColumns: ["avg", "min", "max", "value", "sum"], + type: "timeseries", + requests: [ + { + formulas: [ + { + alias: "Pending Kubectl Execution", + formula: "query1", + }, + ], + queries: [ + { + dataSource: "metrics", + name: "query1", + query: + "sum:argocd.app_controller.kubectl.exec.pending{$host,$kube_cluster_name,$kube_namespace} by {host,kube_cluster_name}", + }, + ], + responseFormat: "timeseries", + style: { + palette: "orange", + }, + displayType: "bars", + }, + ], + yaxis: { + includeZero: true, + scale: "linear", + min: "auto", + max: "auto", + }, + }, + layout: { + x: 6, + y: 6, + width: 6, + height: 3, + }, + }, + ], + }, + layout: { + x: 0, + y: 10, + width: 12, + height: 1, + }, + }, + { + id: 2661663506447074, + definition: { + title: "Server Stats", + backgroundColor: "vivid_purple", + showTitle: true, + type: "group", + layoutType: "ordered", + widgets: [ + { + id: 7853075716472980, + definition: { + title: "Count of Service Requests by Service", + titleSize: "16", + titleAlign: "left", + showLegend: true, + legendLayout: "auto", + legendColumns: ["avg", "min", "max", "value", "sum"], + type: "timeseries", + requests: [ + { + formulas: [ + { + alias: "All Service Request", + formula: "query1", + }, + ], + queries: [ + { + dataSource: "metrics", + name: "query1", + query: + "sum:argocd.api_server.grpc.server.handled.count{$host,$kube_cluster_name,$kube_namespace} by {grpc_service,kube_cluster_name,host}.as_count()", + }, + ], + responseFormat: "timeseries", + style: { + palette: "purple", + lineType: "solid", + lineWidth: "normal", + }, + displayType: "bars", + }, + ], + }, + layout: { + x: 0, + y: 0, + width: 6, + height: 3, + }, + }, + { + id: 2986577135722696, + definition: { + title: "Count of Cluster Service Requests", + titleSize: "16", + titleAlign: "left", + showLegend: true, + legendLayout: "auto", + legendColumns: ["avg", "min", "max", "value", "sum"], + type: "timeseries", + requests: [ + { + formulas: [ + { + alias: "Cluster Service Request", + formula: "query1", + }, + ], + queries: [ + { + dataSource: "metrics", + name: "query1", + query: + "sum:argocd.api_server.grpc.server.handled.count{grpc_service:cluster.clusterservice,$host,$kube_cluster_name,$kube_namespace} by {grpc_code,grpc_method,host,kube_cluster_name}.as_count()", + }, + ], + responseFormat: "timeseries", + style: { + palette: "purple", + lineType: "solid", + lineWidth: "normal", + }, + displayType: "bars", + }, + ], + }, + layout: { + x: 6, + y: 0, + width: 6, + height: 3, + }, + }, + { + id: 4161309530762940, + definition: { + title: "Count of Application Service Requests", + titleSize: "16", + titleAlign: "left", + showLegend: true, + legendLayout: "auto", + legendColumns: ["avg", "min", "max", "value", "sum"], + type: "timeseries", + requests: [ + { + formulas: [ + { + alias: "Application Service Request", + formula: "query1", + }, + ], + queries: [ + { + dataSource: "metrics", + name: "query1", + query: + "sum:argocd.api_server.grpc.server.handled.count{grpc_service:application.applicationservice,$host,$kube_cluster_name,$kube_namespace} by {grpc_code,grpc_method,host,kube_cluster_name}.as_count()", + }, + ], + responseFormat: "timeseries", + style: { + palette: "purple", + lineType: "solid", + lineWidth: "normal", + }, + displayType: "bars", + }, + ], + }, + layout: { + x: 0, + y: 3, + width: 6, + height: 3, + }, + }, + { + id: 3346295316212716, + definition: { + title: "Count of Repository Service Requests", + titleSize: "16", + titleAlign: "left", + showLegend: true, + legendLayout: "auto", + legendColumns: ["avg", "min", "max", "value", "sum"], + type: "timeseries", + requests: [ + { + formulas: [ + { + alias: "Repository Service Request", + formula: "query1", + }, + ], + queries: [ + { + dataSource: "metrics", + name: "query1", + query: + "sum:argocd.api_server.grpc.server.handled.count{grpc_service:repository.repositoryservice,$host,$kube_cluster_name,$kube_namespace} by {grpc_code,grpc_method,kube_cluster_name,host}.as_count()", + }, + ], + responseFormat: "timeseries", + style: { + palette: "purple", + lineType: "solid", + lineWidth: "normal", + }, + displayType: "bars", + }, + ], + }, + layout: { + x: 6, + y: 3, + width: 6, + height: 3, + }, + }, + { + id: 251735075640654, + definition: { + title: "Count of Session Service Requests", + titleSize: "16", + titleAlign: "left", + showLegend: true, + legendLayout: "auto", + legendColumns: ["avg", "min", "max", "value", "sum"], + type: "timeseries", + requests: [ + { + formulas: [ + { + alias: "Session Service Request", + formula: "query1", + }, + ], + queries: [ + { + dataSource: "metrics", + name: "query1", + query: + "sum:argocd.api_server.grpc.server.handled.count{grpc_service:session.sessionservice,$host,$kube_cluster_name,$kube_namespace} by {grpc_code,grpc_method,kube_cluster_name,host}.as_count()", + }, + ], + responseFormat: "timeseries", + style: { + palette: "purple", + lineType: "solid", + lineWidth: "normal", + }, + displayType: "bars", + }, + ], + }, + layout: { + x: 0, + y: 6, + width: 6, + height: 3, + }, + }, + { + id: 6377937600157456, + definition: { + title: "Count of Version Service Requests", + titleSize: "16", + titleAlign: "left", + showLegend: true, + legendLayout: "auto", + legendColumns: ["avg", "min", "max", "value", "sum"], + type: "timeseries", + requests: [ + { + formulas: [ + { + alias: "Version Service Request", + formula: "query1", + }, + ], + queries: [ + { + dataSource: "metrics", + name: "query1", + query: + "sum:argocd.api_server.grpc.server.handled.count{grpc_service:version.versionservice,$host,$kube_cluster_name,$kube_namespace} by {grpc_code,grpc_method,kube_cluster_name}.as_count()", + }, + ], + responseFormat: "timeseries", + style: { + palette: "purple", + lineType: "solid", + lineWidth: "normal", + }, + displayType: "bars", + }, + ], + }, + layout: { + x: 6, + y: 6, + width: 6, + height: 3, + }, + }, + { + id: 8207475356653118, + definition: { + title: "Count of Account Service Requests", + titleSize: "16", + titleAlign: "left", + showLegend: true, + legendLayout: "auto", + legendColumns: ["avg", "min", "max", "value", "sum"], + type: "timeseries", + requests: [ + { + formulas: [ + { + alias: "Account Service Request", + formula: "query1", + }, + ], + queries: [ + { + dataSource: "metrics", + name: "query1", + query: + "sum:argocd.api_server.grpc.server.handled.count{grpc_service:account.accountservice,$host,$kube_cluster_name,$kube_namespace} by {grpc_code,grpc_method,kube_cluster_name,host}.as_count()", + }, + ], + responseFormat: "timeseries", + style: { + palette: "purple", + lineType: "solid", + lineWidth: "normal", + }, + displayType: "bars", + }, + ], + }, + layout: { + x: 0, + y: 9, + width: 6, + height: 3, + }, + }, + { + id: 5496058710860268, + definition: { + title: "Count of Settings Service Requests", + titleSize: "16", + titleAlign: "left", + showLegend: true, + legendLayout: "auto", + legendColumns: ["avg", "min", "max", "value", "sum"], + type: "timeseries", + requests: [ + { + formulas: [ + { + alias: "Settings Service Request ", + formula: "query1", + }, + ], + queries: [ + { + dataSource: "metrics", + name: "query1", + query: + "sum:argocd.api_server.grpc.server.handled.count{grpc_service:cluster.settingsservice,$host,$kube_cluster_name,$kube_namespace} by {grpc_code,grpc_method,host,kube_cluster_name}.as_count()", + }, + ], + responseFormat: "timeseries", + style: { + palette: "purple", + lineType: "solid", + lineWidth: "normal", + }, + displayType: "bars", + }, + ], + }, + layout: { + x: 6, + y: 9, + width: 6, + height: 3, + }, + }, + { + id: 3658743930291138, + definition: { + type: "note", + content: "API Server Telemetry", + backgroundColor: "purple", + fontSize: "18", + textAlign: "center", + verticalAlign: "center", + showTick: false, + tickPos: "50%", + tickEdge: "left", + hasPadding: true, + }, + layout: { + x: 0, + y: 12, + width: 12, + height: 1, + }, + }, + { + id: 5099362422931018, + definition: { + title: "API Server Memory Usage by Cluster", + titleSize: "16", + titleAlign: "left", + showLegend: true, + legendLayout: "auto", + legendColumns: ["avg", "min", "max", "value", "sum"], + type: "timeseries", + requests: [ + { + formulas: [ + { + alias: "Memory Allocated", + formula: "query1", + }, + ], + queries: [ + { + dataSource: "metrics", + name: "query1", + query: + "avg:argocd.api_server.go.memstats.heap.alloc_bytes{$host,$kube_cluster_name,$kube_namespace} by {host,kube_cluster_name}", + }, + ], + responseFormat: "timeseries", + style: { + palette: "dog_classic", + lineType: "solid", + lineWidth: "normal", + }, + displayType: "line", + }, + ], + }, + layout: { + x: 0, + y: 13, + width: 4, + height: 3, + }, + }, + { + id: 5166753638637396, + definition: { + title: "API Server Goroutines Usage by Cluster", + titleSize: "16", + titleAlign: "left", + showLegend: true, + legendLayout: "auto", + legendColumns: ["avg", "min", "max", "value", "sum"], + type: "timeseries", + requests: [ + { + formulas: [ + { + alias: "Goroutines", + formula: "query1", + }, + ], + queries: [ + { + dataSource: "metrics", + name: "query1", + query: + "avg:argocd.api_server.go.goroutines{$host,$kube_cluster_name,$kube_namespace} by {host,kube_cluster_name}", + }, + ], + responseFormat: "timeseries", + style: { + palette: "dog_classic", + lineType: "solid", + lineWidth: "normal", + }, + displayType: "line", + }, + ], + }, + layout: { + x: 4, + y: 13, + width: 4, + height: 3, + }, + }, + { + id: 6597509157761322, + definition: { + title: "API Server CPU Time by Cluster", + titleSize: "16", + titleAlign: "left", + showLegend: true, + legendLayout: "auto", + legendColumns: ["avg", "min", "max", "value", "sum"], + type: "timeseries", + requests: [ + { + formulas: [ + { + alias: "CPU Time", + formula: "query1", + }, + ], + queries: [ + { + dataSource: "metrics", + name: "query1", + query: + "sum:argocd.api_server.process.cpu.seconds.count{$host,$kube_cluster_name,$kube_namespace} by {host,kube_cluster_name}.as_count()", + }, + ], + responseFormat: "timeseries", + style: { + palette: "dog_classic", + lineType: "solid", + lineWidth: "normal", + }, + displayType: "line", + }, + ], + }, + layout: { + x: 8, + y: 13, + width: 4, + height: 3, + }, + }, + ], + }, + layout: { + x: 0, + y: 11, + width: 12, + height: 1, + }, + }, + { + id: 444244913319832, + definition: { + title: "Repository Server Stats", + backgroundColor: "vivid_orange", + showTitle: true, + type: "group", + layoutType: "ordered", + widgets: [ + { + id: 8507386561737364, + definition: { + title: "Count of Git Ls-Remote Requests", + titleSize: "16", + titleAlign: "left", + showLegend: true, + legendLayout: "auto", + legendColumns: ["avg", "min", "max", "value", "sum"], + type: "timeseries", + requests: [ + { + formulas: [ + { + alias: "Ls-remote Request", + formula: "query1", + }, + ], + queries: [ + { + dataSource: "metrics", + name: "query1", + query: + "sum:argocd.repo_server.git.request.count{request_type:ls-remote,$host,$kube_cluster_name,$kube_namespace} by {host,kube_cluster_name}.as_count()", + }, + ], + responseFormat: "timeseries", + style: { + palette: "dog_classic", + lineType: "solid", + lineWidth: "normal", + }, + displayType: "bars", + }, + ], + }, + layout: { + x: 0, + y: 0, + width: 6, + height: 3, + }, + }, + { + id: 5597200409579852, + definition: { + title: "Git Ls-Remote Requests Performance", + titleSize: "16", + titleAlign: "left", + showLegend: true, + legendLayout: "auto", + legendColumns: ["avg", "min", "max", "value", "sum"], + type: "timeseries", + requests: [ + { + formulas: [ + { + formula: "query1", + }, + ], + queries: [ + { + dataSource: "metrics", + name: "query1", + query: + "sum:argocd.repo_server.git.request.duration.seconds.bucket{request_type:ls-remote,$host,$kube_cluster_name,$kube_namespace} by {upper_bound,kube_cluster_name}.as_count()", + }, + ], + responseFormat: "timeseries", + style: { + palette: "dog_classic", + }, + displayType: "bars", + }, + ], + }, + layout: { + x: 6, + y: 0, + width: 6, + height: 3, + }, + }, + { + id: 1635931665551580, + definition: { + title: "Count of Git Fetch Requests", + titleSize: "16", + titleAlign: "left", + showLegend: true, + legendLayout: "auto", + legendColumns: ["avg", "min", "max", "value", "sum"], + type: "timeseries", + requests: [ + { + formulas: [ + { + alias: "Fetch Request", + formula: "query1", + }, + ], + queries: [ + { + dataSource: "metrics", + name: "query1", + query: + "sum:argocd.repo_server.git.request.count{request_type:fetch,$host,$kube_cluster_name,$kube_namespace}.as_count()", + }, + ], + responseFormat: "timeseries", + style: { + palette: "dog_classic", + lineType: "solid", + lineWidth: "normal", + }, + displayType: "bars", + }, + ], + }, + layout: { + x: 0, + y: 3, + width: 6, + height: 3, + }, + }, + { + id: 1418427818359380, + definition: { + title: "Fetch Git Requests Performance", + titleSize: "16", + titleAlign: "left", + showLegend: true, + legendLayout: "auto", + legendColumns: ["avg", "min", "max", "value", "sum"], + type: "timeseries", + requests: [ + { + formulas: [ + { + formula: "query1", + }, + ], + queries: [ + { + dataSource: "metrics", + name: "query1", + query: + "sum:argocd.repo_server.git.request.duration.seconds.bucket{request_type:fetch,kube_cluster_name,$host,$kube_cluster_name,$kube_namespace}.as_count()", + }, + ], + responseFormat: "timeseries", + style: { + palette: "dog_classic", + }, + displayType: "bars", + }, + ], + }, + layout: { + x: 6, + y: 3, + width: 6, + height: 3, + }, + }, + { + id: 1888889021360466, + definition: { + title: "Count of of Redis Requests", + titleSize: "16", + titleAlign: "left", + showLegend: true, + legendLayout: "auto", + legendColumns: ["avg", "min", "max", "value", "sum"], + type: "timeseries", + requests: [ + { + formulas: [ + { + alias: "Request", + formula: "query2", + }, + ], + queries: [ + { + dataSource: "metrics", + name: "query2", + query: + "sum:argocd.api_server.redis.request.count{$host,$kube_cluster_name,$kube_namespace} by {host,kube_cluster_name}.as_count()", + }, + ], + responseFormat: "timeseries", + style: { + palette: "dog_classic", + lineType: "solid", + lineWidth: "normal", + }, + displayType: "bars", + }, + ], + }, + layout: { + x: 0, + y: 6, + width: 6, + height: 3, + }, + }, + { + id: 1452795846002068, + definition: { + title: "Number of Failed Redis Requests", + titleSize: "16", + titleAlign: "left", + showLegend: true, + legendLayout: "auto", + legendColumns: ["avg", "min", "max", "value", "sum"], + type: "timeseries", + requests: [ + { + formulas: [ + { + alias: "Number of Requests Failures", + formula: "query2", + }, + ], + queries: [ + { + dataSource: "metrics", + name: "query2", + query: + "sum:argocd.api_server.redis.request.count{failed:true,$host,$kube_cluster_name,$kube_namespace} by {host,kube_cluster_name}.as_count()", + }, + ], + responseFormat: "timeseries", + style: { + palette: "dog_classic", + lineType: "solid", + lineWidth: "normal", + }, + displayType: "bars", + }, + ], + }, + layout: { + x: 6, + y: 6, + width: 6, + height: 3, + }, + }, + { + id: 915681521277132, + definition: { + type: "note", + content: "Repository Server Telemetry", + backgroundColor: "orange", + fontSize: "18", + textAlign: "center", + verticalAlign: "center", + showTick: false, + tickPos: "50%", + tickEdge: "left", + hasPadding: true, + }, + layout: { + x: 0, + y: 9, + width: 12, + height: 1, + }, + }, + { + id: 4222714840704378, + definition: { + title: "Repository Server Memory Usage by Cluster", + titleSize: "16", + titleAlign: "left", + showLegend: true, + legendLayout: "auto", + legendColumns: ["avg", "min", "max", "value", "sum"], + type: "timeseries", + requests: [ + { + formulas: [ + { + alias: "Memory Allocated", + formula: "query1", + }, + ], + queries: [ + { + dataSource: "metrics", + name: "query1", + query: + "avg:argocd.repo_server.go.memstats.heap.alloc_bytes{$host,$kube_cluster_name,$kube_namespace} by {kube_cluster_name,host}", + }, + ], + responseFormat: "timeseries", + style: { + palette: "dog_classic", + lineType: "solid", + lineWidth: "normal", + }, + displayType: "line", + }, + ], + }, + layout: { + x: 0, + y: 10, + width: 4, + height: 3, + }, + }, + { + id: 1739824276453470, + definition: { + title: "Repository Server Goroutines Usage", + titleSize: "16", + titleAlign: "left", + showLegend: true, + legendLayout: "auto", + legendColumns: ["avg", "min", "max", "value", "sum"], + type: "timeseries", + requests: [ + { + formulas: [ + { + alias: "Goroutines", + formula: "query1", + }, + ], + queries: [ + { + dataSource: "metrics", + name: "query1", + query: + "avg:argocd.repo_server.go.goroutines{$host,$kube_cluster_name,$kube_namespace} by {host,kube_cluster_name}", + }, + ], + responseFormat: "timeseries", + style: { + palette: "dog_classic", + lineType: "solid", + lineWidth: "normal", + }, + displayType: "line", + }, + ], + }, + layout: { + x: 4, + y: 10, + width: 4, + height: 3, + }, + }, + { + id: 7302272394223286, + definition: { + title: "Repository Server CPU Time", + titleSize: "16", + titleAlign: "left", + showLegend: true, + legendLayout: "auto", + legendColumns: ["avg", "min", "max", "value", "sum"], + type: "timeseries", + requests: [ + { + formulas: [ + { + alias: "CPU Time", + formula: "query1", + }, + ], + queries: [ + { + dataSource: "metrics", + name: "query1", + query: + "sum:argocd.repo_server.process.cpu.seconds.count{$host,$kube_cluster_name,$kube_namespace} by {host,kube_cluster_name}.as_count()", + }, + ], + responseFormat: "timeseries", + style: { + palette: "dog_classic", + lineType: "solid", + lineWidth: "normal", + }, + displayType: "line", + }, + ], + }, + layout: { + x: 8, + y: 10, + width: 4, + height: 3, + }, + }, + ], + }, + layout: { + x: 0, + y: 12, + width: 12, + height: 1, + }, + }, + { + id: 5257189791506674, + definition: { + title: "Cluster Stats", + backgroundColor: "vivid_green", + showTitle: true, + type: "group", + layoutType: "ordered", + widgets: [ + { + id: 877335939374388, + definition: { + title: "Count of Cluster Resource Objects", + titleSize: "16", + titleAlign: "left", + showLegend: true, + legendLayout: "auto", + legendColumns: ["avg", "min", "max", "value", "sum"], + type: "timeseries", + requests: [ + { + formulas: [ + { + alias: "API Resource Object", + formula: "query1", + }, + ], + queries: [ + { + dataSource: "metrics", + name: "query1", + query: + "avg:argocd.app_controller.cluster.api.resource_objects{$host,$kube_cluster_name,$kube_namespace} by {host,kube_cluster_name}", + }, + ], + responseFormat: "timeseries", + style: { + palette: "green", + lineType: "solid", + lineWidth: "normal", + }, + displayType: "bars", + }, + ], + }, + layout: { + x: 0, + y: 0, + width: 6, + height: 3, + }, + }, + { + id: 6895703789485698, + definition: { + title: "Count of API Resources", + titleSize: "16", + titleAlign: "left", + showLegend: true, + legendLayout: "auto", + legendColumns: ["avg", "min", "max", "value", "sum"], + type: "timeseries", + requests: [ + { + formulas: [ + { + alias: "API Resource", + formula: "query1", + }, + ], + queries: [ + { + dataSource: "metrics", + name: "query1", + query: + "avg:argocd.app_controller.cluster_api_resources{$host,$kube_cluster_name,$kube_namespace} by {host,kube_cluster_name}", + }, + ], + responseFormat: "timeseries", + style: { + palette: "green", + lineType: "solid", + lineWidth: "normal", + }, + displayType: "bars", + }, + ], + }, + layout: { + x: 6, + y: 0, + width: 6, + height: 3, + }, + }, + { + id: 8008111599023896, + definition: { + title: "Count of Cluster Events", + titleSize: "16", + titleAlign: "left", + showLegend: true, + legendLayout: "auto", + legendColumns: ["avg", "min", "max", "value", "sum"], + type: "timeseries", + requests: [ + { + formulas: [ + { + alias: "Cluster Event", + formula: "query1", + }, + ], + queries: [ + { + dataSource: "metrics", + name: "query1", + query: + "avg:argocd.app_controller.cluster.events.count{$host,$kube_cluster_name,$kube_namespace} by {host,kube_cluster_name}", + }, + ], + responseFormat: "timeseries", + style: { + palette: "green", + lineType: "solid", + lineWidth: "normal", + }, + displayType: "bars", + }, + ], + }, + layout: { + x: 0, + y: 3, + width: 6, + height: 3, + }, + }, + { + id: 1101747570951110, + definition: { + title: "Age of Cluster Cache", + titleSize: "16", + titleAlign: "left", + showLegend: true, + legendLayout: "auto", + legendColumns: ["avg", "min", "max", "value", "sum"], + type: "timeseries", + requests: [ + { + formulas: [ + { + alias: "Cluster Cache Age", + formula: "query1", + }, + ], + queries: [ + { + dataSource: "metrics", + name: "query1", + query: + "avg:argocd.app_controller.cluster.cache.age.seconds{$host,$kube_cluster_name,$kube_namespace} by {host,kube_cluster_name}", + }, + ], + responseFormat: "timeseries", + style: { + palette: "green", + lineType: "solid", + lineWidth: "normal", + }, + displayType: "line", + }, + ], + }, + layout: { + x: 6, + y: 3, + width: 6, + height: 3, + }, + }, + ], + }, + layout: { + x: 0, + y: 13, + width: 12, + height: 7, + isColumnBreak: true, + }, + }, + ], + templateVariables: [ + { + name: "host", + prefix: "host", + availableValues: [], + defaults: ["*"], + }, + { + name: "kube_cluster_name", + prefix: "kube_cluster_name", + availableValues: [], + defaults: ["*"], + }, + { + name: "kube_namespace", + prefix: "kube_namespace", + availableValues: [], + defaults: ["*"], + }, + { + name: "health_status", + prefix: "health_status", + availableValues: [], + defaults: ["*"], + }, + { + name: "repo", + prefix: "repo", + availableValues: [], + defaults: ["*"], + }, + ], + layoutType: "ordered", + notifyList: [], + reflowType: "fixed", + }, + }); + + const dashboardDefinition = JSON.parse( + readFileSync( + pathJoin(__dirname, "fixtures", "argocd-dashboard.json"), + "utf8", + ), + ); + const stackTemplate = Template.fromStack(stack); + // validate dashboard definition against fixture + stackTemplate.hasResourceProperties("Datadog::Dashboards::Dashboard", { + DashboardDefinition: JSON.stringify(dashboardDefinition), + }); +}); diff --git a/test/datadog-monitor.test.ts b/test/datadog-monitor.test.ts index b546bec..fbf47a4 100644 --- a/test/datadog-monitor.test.ts +++ b/test/datadog-monitor.test.ts @@ -1,14 +1,14 @@ -import { Stack } from 'aws-cdk-lib'; -import { Template } from 'aws-cdk-lib/assertions'; -import { DatadogMonitor, MonitorType } from '../src'; +import { Stack } from "aws-cdk-lib"; +import { Template } from "aws-cdk-lib/assertions"; +import { DatadogMonitor, MonitorType } from "../src"; -test('Snapshot test', () => { +test("Snapshot test", () => { const stack = new Stack(); - new DatadogMonitor(stack, 'TestMonitor', { - query: 'avg(last_1h):sum:system.cpu.system{host:host0} > 100', + new DatadogMonitor(stack, "TestMonitor", { + query: "avg(last_1h):sum:system.cpu.system{host:host0} > 100", type: MonitorType.QUERY_ALERT, - name: 'Test Monitor', + name: "Test Monitor", options: { thresholds: { critical: 100, diff --git a/test/datadog-slo.test.ts b/test/datadog-slo.test.ts index fa09f8e..d86a7bb 100644 --- a/test/datadog-slo.test.ts +++ b/test/datadog-slo.test.ts @@ -1,27 +1,27 @@ -import { Stack } from 'aws-cdk-lib'; -import { Template } from 'aws-cdk-lib/assertions'; -import { DatadogSLO, SLOType, TimeframeType } from '../src'; +import { Stack } from "aws-cdk-lib"; +import { Template } from "aws-cdk-lib/assertions"; +import { DatadogSLO, SLOType, TimeframeType } from "../src"; -test('Snapshot test', () => { +test("Snapshot test", () => { const stack = new Stack(); - new DatadogSLO(stack, 'TestSLO', { - name: 'Example-Service-Level-Objective', - description: 'Example SLO', - groups: ['env:test', 'role:mysql'], - tags: ['env:prod', 'app:core'], + new DatadogSLO(stack, "TestSLO", { + name: "Example-Service-Level-Objective", + description: "Example SLO", + groups: ["env:test", "role:mysql"], + tags: ["env:prod", "app:core"], type: SLOType.METRIC, query: { - denominator: 'sum:httpservice.hits{!code:3xx}.as_count()', - numerator: 'sum:httpservice.hits{code:2xx}.as_count()', + denominator: "sum:httpservice.hits{!code:3xx}.as_count()", + numerator: "sum:httpservice.hits{code:2xx}.as_count()", }, thresholds: [ { target: 97.0, - targetDisplay: '97.0', + targetDisplay: "97.0", timeframe: TimeframeType.SEVENDAYS, warning: 98, - warningDisplay: '98.0', + warningDisplay: "98.0", }, ], }); diff --git a/test/fixtures/.gitignore b/test/fixtures/.gitignore new file mode 100644 index 0000000..b5dbe86 --- /dev/null +++ b/test/fixtures/.gitignore @@ -0,0 +1 @@ +*.converted.json diff --git a/test/fixtures/argocd-dashboard.json b/test/fixtures/argocd-dashboard.json new file mode 100644 index 0000000..a3e8bb2 --- /dev/null +++ b/test/fixtures/argocd-dashboard.json @@ -0,0 +1,2380 @@ +{ + "title": "[GNC] Argo CD Overview", + "description": "## Argo CD Overview\n\n### The Argo CD dashboard gives you broad visibility into your Argo CD Clusters\n\nThis dashboard provides a high-level overview of your Argo CD clusters so that you can monitor the deployments, performance, and overall health of a cluster.\n\n### Useful Links\n\n- [Datadog Argo CD Integration Documentation](https://docs.datadoghq.com/integrations/argocd/)\n- [Argo CD Official Documentation](https://argo-cd.readthedocs.io/en/latest/)\n- [Monitoring Argo CD Blogpost](https://www.datadoghq.com/blog/argo-cd-datadog/)\n\nClone this template dashboard to make changes and add your own graph widgets. (cloned)", + "widgets": [ + { + "id": 8741772350597652, + "definition": { + "title": "Overview", + "banner_img": "/static/images/logos/argocd_small.svg", + "show_title": false, + "type": "group", + "layout_type": "ordered", + "widgets": [ + { + "id": 5723783152443636, + "definition": { + "type": "note", + "content": "\n### Useful Links\n- [Datadog Argo CD Integration Documentation](https://docs.datadoghq.com/integrations/argocd/)\n- [Argo CD Official Documentation](https://argo-cd.readthedocs.io/en/latest/)\n- [Monitor Argo CD Blogpost](https://www.datadoghq.com/blog/argo-cd-datadog/)", + "background_color": "transparent", + "font_size": "14", + "text_align": "left", + "vertical_align": "top", + "show_tick": false, + "tick_pos": "50%", + "tick_edge": "left", + "has_padding": true + }, + "layout": { + "x": 0, + "y": 0, + "width": 4, + "height": 2 + } + } + ] + }, + "layout": { + "x": 0, + "y": 0, + "width": 4, + "height": 5 + } + }, + { + "id": 2293131439045202, + "definition": { + "title": "Overview", + "background_color": "vivid_blue", + "show_title": true, + "type": "group", + "layout_type": "ordered", + "widgets": [ + { + "id": 1107851890687136, + "definition": { + "title": "Number of Applications", + "title_size": "16", + "title_align": "left", + "show_legend": true, + "legend_layout": "auto", + "legend_columns": [ + "avg", + "min", + "max", + "value", + "sum" + ], + "type": "timeseries", + "requests": [ + { + "formulas": [ + { + "alias": "Number of Applications", + "formula": "query1" + } + ], + "queries": [ + { + "data_source": "metrics", + "name": "query1", + "query": "sum:argocd.app_controller.app.info{$host,$kube_cluster_name,$health_status,$kube_namespace,$repo} by {host}" + } + ], + "response_format": "timeseries", + "style": { + "palette": "blue", + "line_type": "solid", + "line_width": "normal" + }, + "display_type": "line" + } + ] + }, + "layout": { + "x": 0, + "y": 0, + "width": 4, + "height": 3 + } + }, + { + "id": 148852812141642, + "definition": { + "title": "Containers in ArgoCD namespace by Host", + "title_size": "16", + "title_align": "left", + "type": "hostmap", + "requests": { + "fill": { + "q": "avg:process.stat.container.cpu.user_pct{$kube_cluster_name,$kube_namespace} by {host}" + }, + "size": { + "q": "avg:process.stat.container.memory.rss{$kube_cluster_name,$kube_namespace} by {host}" + } + }, + "node_type": "container", + "no_metric_hosts": true, + "no_group_hosts": true, + "group": [ + "host" + ], + "scope": [ + "$kube_cluster_name", + "$kube_namespace" + ], + "style": { + "palette": "green_to_orange", + "palette_flip": false + } + }, + "layout": { + "x": 4, + "y": 0, + "width": 4, + "height": 3 + } + }, + { + "id": 8391951914104866, + "definition": { + "title": "App Controllers", + "title_size": "16", + "title_align": "left", + "type": "query_value", + "requests": [ + { + "formulas": [ + { + "formula": "query1" + } + ], + "queries": [ + { + "aggregator": "max", + "data_source": "metrics", + "name": "query1", + "query": "count:argocd.app_controller.go.goroutines{$host,$kube_cluster_name,$kube_namespace}" + } + ], + "response_format": "scalar" + } + ], + "autoscale": true, + "precision": 2 + }, + "layout": { + "x": 0, + "y": 3, + "width": 2, + "height": 1 + } + }, + { + "id": 3088551287926924, + "definition": { + "title": "AppSet Controllers (pending)", + "title_size": "16", + "title_align": "left", + "type": "query_value", + "requests": [ + { + "formulas": [ + { + "formula": "query1" + } + ], + "queries": [ + { + "aggregator": "max", + "data_source": "metrics", + "name": "query1", + "query": "count:argocd.app_controller.go.goroutines{$host,$kube_cluster_name,$kube_namespace}" + } + ], + "response_format": "scalar" + } + ], + "autoscale": true, + "precision": 2 + }, + "layout": { + "x": 2, + "y": 3, + "width": 2, + "height": 1 + } + }, + { + "id": 3083362413703058, + "definition": { + "title": "Repository Servers", + "title_size": "16", + "title_align": "left", + "type": "query_value", + "requests": [ + { + "formulas": [ + { + "formula": "query1" + } + ], + "queries": [ + { + "aggregator": "max", + "data_source": "metrics", + "name": "query1", + "query": "count:argocd.repo_server.go.goroutines{$host,$kube_cluster_name,$kube_namespace}" + } + ], + "response_format": "scalar" + } + ], + "autoscale": true, + "precision": 2 + }, + "layout": { + "x": 4, + "y": 3, + "width": 2, + "height": 1 + } + }, + { + "id": 2764269609392968, + "definition": { + "title": "API Servers", + "title_size": "16", + "title_align": "left", + "type": "query_value", + "requests": [ + { + "formulas": [ + { + "formula": "query1" + } + ], + "queries": [ + { + "aggregator": "max", + "data_source": "metrics", + "name": "query1", + "query": "count:argocd.api_server.go.goroutines{$host,$kube_cluster_name,$kube_namespace}" + } + ], + "response_format": "scalar" + } + ], + "autoscale": true, + "precision": 2 + }, + "layout": { + "x": 6, + "y": 3, + "width": 2, + "height": 1 + } + } + ] + }, + "layout": { + "x": 4, + "y": 0, + "width": 8, + "height": 5 + } + }, + { + "id": 5039638453713644, + "definition": { + "title": "Logs", + "background_color": "vivid_blue", + "show_title": true, + "type": "group", + "layout_type": "ordered", + "widgets": [ + { + "id": 7799454257481500, + "definition": { + "title": "", + "title_size": "16", + "title_align": "left", + "requests": [ + { + "response_format": "event_list", + "query": { + "data_source": "logs_pattern_stream", + "query_string": "status:error source:argocd", + "indexes": [], + "group_by": [ + { + "facet": "service" + } + ] + }, + "columns": [ + { + "field": "status_line", + "width": "auto" + }, + { + "field": "matches", + "width": "auto" + }, + { + "field": "volume", + "width": "auto" + }, + { + "field": "service", + "width": "auto" + }, + { + "field": "message", + "width": "auto" + } + ] + } + ], + "type": "list_stream" + }, + "layout": { + "x": 0, + "y": 0, + "width": 12, + "height": 3 + } + } + ] + }, + "layout": { + "x": 0, + "y": 5, + "width": 12, + "height": 4 + } + }, + { + "id": 3103904444573384, + "definition": { + "title": "Application Status", + "background_color": "vivid_green", + "show_title": true, + "type": "group", + "layout_type": "ordered", + "widgets": [ + { + "id": 4761912700194790, + "definition": { + "title": "Applications by Repositories", + "title_size": "16", + "title_align": "left", + "requests": [ + { + "formulas": [ + { + "formula": "query1" + } + ], + "queries": [ + { + "aggregator": "avg", + "data_source": "metrics", + "name": "query1", + "query": "count:argocd.app_controller.app.info{$host,$kube_cluster_name,$health_status,$kube_namespace,$repo} by {repo,host,name}" + } + ], + "response_format": "scalar" + } + ], + "type": "sunburst", + "hide_total": false, + "legend": { + "type": "table" + } + }, + "layout": { + "x": 0, + "y": 0, + "width": 12, + "height": 4 + } + }, + { + "id": 7617765285986134, + "definition": { + "title": "Number of Applications", + "title_size": "16", + "title_align": "left", + "show_legend": true, + "legend_layout": "horizontal", + "legend_columns": [ + "avg", + "min", + "max", + "value", + "sum" + ], + "type": "timeseries", + "requests": [ + { + "formulas": [ + { + "alias": "Number of Applications", + "formula": "query1" + } + ], + "queries": [ + { + "data_source": "metrics", + "name": "query1", + "query": "sum:argocd.app_controller.app.info{$host,$kube_cluster_name,$health_status,$kube_namespace,$repo} by {sync_status}" + } + ], + "response_format": "timeseries", + "style": { + "palette": "dog_classic", + "line_type": "solid", + "line_width": "normal" + }, + "display_type": "bars" + } + ] + }, + "layout": { + "x": 0, + "y": 4, + "width": 6, + "height": 3 + } + }, + { + "id": 8732078285048376, + "definition": { + "title": "Applications Not in Sync by Sync_Status & Host", + "title_size": "16", + "title_align": "left", + "show_legend": true, + "legend_layout": "auto", + "legend_columns": [ + "avg", + "min", + "max", + "value", + "sum" + ], + "type": "timeseries", + "requests": [ + { + "formulas": [ + { + "alias": "Application not Synced", + "formula": "query1" + } + ], + "queries": [ + { + "data_source": "metrics", + "name": "query1", + "query": "sum:argocd.app_controller.app.info{!sync_status:synced,$host,$kube_cluster_name,$health_status,$kube_namespace,$repo} by {sync_status,host,name}" + } + ], + "response_format": "timeseries", + "style": { + "palette": "dog_classic", + "line_type": "solid", + "line_width": "normal" + }, + "display_type": "bars" + } + ] + }, + "layout": { + "x": 6, + "y": 4, + "width": 6, + "height": 3 + } + }, + { + "id": 4491005302659932, + "definition": { + "title": "Number of Application Syncs", + "title_size": "16", + "title_align": "left", + "show_legend": true, + "legend_layout": "auto", + "legend_columns": [ + "avg", + "min", + "max", + "value", + "sum" + ], + "type": "timeseries", + "requests": [ + { + "formulas": [ + { + "alias": "Application Syncs", + "formula": "query1" + } + ], + "queries": [ + { + "data_source": "metrics", + "name": "query1", + "query": "sum:argocd.app_controller.app.sync.count{$host,$kube_cluster_name,$health_status,$kube_namespace,$repo} by {host}.as_count()" + } + ], + "response_format": "timeseries", + "style": { + "palette": "blue", + "line_type": "solid", + "line_width": "normal" + }, + "display_type": "bars" + } + ] + }, + "layout": { + "x": 0, + "y": 7, + "width": 6, + "height": 3 + } + }, + { + "id": 3479937394251732, + "definition": { + "title": "Number of Non Successful Application Syncs", + "title_size": "16", + "title_align": "left", + "show_legend": true, + "legend_layout": "auto", + "legend_columns": [ + "avg", + "min", + "max", + "value", + "sum" + ], + "type": "timeseries", + "requests": [ + { + "formulas": [ + { + "alias": "Unsuccessful Syncs", + "formula": "query1" + } + ], + "queries": [ + { + "data_source": "metrics", + "name": "query1", + "query": "sum:argocd.app_controller.app.sync.count{!phase:succeeded,$host,$kube_cluster_name,$health_status,$kube_namespace,$repo} by {phase,host}.as_count()" + } + ], + "response_format": "timeseries", + "style": { + "palette": "blue", + "line_type": "solid", + "line_width": "normal" + }, + "display_type": "bars" + } + ] + }, + "layout": { + "x": 6, + "y": 7, + "width": 6, + "height": 3 + } + }, + { + "id": 2091528630387406, + "definition": { + "type": "note", + "content": "Application Controller Telemetry", + "background_color": "green", + "font_size": "18", + "text_align": "center", + "vertical_align": "center", + "show_tick": false, + "tick_pos": "50%", + "tick_edge": "left", + "has_padding": true + }, + "layout": { + "x": 0, + "y": 10, + "width": 12, + "height": 1 + } + }, + { + "id": 4927792811835832, + "definition": { + "title": "Application Controller Memory Usage by Cluster", + "title_size": "16", + "title_align": "left", + "show_legend": true, + "legend_layout": "auto", + "legend_columns": [ + "avg", + "min", + "max", + "value", + "sum" + ], + "type": "timeseries", + "requests": [ + { + "formulas": [ + { + "alias": "Memory Allocated", + "formula": "query1" + } + ], + "queries": [ + { + "data_source": "metrics", + "name": "query1", + "query": "avg:argocd.app_controller.go.memstats.heap.alloc_bytes{$host,$kube_cluster_name,$kube_namespace} by {cluster_name,host}" + } + ], + "response_format": "timeseries", + "style": { + "palette": "dog_classic", + "line_type": "solid", + "line_width": "normal" + }, + "display_type": "line" + } + ] + }, + "layout": { + "x": 0, + "y": 11, + "width": 4, + "height": 3 + } + }, + { + "id": 6525343257017112, + "definition": { + "title": "Application Controller Goroutines Usage by Cluster", + "title_size": "16", + "title_align": "left", + "show_legend": true, + "legend_layout": "auto", + "legend_columns": [ + "avg", + "min", + "max", + "value", + "sum" + ], + "type": "timeseries", + "requests": [ + { + "formulas": [ + { + "alias": "Goroutines", + "formula": "query1" + } + ], + "queries": [ + { + "data_source": "metrics", + "name": "query1", + "query": "avg:argocd.app_controller.go.goroutines{$host,$kube_cluster_name,$kube_namespace} by {kube_namespace,host}" + } + ], + "response_format": "timeseries", + "style": { + "palette": "dog_classic", + "line_type": "solid", + "line_width": "normal" + }, + "display_type": "line" + } + ] + }, + "layout": { + "x": 4, + "y": 11, + "width": 4, + "height": 3 + } + }, + { + "id": 3471621043457984, + "definition": { + "title": "Application Controller CPU Time by Cluster", + "title_size": "16", + "title_align": "left", + "show_legend": true, + "legend_layout": "auto", + "legend_columns": [ + "avg", + "min", + "max", + "value", + "sum" + ], + "type": "timeseries", + "requests": [ + { + "formulas": [ + { + "alias": "CPU Time", + "formula": "query1" + } + ], + "queries": [ + { + "data_source": "metrics", + "name": "query1", + "query": "sum:argocd.app_controller.process.cpu.seconds.count{$host,$kube_cluster_name,$kube_namespace} by {kube_namespace,host}.as_count()" + } + ], + "response_format": "timeseries", + "style": { + "palette": "dog_classic", + "line_type": "solid", + "line_width": "normal" + }, + "display_type": "line" + } + ] + }, + "layout": { + "x": 8, + "y": 11, + "width": 4, + "height": 3 + } + } + ] + }, + "layout": { + "x": 0, + "y": 9, + "width": 12, + "height": 1 + } + }, + { + "id": 8970831812548910, + "definition": { + "title": "Controller Stats", + "background_color": "vivid_orange", + "show_title": true, + "type": "group", + "layout_type": "ordered", + "widgets": [ + { + "id": 1683090577470882, + "definition": { + "title": "Count of Application Reconciliation", + "title_size": "16", + "title_align": "left", + "show_legend": true, + "legend_layout": "auto", + "legend_columns": [ + "avg", + "min", + "max", + "value", + "sum" + ], + "type": "timeseries", + "requests": [ + { + "formulas": [ + { + "alias": "Application Reconciliation", + "formula": "query1" + } + ], + "queries": [ + { + "data_source": "metrics", + "name": "query1", + "query": "sum:argocd.app_controller.app.reconcile.count{$host,$kube_cluster_name,$kube_namespace} by {namespace,host}.as_count()" + } + ], + "response_format": "timeseries", + "style": { + "palette": "orange", + "line_type": "solid", + "line_width": "normal" + }, + "display_type": "bars" + } + ] + }, + "layout": { + "x": 0, + "y": 0, + "width": 6, + "height": 3 + } + }, + { + "id": 2882037992742898, + "definition": { + "title": "Count of Application Reconciliation by Duration Bounds", + "title_size": "16", + "title_align": "left", + "show_legend": true, + "legend_layout": "auto", + "legend_columns": [ + "avg", + "min", + "max", + "value", + "sum" + ], + "type": "timeseries", + "requests": [ + { + "formulas": [ + { + "alias": "Reconciliation Duration", + "formula": "query1" + } + ], + "queries": [ + { + "data_source": "metrics", + "name": "query1", + "query": "sum:argocd.app_controller.app.reconcile.bucket{$host,$kube_cluster_name,$kube_namespace} by {upper_bound,host}.as_count()" + } + ], + "response_format": "timeseries", + "style": { + "palette": "orange", + "line_type": "solid", + "line_width": "normal" + }, + "display_type": "bars" + } + ] + }, + "layout": { + "x": 6, + "y": 0, + "width": 6, + "height": 3 + } + }, + { + "id": 2092421836560578, + "definition": { + "title": "Depth of the Workqueue", + "title_size": "16", + "title_align": "left", + "show_legend": true, + "legend_layout": "auto", + "legend_columns": [ + "avg", + "min", + "max", + "value", + "sum" + ], + "type": "timeseries", + "requests": [ + { + "formulas": [ + { + "alias": "Workqueue depth", + "formula": "query1" + } + ], + "queries": [ + { + "data_source": "metrics", + "name": "query1", + "query": "sum:argocd.app_controller.workqueue.depth{$host,$kube_cluster_name,$kube_namespace} by {host,kube_cluster_name}" + } + ], + "response_format": "timeseries", + "style": { + "palette": "orange" + }, + "display_type": "bars" + } + ], + "yaxis": { + "include_zero": true, + "scale": "linear", + "min": "auto", + "max": "auto" + } + }, + "layout": { + "x": 0, + "y": 3, + "width": 6, + "height": 3 + } + }, + { + "id": 4125569125075486, + "definition": { + "title": "Count of Kubernetes Requests Executed", + "title_size": "16", + "title_align": "left", + "show_legend": true, + "legend_layout": "auto", + "legend_columns": [ + "avg", + "min", + "max", + "value", + "sum" + ], + "type": "timeseries", + "requests": [ + { + "formulas": [ + { + "alias": "Kubectl Request Executed", + "formula": "query1" + } + ], + "queries": [ + { + "data_source": "metrics", + "name": "query1", + "query": "sum:argocd.app_controller.app.k8s.request.count{$host,$kube_cluster_name,$kube_namespace} by {host,kube_cluster_name}.as_count()" + } + ], + "response_format": "timeseries", + "style": { + "palette": "orange" + }, + "display_type": "bars" + } + ], + "yaxis": { + "include_zero": true, + "scale": "linear", + "min": "auto", + "max": "auto" + } + }, + "layout": { + "x": 6, + "y": 3, + "width": 6, + "height": 3 + } + }, + { + "id": 6916335121689932, + "definition": { + "title": "Count of Kubectl Executions", + "title_size": "16", + "title_align": "left", + "show_legend": true, + "legend_layout": "auto", + "legend_columns": [ + "avg", + "min", + "max", + "value", + "sum" + ], + "type": "timeseries", + "requests": [ + { + "formulas": [ + { + "alias": "Kubectl Execution", + "formula": "query1" + } + ], + "queries": [ + { + "data_source": "metrics", + "name": "query1", + "query": "sum:argocd.app_controller.kubectl.exec.count{$host,$kube_cluster_name,$kube_namespace} by {host,kube_cluster_name}.as_count()" + } + ], + "response_format": "timeseries", + "style": { + "palette": "orange" + }, + "display_type": "bars" + } + ], + "yaxis": { + "include_zero": true, + "scale": "linear", + "min": "auto", + "max": "auto" + } + }, + "layout": { + "x": 0, + "y": 6, + "width": 6, + "height": 3 + } + }, + { + "id": 1713544962494578, + "definition": { + "title": "Count of Pending Kubectl Executions", + "title_size": "16", + "title_align": "left", + "show_legend": true, + "legend_layout": "auto", + "legend_columns": [ + "avg", + "min", + "max", + "value", + "sum" + ], + "type": "timeseries", + "requests": [ + { + "formulas": [ + { + "alias": "Pending Kubectl Execution", + "formula": "query1" + } + ], + "queries": [ + { + "data_source": "metrics", + "name": "query1", + "query": "sum:argocd.app_controller.kubectl.exec.pending{$host,$kube_cluster_name,$kube_namespace} by {host,kube_cluster_name}" + } + ], + "response_format": "timeseries", + "style": { + "palette": "orange" + }, + "display_type": "bars" + } + ], + "yaxis": { + "include_zero": true, + "scale": "linear", + "min": "auto", + "max": "auto" + } + }, + "layout": { + "x": 6, + "y": 6, + "width": 6, + "height": 3 + } + } + ] + }, + "layout": { + "x": 0, + "y": 10, + "width": 12, + "height": 1 + } + }, + { + "id": 2661663506447074, + "definition": { + "title": "Server Stats", + "background_color": "vivid_purple", + "show_title": true, + "type": "group", + "layout_type": "ordered", + "widgets": [ + { + "id": 7853075716472980, + "definition": { + "title": "Count of Service Requests by Service", + "title_size": "16", + "title_align": "left", + "show_legend": true, + "legend_layout": "auto", + "legend_columns": [ + "avg", + "min", + "max", + "value", + "sum" + ], + "type": "timeseries", + "requests": [ + { + "formulas": [ + { + "alias": "All Service Request", + "formula": "query1" + } + ], + "queries": [ + { + "data_source": "metrics", + "name": "query1", + "query": "sum:argocd.api_server.grpc.server.handled.count{$host,$kube_cluster_name,$kube_namespace} by {grpc_service,kube_cluster_name,host}.as_count()" + } + ], + "response_format": "timeseries", + "style": { + "palette": "purple", + "line_type": "solid", + "line_width": "normal" + }, + "display_type": "bars" + } + ] + }, + "layout": { + "x": 0, + "y": 0, + "width": 6, + "height": 3 + } + }, + { + "id": 2986577135722696, + "definition": { + "title": "Count of Cluster Service Requests", + "title_size": "16", + "title_align": "left", + "show_legend": true, + "legend_layout": "auto", + "legend_columns": [ + "avg", + "min", + "max", + "value", + "sum" + ], + "type": "timeseries", + "requests": [ + { + "formulas": [ + { + "alias": "Cluster Service Request", + "formula": "query1" + } + ], + "queries": [ + { + "data_source": "metrics", + "name": "query1", + "query": "sum:argocd.api_server.grpc.server.handled.count{grpc_service:cluster.clusterservice,$host,$kube_cluster_name,$kube_namespace} by {grpc_code,grpc_method,host,kube_cluster_name}.as_count()" + } + ], + "response_format": "timeseries", + "style": { + "palette": "purple", + "line_type": "solid", + "line_width": "normal" + }, + "display_type": "bars" + } + ] + }, + "layout": { + "x": 6, + "y": 0, + "width": 6, + "height": 3 + } + }, + { + "id": 4161309530762940, + "definition": { + "title": "Count of Application Service Requests", + "title_size": "16", + "title_align": "left", + "show_legend": true, + "legend_layout": "auto", + "legend_columns": [ + "avg", + "min", + "max", + "value", + "sum" + ], + "type": "timeseries", + "requests": [ + { + "formulas": [ + { + "alias": "Application Service Request", + "formula": "query1" + } + ], + "queries": [ + { + "data_source": "metrics", + "name": "query1", + "query": "sum:argocd.api_server.grpc.server.handled.count{grpc_service:application.applicationservice,$host,$kube_cluster_name,$kube_namespace} by {grpc_code,grpc_method,host,kube_cluster_name}.as_count()" + } + ], + "response_format": "timeseries", + "style": { + "palette": "purple", + "line_type": "solid", + "line_width": "normal" + }, + "display_type": "bars" + } + ] + }, + "layout": { + "x": 0, + "y": 3, + "width": 6, + "height": 3 + } + }, + { + "id": 3346295316212716, + "definition": { + "title": "Count of Repository Service Requests", + "title_size": "16", + "title_align": "left", + "show_legend": true, + "legend_layout": "auto", + "legend_columns": [ + "avg", + "min", + "max", + "value", + "sum" + ], + "type": "timeseries", + "requests": [ + { + "formulas": [ + { + "alias": "Repository Service Request", + "formula": "query1" + } + ], + "queries": [ + { + "data_source": "metrics", + "name": "query1", + "query": "sum:argocd.api_server.grpc.server.handled.count{grpc_service:repository.repositoryservice,$host,$kube_cluster_name,$kube_namespace} by {grpc_code,grpc_method,kube_cluster_name,host}.as_count()" + } + ], + "response_format": "timeseries", + "style": { + "palette": "purple", + "line_type": "solid", + "line_width": "normal" + }, + "display_type": "bars" + } + ] + }, + "layout": { + "x": 6, + "y": 3, + "width": 6, + "height": 3 + } + }, + { + "id": 251735075640654, + "definition": { + "title": "Count of Session Service Requests", + "title_size": "16", + "title_align": "left", + "show_legend": true, + "legend_layout": "auto", + "legend_columns": [ + "avg", + "min", + "max", + "value", + "sum" + ], + "type": "timeseries", + "requests": [ + { + "formulas": [ + { + "alias": "Session Service Request", + "formula": "query1" + } + ], + "queries": [ + { + "data_source": "metrics", + "name": "query1", + "query": "sum:argocd.api_server.grpc.server.handled.count{grpc_service:session.sessionservice,$host,$kube_cluster_name,$kube_namespace} by {grpc_code,grpc_method,kube_cluster_name,host}.as_count()" + } + ], + "response_format": "timeseries", + "style": { + "palette": "purple", + "line_type": "solid", + "line_width": "normal" + }, + "display_type": "bars" + } + ] + }, + "layout": { + "x": 0, + "y": 6, + "width": 6, + "height": 3 + } + }, + { + "id": 6377937600157456, + "definition": { + "title": "Count of Version Service Requests", + "title_size": "16", + "title_align": "left", + "show_legend": true, + "legend_layout": "auto", + "legend_columns": [ + "avg", + "min", + "max", + "value", + "sum" + ], + "type": "timeseries", + "requests": [ + { + "formulas": [ + { + "alias": "Version Service Request", + "formula": "query1" + } + ], + "queries": [ + { + "data_source": "metrics", + "name": "query1", + "query": "sum:argocd.api_server.grpc.server.handled.count{grpc_service:version.versionservice,$host,$kube_cluster_name,$kube_namespace} by {grpc_code,grpc_method,kube_cluster_name}.as_count()" + } + ], + "response_format": "timeseries", + "style": { + "palette": "purple", + "line_type": "solid", + "line_width": "normal" + }, + "display_type": "bars" + } + ] + }, + "layout": { + "x": 6, + "y": 6, + "width": 6, + "height": 3 + } + }, + { + "id": 8207475356653118, + "definition": { + "title": "Count of Account Service Requests", + "title_size": "16", + "title_align": "left", + "show_legend": true, + "legend_layout": "auto", + "legend_columns": [ + "avg", + "min", + "max", + "value", + "sum" + ], + "type": "timeseries", + "requests": [ + { + "formulas": [ + { + "alias": "Account Service Request", + "formula": "query1" + } + ], + "queries": [ + { + "data_source": "metrics", + "name": "query1", + "query": "sum:argocd.api_server.grpc.server.handled.count{grpc_service:account.accountservice,$host,$kube_cluster_name,$kube_namespace} by {grpc_code,grpc_method,kube_cluster_name,host}.as_count()" + } + ], + "response_format": "timeseries", + "style": { + "palette": "purple", + "line_type": "solid", + "line_width": "normal" + }, + "display_type": "bars" + } + ] + }, + "layout": { + "x": 0, + "y": 9, + "width": 6, + "height": 3 + } + }, + { + "id": 5496058710860268, + "definition": { + "title": "Count of Settings Service Requests", + "title_size": "16", + "title_align": "left", + "show_legend": true, + "legend_layout": "auto", + "legend_columns": [ + "avg", + "min", + "max", + "value", + "sum" + ], + "type": "timeseries", + "requests": [ + { + "formulas": [ + { + "alias": "Settings Service Request ", + "formula": "query1" + } + ], + "queries": [ + { + "data_source": "metrics", + "name": "query1", + "query": "sum:argocd.api_server.grpc.server.handled.count{grpc_service:cluster.settingsservice,$host,$kube_cluster_name,$kube_namespace} by {grpc_code,grpc_method,host,kube_cluster_name}.as_count()" + } + ], + "response_format": "timeseries", + "style": { + "palette": "purple", + "line_type": "solid", + "line_width": "normal" + }, + "display_type": "bars" + } + ] + }, + "layout": { + "x": 6, + "y": 9, + "width": 6, + "height": 3 + } + }, + { + "id": 3658743930291138, + "definition": { + "type": "note", + "content": "API Server Telemetry", + "background_color": "purple", + "font_size": "18", + "text_align": "center", + "vertical_align": "center", + "show_tick": false, + "tick_pos": "50%", + "tick_edge": "left", + "has_padding": true + }, + "layout": { + "x": 0, + "y": 12, + "width": 12, + "height": 1 + } + }, + { + "id": 5099362422931018, + "definition": { + "title": "API Server Memory Usage by Cluster", + "title_size": "16", + "title_align": "left", + "show_legend": true, + "legend_layout": "auto", + "legend_columns": [ + "avg", + "min", + "max", + "value", + "sum" + ], + "type": "timeseries", + "requests": [ + { + "formulas": [ + { + "alias": "Memory Allocated", + "formula": "query1" + } + ], + "queries": [ + { + "data_source": "metrics", + "name": "query1", + "query": "avg:argocd.api_server.go.memstats.heap.alloc_bytes{$host,$kube_cluster_name,$kube_namespace} by {host,kube_cluster_name}" + } + ], + "response_format": "timeseries", + "style": { + "palette": "dog_classic", + "line_type": "solid", + "line_width": "normal" + }, + "display_type": "line" + } + ] + }, + "layout": { + "x": 0, + "y": 13, + "width": 4, + "height": 3 + } + }, + { + "id": 5166753638637396, + "definition": { + "title": "API Server Goroutines Usage by Cluster", + "title_size": "16", + "title_align": "left", + "show_legend": true, + "legend_layout": "auto", + "legend_columns": [ + "avg", + "min", + "max", + "value", + "sum" + ], + "type": "timeseries", + "requests": [ + { + "formulas": [ + { + "alias": "Goroutines", + "formula": "query1" + } + ], + "queries": [ + { + "data_source": "metrics", + "name": "query1", + "query": "avg:argocd.api_server.go.goroutines{$host,$kube_cluster_name,$kube_namespace} by {host,kube_cluster_name}" + } + ], + "response_format": "timeseries", + "style": { + "palette": "dog_classic", + "line_type": "solid", + "line_width": "normal" + }, + "display_type": "line" + } + ] + }, + "layout": { + "x": 4, + "y": 13, + "width": 4, + "height": 3 + } + }, + { + "id": 6597509157761322, + "definition": { + "title": "API Server CPU Time by Cluster", + "title_size": "16", + "title_align": "left", + "show_legend": true, + "legend_layout": "auto", + "legend_columns": [ + "avg", + "min", + "max", + "value", + "sum" + ], + "type": "timeseries", + "requests": [ + { + "formulas": [ + { + "alias": "CPU Time", + "formula": "query1" + } + ], + "queries": [ + { + "data_source": "metrics", + "name": "query1", + "query": "sum:argocd.api_server.process.cpu.seconds.count{$host,$kube_cluster_name,$kube_namespace} by {host,kube_cluster_name}.as_count()" + } + ], + "response_format": "timeseries", + "style": { + "palette": "dog_classic", + "line_type": "solid", + "line_width": "normal" + }, + "display_type": "line" + } + ] + }, + "layout": { + "x": 8, + "y": 13, + "width": 4, + "height": 3 + } + } + ] + }, + "layout": { + "x": 0, + "y": 11, + "width": 12, + "height": 1 + } + }, + { + "id": 444244913319832, + "definition": { + "title": "Repository Server Stats", + "background_color": "vivid_orange", + "show_title": true, + "type": "group", + "layout_type": "ordered", + "widgets": [ + { + "id": 8507386561737364, + "definition": { + "title": "Count of Git Ls-Remote Requests", + "title_size": "16", + "title_align": "left", + "show_legend": true, + "legend_layout": "auto", + "legend_columns": [ + "avg", + "min", + "max", + "value", + "sum" + ], + "type": "timeseries", + "requests": [ + { + "formulas": [ + { + "alias": "Ls-remote Request", + "formula": "query1" + } + ], + "queries": [ + { + "data_source": "metrics", + "name": "query1", + "query": "sum:argocd.repo_server.git.request.count{request_type:ls-remote,$host,$kube_cluster_name,$kube_namespace} by {host,kube_cluster_name}.as_count()" + } + ], + "response_format": "timeseries", + "style": { + "palette": "dog_classic", + "line_type": "solid", + "line_width": "normal" + }, + "display_type": "bars" + } + ] + }, + "layout": { + "x": 0, + "y": 0, + "width": 6, + "height": 3 + } + }, + { + "id": 5597200409579852, + "definition": { + "title": "Git Ls-Remote Requests Performance", + "title_size": "16", + "title_align": "left", + "show_legend": true, + "legend_layout": "auto", + "legend_columns": [ + "avg", + "min", + "max", + "value", + "sum" + ], + "type": "timeseries", + "requests": [ + { + "formulas": [ + { + "formula": "query1" + } + ], + "queries": [ + { + "data_source": "metrics", + "name": "query1", + "query": "sum:argocd.repo_server.git.request.duration.seconds.bucket{request_type:ls-remote,$host,$kube_cluster_name,$kube_namespace} by {upper_bound,kube_cluster_name}.as_count()" + } + ], + "response_format": "timeseries", + "style": { + "palette": "dog_classic" + }, + "display_type": "bars" + } + ] + }, + "layout": { + "x": 6, + "y": 0, + "width": 6, + "height": 3 + } + }, + { + "id": 1635931665551580, + "definition": { + "title": "Count of Git Fetch Requests", + "title_size": "16", + "title_align": "left", + "show_legend": true, + "legend_layout": "auto", + "legend_columns": [ + "avg", + "min", + "max", + "value", + "sum" + ], + "type": "timeseries", + "requests": [ + { + "formulas": [ + { + "alias": "Fetch Request", + "formula": "query1" + } + ], + "queries": [ + { + "data_source": "metrics", + "name": "query1", + "query": "sum:argocd.repo_server.git.request.count{request_type:fetch,$host,$kube_cluster_name,$kube_namespace}.as_count()" + } + ], + "response_format": "timeseries", + "style": { + "palette": "dog_classic", + "line_type": "solid", + "line_width": "normal" + }, + "display_type": "bars" + } + ] + }, + "layout": { + "x": 0, + "y": 3, + "width": 6, + "height": 3 + } + }, + { + "id": 1418427818359380, + "definition": { + "title": "Fetch Git Requests Performance", + "title_size": "16", + "title_align": "left", + "show_legend": true, + "legend_layout": "auto", + "legend_columns": [ + "avg", + "min", + "max", + "value", + "sum" + ], + "type": "timeseries", + "requests": [ + { + "formulas": [ + { + "formula": "query1" + } + ], + "queries": [ + { + "data_source": "metrics", + "name": "query1", + "query": "sum:argocd.repo_server.git.request.duration.seconds.bucket{request_type:fetch,kube_cluster_name,$host,$kube_cluster_name,$kube_namespace}.as_count()" + } + ], + "response_format": "timeseries", + "style": { + "palette": "dog_classic" + }, + "display_type": "bars" + } + ] + }, + "layout": { + "x": 6, + "y": 3, + "width": 6, + "height": 3 + } + }, + { + "id": 1888889021360466, + "definition": { + "title": "Count of of Redis Requests", + "title_size": "16", + "title_align": "left", + "show_legend": true, + "legend_layout": "auto", + "legend_columns": [ + "avg", + "min", + "max", + "value", + "sum" + ], + "type": "timeseries", + "requests": [ + { + "formulas": [ + { + "alias": "Request", + "formula": "query2" + } + ], + "queries": [ + { + "data_source": "metrics", + "name": "query2", + "query": "sum:argocd.api_server.redis.request.count{$host,$kube_cluster_name,$kube_namespace} by {host,kube_cluster_name}.as_count()" + } + ], + "response_format": "timeseries", + "style": { + "palette": "dog_classic", + "line_type": "solid", + "line_width": "normal" + }, + "display_type": "bars" + } + ] + }, + "layout": { + "x": 0, + "y": 6, + "width": 6, + "height": 3 + } + }, + { + "id": 1452795846002068, + "definition": { + "title": "Number of Failed Redis Requests", + "title_size": "16", + "title_align": "left", + "show_legend": true, + "legend_layout": "auto", + "legend_columns": [ + "avg", + "min", + "max", + "value", + "sum" + ], + "type": "timeseries", + "requests": [ + { + "formulas": [ + { + "alias": "Number of Requests Failures", + "formula": "query2" + } + ], + "queries": [ + { + "data_source": "metrics", + "name": "query2", + "query": "sum:argocd.api_server.redis.request.count{failed:true,$host,$kube_cluster_name,$kube_namespace} by {host,kube_cluster_name}.as_count()" + } + ], + "response_format": "timeseries", + "style": { + "palette": "dog_classic", + "line_type": "solid", + "line_width": "normal" + }, + "display_type": "bars" + } + ] + }, + "layout": { + "x": 6, + "y": 6, + "width": 6, + "height": 3 + } + }, + { + "id": 915681521277132, + "definition": { + "type": "note", + "content": "Repository Server Telemetry", + "background_color": "orange", + "font_size": "18", + "text_align": "center", + "vertical_align": "center", + "show_tick": false, + "tick_pos": "50%", + "tick_edge": "left", + "has_padding": true + }, + "layout": { + "x": 0, + "y": 9, + "width": 12, + "height": 1 + } + }, + { + "id": 4222714840704378, + "definition": { + "title": "Repository Server Memory Usage by Cluster", + "title_size": "16", + "title_align": "left", + "show_legend": true, + "legend_layout": "auto", + "legend_columns": [ + "avg", + "min", + "max", + "value", + "sum" + ], + "type": "timeseries", + "requests": [ + { + "formulas": [ + { + "alias": "Memory Allocated", + "formula": "query1" + } + ], + "queries": [ + { + "data_source": "metrics", + "name": "query1", + "query": "avg:argocd.repo_server.go.memstats.heap.alloc_bytes{$host,$kube_cluster_name,$kube_namespace} by {kube_cluster_name,host}" + } + ], + "response_format": "timeseries", + "style": { + "palette": "dog_classic", + "line_type": "solid", + "line_width": "normal" + }, + "display_type": "line" + } + ] + }, + "layout": { + "x": 0, + "y": 10, + "width": 4, + "height": 3 + } + }, + { + "id": 1739824276453470, + "definition": { + "title": "Repository Server Goroutines Usage", + "title_size": "16", + "title_align": "left", + "show_legend": true, + "legend_layout": "auto", + "legend_columns": [ + "avg", + "min", + "max", + "value", + "sum" + ], + "type": "timeseries", + "requests": [ + { + "formulas": [ + { + "alias": "Goroutines", + "formula": "query1" + } + ], + "queries": [ + { + "data_source": "metrics", + "name": "query1", + "query": "avg:argocd.repo_server.go.goroutines{$host,$kube_cluster_name,$kube_namespace} by {host,kube_cluster_name}" + } + ], + "response_format": "timeseries", + "style": { + "palette": "dog_classic", + "line_type": "solid", + "line_width": "normal" + }, + "display_type": "line" + } + ] + }, + "layout": { + "x": 4, + "y": 10, + "width": 4, + "height": 3 + } + }, + { + "id": 7302272394223286, + "definition": { + "title": "Repository Server CPU Time", + "title_size": "16", + "title_align": "left", + "show_legend": true, + "legend_layout": "auto", + "legend_columns": [ + "avg", + "min", + "max", + "value", + "sum" + ], + "type": "timeseries", + "requests": [ + { + "formulas": [ + { + "alias": "CPU Time", + "formula": "query1" + } + ], + "queries": [ + { + "data_source": "metrics", + "name": "query1", + "query": "sum:argocd.repo_server.process.cpu.seconds.count{$host,$kube_cluster_name,$kube_namespace} by {host,kube_cluster_name}.as_count()" + } + ], + "response_format": "timeseries", + "style": { + "palette": "dog_classic", + "line_type": "solid", + "line_width": "normal" + }, + "display_type": "line" + } + ] + }, + "layout": { + "x": 8, + "y": 10, + "width": 4, + "height": 3 + } + } + ] + }, + "layout": { + "x": 0, + "y": 12, + "width": 12, + "height": 1 + } + }, + { + "id": 5257189791506674, + "definition": { + "title": "Cluster Stats", + "background_color": "vivid_green", + "show_title": true, + "type": "group", + "layout_type": "ordered", + "widgets": [ + { + "id": 877335939374388, + "definition": { + "title": "Count of Cluster Resource Objects", + "title_size": "16", + "title_align": "left", + "show_legend": true, + "legend_layout": "auto", + "legend_columns": [ + "avg", + "min", + "max", + "value", + "sum" + ], + "type": "timeseries", + "requests": [ + { + "formulas": [ + { + "alias": "API Resource Object", + "formula": "query1" + } + ], + "queries": [ + { + "data_source": "metrics", + "name": "query1", + "query": "avg:argocd.app_controller.cluster.api.resource_objects{$host,$kube_cluster_name,$kube_namespace} by {host,kube_cluster_name}" + } + ], + "response_format": "timeseries", + "style": { + "palette": "green", + "line_type": "solid", + "line_width": "normal" + }, + "display_type": "bars" + } + ] + }, + "layout": { + "x": 0, + "y": 0, + "width": 6, + "height": 3 + } + }, + { + "id": 6895703789485698, + "definition": { + "title": "Count of API Resources", + "title_size": "16", + "title_align": "left", + "show_legend": true, + "legend_layout": "auto", + "legend_columns": [ + "avg", + "min", + "max", + "value", + "sum" + ], + "type": "timeseries", + "requests": [ + { + "formulas": [ + { + "alias": "API Resource", + "formula": "query1" + } + ], + "queries": [ + { + "data_source": "metrics", + "name": "query1", + "query": "avg:argocd.app_controller.cluster_api_resources{$host,$kube_cluster_name,$kube_namespace} by {host,kube_cluster_name}" + } + ], + "response_format": "timeseries", + "style": { + "palette": "green", + "line_type": "solid", + "line_width": "normal" + }, + "display_type": "bars" + } + ] + }, + "layout": { + "x": 6, + "y": 0, + "width": 6, + "height": 3 + } + }, + { + "id": 8008111599023896, + "definition": { + "title": "Count of Cluster Events", + "title_size": "16", + "title_align": "left", + "show_legend": true, + "legend_layout": "auto", + "legend_columns": [ + "avg", + "min", + "max", + "value", + "sum" + ], + "type": "timeseries", + "requests": [ + { + "formulas": [ + { + "alias": "Cluster Event", + "formula": "query1" + } + ], + "queries": [ + { + "data_source": "metrics", + "name": "query1", + "query": "avg:argocd.app_controller.cluster.events.count{$host,$kube_cluster_name,$kube_namespace} by {host,kube_cluster_name}" + } + ], + "response_format": "timeseries", + "style": { + "palette": "green", + "line_type": "solid", + "line_width": "normal" + }, + "display_type": "bars" + } + ] + }, + "layout": { + "x": 0, + "y": 3, + "width": 6, + "height": 3 + } + }, + { + "id": 1101747570951110, + "definition": { + "title": "Age of Cluster Cache", + "title_size": "16", + "title_align": "left", + "show_legend": true, + "legend_layout": "auto", + "legend_columns": [ + "avg", + "min", + "max", + "value", + "sum" + ], + "type": "timeseries", + "requests": [ + { + "formulas": [ + { + "alias": "Cluster Cache Age", + "formula": "query1" + } + ], + "queries": [ + { + "data_source": "metrics", + "name": "query1", + "query": "avg:argocd.app_controller.cluster.cache.age.seconds{$host,$kube_cluster_name,$kube_namespace} by {host,kube_cluster_name}" + } + ], + "response_format": "timeseries", + "style": { + "palette": "green", + "line_type": "solid", + "line_width": "normal" + }, + "display_type": "line" + } + ] + }, + "layout": { + "x": 6, + "y": 3, + "width": 6, + "height": 3 + } + } + ] + }, + "layout": { + "x": 0, + "y": 13, + "width": 12, + "height": 7, + "is_column_break": true + } + } + ], + "template_variables": [ + { + "name": "host", + "prefix": "host", + "available_values": [], + "defaults": [ + "*" + ] + }, + { + "name": "kube_cluster_name", + "prefix": "kube_cluster_name", + "available_values": [], + "defaults": [ + "*" + ] + }, + { + "name": "kube_namespace", + "prefix": "kube_namespace", + "available_values": [], + "defaults": [ + "*" + ] + }, + { + "name": "health_status", + "prefix": "health_status", + "available_values": [], + "defaults": [ + "*" + ] + }, + { + "name": "repo", + "prefix": "repo", + "available_values": [], + "defaults": [ + "*" + ] + } + ], + "layout_type": "ordered", + "notify_list": [], + "reflow_type": "fixed" +} diff --git a/version.json b/version.json deleted file mode 100644 index 275457d..0000000 --- a/version.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "version": "0.0.4" -} diff --git a/yarn.lock b/yarn.lock index 770eaaf..80a1f93 100644 --- a/yarn.lock +++ b/yarn.lock @@ -981,6 +981,18 @@ resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33" integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== +"@pkgr/utils@^2.3.1": + version "2.4.2" + resolved "https://registry.yarnpkg.com/@pkgr/utils/-/utils-2.4.2.tgz#9e638bbe9a6a6f165580dc943f138fd3309a2cbc" + integrity sha512-POgTXhjrTfbTV63DiFXav4lBHiICLKKwDeaKn9Nphwj7WH6m0hMMCaJkMyRWjgtPFyRKRVoMXXjczsTQRDEhYw== + dependencies: + cross-spawn "^7.0.3" + fast-glob "^3.3.0" + is-glob "^4.0.3" + open "^9.1.0" + picocolors "^1.0.0" + tslib "^2.6.0" + "@pnpm/config.env-replace@^1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@pnpm/config.env-replace/-/config.env-replace-1.1.0.tgz#ab29da53df41e8948a00f2433f085f54de8b3a4c" @@ -1708,6 +1720,11 @@ balanced-match@^1.0.0: resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== +big-integer@^1.6.44: + version "1.6.51" + resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.51.tgz#0df92a5d9880560d3ff2d5fd20245c889d130686" + integrity sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg== + boxen@^7.0.0: version "7.1.1" resolved "https://registry.yarnpkg.com/boxen/-/boxen-7.1.1.tgz#f9ba525413c2fec9cdb88987d835c4f7cad9c8f4" @@ -1722,6 +1739,13 @@ boxen@^7.0.0: widest-line "^4.0.1" wrap-ansi "^8.1.0" +bplist-parser@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/bplist-parser/-/bplist-parser-0.2.0.tgz#43a9d183e5bf9d545200ceac3e712f79ebbe8d0e" + integrity sha512-z0M+byMThzQmD9NILRniCUXYsYpjwnlO8N5uCFaCqIOpqRsJCrQL9NK3JsD67CN5a08nF5oIL2bD6loTdHOuKw== + dependencies: + big-integer "^1.6.44" + brace-expansion@^1.1.7: version "1.1.11" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" @@ -1796,6 +1820,13 @@ builtins@^5.0.0: dependencies: semver "^7.0.0" +bundle-name@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/bundle-name/-/bundle-name-3.0.0.tgz#ba59bcc9ac785fb67ccdbf104a2bf60c099f0e1a" + integrity sha512-PKA4BeSvBpQKQ8iPOGCSiell+N8P+Tf1DlwqmYhpe2gAhKPHn8EYOxVT+ShuGmhg8lN8XiSlS80yiExKXrURlw== + dependencies: + run-applescript "^5.0.0" + cacache@^17.0.0: version "17.1.4" resolved "https://registry.yarnpkg.com/cacache/-/cacache-17.1.4.tgz#b3ff381580b47e85c6e64f801101508e26604b35" @@ -1874,15 +1905,10 @@ camelcase@^7.0.1: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-7.0.1.tgz#f02e50af9fd7782bc8b88a3558c32fd3a388f048" integrity sha512-xlx1yCK2Oc1APsPXDL2LdlNP6+uu8OCDdhOBSVT279M/S+y75O30C2VuD8T2ogdePBBl7PfPF4504tnLgX3zfw== -caniuse-lite@^1.0.30001274: - version "1.0.30001278" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001278.tgz#51cafc858df77d966b17f59b5839250b24417fff" - integrity sha512-mpF9KeH8u5cMoEmIic/cr7PNS+F5LWBk0t2ekGT60lFf0Wq+n9LspAj0g3P+o7DQhD3sUdlMln4YFAWhFYn9jg== - -caniuse-lite@^1.0.30001517: - version "1.0.30001524" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001524.tgz#1e14bce4f43c41a7deaeb5ebfe86664fe8dadb80" - integrity sha512-Jj917pJtYg9HSJBF95HVX3Cdr89JUyLT4IZ8SvM5aDRni95swKgYi3TgYLH5hnGfPE/U1dg6IfZ50UsIlLkwSA== +caniuse-lite@^1.0.30001274, caniuse-lite@^1.0.30001517: + version "1.0.30001527" + resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001527.tgz" + integrity sha512-YkJi7RwPgWtXVSgK4lG9AHH57nSzvvOp9MesgXmw4Q7n0C3H04L0foHqfxcmSAm5AcWb8dW9AYj2tR7/5GnddQ== case@1.6.3, case@^1.6.3: version "1.6.3" @@ -2445,11 +2471,34 @@ deepmerge@^4.2.2: resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955" integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg== +default-browser-id@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/default-browser-id/-/default-browser-id-3.0.0.tgz#bee7bbbef1f4e75d31f98f4d3f1556a14cea790c" + integrity sha512-OZ1y3y0SqSICtE8DE4S8YOE9UZOJ8wO16fKWVP5J1Qz42kV9jcnMVFrEE/noXb/ss3Q4pZIH79kxofzyNNtUNA== + dependencies: + bplist-parser "^0.2.0" + untildify "^4.0.0" + +default-browser@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/default-browser/-/default-browser-4.0.0.tgz#53c9894f8810bf86696de117a6ce9085a3cbc7da" + integrity sha512-wX5pXO1+BrhMkSbROFsyxUm0i/cJEScyNhA4PPxc41ICuv05ZZB/MX28s8aZx6xjmatvebIapF6hLEKEcpneUA== + dependencies: + bundle-name "^3.0.0" + default-browser-id "^3.0.0" + execa "^7.1.1" + titleize "^3.0.0" + defer-to-connect@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-2.0.1.tgz#8016bdb4143e4632b77a3449c6236277de520587" integrity sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg== +define-lazy-prop@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz#dbb19adfb746d7fc6d734a06b72f4a00d021255f" + integrity sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg== + define-properties@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" @@ -2723,6 +2772,11 @@ escodegen@^2.0.0: optionalDependencies: source-map "~0.6.1" +eslint-config-prettier@^9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-9.0.0.tgz#eb25485946dd0c66cd216a46232dc05451518d1f" + integrity sha512-IcJsTkJae2S35pRsRAwoCE+925rJJStOdkKnLVgtE+tEpqU0EVVM7OqrwxqgptKdX29NUwC82I5pXsGFIgSevw== + eslint-import-resolver-node@^0.3.6: version "0.3.6" resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz#4048b958395da89668252001dbd9eca6b83bacbd" @@ -2770,6 +2824,14 @@ eslint-plugin-import@^2.25.2: resolve "^1.20.0" tsconfig-paths "^3.11.0" +eslint-plugin-prettier@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-5.0.0.tgz#6887780ed95f7708340ec79acfdf60c35b9be57a" + integrity sha512-AgaZCVuYDXHUGxj/ZGu1u8H8CYgDY3iG6w5kUFw4AzMVXzB7VvbKgYR4nATIN+OvUrghMbiDLeimVjVY5ilq3w== + dependencies: + prettier-linter-helpers "^1.0.0" + synckit "^0.8.5" + eslint-scope@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" @@ -2900,6 +2962,21 @@ execa@^5.0.0: signal-exit "^3.0.3" strip-final-newline "^2.0.0" +execa@^7.1.1: + version "7.2.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-7.2.0.tgz#657e75ba984f42a70f38928cedc87d6f2d4fe4e9" + integrity sha512-UduyVP7TLB5IcAQl+OzLyLcS/l32W/GLg+AhHJ+ow40FOk2U3SAllPwR44v4vmdFwIWqpdwxxpQbF1n5ta9seA== + dependencies: + cross-spawn "^7.0.3" + get-stream "^6.0.1" + human-signals "^4.3.0" + is-stream "^3.0.0" + merge-stream "^2.0.0" + npm-run-path "^5.1.0" + onetime "^6.0.0" + signal-exit "^3.0.7" + strip-final-newline "^3.0.0" + exit@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" @@ -2932,6 +3009,11 @@ fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== +fast-diff@^1.1.2: + version "1.3.0" + resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.3.0.tgz#ece407fa550a64d638536cd727e129c61616e0f0" + integrity sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw== + fast-glob@^3.1.1: version "3.2.7" resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.7.tgz#fd6cb7a2d7e9aa7a7846111e85a196d6b2f766a1" @@ -2943,7 +3025,7 @@ fast-glob@^3.1.1: merge2 "^1.3.0" micromatch "^4.0.4" -fast-glob@^3.2.9, fast-glob@^3.3.1: +fast-glob@^3.2.9, fast-glob@^3.3.0, fast-glob@^3.3.1: version "3.3.1" resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.1.tgz#784b4e897340f3dbbef17413b3f11acf03c874c4" integrity sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg== @@ -3557,6 +3639,11 @@ human-signals@^2.1.0: resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== +human-signals@^4.3.0: + version "4.3.1" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-4.3.1.tgz#ab7f811e851fca97ffbd2c1fe9a958964de321b2" + integrity sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ== + humanize-ms@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/humanize-ms/-/humanize-ms-1.2.1.tgz#c46e3159a293f6b896da29316d8b6fe8bb79bbed" @@ -3726,6 +3813,16 @@ is-date-object@^1.0.1: dependencies: has-tostringtag "^1.0.0" +is-docker@^2.0.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" + integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== + +is-docker@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-3.0.0.tgz#90093aa3106277d8a77a5910dbae71747e15a200" + integrity sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ== + is-extglob@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" @@ -3748,6 +3845,13 @@ is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3: dependencies: is-extglob "^2.1.1" +is-inside-container@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-inside-container/-/is-inside-container-1.0.0.tgz#e81fba699662eb31dbdaf26766a61d4814717ea4" + integrity sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA== + dependencies: + is-docker "^3.0.0" + is-installed-globally@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-0.4.0.tgz#9a0fd407949c30f86eb6959ef1b7994ed0b7b520" @@ -3826,6 +3930,11 @@ is-stream@^2.0.0: resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== +is-stream@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-3.0.0.tgz#e6bfd7aa6bef69f4f472ce9bb681e3e57b4319ac" + integrity sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA== + is-string@^1.0.5, is-string@^1.0.7: version "1.0.7" resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.7.tgz#0dd12bf2006f255bb58f695110eff7491eebc0fd" @@ -3859,6 +3968,13 @@ is-weakref@^1.0.1: dependencies: call-bind "^1.0.0" +is-wsl@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" + integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== + dependencies: + is-docker "^2.0.0" + is-yarn-global@^0.4.0: version "0.4.1" resolved "https://registry.yarnpkg.com/is-yarn-global/-/is-yarn-global-0.4.1.tgz#b312d902b313f81e4eaf98b6361ba2b45cd694bb" @@ -4942,6 +5058,11 @@ mimic-fn@^2.1.0: resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== +mimic-fn@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-4.0.0.tgz#60a90550d5cb0b239cca65d893b1a53b29871ecc" + integrity sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw== + mimic-response@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-3.1.0.tgz#2d1d59af9c1b129815accc2c46a022a5ce1fa3c9" @@ -5317,6 +5438,13 @@ npm-run-path@^4.0.1: dependencies: path-key "^3.0.0" +npm-run-path@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-5.1.0.tgz#bc62f7f3f6952d9894bd08944ba011a6ee7b7e00" + integrity sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q== + dependencies: + path-key "^4.0.0" + npmlog@^6.0.0: version "6.0.2" resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-6.0.2.tgz#c8166017a42f2dea92d6453168dd865186a70830" @@ -5385,6 +5513,13 @@ onetime@^5.1.2: dependencies: mimic-fn "^2.1.0" +onetime@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-6.0.0.tgz#7c24c18ed1fd2e9bca4bd26806a33613c77d34b4" + integrity sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ== + dependencies: + mimic-fn "^4.0.0" + oo-ascii-tree@^1.42.0: version "1.42.0" resolved "https://registry.yarnpkg.com/oo-ascii-tree/-/oo-ascii-tree-1.42.0.tgz#e9ab47834b004ec2789a5e8b3e477b3fac770804" @@ -5395,6 +5530,16 @@ oo-ascii-tree@^1.88.0: resolved "https://registry.yarnpkg.com/oo-ascii-tree/-/oo-ascii-tree-1.88.0.tgz#3ed84cdcaab9e5b7970fcfc2d086c2c069db65b7" integrity sha512-A7m3z7XlUD3DnXSYxWmAdKQTIY6+1JzWS0lhaqgPGhj6g7a/odCsV1ctaRnjJljCB3zQBrbp2QHdYTUsD9AXcQ== +open@^9.1.0: + version "9.1.0" + resolved "https://registry.yarnpkg.com/open/-/open-9.1.0.tgz#684934359c90ad25742f5a26151970ff8c6c80b6" + integrity sha512-OS+QTnw1/4vrf+9hh1jc1jnYjzSG4ttTBB8UxOwAnInG3Uo4ssetzC1ihqaIHjLJnA5GGlRl6QlZXOTQhRBUvg== + dependencies: + default-browser "^4.0.0" + define-lazy-prop "^3.0.0" + is-inside-container "^1.0.0" + is-wsl "^2.2.0" + optionator@^0.8.1: version "0.8.3" resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" @@ -5579,6 +5724,11 @@ path-key@^3.0.0, path-key@^3.1.0: resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== +path-key@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-4.0.0.tgz#295588dc3aee64154f877adb9d780b81c554bf18" + integrity sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ== + path-parse@^1.0.6: version "1.0.7" resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" @@ -5653,16 +5803,23 @@ prelude-ls@~1.1.2: resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= -prettier@^2.4.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.4.1.tgz#671e11c89c14a4cfc876ce564106c4a6726c9f5c" - integrity sha512-9fbDAXSBcc6Bs1mZrDYb3XKzDLm4EXXL9sC1LqKP5rZkT6KRr/rf9amVUcODVXgguK/isJz0d0hP72WeaKWsvA== +prettier-linter-helpers@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz#d23d41fe1375646de2d0104d3454a3008802cf7b" + integrity sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w== + dependencies: + fast-diff "^1.1.2" prettier@^2.6.2: version "2.8.8" resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.8.tgz#e8c5d7e98a4305ffe3de2e1fc4aca1a71c28b1da" integrity sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q== +prettier@^3.0.0: + version "3.0.3" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.0.3.tgz#432a51f7ba422d1469096c0fdc28e235db8f9643" + integrity sha512-L/4pUDMxcNa8R/EthV08Zt42WBO4h1rarVtK0K+QJG0X187OLo7l699jWw0GKuwzkPQ//jMFA/8Xm6Fh3J/DAg== + pretty-format@^27.0.0, pretty-format@^27.5.1: version "27.5.1" resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-27.5.1.tgz#2181879fdea51a7a5851fb39d920faa63f01d88e" @@ -6012,6 +6169,13 @@ rimraf@^5.0.1: dependencies: glob "^10.2.5" +run-applescript@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/run-applescript/-/run-applescript-5.0.0.tgz#e11e1c932e055d5c6b40d98374e0268d9b11899c" + integrity sha512-XcT5rBksx1QdIhlFOCtgZkB99ZEouFZ1E2Kc2LHqNW13U3/74YGdkQRmThTwxy4QIyookibDKYZOPqX//6BlAg== + dependencies: + execa "^5.0.0" + run-parallel@^1.1.9: version "1.2.0" resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" @@ -6461,6 +6625,11 @@ strip-final-newline@^2.0.0: resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== +strip-final-newline@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-3.0.0.tgz#52894c313fbff318835280aed60ff71ebf12b8fd" + integrity sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw== + strip-indent@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-3.0.0.tgz#c32e1cee940b6b3432c771bc2c54bcce73cd3001" @@ -6517,6 +6686,14 @@ symbol-tree@^3.2.4: resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== +synckit@^0.8.5: + version "0.8.5" + resolved "https://registry.yarnpkg.com/synckit/-/synckit-0.8.5.tgz#b7f4358f9bb559437f9f167eb6bc46b3c9818fa3" + integrity sha512-L1dapNV6vu2s/4Sputv8xGsCdAVlb5nRDMFU/E27D44l5U6cw1g0dGd45uLc+OXjNMmF4ntiMdCimzcjFKQI8Q== + dependencies: + "@pkgr/utils" "^2.3.1" + tslib "^2.5.0" + table@^6.8.1: version "6.8.1" resolved "https://registry.yarnpkg.com/table/-/table-6.8.1.tgz#ea2b71359fe03b017a5fbc296204471158080bdf" @@ -6614,6 +6791,11 @@ timers-ext@^0.1.7: es5-ext "~0.10.46" next-tick "1" +titleize@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/titleize/-/titleize-3.0.0.tgz#71c12eb7fdd2558aa8a44b0be83b8a76694acd53" + integrity sha512-KxVu8EYHDPBdUYdKZdKtU2aj2XfEx9AfjXxE/Aj0vT06w2icA09Vus1rh6eSu1y01akYg6BjIK/hxyLJINoMLQ== + tmpl@1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.5.tgz#8683e0b902bb9c20c4f726e3c0b69f36518c07cc" @@ -6700,6 +6882,11 @@ tslib@^1.8.1: resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== +tslib@^2.5.0, tslib@^2.6.0: + version "2.6.2" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae" + integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q== + tsutils@^3.21.0: version "3.21.0" resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623"